#include #include using namespace alsk::arg; using namespace alsk::edsl; static int counterDo, counterThen, counterDone; struct Do { void operator()() { ++counterDo; } }; struct Then { void operator()() { ++counterThen; } }; struct Done { void operator()() { ++counterDone; } }; struct Produce0 { int operator()(int x) { return x+1; } }; struct Produce1 { int operator()(int x) { return x-2; } }; struct Consume { int operator()(int x, int y) { return x*y; } }; // TODO? avoid copies so it is truly stateful struct Generate { int value; int operator()(int b) { return ++value+b; } }; struct Transform0 { int operator()(int x) { return x+1; } }; struct Transform1 { int operator()(int x) { return x-2; } }; struct Produce { int operator()(int x, int y) { return x*y; } }; struct Select { int mod; int operator()(int a, int b) { if(a%mod == b%mod) return std::min(a, b); return (a%mod > b%mod)? a : b; } }; TEST_CASE("edsl") { auto aDo = makeOperand(); auto aThen = makeOperand(); auto aDone = makeOperand(); auto aProduce0 = makeOperand(); auto aProduce1 = makeOperand(); auto aConsume = makeOperand(); auto e0 = aDo & (5*aThen) & aDone; using E0 = decltype(e0); using S0 = alsk::S, Done>; using L0 = alsk::L, void()>; auto e1 = 5*(aDo, 2*aThen, aDone); using E1 = decltype(e1); using S1 = alsk::S, Done>>; using L1 = alsk::L, void()>>; auto e2 = link(int)>( link)>(aProduce0), link)>(aProduce1), link, R<0>)>(aConsume) ); SECTION("Construction") { REQUIRE(std::is_same{}); REQUIRE(std::is_same{}); REQUIRE(std::is_same{}); REQUIRE(std::is_same{}); REQUIRE(std::is_same{}); REQUIRE(std::is_same{}); } SECTION("Linking") { { auto f2 = implement(e2); REQUIRE(f2(0) == -2); REQUIRE(f2(2) == 0); REQUIRE(f2(5) == 18); } } SECTION("Setup") { auto f0 = implement(e0); REQUIRE(f0.skeleton.task<1>().n == 5); } SECTION("Check run") { { auto f0 = implement(e0); counterDo = counterThen = counterDone = 0; f0(); REQUIRE(counterDo == 1); REQUIRE(counterThen == 5); REQUIRE(counterDone == 1); } { auto f1 = implement(e1); counterDo = counterThen = counterDone = 0; f1(); REQUIRE(counterDo == 5); REQUIRE(counterThen == 10); REQUIRE(counterDone == 5); } } SECTION("Complex case") { auto generate = makeOperand(); auto transform0 = makeOperand(); auto transform1 = makeOperand(); auto produce = makeOperand(); auto select = makeOperand(); auto innerTask = link(int)>( link)>(generate), link)>(transform0), link)>(transform1), link, R<1>)>(produce) ); auto task = link(10 * link(P<0>)>(innerTask)) ->* select; auto f = implement(task); f.skeleton.select.mod = 5; REQUIRE(f(4) == 18); REQUIRE(f(5) == 28); REQUIRE(f(6) == 40); REQUIRE(f(7) == 54); REQUIRE(f(8) == 70); } }