summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/kernel')
-rw-r--r--sca-cpp/trunk/kernel/element.hpp31
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp31
-rw-r--r--sca-cpp/trunk/kernel/kernel-test.cpp105
-rw-r--r--sca-cpp/trunk/kernel/list.hpp218
-rw-r--r--sca-cpp/trunk/kernel/stream.hpp2
-rw-r--r--sca-cpp/trunk/kernel/tree.hpp168
-rw-r--r--sca-cpp/trunk/kernel/value.hpp61
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