diff options
Diffstat (limited to 'sca-cpp/trunk/kernel')
-rw-r--r-- | sca-cpp/trunk/kernel/element.hpp | 31 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/gc.hpp | 31 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/kernel-test.cpp | 105 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/list.hpp | 218 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/stream.hpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/tree.hpp | 168 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/value.hpp | 61 |
7 files changed, 440 insertions, 176 deletions
diff --git a/sca-cpp/trunk/kernel/element.hpp b/sca-cpp/trunk/kernel/element.hpp index 9ae1e632cb..d8907c8d21 100644 --- a/sca-cpp/trunk/kernel/element.hpp +++ b/sca-cpp/trunk/kernel/element.hpp @@ -228,33 +228,12 @@ inline const list<value> valuesToElements(const list<value>& l) { } /** - * Returns a selector lambda function which can be used to filter - * elements against the given element pattern. - */ -inline const lambda<const bool(const value&)> selector(const list<value>& select) { - return [select](const value& v) -> const bool { - const lambda<const bool(const list<value>&, const list<value>&)> evalSelect = [&evalSelect](const list<value>& s, const list<value>& v) -> const bool { - if (isNil(s)) - return true; - if (isNil(v)) - return false; - if (car(s) != car(v)) - return false; - return evalSelect(cdr(s), cdr(v)); - }; - if (!isList(v)) - return false; - return evalSelect(select, v); - }; -} - -/** * Returns the value of the attribute with the given name. */ -inline const value attributeValue(const value& name, const value& l) { +inline const value attributeValue(const value& name, const list<value>& l) { const list<value> f = filter<value>([name](const value& v) { return isAttribute(v) && attributeName((list<value>)v) == name; - }, list<value>(l)); + }, l); if (isNil(f)) return nilValue; return caddr<value>(car(f)); @@ -263,16 +242,16 @@ inline const value attributeValue(const value& name, const value& l) { /** * Returns child elements with the given name. */ -inline const value elementChildren(const value& name, const value& l) { +inline const list<value> elementChildren(const value& name, const list<value>& l) { return filter<value>([name](const value& v) { return isElement(v) && elementName((list<value>)v) == name; - }, list<value>(l)); + }, l); } /** * Return the child element with the given name. */ -inline const value elementChild(const value& name, const value& l) { +inline const value elementChild(const value& name, const list<value>& l) { const list<value> f = elementChildren(name, l); if (isNil(f)) return nilValue; diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp index 7853c551dc..2b65132588 100644 --- a/sca-cpp/trunk/kernel/gc.hpp +++ b/sca-cpp/trunk/kernel/gc.hpp @@ -214,7 +214,7 @@ public: gc_pool& operator=(const gc_pool& pool) = delete; private: - friend apr_pool_t* pool(const gc_pool& pool) noexcept; + friend apr_pool_t* const pool(const gc_pool& pool) noexcept; friend class gc_global_pool_t; friend class gc_child_pool; friend class gc_local_pool; @@ -226,7 +226,7 @@ private: /** * Return the APR pool used by a gc_pool. */ -inline apr_pool_t* pool(const gc_pool& pool) noexcept { +inline apr_pool_t* const pool(const gc_pool& pool) noexcept { return pool.apr_pool; } @@ -242,21 +242,22 @@ public: inline gc_pool_stack_t() noexcept : key(mkkey()) { } - inline operator apr_pool_t*() const noexcept { - return (apr_pool_t*)pthread_getspecific(key); + inline operator apr_pool_t* const () const noexcept { + return (apr_pool_t* const )pthread_getspecific(key); } - inline const gc_pool_stack_t& operator=(apr_pool_t* p) noexcept { - pthread_setspecific(key, p); + const gc_pool_stack_t& operator=(apr_pool_t* const p) noexcept { + const int rc = pthread_setspecific(key, p); + assertOrFail(rc == 0); return *this; } private: - pthread_key_t key; + const pthread_key_t key; - pthread_key_t mkkey() { + inline const pthread_key_t mkkey() noexcept { pthread_key_t k; - int rc = pthread_key_create(&k, NULL); + const int rc = pthread_key_create(&k, NULL); assertOrFail(rc == 0); return k; } @@ -278,7 +279,7 @@ apr_pool_t* gc_pool_stack = NULL; /** * Push a pool onto the stack. */ -inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept { +inline apr_pool_t* const gc_push_pool(apr_pool_t* const pool) noexcept { apr_pool_t* const p = gc_pool_stack; gc_pool_stack = pool; return p; @@ -287,7 +288,7 @@ inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept { /** * Pop a pool from the stack. */ -inline apr_pool_t* const gc_pop_pool(apr_pool_t* pool) noexcept { +inline apr_pool_t* const gc_pop_pool(apr_pool_t* const pool) noexcept { apr_pool_t* const p = gc_pool_stack; gc_pool_stack = pool; return p; @@ -326,7 +327,7 @@ public: private: const bool owner; - apr_pool_t* const mkpool() { + inline apr_pool_t* const mkpool() noexcept { apr_pool_t* p; apr_pool_create(&p, gc_current_pool()); assertOrFail(p != NULL); @@ -356,7 +357,7 @@ public: private: const bool owner; - apr_pool_t* const mkpool() { + inline apr_pool_t* const mkpool() noexcept { apr_pool_t* p; apr_pool_create(&p, gc_current_pool()); assertOrFail(p != NULL); @@ -375,7 +376,7 @@ public: gc_push_pool(apr_pool); } - inline gc_scoped_pool(apr_pool_t* p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) { + inline gc_scoped_pool(apr_pool_t* const p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) { gc_push_pool(apr_pool); } @@ -394,7 +395,7 @@ private: apr_pool_t* const prev; const bool owner; - apr_pool_t* const mkpool() { + inline apr_pool_t* const mkpool() noexcept { apr_pool_t* p; apr_pool_create(&p, gc_current_pool()); assertOrFail(p != NULL); diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp index 0e2a14246a..4c68975961 100644 --- a/sca-cpp/trunk/kernel/kernel-test.cpp +++ b/sca-cpp/trunk/kernel/kernel-test.cpp @@ -557,11 +557,37 @@ const bool testListRef() { 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(isNil(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")); @@ -570,6 +596,50 @@ const bool testAssoc() { 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; } @@ -638,7 +708,7 @@ const bool testValue() { 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((list<list<value> >)value(v)) == mklist<value>("a", "A")); + 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)); @@ -662,16 +732,16 @@ const bool testValueGC() { return true; } -const bool testTree() { - const list<value> t = mktree<value>("a", nilListValue, nilListValue); - const list<value> ct = constree<value>("d", constree<value>("f", constree<value>("c", constree<value>("e", constree<value>("b", t))))); - const list<value> mt = mktree(mklist<value>("d", "f", "c", "e", "b", "a")); +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 = mkbtree<value>(l); + const list<value> bt = mkbrbtree<value>(l); assert(car(bt) == "c"); return true; } @@ -680,19 +750,19 @@ const list<value> lta(const string& x) { return mklist<value>(c_str(x), c_str(x + x)); } -const bool testTreeAssoc() { - const list<value> t = mktree<value>(lta("a"), nilListValue, nilListValue); - const list<value> at = constree<value>(lta("d"), constree<value>(lta("f"), constree<value>(lta("c"), constree<value>(lta("e"), constree<value>(lta("b"), t))))); +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 = mkbtree<value>(l); + const list<value> bt = mkbrbtree<value>(l); assert(car(bt) == mklist<value>("c", "cc")); - assert(assoctree<value>("a", bt) == mklist<value>("a", "aa")); - assert(assoctree<value>("b", bt) == mklist<value>("b", "bb")); - assert(assoctree<value>("f", bt) == mklist<value>("f", "ff")); - assert(isNil(assoctree<value>("x", bt))); + 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(isNil(rbtreeAssoc<value>("x", bt))); return true; } @@ -893,14 +963,17 @@ int main() { 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::testTree(); - tuscany::testTreeAssoc(); + tuscany::testBinaryTree(); + tuscany::testBinaryTreeAssoc(); tuscany::testCppPerf(); tuscany::testIdMonad(); tuscany::testMaybeMonad(); diff --git a/sca-cpp/trunk/kernel/list.hpp b/sca-cpp/trunk/kernel/list.hpp index 16a0649fe9..02df2c2dc5 100644 --- a/sca-cpp/trunk/kernel/list.hpp +++ b/sca-cpp/trunk/kernel/list.hpp @@ -43,16 +43,16 @@ long countILists = 0; long countCLists = 0; long countELists = 0; -inline const bool resetListCounters() { +inline const bool resetListCounters() noexcept { countLists = countILists = countCLists = countELists = 0; return true; } -inline const bool checkListCounters() { +inline const bool checkListCounters() noexcept { return countLists == 0; } -inline const bool printListCounters() { +inline const bool printListCounters() noexcept { cout << "countLists " << countLists << endl; cout << "countELists " << countELists << endl; cout << "countILists " << countILists << endl; @@ -91,19 +91,19 @@ inline const bool printListCounters() { template<typename T> class list { public: - inline list() : car() { + inline list() noexcept : car() { debug_inc(countLists); debug_inc(countELists); debug_watchList(); } - inline list(const T& car, const lambda<list<T>()>& cdr) : car(car), cdr(cdr) { + inline list(const T& car, const lambda<list<T>()>& cdr) noexcept : car(car), cdr(cdr) { debug_inc(countLists); debug_inc(countILists); debug_watchList(); } - inline list(const list& p) : car(p.car), cdr(p.cdr) { + inline list(const list& p) noexcept : car(p.car), cdr(p.cdr) { debug_inc(countLists); debug_inc(countCLists); #ifdef WANT_MAINTAINER_WATCH @@ -113,11 +113,11 @@ public: list<T>& operator=(const list<T>& p) = delete; - inline ~list() { + inline ~list() noexcept { debug_dec(countLists); } - inline const bool operator==(const list<T>& p) const { + inline const bool operator==(const list<T>& p) const noexcept { if(this == &p) return true; if(isNil(cdr)) @@ -131,7 +131,7 @@ public: return cdr() == p.cdr(); } - inline const bool operator<(const list<T>& p) const { + inline const bool operator<(const list<T>& p) const noexcept { if(this == &p) return false; if (isNil(cdr)) @@ -145,7 +145,7 @@ public: return cdr() < p.cdr(); } - inline const bool operator>(const list<T>& p) const { + inline const bool operator>(const list<T>& p) const noexcept { if(this == &p) return false; if (isNil(cdr)) @@ -159,24 +159,23 @@ public: return cdr() > p.cdr(); } - inline const bool operator!=(const list<T>& p) const { + inline const bool operator!=(const list<T>& p) const noexcept { return !this->operator==(p); } - inline operator const list<list<T> >() const { + inline operator const list<list<T> >() const noexcept { return (list<list<T> >)T(*this); } private: #ifdef WANT_MAINTAINER_WATCH - template<typename X> friend const string watchList(const list<X>& p); + template<typename X> friend const string watchList(const list<X>& p) noexcept; string watch; #endif - template<typename X> friend const bool isNil(const list<X>& p); - template<typename X> friend const X car(const list<X>& p); - template<typename X> friend const list<X> cdr(const list<X>& p); - template<typename X> friend const bool setlist(list<X>& target, const list<X>& l); + template<typename X> friend const bool isNil(const list<X>& p) noexcept; + template<typename X> friend const X car(const list<X>& p) noexcept; + template<typename X> friend const list<X> cdr(const list<X>& p) noexcept; const T car; const lambda<list<T>()> cdr; @@ -188,7 +187,7 @@ private: * Debug utility used to write the contents of a list to a string, easier * to watch than the list itself in a debugger. */ -template<typename T> inline const string watchList(const list<T>& p) { +template<typename T> inline const string watchList(const list<T>& p) noexcept { if(isNil(p)) return "()"; odebugstream os; @@ -201,21 +200,21 @@ template<typename T> inline const string watchList(const list<T>& p) { /** * Returns true if the given list is nil. */ -template<typename T> inline const bool isNil(const list<T>& p) { +template<typename T> inline const bool isNil(const list<T>& p) noexcept { return isNil(p.cdr); } /** * Write a list to an output stream. */ -template<typename T> inline ostream& writeHelper(ostream& out, const list<T>& l) { +template<typename T> inline ostream& writeHelper(ostream& out, const list<T>& l) noexcept { if (isNil(l)) return out; out << " " << car(l); return writeHelper(out, cdr(l)); } -template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) { +template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) noexcept { if(isNil(l)) return out << "()"; out << "(" << car(l); @@ -226,74 +225,74 @@ template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) /** * Construct a (lazy) list from a value and a lambda function that returns the cdr. */ -template<typename T> inline const list<T> cons(const T& car, const lambda<const list<T>()>& cdr) { +template<typename T> inline const list<T> cons(const T& car, const lambda<const list<T>()>& cdr) noexcept { return list<T> (car, cdr); } /** * Construct a list from a value and a cdr list. */ -template<typename T> inline const list<T> cons(const T& car, const list<T>& cdr) { +template<typename T> inline const list<T> cons(const T& car, const list<T>& cdr) noexcept { return list<T> (car, result(cdr)); } /** * Cons variations for use with the reduce and reduceRight functions. */ -template<typename T> inline const list<T> lcons(const list<T>& cdr, const T& car) { +template<typename T> inline const list<T> lcons(const list<T>& cdr, const T& car) noexcept { return cons<T>(car, cdr); } -template<typename T> inline const list<T> rcons(const T& car, const list<T>& cdr) { +template<typename T> inline const list<T> rcons(const T& car, const list<T>& cdr) noexcept { return cons<T>(car, cdr); } /** * Construct a list of one value. */ -template<typename T> inline const list<T> mklist(const T& car) { +template<typename T> inline const list<T> mklist(const T& car) noexcept { return list<T> (car, result(list<T> ())); } /** * Construct a list of two values. */ -template<typename T> inline const list<T> mklist(const T& a, const T& b) { +template<typename T> inline const list<T> mklist(const T& a, const T& b) noexcept { return cons(a, mklist(b)); } /** * Construct a list of three values. */ -template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c) { +template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c) noexcept { return cons(a, cons(b, mklist(c))); } /** * Construct a list of four values. */ -template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d) { +template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d) noexcept { return cons(a, cons(b, cons(c, mklist(d)))); } /** * Construct a list of five values. */ -template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) { +template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) noexcept { return cons(a, cons(b, cons(c, cons(d, mklist(e))))); } /** * Construct a list of six values. */ -template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) { +template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) noexcept { return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f)))))); } /** * Returns the car of a list. */ -template<typename T> inline const T car(const list<T>& p) { +template<typename T> inline const T car(const list<T>& p) noexcept { // Abort if trying to access the car of a nil list assertOrFail(!isNil(p.cdr)); return p.car; @@ -302,105 +301,105 @@ template<typename T> inline const T car(const list<T>& p) { /** * Returns the cdr of a list. */ -template<typename T> inline const list<T> cdr(const list<T>& p) { +template<typename T> inline const list<T> cdr(const list<T>& p) noexcept { return p.cdr(); } /** * Returns the car of the cdr (the 2nd element) of a list. */ -template<typename T> inline const T cadr(const list<T>& p) { +template<typename T> inline const T cadr(const list<T>& p) noexcept { return car(cdr(p)); } /** * Returns the 3rd element of a list. */ -template<typename T> inline const T caddr(const list<T>& p) { +template<typename T> inline const T caddr(const list<T>& p) noexcept { return car(cdr(cdr(p))); } /** * Returns the 4th element of a list. */ -template<typename T> inline const T cadddr(const list<T>& p) { +template<typename T> inline const T cadddr(const list<T>& p) noexcept { return car(cdr(cdr(cdr(p)))); } /** * Returns the 5th element of a list. */ -template<typename T> inline const T caddddr(const list<T>& p) { +template<typename T> inline const T caddddr(const list<T>& p) noexcept { return car(cdr(cdr(cdr(cdr(p))))); } /** * Returns the 6th element of a list. */ -template<typename T> inline const T cadddddr(const list<T>& p) { +template<typename T> inline const T cadddddr(const list<T>& p) noexcept { return car(cdr(cdr(cdr(cdr(cdr(p)))))); } /** * Returns the 7th element of a list. */ -template<typename T> inline const T caddddddr(const list<T>& p) { +template<typename T> inline const T caddddddr(const list<T>& p) noexcept { return car(cdr(cdr(cdr(cdr(cdr(cdr(p))))))); } /** * Returns the 8th element of a list. */ -template<typename T> inline const T cadddddddr(const list<T>& p) { +template<typename T> inline const T cadddddddr(const list<T>& p) noexcept { return car(cdr(cdr(cdr(cdr(cdr(cdr(cdr(p)))))))); } /** * Returns a list of elements from the 3rd to the end of a list. */ -template<typename T> inline const list<T> cddr(const list<T>& p) { +template<typename T> inline const list<T> cddr(const list<T>& p) noexcept { return cdr(cdr(p)); } /** * Returns a list of elements from the 4th to the end of a list. */ -template<typename T> inline const list<T> cdddr(const list<T>& p) { +template<typename T> inline const list<T> cdddr(const list<T>& p) noexcept { return cdr(cdr(cdr(p))); } /** * Returns a list of elements from the 5th to the end of a list. */ -template<typename T> inline const list<T> cddddr(const list<T>& p) { +template<typename T> inline const list<T> cddddr(const list<T>& p) noexcept { return cdr(cdr(cdr(cdr(p)))); } /** * Returns a list of elements from the 6th to the end of a list. */ -template<typename T> inline const list<T> cdddddr(const list<T>& p) { +template<typename T> inline const list<T> cdddddr(const list<T>& p) noexcept { return cdr(cdr(cdr(cdr(cdr(p))))); } /** * Returns a list of elements from the 7th to the end of a list. */ -template<typename T> inline const list<T> cddddddr(const list<T>& p) { +template<typename T> inline const list<T> cddddddr(const list<T>& p) noexcept { return cdr(cdr(cdr(cdr(cdr(cdr(p)))))); } /** * Returns a list of elements from the 8th to the end of a list. */ -template<typename T> inline const list<T> cdddddddr(const list<T>& p) { +template<typename T> inline const list<T> cdddddddr(const list<T>& p) noexcept { return cdr(cdr(cdr(cdr(cdr(cdr(cdr(p))))))); } /** * Returns the length of a list. */ -template<typename T> inline const size_t length(const list<T>& p) { +template<typename T> inline const size_t length(const list<T>& p) noexcept { const lambda<size_t(const size_t, const list<T>&)> lengthRef = [&lengthRef](const size_t c, const list<T>& p) -> const size_t { if(isNil(p)) return c; @@ -412,7 +411,7 @@ template<typename T> inline const size_t length(const list<T>& p) { /** * Appends a list and a lambda function returning a list. */ -template<typename T> inline const list<T> append(const list<T>&a, const lambda<const list<T>()>& fb) { +template<typename T> inline const list<T> append(const list<T>&a, const lambda<const list<T>()>& fb) noexcept { if(isNil(a)) return fb(); return cons<T>(car(a), [a, fb]() { return append(cdr(a), fb); }); @@ -421,25 +420,25 @@ template<typename T> inline const list<T> append(const list<T>&a, const lambda<c /** * Appends two lists. */ -template<typename T> inline const list<T> append(const list<T>&a, const list<T>& b) { +template<typename T> inline const list<T> append(const list<T>&a, const list<T>& b) noexcept { return append(a, result(b)); } /** * Append a value to a list. */ -template<typename T> inline const list<T> operator+(const list<T>& l, const T& v) { +template<typename T> inline const list<T> operator+(const list<T>& l, const T& v) noexcept { return append(l, mklist(v)); } -template<typename T, typename V> const list<T> inline operator+(const list<T>& l, const V& v) { +template<typename T, typename V> const list<T> inline operator+(const list<T>& l, const V& v) noexcept { return append(l, mklist<T>(v)); } /** - * Map a lambda function on a list. + * Run a map lambda function on a list. */ -template<typename T, typename R> inline const list<R> map(const lambda<const R(const T)>& f, const list<T>& p) { +template<typename T, typename R> inline const list<R> map(const lambda<const R(const T)>& f, const list<T>& p) noexcept { if(isNil(p)) return list<R> (); return cons(f(car(p)), map(f, cdr(p))); @@ -448,7 +447,7 @@ template<typename T, typename R> inline const list<R> map(const lambda<const R(c /** * Run a reduce lambda function on a list. */ -template<typename T, typename R> inline const R reduce(const lambda<const R(const R, const T)>& f, const R& initial, const list<T>& p) { +template<typename T, typename R> inline const R reduce(const lambda<const R(const R, const T)>& f, const R& initial, const list<T>& p) noexcept { const lambda<const R(const R&, const list<T>&p)> reduceAccumulate = [f, &reduceAccumulate](const R& acc, const list<T>& p) -> R { if(isNil(p)) return acc; @@ -457,7 +456,7 @@ template<typename T, typename R> inline const R reduce(const lambda<const R(cons return reduceAccumulate(initial, p); } -template<typename T, typename R> inline const R reduceRight(const lambda<const R(const T, const R)>& f, const R& initial, const list<T>& p) { +template<typename T, typename R> inline const R reduceRight(const lambda<const R(const T, const R)>& f, const R& initial, const list<T>& p) noexcept { const lambda<const R(const list<T>&p, const R&)> reduceRightAccumulate = [f, &reduceRightAccumulate](const list<T>& p, const R& acc) -> R { if(isNil(p)) return acc; @@ -469,7 +468,7 @@ template<typename T, typename R> inline const R reduceRight(const lambda<const R /** * Run a filter lambda function on a list. */ -template<typename T> inline const list<T> filter(const lambda<const bool(const T)>& f, const list<T>& p) { +template<typename T> inline const list<T> filter(const lambda<const bool(const T)>& f, const list<T>& p) noexcept { if(isNil(p)) return list<T> (); if(f(car(p))) { @@ -482,7 +481,7 @@ template<typename T> inline const list<T> filter(const lambda<const bool(const T /** * Returns a list pointing to a member of a list. */ -template<typename T> inline const list<T> member(const T& t, const list<T>& p) { +template<typename T> inline const list<T> member(const T& t, const list<T>& p) noexcept { if(isNil(p)) return list<T> (); if(t == car(p)) @@ -493,20 +492,20 @@ template<typename T> inline const list<T> member(const T& t, const list<T>& p) { /** * Reverse a list. */ -template<typename T> inline const list<T> reverseIter(const list<T>& acc, const list<T>& p) { +template<typename T> inline const list<T> reverseIter(const list<T>& acc, const list<T>& p) noexcept { if(isNil(p)) return acc; return reverseIter(cons(car(p), acc), cdr(p)); } -template<typename T> inline const list<T> reverse(const list<T>& p) { +template<typename T> inline const list<T> reverse(const list<T>& p) noexcept { return reverseIter(list<T> (), p); } /** * Returns a sequence of values between the given bounds. */ -template<typename T> inline const list<T> seq(const T& start, const T& end) { +template<typename T> inline const list<T> seq(const T& start, const T& end) noexcept { if(start == end) return mklist(start); if(start < end) @@ -517,27 +516,62 @@ template<typename T> inline const list<T> seq(const T& start, const T& end) { /** * Returns the i-th element of a list. */ -template<typename T> inline const T listRef(const list<T>& l, const size_t i) { - if (i == 0) +template<typename T> inline const T listRef(const list<T>& l, const size_t i) noexcept { + if(i == 0) return car(l); return listRef(cdr(l), i - 1); } /** + * Returns the tail of a list, ommiting the first k elements. + */ +template<typename T> inline const list<T> listTail(const list<T>& l, const size_t k) noexcept { + if(k == 0) + return l; + if(isNil(l)) + return l; + return listTail(cdr(l), k - 1); +} + +/** + * Substitute elements in a list. + */ +template<typename T> inline const list<T> subst(const T& o, const T& n, const list<T>& p) noexcept { + if(isNil(p)) + return p; + if(o == car(p)) + return cons<T>(n, subst(o, n, cdr(p))); + return cons<T>(car(p), subst(o, n, cdr(p))); +} + +/** * Returns the first pair matching a key from a list of key value pairs. */ -template<typename T> inline const list<T> assoc(const T& k, const list<list<T> >& p) { +template<typename T> inline const list<T> assoc(const T& k, const list<list<T> >& p) noexcept { if(isNil(p)) - return list<T> (); + return list<T>(); if(k == car(car(p))) return car(p); return assoc(k, cdr(p)); } /** + * Returns the first pair matching a key from a list of key value pairs. + * Requires T to support isList and cast to list<T>. + */ +template<typename T> inline const list<T> assoc(const T& k, const list<T>& p) noexcept { + if(isNil(p)) + return list<T>(); + const T c = car(p); + if(isList(c) && k == car<T>(c)) + return c; + return assoc(k, cdr(p)); +} + +/** * Returns a list of lists containing elements from two input lists. */ -template<typename T> inline const list<list<T> > zip(const list<T>& a, const list<T>& b) { +template<typename T> inline const list<list<T> > zip(const list<T>& a, const list<T>& b) noexcept { if (isNil(a) || isNil(b)) return list<list<T> >(); return cons<list<T> >(mklist<T>(car(a), car(b)), zip(cdr(a), cdr(b))); @@ -546,22 +580,70 @@ template<typename T> inline const list<list<T> > zip(const list<T>& a, const lis /** * Converts a list of key value pairs to a list containing the list of keys and the list of values. */ -template<typename T> inline const list<T> unzipKeys(const list<list<T> >& l) { +template<typename T> inline const list<T> unzipKeys(const list<list<T> >& l) noexcept { if (isNil(l)) return list<T>(); return cons(car(car(l)), unzipKeys(cdr(l))); } -template<typename T> inline const list<T> unzipValues(const list<list<T> >& l) { +template<typename T> inline const list<T> unzipValues(const list<list<T> >& l) noexcept { if (isNil(l)) return list<T>(); return cons(cadr(car(l)), unzipValues(cdr(l))); } -template<typename T> inline const list<list<T> > unzip(const list<list<T> >& l) { +template<typename T> inline const list<list<T> > unzip(const list<list<T> >& l) noexcept { return mklist<list<T> >(unzipKeys(l), unzipValues(l)); } +/** + * Delete assocs matching a key from a list of assocs. + */ +template<typename T> inline const list<list<T> > delAssoc(const T& k, const list<list<T> >& p) noexcept { + if(isNil(p)) + return p; + if(k == car(car(p))) + return delAssoc(k, cdr(p)); + return cons<list<T> >(car(p), delAssoc(k, cdr(p))); +} + +/** + * Delete assocs matching a key from a list of assocs. + * Requires T to support isList, isAssoc, and cast to list<T>. + */ +template<typename T> inline const list<T> delAssoc(const T& k, const list<T>& p) noexcept { + if(isNil(p)) + return p; + const T c = car(p); + if(isList(c) && k == car<T>(c)) + return delAssoc(k, cdr(p)); + return cons<T>(c, delAssoc(k, cdr(p))); +} + +/** + * Substitute assocs with matching keys in a list of assocs. + */ +template<typename T> inline const list<list<T> > substAssoc(const T& k, const list<T>& n, const list<list<T> >& p, const bool add = false) noexcept { + if(isNil(p)) + return add? mklist<list<T> >(n) : p; + if(k == car(car(p))) + return cons<list<T> >(n, substAssoc(k, n, cdr(p), false)); + return cons<list<T> >(car(p), substAssoc(k, n, cdr(p), add)); +} + +/** + * Substitute assocs with matching keys in a list of assocs. + * Requires T to support isList, isAssoc, and cast to list<T>. + */ +template<typename T> inline const list<T> substAssoc(const T& k, const list<T>& n, const list<T>& p, const bool add = false) noexcept { + if(isNil(p)) + return add? mklist<T>(n) : p; + const T c = car(p); + if(isList(c) && k == car<T>(c)) + return cons<T>(n, substAssoc(k, n, cdr(p), false)); + return cons<T>(c, substAssoc(k, n, cdr(p), add)); +} + } #endif /* tuscany_list_hpp */ diff --git a/sca-cpp/trunk/kernel/stream.hpp b/sca-cpp/trunk/kernel/stream.hpp index e59e6a4ef5..a4f4d3c950 100644 --- a/sca-cpp/trunk/kernel/stream.hpp +++ b/sca-cpp/trunk/kernel/stream.hpp @@ -83,7 +83,7 @@ inline ostream& operator<<(ostream& os, const long unsigned int v) { } inline ostream& operator<<(ostream& os, const double v) { - return os.vprintf("%.10g", v); + return os.vprintf("%.16g", v); } inline ostream& operator<<(ostream& os, const void* const v) { diff --git a/sca-cpp/trunk/kernel/tree.hpp b/sca-cpp/trunk/kernel/tree.hpp index 44af09fa64..d350879ce7 100644 --- a/sca-cpp/trunk/kernel/tree.hpp +++ b/sca-cpp/trunk/kernel/tree.hpp @@ -31,54 +31,172 @@ #include "function.hpp" #include "list.hpp" #include "monad.hpp" -#include "value.hpp" namespace tuscany { /** - * Make a tree from a leaf and two branches. + * Delete assocs matching a path of keys in a tree of assocs. + * The path can be a complete or partial path to an assoc. + * Requires T to support isList, isAssoc, and cast to list<T>. */ -template<typename T> inline const list<T> mktree(const T& e, const list<T>& left, const list<T>& right) { +template<typename T> inline const list<T> treeDelAssoc(const list<T>& k, const list<T>& l) noexcept { + if (isNil(k) || isNil(l)) + return l; + const list<T> lv = l; + + // If list is an assoc and matches, skip it + if (isAssoc(lv)) { + if (car<T>(lv) == car(k) && isNil(cdr(k))) + return list<T>(); + } + + // If list element is not an assoc, lookup children and rest of the list + const T a = car(lv); + if (!isAssoc(a)) { + if (!isList(a)) + return cons<T>(a, treeDelAssoc<T>(k, cdr(lv))); + const list<T> da = treeDelAssoc<T>(k, a); + return isNil(da)? treeDelAssoc<T>(k, cdr(lv)) : cons<T>(da, treeDelAssoc<T>(k, cdr(lv))); + } + + // If we found a match, skip it and lookup children and rest of the list + if (car<T>(a) == car(k)) { + if (isNil(cdr(k))) + return treeDelAssoc<T>(k, cdr(lv)); + return cons<T>(cons<T>(car<T>(a), treeDelAssoc<T>(cdr(k), cdr<T>(a))), treeDelAssoc<T>(k, cdr(lv))); + } + + // No match, lookup children and rest of the list + if (isNil(cdr<T>(a))) + return cons<T>(a, treeDelAssoc<T>(k, cdr(lv))); + if (!isList(cadr<T>(a))) + return cons<T>(cons<T>(car<T>(a), cons<T>(cadr<T>(a), treeDelAssoc<T>(k, cddr<T>(a)))), treeDelAssoc<T>(k, cdr(lv))); + const list<T> da = treeDelAssoc<T>(k, cadr<T>(a)); + if (isNil(da)) + return cons<T>(cons<T>(car<T>(a), treeDelAssoc<T>(k, cddr<T>(a))), treeDelAssoc<T>(k, cdr(lv))); + return cons<T>(cons<T>(car<T>(a), cons<T>(da, treeDelAssoc<T>(k, cddr<T>(a)))), treeDelAssoc<T>(k, cdr(lv))); +} + +/** + * Substitute assocs matching a path of keys in a tree of assocs. + * The path can be a complete or partial path to an assoc. + * Requires T to support isList, isAssoc, and cast to list<T>. + */ +template<typename T> inline const list<T> treeSubstAssoc(const list<T>& k, const list<T>& n, const list<T>& lv) noexcept { + if (isNil(k) || isNil(lv)) + return lv; + + // If list is an assoc and matches, substitute it + if (isAssoc(lv)) { + if (car<T>(lv) == car(k) && isNil(cdr(k))) + return n; + } + + // If list element is not an assoc, lookup children and rest of the list + const T a = car(lv); + if (!isAssoc(a)) { + if (!isList(a)) + return cons<T>(a, treeSubstAssoc<T>(k, n, cdr(lv))); + return cons<T>(treeSubstAssoc<T>(k, n, a), treeSubstAssoc<T>(k, n, cdr(lv))); + } + + // If we found a match, substitute it and lookup children and rest of the list + if (car<T>(a) == car(k)) { + if (isNil(cdr(k))) + return cons<T>(n, treeSubstAssoc<T>(k, n, cdr(lv))); + return cons<T>(cons<T>(car<T>(a), treeSubstAssoc<T>(cdr(k), n, cdr<T>(a))), treeSubstAssoc<T>(k, n, cdr(lv))); + } + + // No match, lookup children and rest of the list + if (isNil(cdr<T>(a))) + return cons<T>(a, treeSubstAssoc<T>(k, n, cdr(lv))); + if (!isList(cadr<T>(a))) + return cons<T>(cons<T>(car<T>(a), cons<T>(cadr<T>(a), treeSubstAssoc<T>(k, n, cddr<T>(a)))), treeSubstAssoc<T>(k, n, cdr(lv))); + return cons<T>(cons<T>(car<T>(a), cons<T>(treeSubstAssoc<T>(k, n, cadr<T>(a)), treeSubstAssoc<T>(k, n, cddr<T>(a)))), treeSubstAssoc<T>(k, n, cdr(lv))); +} + +/** + * Select assocs matching a path of keys in a tree of assocs. + * The path can be a complete or partial path to an assoc. + * Requires T to support isList, isAssoc, and cast to list<T>. + */ +template<typename T> inline const list<T> treeSelectAssoc(const list<T>& k, const list<T>& lv) noexcept { + if (isNil(k) || isNil(lv)) + return list<T>(); + + // If list is an assoc and matches, select it + if (isAssoc(lv)) { + if (car<T>(lv) == car(k) && isNil(cdr(k))) + return mklist<T>(lv); + } + + // If list element is not an assoc, lookup children and rest of the list + const T a = car(lv); + if (!isAssoc(a)) { + if (!isList(a)) + return treeSelectAssoc<T>(k, cdr(lv)); + return append<T>(treeSelectAssoc<T>(k, a), treeSelectAssoc<T>(k, cdr(lv))); + } + + // If we found a match, select it and lookup children and rest of the list + if (car<T>(a) == car(k)) { + if (isNil(cdr(k))) + return cons<T>(a, treeSelectAssoc<T>(k, cdr(lv))); + return append<T>(treeSelectAssoc<T>(cdr(k), cdr<T>(a)), treeSelectAssoc<T>(k, cdr(lv))); + } + + // No match, lookup children and rest of the list + if (isNil(cdr<T>(a))) + return treeSelectAssoc<T>(k, cdr(lv)); + if (!isList(cadr<T>(a))) + return append<T>(treeSelectAssoc<T>(k, cddr<T>(a)), treeSelectAssoc<T>(k, cdr(lv))); + return append<T>(append<T>(treeSelectAssoc<T>(k, cadr<T>(a)), treeSelectAssoc<T>(k, cddr<T>(a))), treeSelectAssoc<T>(k, cdr(lv))); +} + +/** + * Make a rooted binary tree from a leaf and two branches. + */ +template<typename T> inline const list<T> mkrbtree(const T& e, const list<T>& left, const list<T>& right) { return mklist<T>(e, left, right); } /** - * Find a leaf with the given key in a tree. + * Find a leaf with the given key in a rooted binary tree. */ -template<typename T> inline const list<T> assoctree(const T& k, const list<T>& tree) { +template<typename T> inline const list<T> rbtreeAssoc(const T& k, const list<T>& tree) { if (isNil(tree)) return tree; if (k == car<T>(car(tree))) return car(tree); if (k < car<T>(car(tree))) - return assoctree<T>(k, cadr(tree)); - return assoctree<T>(k, caddr(tree)); + return rbtreeAssoc<T>(k, cadr(tree)); + return rbtreeAssoc<T>(k, caddr(tree)); } /** - * Construct a new tree from a leaf and a tree. + * Construct a new rooted binary tree from a leaf and a tree. */ -template<typename T> inline const list<T> constree(const T& e, const list<T>& tree) { +template<typename T> inline const list<T> rbtreeCons(const T& e, const list<T>& tree) { if (isNil(tree)) - return mktree(e, list<T>(), list<T>()); + return mkrbtree(e, list<T>(), list<T>()); if (e == car(tree)) return tree; if (e < car(tree)) - return mktree<T>(car(tree), constree<T>(e, cadr(tree)), caddr(tree)); - return mktree<T>(car(tree), cadr(tree), constree<T>(e, caddr(tree))); + return mkrbtree<T>(car(tree), rbtreeCons<T>(e, cadr(tree)), caddr(tree)); + return mkrbtree<T>(car(tree), cadr(tree), rbtreeCons<T>(e, caddr(tree))); } /** - * Make a tree from an unordered list of leaves. + * Make a rooted binary tree from an unordered list of leaves. */ -template<typename T> inline const list<T> mktree(const list<T>& l) { +template<typename T> inline const list<T> mkrbtree(const list<T>& l) { if (isNil(l)) return l; - return constree(car(l), mktree(cdr(l))); + return rbtreeCons(car(l), mkrbtree(cdr(l))); } /** - * Convert a tree to an ordered list of leaves. + * Convert a rooted binary tree to an ordered list of leaves. */ template<typename T> inline const list<T> flatten(const list<T>& tree) { if (isNil(tree)) @@ -87,28 +205,28 @@ template<typename T> inline const list<T> flatten(const list<T>& tree) { } /** - * Sort a list. + * Sort a list, using a rooted binary tree. */ template<typename T> inline const list<T> sort(const list<T>& l) { - return flatten(mktree(l)); + return flatten(mkrbtree(l)); } /** - * Make a balanced tree from an ordered list of leaves. + * Make a balanced rooted binary tree from an ordered list of leaves. */ -template<typename T> inline const list<T> btreeHelper(const list<T>& elements, const size_t n) { +template<typename T> inline const list<T> brbtreeHelper(const list<T>& elements, const size_t n) { if (n == 0) return cons<T>(list<T>(), elements); const size_t leftSize = (n - 1) / 2; { - const list<T> leftResult = btreeHelper<T>(elements, leftSize); { + const list<T> leftResult = brbtreeHelper<T>(elements, leftSize); { const list<T> leftTree = car(leftResult); const list<T> nonLeftElements = cdr(leftResult); const size_t rightSize = n - (leftSize + 1); { const T thisEntry = car(nonLeftElements); - const list<T> rightResult = btreeHelper<T>(cdr(nonLeftElements), rightSize); { + const list<T> rightResult = brbtreeHelper<T>(cdr(nonLeftElements), rightSize); { const list<T> rightTree = car(rightResult); const list<T> remainingElements = cdr(rightResult); { - return cons<T>(mktree<T>(thisEntry, leftTree, rightTree), remainingElements); + return cons<T>(mkrbtree<T>(thisEntry, leftTree, rightTree), remainingElements); } } } @@ -116,8 +234,8 @@ template<typename T> inline const list<T> btreeHelper(const list<T>& elements, c } } -template<typename T> inline const list<T> mkbtree(const list<T>& elements) { - return car(btreeHelper<T>(elements, length(elements))); +template<typename T> inline const list<T> mkbrbtree(const list<T>& elements) { + return car(brbtreeHelper<T>(elements, length(elements))); } } diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index 60fb29070c..d5ce34084a 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -27,6 +27,7 @@ */ #include <stdlib.h> +#include <math.h> #include <apr_uuid.h> #include <apr_time.h> @@ -184,12 +185,6 @@ public: debug_watchValue(); } - inline value(const list<list<value> >& l) noexcept : type(value::List), lst(new (gc_new<list<value> >()) list<value>(listOfValues(l))) { - debug_inc(countValues); - debug_inc(countVValues); - debug_watchValue(); - } - inline value(const double d) noexcept : type(value::Number), num(d) { debug_inc(countValues); debug_inc(countVValues); @@ -249,7 +244,8 @@ public: case value::String: return (v.type == value::Symbol || v.type == value::String) && str == v.str; case value::Number: - return v.type == value::Number && num == v.num; + // Handle double floating point rounding + return v.type == value::Number && fabs(num - v.num) < 5e-16; case value::Bool: return v.type == value::Bool && boo == v.boo; case value::Ptr: @@ -363,33 +359,23 @@ public: } inline operator const list<value>() const noexcept { + switch(type) { + case value::List: + return *lst; + default: + return nilListValue; + } return *lst; } - inline operator const list<list<value> >() const noexcept { - return listOfListOfValues(*lst); - } - inline operator const lvvlambda() const noexcept { return func; } private: - inline const list<value> listOfValues(const list<list<value> >& l) const noexcept { - if (isNil(l)) - return nilListValue; - return cons<value>(car(l), listOfValues(cdr(l))); - } - - inline const list<list<value> > listOfListOfValues(const list<value>& l) const noexcept { - if (isNil(l)) - return list<list<value> >(); - return cons<list<value> >(car(l).type == value::List? list<value>(car(l)) : nilPairValue, listOfListOfValues(cdr(l))); - } - friend ostream& operator<<(ostream&, const value&) noexcept; friend const value::ValueType type(const value& v) noexcept; - friend const bool setvalue(value& target, const value& v); + friend const bool setvalue(value& target, const value& v) noexcept; #ifdef WANT_MAINTAINER_WATCH friend const string watchValue(const value& v); @@ -566,6 +552,13 @@ inline const bool isTaggedList(const value& exp, const value& tag) noexcept { } /** + * Returns true if a value is an assoc. + */ +inline const bool isAssoc(const value& exp) noexcept { + return isList(exp) && !isNil((list<value>)exp) && isSymbol(car<value>(exp)); +} + +/** * Make a list of values from a list of other things. */ template<typename T> inline const list<value> mkvalues(const list<T>& l) noexcept { @@ -584,6 +577,24 @@ template<typename T> inline const list<T> convertValues(const list<value>& l) no } /** + * Convert a list of lists of values to a list of values. + */ +inline const list<value> listOfValues(const list<list<value> >& l) noexcept { + if (isNil(l)) + return nilListValue; + return cons<value>(car(l), listOfValues(cdr(l))); +} + +/** + * Convert a list of values to a list of lists of values. + */ +inline const list<list<value> > listOfListOfValues(const list<value>& l) noexcept { + if (isNil(l)) + return list<list<value> >(); + return cons<list<value> >(type(car(l)) == value::List? list<value>(car(l)) : nilPairValue, listOfListOfValues(cdr(l))); +} + +/** * Convert a path string value to a list of values. */ inline const list<string> pathTokens(const char* const p) noexcept { @@ -638,7 +649,7 @@ inline const value mkrand() noexcept { /** * Set a value. Use with moderation. */ -inline const bool setvalue(value& target, const value& v) { +inline const bool setvalue(value& target, const value& v) noexcept { if (&target == &v) return true; #ifdef WANT_MAINTAINER_WATCH |