/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* $Rev$ $Date$ */ /** * Test kernel functions. */ #include #include #include "string.hpp" #include "sstream.hpp" #include "function.hpp" #include "list.hpp" #include "tree.hpp" #include "value.hpp" #include "monad.hpp" #include "dynlib.hpp" #include "perf.hpp" namespace tuscany { const bool ptrPerf() { int x = 1; for (int i = 0; i < 10000; i++) { int* const y = &x; int z = *y + *y; z = z + 1; } return true; } const bool gcptrPerf() { int x = 1; for (int i = 0; i < 10000; i++) { const gc_ptr y = &x; int z = *y + *y; z = z + 1; } return true; } const bool testPtrPerf() { { const gc_scoped_pool gcp; const blambda pp = ptrPerf; cout << "Pointer test " << (time(pp, 5, 10000) / 10000) << " ms" << endl; } { const gc_scoped_pool gcp; const blambda gpp = gcptrPerf; cout << "GC Pointer test " << (time(gpp, 5, 10000) / 10000) << " ms" << endl; } return true; } class incFunctor { public: incFunctor(const int i) : i(i) { } const int operator()(const int x) const { return x + i; } private: const int i; }; const int square(const int x) { return x * x; } const int mapLambda(lambda f, int v) { return f(v); } const lambda mksquare() { return square; } const bool testSizes() { const gc_ptr p(NULL); cout << "sizeof gc_ptr " << sizeof(p) << endl; const lambda sq(square); cout << "sizeof C function lambda " << sizeof(sq) << endl; const lambda incl(incFunctor(10)); cout << "sizeof functor lambda " << sizeof(incl) << endl; const std::function sqf(square); cout << "sizeof C function std::function " << sizeof(sqf) << endl; const std::function incf(incFunctor(10)); cout << "sizeof functor std::function " << sizeof(incf) << endl; const string s("abcd"); cout << "sizeof string " << sizeof(s) << endl; const string v(s); cout << "sizeof val " << sizeof(v) << endl; const list li = cons(2, mklist(3, 4)); cout << "sizeof list " << sizeof(li) << endl; const list ls = cons("a", mklist("b", "c")); cout << "sizeof list " << sizeof(ls) << endl; const list lv = cons("a", mklist("b", "c")); cout << "sizeof list " << sizeof(lv) << endl; return true; } const bool testLambda() { const lambda sq(square); assert(sq(2) == 4); const lambda()> mksq(mksquare); assert(mksq()(2) == 4); assert(mapLambda(sq, 2) == 4); assert(mapLambda(square, 2) == 4); const lambda incf(incFunctor(10)); assert(incf(1) == 11); assert(mapLambda(incf, 1) == 11); assert(mapLambda(incFunctor(10), 1) == 11); const int base = 10; auto incl11 = [base](const int i) { return base + i; }; const lambda incl(incl11); assert(incl(1) == 11); assert(mapLambda(incl, 1) == 11); assert(mapLambda(incl11, 1) == 11); const lambda il(incf); assert(il(1) == 11); const lambda sl(square); assert(sl(2) == 4); return true; } int constructCopiable = 0; int copyCopiable = 0; class Copiable { public: Copiable() { assert(false); } Copiable(const string& s) : s(s) { constructCopiable++; } Copiable(const Copiable& c) : s(c.s) { copyCopiable++; } Copiable& operator=(const Copiable& c) = delete; ~Copiable() { } void doit() const { } private: const string s; }; bool testLambdaRef(const Copiable& c) { [&c] { c.doit(); }(); return true; } bool testLambdaCopy(const Copiable& c) { [c] { c.doit(); }(); return true; } const bool testCopiable() { const Copiable ac = Copiable("assigned"); ac.doit(); assert(constructCopiable = 1); assert(copyCopiable = 1); const Copiable ac2 = []{ return Copiable("returned"); }(); ac2.doit(); assert(constructCopiable = 2); assert(copyCopiable = 2); const Copiable rc = Copiable("captured by ref"); testLambdaRef(rc); assert(constructCopiable = 3); assert(copyCopiable = 3); const Copiable cc = Copiable("captured by value"); testLambdaCopy(cc); assert(constructCopiable = 4); assert(copyCopiable = 5); return true; } const bool testMutable() { { gc_mutable_ref s = string("aaa"); s = "bbb"; assert(s == "bbb"); } { gc_mutable_ref s; assert(s == ""); s = "bbb"; assert(s == "bbb"); } { gc_mutable_ref v; assert(isNull((value)v)); v = 1; assert(v == 1); } return true; } const bool testLambdaGC() { resetLambdaCounters(); { const gc_scoped_pool gcp; testLambda(); } assert(checkLambdaCounters()); return true; } class sint { public: sint(const int i) : i(i) { } const int i; char b[4]; }; const int mult(const sint& a, const sint& b) { return a.i * b.i; } const bool testCurry() { const lambda mult2 = curry((lambda)mult, sint(2)); assert(6 == mult2(sint(3))); return true; } const bool curryPerf() { const sint a(2); const sint b(3); const lambda mult2 = curry((lambda)mult, a); for(int i = 0; i < 1000; i++) mult2(b); return true; } class multFunctor { public: multFunctor(const sint& a) : a(a) { } const int operator()(const sint& b) const { return a.i * b.i; } private: const sint a; }; const bool testFunctor() { const lambda mult2 = multFunctor(sint(2)); assert(6 == mult2(sint(3))); return true; } const bool functorPerf() { const sint a(2); const sint b(3); const lambda mult2 = lambda(multFunctor(a)); for(int i = 0; i < 1000; i++) mult2(b); return true; } const bool test11Lambda() { const sint a(2); assert(6 == [a](const sint& b) { return a.i * b.i; } (sint(3))); return true; } const lambda multlambda11(const sint& a) { return [a](const sint& b) { return a.i * b.i; }; } const bool lambda11Perf() { const sint a(2); const sint b(3); const lambda mult2 = multlambda11(a); for(int i = 0; i < 1000; i++) mult2(b); return true; } const std::function multfunction11(const sint& a) { return [a](const sint& b) { return a.i * b.i; }; } const bool function11Perf() { const sint a(2); const sint b(3); const std::function mult2 = multfunction11(a); for(int i = 0; i < 1000; i++) mult2(b); return true; } const bool testFuncPerf() { { const gc_scoped_pool gcp; const blambda cp = curryPerf; cout << "Curry test " << (time(cp, 5, 1000) / 1000) << " ms" << endl; } { const gc_scoped_pool gcp; const blambda fp = functorPerf; cout << "Functor test " << (time(fp, 5, 1000) / 1000) << " ms" << endl; } { const gc_scoped_pool gcp; const blambda lp = lambda11Perf; cout << "Lambda11 test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; } { const gc_scoped_pool gcp; const blambda lp = function11Perf; cout << "Function11 test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; } return true; } int countElements = 0; class Element { public: Element() : i(0) { countElements++; } Element(int i) : i(i) { countElements++; } Element(const Element& o) : i(o.i) { countElements++; } ~Element() { countElements--; } const bool operator==(const Element& o) const { return o.i == i; } int i; }; ostream& operator<<(ostream& out, const Element& v) { out << v.i ; return out; } const bool testCons() { assert(car(cons(2, mklist(3))) == 2); assert(car(cdr(cons(2, mklist(3)))) == 3); assert(isNull(cdr(cdr(cons(2, mklist(3)))))); assert(cons(Element(1), mklist(Element(2))) == mklist(Element(1), Element(2))); return true; } const bool testListGC() { resetLambdaCounters(); resetListCounters(); countElements = 0; { const gc_scoped_pool gcp; testCons(); } assert(checkLambdaCounters()); assert(checkListCounters()); assert(countElements == 0); return true; } template const list listPerf(const T& v, const long int i) { if (i == 0) return list(); return cons(v, listPerf(v, i -1)); } const bool testListPerf() { { const gc_scoped_pool gcp; const blambda lp = []() -> const bool { listPerf(0, 1000); return true; }; cout << "List test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; } { const gc_scoped_pool gcp; const blambda lp = []() -> const bool { listPerf(string("x"), 1000); return true; }; cout << "List test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; } { const gc_scoped_pool gcp; const blambda lp = []() -> const bool { listPerf(value("x"), 1000); return true; }; cout << "List test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; } return true; } const bool testOut() { ostringstream os1; os1 << list (); assert(str(os1) == "()"); ostringstream os2; os2 << mklist(1, 2, 3); assert(str(os2) == "(1 2 3)"); return true; } const bool testEquals() { assert(list() == list()); assert(mklist(1, 2) == mklist(1, 2)); assert(list() != mklist(1, 2)); assert(mklist(1, 2, 3) == mklist(1, 2, 3)); assert(mklist(1, 2) != mklist(1, 2, 3)); return true; } const bool testLength() { assert(0 == length(list())); assert(1 == length(mklist(1))); assert(2 == length(cons(1, mklist(2)))); return true; } const bool testAppend() { assert(car(append(mklist(1), mklist(2))) == 1); assert(car(cdr(append(mklist(1), mklist(2)))) == 2); assert(car(cdr(cdr(append(mklist(1), mklist(2, 3))))) == 3); assert(isNull(cdr(cdr(cdr(append(mklist(1), mklist(2, 3))))))); assert(list() + 1 + 2 + 3 == mklist(1, 2, 3)); return true; } const bool testSublist() { assert(listHead(mklist(1, 2), 0) == list()); assert(listHead(mklist(1, 2), 1) == mklist(1)); assert(listHead(mklist(1, 2), 2) == mklist(1, 2)); assert(listHead(mklist(1, 2), 3) == mklist(1, 2)); assert(listTail(mklist(1, 2), 0) == mklist(1, 2)); assert(listTail(mklist(1, 2), 1) == mklist(2)); assert(listTail(mklist(1, 2), 2) == list()); assert(listTail(mklist(1, 2), 3) == list()); return true; } class Complex { public: Complex() : x(0), y(0) { } Complex(const int x, const int y) : x(x), y(y) { } const int x; const int y; }; ostream& operator<<(ostream& out, const Complex& v) { out << "[" << v.x << ":" << v.y << "]"; return out; } const bool testComplex() { const list p = mklist(Complex(1, 2), Complex(3, 4)); assert(car(p).x == 1); assert(car(cdr(p)).x == 3); assert(isNull(cdr(cdr(p)))); return true; } const bool testMap() { assert(isNull(map(square, list()))); const list m = map(square, mklist(2, 3)); assert(car(m) == 4); assert(car(cdr(m)) == 9); return true; } const int add(const int x, const int y) { return x + y; } const bool testReduce() { const lambda r(add); assert(reduce(r, 0, mklist(1, 2, 3)) == 6); return true; } const bool isPositive(const int x) { if(x >= 0) return true; else return false; } const bool testFilter() { assert(car(filter(isPositive, mklist(1, -1, 2, -2))) == 1); assert(cadr(filter(isPositive, mklist(1, -1, 2, -2))) == 2); return true; } const bool testMember() { assert(isNull(member(4, mklist(1, 2, 3)))); assert(car(member(1, mklist(1, 2, 3))) == 1); assert(car(member(2, mklist(1, 2, 3))) == 2); assert(car(member(3, mklist(1, 2, 3))) == 3); return true; } const bool testReverse() { assert(isNull(reverse(list()))); assert(car(reverse(mklist(1, 2, 3))) == 3); assert(cadr(reverse(mklist(1, 2, 3))) == 2); return true; } const bool testListRef() { assert(listRef(mklist(1), 0) == 1); assert(listRef(mklist(1, 2, 3), 0) == 1); assert(listRef(mklist(1, 2, 3), 1) == 2); assert(listRef(mklist(1, 2, 3), 2) == 3); return true; } const bool testSubst() { assert(subst(1, 9, mklist(1, 2, 1, 3, 1)) == mklist(9, 2, 9, 3, 9)); assert(subst(1, 9, mklist(1, 2, 1, 3, 1)) == mklist(9, 2, 9, 3, 9)); return true; } const bool testAssoc() { const list > l = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", l) == mklist("a", "A")); assert(isNull(assoc("z", l))); const list > l3 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("a", "AA")); assert(delAssoc("y", l) == l3); const list > l4 = mklist(mklist("x", "X"), mklist("y", "Y")); assert(delAssoc("a", l) == l4); const list > l5 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "YY"), mklist("a", "AA")); assert(substAssoc("y", mklist("y", "YY"), l) == l5); const list > l6 = mklist(mklist("x", "X"), mklist("a", "AAA"), mklist("y", "Y"), mklist("a", "AAA")); assert(substAssoc("a", mklist("a", "AAA"), l) == l6); const list > l7 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA"), mklist("z", "ZZ")); assert(substAssoc("z", mklist("z", "ZZ"), l) == l); assert(substAssoc("z", mklist("z", "ZZ"), l, true) == l7); return true; } const bool testValueAssoc() { const list > u = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", u) == mklist("a", "A")); const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", v) == mklist("a", "A")); const list v2 = mklist(mklist("x", "X"), "a", mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", v2) == mklist("a", "A")); const list v3 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("a", "AA")); assert(delAssoc("y", v) == v3); const list v4 = mklist(mklist("x", "X"), mklist("y", "Y")); assert(delAssoc("a", v) == v4); const list v5 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "YY"), mklist("a", "AA")); assert(substAssoc("y", mklist("y", "YY"), v) == v5); const list v6 = mklist(mklist("x", "X"), mklist("a", "AAA"), mklist("y", "Y"), mklist("a", "AAA")); assert(substAssoc("a", mklist("a", "AAA"), v) == v6); const list v7 = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA"), mklist("z", "ZZ")); assert(substAssoc("z", mklist("z", "ZZ"), v) == v); assert(substAssoc("z", mklist("z", "ZZ"), v, true) == v7); return true; } const bool testTreeAssoc() { const list tv = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZ"), mklist("bda", "BDA"))), mklist("z", "Z")); assert(treeSelectAssoc(mklist("a"), tv) == mklist(mklist("a", "A"))); assert(treeSelectAssoc(mklist("b", "bc"), tv) == mklist(mklist("bc", "BC"))); assert(treeSelectAssoc(mklist("b", "bx"), tv) == list()); assert(treeSelectAssoc(mklist("b", "bd", "bda"), tv) == mklist(mklist("bda", "BDA"))); assert(treeSelectAssoc(mklist("bc"), tv) == mklist(mklist("bc", "BC"))); assert(treeSelectAssoc(mklist("bda"), tv) == mklist(mklist("bda", "BDA"))); assert(treeSelectAssoc(mklist("bd", "bda"), tv) == mklist(mklist("bda", "BDA"))); assert(treeSelectAssoc(mklist("bd", "bda", "bdax"), tv) == list()); assert(treeSelectAssoc(mklist("z"), tv) == mklist(mklist("z", "ZZ"), mklist("z", "Z"))); const list tv2 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("bda", "BDA")))); const list tv3 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZ"))), mklist("z", "Z")); assert(treeDelAssoc(mklist("z"), tv) == tv2); assert(treeDelAssoc(mklist("bda"), tv) == tv3); assert(treeDelAssoc(mklist("bd", "bda"), tv) == tv3); assert(treeDelAssoc(mklist("bd", "bda", "bdax"), tv) == tv); const list tv4 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZZ"), mklist("bda", "BDA"))), mklist("z", "ZZZ")); const list tv5 = mklist(mklist("a", "A"), mklist("b", mklist("ba", "BA"), mklist("bc", "BC"), mklist("bd", mklist("z", "ZZ"), mklist("bda", "BDAX"))), mklist("z", "Z")); assert(treeSubstAssoc(mklist("z"), mklist("z", "ZZZ"), tv) == tv4); assert(treeSubstAssoc(mklist("bda"), mklist("bda", "BDAX"), tv) == tv5); assert(treeSubstAssoc(mklist("bd", "bda"), mklist("bda", "BDAX"), tv) == tv5); assert(treeSubstAssoc(mklist("bd", "bda", "bdax"), mklist("bda", "BDAX"), tv) == tv); return true; } const bool testZip() { const list k = mklist("x", "a", "y", "a"); const list v = mklist("X", "A", "Y", "AA"); const list > z = mklist(k, v); const list > u = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(zip(k, v) == u); assert(unzip(u) == z); return true; } const bool testTokenize() { assert(tokenize("/", "") == list()); assert(tokenize("/", "aaa") == mklist("aaa")); assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist("aaa", "bbb", "ccc", "ddd")); assert(tokenize("/", "/bbb/ccc/ddd") == mklist("", "bbb", "ccc", "ddd")); assert(tokenize("/", "/bbb/ccc/") == mklist("", "bbb", "ccc")); assert(tokenize("/", "/bbb//ccc/") == mklist("", "bbb", "", "ccc")); assert(tokenize("/", "abc/def/") == mklist("abc", "def")); assert(join("/", list()) == ""); assert(join("/", mklist("aaa")) == "aaa"); assert(join("/", mklist("aaa", "bbb", "ccc", "ddd")) == "aaa/bbb/ccc/ddd"); assert(join("/", mklist("", "bbb", "ccc", "ddd")) == "/bbb/ccc/ddd"); assert(join("/", mklist("bbb", "ccc", "")) == "bbb/ccc/"); assert(join("/", mklist("bbb", "", "ccc")) == "bbb//ccc"); return true; } const double testSeqMap(const double x) { return x; } double testSeqReduce(const double accum, unused const double v) { return accum + 1.0; } bool testSeq() { resetLambdaCounters(); resetListCounters(); list s = seq(0.0, 1000.0); assert(1001 == length(s)); assert(1001 == length(map(testSeqMap, s))); assert(801 == length(member(200.0, s))); assert(201 == length(member(200.0, reverse(s)))); assert(1001 == (reduce(testSeqReduce, 0.0, s))); return true; } const value valueSquare(const list& x) { return (int)car(x) * (int)car(x); } const bool testValue() { assert(value(true) == trueValue); assert(value(1) == value(1)); assert(value("abcd") == value("abcd")); lvvlambda vl(valueSquare); //assert(value(vl) == value(vl)); assert(value(mklist(1, 2)) == value(mklist(1, 2))); const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y")); assert(cadr(value(v)) == mklist("a", "A")); const value pv(gc_ptr(new (gc_new()) value(1))); assert(*(gc_ptr)pv == value(1)); const list lpv = mklist(gc_ptr(new (gc_new()) value(1)), gc_ptr(new (gc_new()) value(2))); assert(*(gc_ptr)car(lpv) == value(1)); return true; } const bool testValueGC() { resetLambdaCounters(); resetListCounters(); resetValueCounters(); { const gc_scoped_pool gcp; testValue(); } assert(checkValueCounters()); assert(checkLambdaCounters()); assert(checkListCounters()); return true; } const bool testBinaryTree() { const list t = mkrbtree("a", nilListValue, nilListValue); const list ct = rbtreeCons("d", rbtreeCons("f", rbtreeCons("c", rbtreeCons("e", rbtreeCons("b", t))))); const list mt = mkrbtree(mklist("d", "f", "c", "e", "b", "a")); assert(mt == ct); const list l = flatten(mt); assert(length(l) == 6); assert(car(l) == "a"); assert(car(reverse(l)) == "f"); const list bt = mkbrbtree(l); assert(car(bt) == "c"); return true; } const list lta(const string& x) { return mklist(c_str(x), c_str(x + x)); } const bool testBinaryTreeAssoc() { const list t = mkrbtree(lta("a"), nilListValue, nilListValue); const list at = rbtreeCons(lta("d"), rbtreeCons(lta("f"), rbtreeCons(lta("c"), rbtreeCons(lta("e"), rbtreeCons(lta("b"), t))))); const list l = flatten(at); assert(length(l) == 6); assert(car(l) == mklist("a", "aa")); assert(car(reverse(l)) == mklist("f", "ff")); const list bt = mkbrbtree(l); assert(car(bt) == mklist("c", "cc")); assert(rbtreeAssoc("a", bt) == mklist("a", "aa")); assert(rbtreeAssoc("b", bt) == mklist("b", "bb")); assert(rbtreeAssoc("f", bt) == mklist("f", "ff")); assert(isNull(rbtreeAssoc("x", bt))); return true; } const double fib_aux(const double n, const double a, const double b) { if(n == 0.0) return a; return fib_aux(n - 1.0, b, a + b); } const double fib(const double n) { return fib_aux(n, 0.0, 1.0); } const bool fibMapPerf() { const list s = seq(0.0, 999.0); const list r = map(fib, s); assert(1000 == length(r)); return true; } const bool testCppPerf() { { const gc_scoped_pool gcp; const blambda fml = fibMapPerf; cout << "Fibonacci map test " << (time(fml, 1, 1) / 1000) << " ms" << endl; } { const lambda fib = [](const double n) -> const double { const lambda fib_aux = [&fib_aux](double n, double a, double b) -> const double { if(n == 0.0) return a; return fib_aux(n - 1.0, b, a + b); }; return fib_aux(n, 0.0, 1.0); }; const blambda nfml = [fib]() -> const bool { const list s = seq(0.0, 999.0); const list r = map(fib, s); assert(1000 == length(r)); return true; }; cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << endl; } return true; } const id idF(const int v) { return v * 2; } const id idG(const int v) { return v * 3; } const id idH(const int v) { return idF(v) >> idG; } const bool testIdMonad() { const id m(2); assert(m >> idF == idF(2)); assert(m >> unit() == m); assert(m >> idF >> idG == m >> idH); return true; } const maybe maybeF(const int v) { return v * 2; } const maybe maybeG(const int v) { return v * 3; } const maybe maybeH(const int v) { return maybeF(v) >> maybeG; } const bool testMaybeMonad() { const maybe m(2); assert(m >> maybeF == maybeF(2)); assert((m >> just()) == m); assert(m >> maybeF >> maybeG == m >> maybeH); assert(maybe() >> maybeF >> maybeG == maybe()); return true; } const failable failableF(const int v) { return v * 2; } const failable failableG(const int v) { return v * 3; } const failable failableH(const int v) { return failableF(v) >> failableG; } const bool testFailableMonad() { const failable m(2); assert(m >> failableF == failableF(2)); assert((m >> success()) == m); assert(m >> failableF >> failableG == m >> failableH); cout << "Failable monad test... " << endl; const failable ooops = mkfailure("test", 500); assert(reason(ooops) == "test"); assert(rcode(ooops) == 500); assert(ooops >> failableF >> failableG == ooops); const failable vooops = mkfailure(ooops); assert(reason(vooops) == "test"); assert(rcode(vooops) == 500); const value v = value(vooops); assert(car(v) == nilValue); assert(cadr(v) == string("test")); assert(caddr(v) == value((double)500)); return true; } const state tick(const double v) { return transformer([v](const int s) { return scp(s + 1, v); }); } const state stateF(const double v) { return result(v * 2.0) >> tick; } const state stateG(const double v) { return result(v + 5); } const state stateH(const double v) { return stateF(v) >> stateG; } const bool testStateMonad() { const lambda(const double)> r(result); state m = result(2.0); assert((m >> stateF)(0) == stateF(2.0)(0)); assert(1 == (int)(m >> stateF)(0)); assert((m >> r)(0) == m(0)); assert((m >> stateF >> stateG)(0) == (m >> stateH)(0)); return true; } const bool testDynLib() { const lib dl(string("./libdynlib-test") + dynlibExt); const failable > sq(dynlambda("csquare", dl)); assert(hasContent(sq)); lambda l(content(sq)); assert(l(2) == 4); const failable()> > sql(dynlambda()>("csquarel", dl)); assert(hasContent(sql)); lambda()> ll(content(sql)); assert(ll()(3) == 9); return true; } } int main() { const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; tuscany::testSizes(); tuscany::testCopiable(); tuscany::testMutable(); tuscany::testPtrPerf(); tuscany::testLambda(); tuscany::testLambdaGC(); tuscany::testCurry(); tuscany::testFunctor(); tuscany::test11Lambda(); tuscany::testFuncPerf(); tuscany::testCons(); tuscany::testListGC(); tuscany::testListPerf(); tuscany::testOut(); tuscany::testEquals(); tuscany::testLength(); tuscany::testAppend(); tuscany::testSublist(); tuscany::testComplex(); tuscany::testMap(); tuscany::testReduce(); tuscany::testFilter(); tuscany::testMember(); tuscany::testReverse(); tuscany::testListRef(); tuscany::testSubst(); tuscany::testAssoc(); tuscany::testValueAssoc(); tuscany::testTreeAssoc(); tuscany::testZip(); tuscany::testTokenize(); tuscany::testSeq(); tuscany::testValue(); tuscany::testValueGC(); tuscany::testBinaryTree(); tuscany::testBinaryTreeAssoc(); tuscany::testCppPerf(); tuscany::testIdMonad(); tuscany::testMaybeMonad(); tuscany::testFailableMonad(); tuscany::testStateMonad(); tuscany::testDynLib(); tuscany::cout << "OK" << tuscany::endl; return 0; }