7905926c41
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1517412 13f79535-47bb-0310-9956-ffa450edef68
1001 lines
30 KiB
C++
1001 lines
30 KiB
C++
/*
|
|
* 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 <functional>
|
|
#include <assert.h>
|
|
#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<int> 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<const int(const int)> f, int v) {
|
|
return f(v);
|
|
}
|
|
|
|
const lambda<const int(const int)> mksquare() {
|
|
return square;
|
|
}
|
|
|
|
const bool testSizes() {
|
|
const gc_ptr<int> p(NULL);
|
|
cout << "sizeof gc_ptr " << sizeof(p) << endl;
|
|
const lambda<const int(const int)> sq(square);
|
|
cout << "sizeof C function lambda " << sizeof(sq) << endl;
|
|
const lambda<const int(const int)> incl(incFunctor(10));
|
|
cout << "sizeof functor lambda " << sizeof(incl) << endl;
|
|
const std::function<int(const int)> sqf(square);
|
|
cout << "sizeof C function std::function " << sizeof(sqf) << endl;
|
|
const std::function<int(const int)> 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<int> li = cons<int>(2, mklist<int>(3, 4));
|
|
cout << "sizeof list<int> " << sizeof(li) << endl;
|
|
const list<string> ls = cons<string>("a", mklist<string>("b", "c"));
|
|
cout << "sizeof list<string> " << sizeof(ls) << endl;
|
|
const list<value> lv = cons<value>("a", mklist<value>("b", "c"));
|
|
cout << "sizeof list<value> " << sizeof(lv) << endl;
|
|
return true;
|
|
}
|
|
|
|
const bool testLambda() {
|
|
const lambda<const int(const int)> sq(square);
|
|
assert(sq(2) == 4);
|
|
|
|
const lambda<const lambda<const int(const int)>()> mksq(mksquare);
|
|
assert(mksq()(2) == 4);
|
|
|
|
assert(mapLambda(sq, 2) == 4);
|
|
assert(mapLambda(square, 2) == 4);
|
|
|
|
const lambda<const int(const int)> 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<const int(const int)> incl(incl11);
|
|
assert(incl(1) == 11);
|
|
assert(mapLambda(incl, 1) == 11);
|
|
assert(mapLambda(incl11, 1) == 11);
|
|
|
|
const lambda<const int(const int)> il(incf);
|
|
assert(il(1) == 11);
|
|
const lambda<const int(const int)> 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<string> s = string("aaa");
|
|
s = "bbb";
|
|
assert(s == "bbb");
|
|
}
|
|
{
|
|
gc_mutable_ref<string> s;
|
|
assert(s == "");
|
|
s = "bbb";
|
|
assert(s == "bbb");
|
|
}
|
|
{
|
|
gc_mutable_ref<value> 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<const int(const sint)> mult2 = curry((lambda<const int(const sint, const sint)>)mult, sint(2));
|
|
assert(6 == mult2(sint(3)));
|
|
return true;
|
|
}
|
|
|
|
const bool curryPerf() {
|
|
const sint a(2);
|
|
const sint b(3);
|
|
const lambda<const int(const sint)> mult2 = curry((lambda<const int(const sint, const sint)>)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<const int(const sint)> mult2 = multFunctor(sint(2));
|
|
assert(6 == mult2(sint(3)));
|
|
return true;
|
|
}
|
|
|
|
const bool functorPerf() {
|
|
const sint a(2);
|
|
const sint b(3);
|
|
const lambda<const int(const sint)> mult2 = lambda<const int(const sint)>(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<const sint(const sint)> 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<const sint(const sint)> mult2 = multlambda11(a);
|
|
for(int i = 0; i < 1000; i++)
|
|
mult2(b);
|
|
return true;
|
|
}
|
|
|
|
const std::function<sint(const sint&)> 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<sint(const sint&)> 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<typename T> const list<T> listPerf(const T& v, const long int i) {
|
|
if (i == 0)
|
|
return list<T>();
|
|
return cons<T>(v, listPerf<T>(v, i -1));
|
|
}
|
|
|
|
const bool testListPerf() {
|
|
{
|
|
const gc_scoped_pool gcp;
|
|
const blambda lp = []() -> const bool {
|
|
listPerf<int>(0, 1000);
|
|
return true;
|
|
};
|
|
cout << "List<int> test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
|
|
}
|
|
{
|
|
const gc_scoped_pool gcp;
|
|
const blambda lp = []() -> const bool {
|
|
listPerf<string>(string("x"), 1000);
|
|
return true;
|
|
};
|
|
cout << "List<string> test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
|
|
}
|
|
{
|
|
const gc_scoped_pool gcp;
|
|
const blambda lp = []() -> const bool {
|
|
listPerf<string>(value("x"), 1000);
|
|
return true;
|
|
};
|
|
cout << "List<value> test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const bool testOut() {
|
|
ostringstream os1;
|
|
os1 << list<int> ();
|
|
assert(str(os1) == "()");
|
|
|
|
ostringstream os2;
|
|
os2 << mklist(1, 2, 3);
|
|
assert(str(os2) == "(1 2 3)");
|
|
return true;
|
|
}
|
|
|
|
const bool testEquals() {
|
|
assert(list<int>() == list<int>());
|
|
assert(mklist(1, 2) == mklist(1, 2));
|
|
assert(list<int>() != 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<int>()));
|
|
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<int>() + 1 + 2 + 3 == mklist(1, 2, 3));
|
|
return true;
|
|
}
|
|
|
|
const bool testSublist() {
|
|
assert(listHead(mklist(1, 2), 0) == list<int>());
|
|
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<int>());
|
|
assert(listTail(mklist(1, 2), 3) == list<int>());
|
|
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<Complex> 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<int, int>(square, list<int>())));
|
|
|
|
const list<int> m = map<int, int>(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<const int(const int, const int)> 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<int>(isPositive, mklist(1, -1, 2, -2))) == 1);
|
|
assert(cadr(filter<int>(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<int>())));
|
|
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<value>(1, 9, mklist<value>(1, 2, 1, 3, 1)) == mklist<value>(9, 2, 9, 3, 9));
|
|
return true;
|
|
}
|
|
|
|
const bool testAssoc() {
|
|
const list<list<string> > l = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
|
|
assert(assoc<string>("a", l) == mklist<string>("a", "A"));
|
|
assert(isNull(assoc<string>("z", l)));
|
|
|
|
const list<list<string> > l3 = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("a", "AA"));
|
|
assert(delAssoc<string>("y", l) == l3);
|
|
|
|
const list<list<string> > l4 = mklist(mklist<string>("x", "X"), mklist<string>("y", "Y"));
|
|
assert(delAssoc<string>("a", l) == l4);
|
|
|
|
const list<list<string> > l5 = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "YY"), mklist<string>("a", "AA"));
|
|
assert(substAssoc<string>("y", mklist<string>("y", "YY"), l) == l5);
|
|
|
|
const list<list<string> > l6 = mklist(mklist<string>("x", "X"), mklist<string>("a", "AAA"), mklist<string>("y", "Y"), mklist<string>("a", "AAA"));
|
|
assert(substAssoc<string>("a", mklist<string>("a", "AAA"), l) == l6);
|
|
|
|
const list<list<string> > l7 = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"), mklist<string>("z", "ZZ"));
|
|
assert(substAssoc<string>("z", mklist<string>("z", "ZZ"), l) == l);
|
|
assert(substAssoc<string>("z", mklist<string>("z", "ZZ"), l, true) == l7);
|
|
|
|
return true;
|
|
}
|
|
|
|
const bool testValueAssoc() {
|
|
const list<list<value> > u = mklist(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
|
|
assert(assoc<value>("a", u) == mklist<value>("a", "A"));
|
|
|
|
const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
|
|
assert(assoc<value>("a", v) == mklist<value>("a", "A"));
|
|
|
|
const list<value> v2 = mklist<value>(mklist<value>("x", "X"), "a", mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
|
|
assert(assoc<value>("a", v2) == mklist<value>("a", "A"));
|
|
|
|
const list<value> v3 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("a", "AA"));
|
|
assert(delAssoc<value>("y", v) == v3);
|
|
|
|
const list<value> v4 = mklist<value>(mklist<value>("x", "X"), mklist<value>("y", "Y"));
|
|
assert(delAssoc<value>("a", v) == v4);
|
|
|
|
const list<value> v5 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "YY"), mklist<value>("a", "AA"));
|
|
assert(substAssoc<value>("y", mklist<value>("y", "YY"), v) == v5);
|
|
|
|
const list<value> v6 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "AAA"), mklist<value>("y", "Y"), mklist<value>("a", "AAA"));
|
|
assert(substAssoc<value>("a", mklist<value>("a", "AAA"), v) == v6);
|
|
|
|
const list<value> v7 = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"), mklist<value>("z", "ZZ"));
|
|
assert(substAssoc<value>("z", mklist<value>("z", "ZZ"), v) == v);
|
|
assert(substAssoc<value>("z", mklist<value>("z", "ZZ"), v, true) == v7);
|
|
return true;
|
|
}
|
|
|
|
const bool testTreeAssoc() {
|
|
const list<value> tv = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZ"), mklist<value>("bda", "BDA"))), mklist<value>("z", "Z"));
|
|
assert(treeSelectAssoc<value>(mklist<value>("a"), tv) == mklist<value>(mklist<value>("a", "A")));
|
|
assert(treeSelectAssoc<value>(mklist<value>("b", "bc"), tv) == mklist<value>(mklist<value>("bc", "BC")));
|
|
assert(treeSelectAssoc<value>(mklist<value>("b", "bx"), tv) == list<value>());
|
|
assert(treeSelectAssoc<value>(mklist<value>("b", "bd", "bda"), tv) == mklist<value>(mklist<value>("bda", "BDA")));
|
|
assert(treeSelectAssoc<value>(mklist<value>("bc"), tv) == mklist<value>(mklist<value>("bc", "BC")));
|
|
assert(treeSelectAssoc<value>(mklist<value>("bda"), tv) == mklist<value>(mklist<value>("bda", "BDA")));
|
|
assert(treeSelectAssoc<value>(mklist<value>("bd", "bda"), tv) == mklist<value>(mklist<value>("bda", "BDA")));
|
|
assert(treeSelectAssoc<value>(mklist<value>("bd", "bda", "bdax"), tv) == list<value>());
|
|
assert(treeSelectAssoc<value>(mklist<value>("z"), tv) == mklist<value>(mklist<value>("z", "ZZ"), mklist<value>("z", "Z")));
|
|
|
|
const list<value> tv2 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("bda", "BDA"))));
|
|
const list<value> tv3 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZ"))), mklist<value>("z", "Z"));
|
|
assert(treeDelAssoc<value>(mklist<value>("z"), tv) == tv2);
|
|
assert(treeDelAssoc<value>(mklist<value>("bda"), tv) == tv3);
|
|
assert(treeDelAssoc<value>(mklist<value>("bd", "bda"), tv) == tv3);
|
|
assert(treeDelAssoc<value>(mklist<value>("bd", "bda", "bdax"), tv) == tv);
|
|
|
|
const list<value> tv4 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZZ"), mklist<value>("bda", "BDA"))), mklist<value>("z", "ZZZ"));
|
|
const list<value> tv5 = mklist<value>(mklist<value>("a", "A"), mklist<value>("b", mklist<value>("ba", "BA"), mklist<value>("bc", "BC"), mklist<value>("bd", mklist<value>("z", "ZZ"), mklist<value>("bda", "BDAX"))), mklist<value>("z", "Z"));
|
|
assert(treeSubstAssoc<value>(mklist<value>("z"), mklist<value>("z", "ZZZ"), tv) == tv4);
|
|
assert(treeSubstAssoc<value>(mklist<value>("bda"), mklist<value>("bda", "BDAX"), tv) == tv5);
|
|
assert(treeSubstAssoc<value>(mklist<value>("bd", "bda"), mklist<value>("bda", "BDAX"), tv) == tv5);
|
|
assert(treeSubstAssoc<value>(mklist<value>("bd", "bda", "bdax"), mklist<value>("bda", "BDAX"), tv) == tv);
|
|
return true;
|
|
}
|
|
|
|
const bool testZip() {
|
|
const list<string> k = mklist<string>("x", "a", "y", "a");
|
|
const list<string> v = mklist<string>("X", "A", "Y", "AA");
|
|
const list<list<string> > z = mklist(k, v);
|
|
const list<list<string> > u = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
|
|
assert(zip(k, v) == u);
|
|
assert(unzip(u) == z);
|
|
return true;
|
|
}
|
|
|
|
const bool testTokenize() {
|
|
assert(tokenize("/", "") == list<string>());
|
|
assert(tokenize("/", "aaa") == mklist<string>("aaa"));
|
|
assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist<string>("aaa", "bbb", "ccc", "ddd"));
|
|
assert(tokenize("/", "/bbb/ccc/ddd") == mklist<string>("", "bbb", "ccc", "ddd"));
|
|
assert(tokenize("/", "/bbb/ccc/") == mklist<string>("", "bbb", "ccc"));
|
|
assert(tokenize("/", "/bbb//ccc/") == mklist<string>("", "bbb", "", "ccc"));
|
|
assert(tokenize("/", "abc/def/") == mklist<string>("abc", "def"));
|
|
|
|
assert(join("/", list<string>()) == "");
|
|
assert(join("/", mklist<string>("aaa")) == "aaa");
|
|
assert(join("/", mklist<string>("aaa", "bbb", "ccc", "ddd")) == "aaa/bbb/ccc/ddd");
|
|
assert(join("/", mklist<string>("", "bbb", "ccc", "ddd")) == "/bbb/ccc/ddd");
|
|
assert(join("/", mklist<string>("bbb", "ccc", "")) == "bbb/ccc/");
|
|
assert(join("/", mklist<string>("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<double> s = seq(0.0, 1000.0);
|
|
assert(1001 == length(s));
|
|
|
|
assert(1001 == length(map<double, double>(testSeqMap, s)));
|
|
|
|
assert(801 == length(member(200.0, s)));
|
|
assert(201 == length(member(200.0, reverse(s))));
|
|
|
|
assert(1001 == (reduce<double, double>(testSeqReduce, 0.0, s)));
|
|
return true;
|
|
}
|
|
|
|
const value valueSquare(const list<value>& 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<value>(1, 2)) == value(mklist<value>(1, 2)));
|
|
|
|
const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"));
|
|
assert(cadr<value>(value(v)) == mklist<value>("a", "A"));
|
|
|
|
const value pv(gc_ptr<value>(new (gc_new<value>()) value(1)));
|
|
assert(*(gc_ptr<value>)pv == value(1));
|
|
|
|
const list<value> lpv = mklist<value>(gc_ptr<value>(new (gc_new<value>()) value(1)), gc_ptr<value>(new (gc_new<value>()) value(2)));
|
|
assert(*(gc_ptr<value>)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<value> t = mkrbtree<value>("a", nilListValue, nilListValue);
|
|
const list<value> ct = rbtreeCons<value>("d", rbtreeCons<value>("f", rbtreeCons<value>("c", rbtreeCons<value>("e", rbtreeCons<value>("b", t)))));
|
|
const list<value> mt = mkrbtree(mklist<value>("d", "f", "c", "e", "b", "a"));
|
|
assert(mt == ct);
|
|
const list<value> l = flatten<value>(mt);
|
|
assert(length(l) == 6);
|
|
assert(car(l) == "a");
|
|
assert(car(reverse(l)) == "f");
|
|
const list<value> bt = mkbrbtree<value>(l);
|
|
assert(car(bt) == "c");
|
|
return true;
|
|
}
|
|
|
|
const list<value> lta(const string& x) {
|
|
return mklist<value>(c_str(x), c_str(x + x));
|
|
}
|
|
|
|
const bool testBinaryTreeAssoc() {
|
|
const list<value> t = mkrbtree<value>(lta("a"), nilListValue, nilListValue);
|
|
const list<value> at = rbtreeCons<value>(lta("d"), rbtreeCons<value>(lta("f"), rbtreeCons<value>(lta("c"), rbtreeCons<value>(lta("e"), rbtreeCons<value>(lta("b"), t)))));
|
|
const list<value> l = flatten<value>(at);
|
|
assert(length(l) == 6);
|
|
assert(car(l) == mklist<value>("a", "aa"));
|
|
assert(car(reverse(l)) == mklist<value>("f", "ff"));
|
|
const list<value> bt = mkbrbtree<value>(l);
|
|
assert(car(bt) == mklist<value>("c", "cc"));
|
|
assert(rbtreeAssoc<value>("a", bt) == mklist<value>("a", "aa"));
|
|
assert(rbtreeAssoc<value>("b", bt) == mklist<value>("b", "bb"));
|
|
assert(rbtreeAssoc<value>("f", bt) == mklist<value>("f", "ff"));
|
|
assert(isNull(rbtreeAssoc<value>("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<double> s = seq(0.0, 999.0);
|
|
const list<double> r = map<double, double>(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<const double(const double n)> fib = [](const double n) -> const double {
|
|
const lambda<const double(const double, const double, const double)> 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<double> s = seq(0.0, 999.0);
|
|
const list<double> r = map<double, double>(fib, s);
|
|
assert(1000 == length(r));
|
|
return true;
|
|
};
|
|
cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << endl;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const id<int> idF(const int v) {
|
|
return v * 2;
|
|
}
|
|
|
|
const id<int> idG(const int v) {
|
|
return v * 3;
|
|
}
|
|
|
|
const id<int> idH(const int v) {
|
|
return idF(v) >> idG;
|
|
}
|
|
|
|
const bool testIdMonad() {
|
|
const id<int> m(2);
|
|
assert(m >> idF == idF(2));
|
|
assert(m >> unit<int>() == m);
|
|
assert(m >> idF >> idG == m >> idH);
|
|
return true;
|
|
}
|
|
|
|
const maybe<int> maybeF(const int v) {
|
|
return v * 2;
|
|
}
|
|
|
|
const maybe<int> maybeG(const int v) {
|
|
return v * 3;
|
|
}
|
|
|
|
const maybe<int> maybeH(const int v) {
|
|
return maybeF(v) >> maybeG;
|
|
}
|
|
|
|
const bool testMaybeMonad() {
|
|
const maybe<int> m(2);
|
|
assert(m >> maybeF == maybeF(2));
|
|
assert((m >> just<int>()) == m);
|
|
assert(m >> maybeF >> maybeG == m >> maybeH);
|
|
|
|
assert(maybe<int>() >> maybeF >> maybeG == maybe<int>());
|
|
return true;
|
|
}
|
|
|
|
const failable<int> failableF(const int v) {
|
|
return v * 2;
|
|
}
|
|
|
|
const failable<int> failableG(const int v) {
|
|
return v * 3;
|
|
}
|
|
|
|
const failable<int> failableH(const int v) {
|
|
return failableF(v) >> failableG;
|
|
}
|
|
|
|
const bool testFailableMonad() {
|
|
const failable<int> m(2);
|
|
assert(m >> failableF == failableF(2));
|
|
assert((m >> success<int, string, int>()) == m);
|
|
assert(m >> failableF >> failableG == m >> failableH);
|
|
|
|
cout << "Failable monad test... " << endl;
|
|
const failable<int> ooops = mkfailure<int>("test", 500);
|
|
assert(reason(ooops) == "test");
|
|
assert(rcode(ooops) == 500);
|
|
assert(ooops >> failableF >> failableG == ooops);
|
|
|
|
const failable<value> vooops = mkfailure<value>(ooops);
|
|
assert(reason(vooops) == "test");
|
|
assert(rcode(vooops) == 500);
|
|
|
|
const value v = value(vooops);
|
|
assert(car<value>(v) == nilValue);
|
|
assert(cadr<value>(v) == string("test"));
|
|
assert(caddr<value>(v) == value((double)500));
|
|
return true;
|
|
}
|
|
|
|
const state<int, double> tick(const double v) {
|
|
return transformer<int, double>([v](const int s) {
|
|
return scp<int, double>(s + 1, v);
|
|
});
|
|
}
|
|
|
|
const state<int, double> stateF(const double v) {
|
|
return result<int, double>(v * 2.0) >> tick;
|
|
}
|
|
|
|
const state<int, double> stateG(const double v) {
|
|
return result<int, double>(v + 5);
|
|
}
|
|
|
|
const state<int, double> stateH(const double v) {
|
|
return stateF(v) >> stateG;
|
|
}
|
|
|
|
const bool testStateMonad() {
|
|
const lambda<const state<int, double>(const double)> r(result<int, double>);
|
|
|
|
state<int, double> m = result<int, double>(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<lambda<const int(const int)> > sq(dynlambda<const int(const int)>("csquare", dl));
|
|
assert(hasContent(sq));
|
|
lambda<const int(const int)> l(content(sq));
|
|
assert(l(2) == 4);
|
|
|
|
const failable<lambda<const lambda<const int(const int)>()> > sql(dynlambda<const lambda<const int(const int)>()>("csquarel", dl));
|
|
assert(hasContent(sql));
|
|
lambda<const lambda<const int(const int)>()> 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;
|
|
}
|