diff options
Diffstat (limited to 'sca-cpp/trunk')
-rw-r--r-- | sca-cpp/trunk/kernel/debug.hpp | 9 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/dynlib-test.cpp | 4 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/element.hpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/function.hpp | 6 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/gc.hpp | 7 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/kernel-test.cpp | 313 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/list.hpp | 127 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/monad.hpp | 26 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/parallel.hpp | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/tree.hpp | 125 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/value.hpp | 226 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/xml.hpp | 6 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/atom/atom.hpp | 4 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/curl.hpp | 18 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/json/json.hpp | 6 |
15 files changed, 515 insertions, 366 deletions
diff --git a/sca-cpp/trunk/kernel/debug.hpp b/sca-cpp/trunk/kernel/debug.hpp index 8dad5fdd3c..c06fe55f4a 100644 --- a/sca-cpp/trunk/kernel/debug.hpp +++ b/sca-cpp/trunk/kernel/debug.hpp @@ -26,6 +26,9 @@ * Functions to help log and debug. */ +#include <string> +#include <ostream> + namespace tuscany { @@ -35,7 +38,7 @@ namespace tuscany * Debug log. */ template<typename V> const bool debug(const V& v, const std::string& msg) { - std::cerr<< msg << ": " << v << std::endl; + std::cerr << msg << ": " << v << std::endl; return true; } @@ -52,6 +55,9 @@ bool debug_dec(long int& c) { return true; } +/** + * Attribute used to mark unused parameters. + */ #define unused __attribute__ ((unused)) #else @@ -60,6 +66,7 @@ bool debug_dec(long int& c) { #define debug_inc(c) #define debug_dec(c) + #define unused #endif diff --git a/sca-cpp/trunk/kernel/dynlib-test.cpp b/sca-cpp/trunk/kernel/dynlib-test.cpp index 3cc666df1a..9d0e6a2186 100644 --- a/sca-cpp/trunk/kernel/dynlib-test.cpp +++ b/sca-cpp/trunk/kernel/dynlib-test.cpp @@ -42,8 +42,8 @@ extern "C" { return tuscany::test::cppsquare(x); } - const tuscany::lambda<int(int)> csquarel() { - return tuscany::lambda<int(int)>(tuscany::test::cppsquare); + const tuscany::lambda<int(const int)> csquarel() { + return tuscany::lambda<int(const int)>(tuscany::test::cppsquare); } } diff --git a/sca-cpp/trunk/kernel/element.hpp b/sca-cpp/trunk/kernel/element.hpp index 2b5336ba5c..612752d1df 100644 --- a/sca-cpp/trunk/kernel/element.hpp +++ b/sca-cpp/trunk/kernel/element.hpp @@ -247,7 +247,7 @@ struct selectorLambda { } }; -const lambda<bool(value)> selector(const list<value> s) { +const lambda<bool(const value&)> selector(const list<value> s) { return selectorLambda(s); } diff --git a/sca-cpp/trunk/kernel/function.hpp b/sca-cpp/trunk/kernel/function.hpp index fb2ad296d7..54784b5549 100644 --- a/sca-cpp/trunk/kernel/function.hpp +++ b/sca-cpp/trunk/kernel/function.hpp @@ -140,11 +140,11 @@ public: debug_inc(countELambdas); } - template<typename F> lambda(const F f) : callable(0) { - typedef typename CallableType::template Proxy<F> ProxyType; - + template<typename F> lambda(const F f) { debug_inc(countLambdas); debug_inc(countFLambdas); + + typedef typename CallableType::template Proxy<F> ProxyType; callable = gc_counting_ptr<CallableType>(new ProxyType(f)); } diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp index bb5bbccb24..c9a1a35756 100644 --- a/sca-cpp/trunk/kernel/gc.hpp +++ b/sca-cpp/trunk/kernel/gc.hpp @@ -35,11 +35,10 @@ namespace tuscany /** * Macros used to add or subtract values to reference counters. - * In a multithreaded environment, define MTHREAD_GC to use - * the GCC __sync_add_and_fetch and __sync_sub_and_fetch built - * in functions. + * In a multithreaded environment, use the GCC __sync_add_and_fetch + * and __sync_sub_and_fetch built in functions. */ -#ifdef MTHREAD_GC +#ifdef _REENTRANT #define gc_add_and_fetch(t, v) __sync_add_and_fetch(&(t), v) #define gc_sub_and_fetch(t, v) __sync_sub_and_fetch(&(t), v) diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp index 388fbf7436..8a5e4a704d 100644 --- a/sca-cpp/trunk/kernel/kernel-test.cpp +++ b/sca-cpp/trunk/kernel/kernel-test.cpp @@ -20,24 +20,21 @@ /* $Rev$ $Date$ */ /** - * Test core utils. + * Test kernel functions. */ #include <assert.h> -#include <sys/time.h> -#include <time.h> #include <iostream> #include <string> #include <sstream> #include "function.hpp" #include "list.hpp" #include "slist.hpp" -#include "parallel.hpp" +#include "tree.hpp" #include "value.hpp" -#include "element.hpp" -#include "xml.hpp" #include "monad.hpp" #include "dynlib.hpp" +#include "perf.hpp" namespace tuscany { @@ -55,22 +52,22 @@ const int square(const int x) { return x * x; } -int mapLambda(lambda<int(int)> f, int v) { +int mapLambda(lambda<int(const int)> f, int v) { return f(v); } bool testLambda() { - const lambda<int(int)> sq(square); + const lambda<int(const int)> sq(square); assert(sq(2) == 4); assert(mapLambda(sq, 2) == 4); assert(mapLambda(square, 2) == 4); - const lambda<int(int)> incf(inc(10)); + const lambda<int(const int)> incf(inc(10)); assert(incf(1) == 11); assert(mapLambda(incf, 1) == 11); assert(mapLambda(inc(10), 1) == 11); - lambda<int(int)> l; + lambda<int(const int)> l; l = incf; assert(l(1) == 11); l = square; @@ -113,6 +110,10 @@ struct Element { return o.i == i; } }; +std::ostream& operator<<(std::ostream& out, const Element& v) { + out << v.i ; + return out; +} bool testCons() { assert(car(cons(2, mklist(3))) == 2); @@ -195,6 +196,10 @@ struct Complex { x(x), y(y) { } }; +std::ostream& operator<<(std::ostream& out, const Complex& v) { + out << "[" << v.x << ":" << v.y << "]"; + return out; +} bool testComplex() { const list<Complex> p = mklist(Complex(1, 2), Complex(3, 4)); @@ -219,12 +224,12 @@ const int add(const int x, const int y) { } bool testReduce() { - const lambda<int(int, int)> r(add); + const lambda<int(const int, const int)> r(add); assert(reduce(r, 0, mklist(1, 2, 3)) == 6); return true; } -bool isPositive(int x) { +bool isPositive(const int x) { if(x >= 0) return true; else @@ -306,8 +311,6 @@ bool testSeq() { list<double> s = seq(0.0, 1000.0); assert(1001 == length(s)); - //printLambdaCounters(); - //printListCounters(); assert(1001 == length(map<double, double>(testSeqMap, s))); @@ -315,9 +318,6 @@ bool testSeq() { assert(201 == length(member(200.0, reverse(s)))); assert(1001 == (reduce<double, double>(testSeqReduce, 0.0, s))); - //printLambdaCounters(); - //printListCounters(); - return true; } @@ -329,7 +329,7 @@ bool testValue() { assert(value(true) == value(true)); assert(value(1) == value(1)); assert(value("abcd") == value("abcd")); - lambda<value(list<value>&)> vl(valueSquare); + lambda<value(const list<value>&)> vl(valueSquare); assert(value(vl) == value(vl)); assert(value(mklist<value>(1, 2)) == value(mklist<value>(1, 2))); @@ -357,6 +357,40 @@ bool testValueGC() { return true; } +bool testTree() { + const list<value> t = mktree<value>("a", list<value>(), list<value>()); + 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")); + 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); + assert(car(bt) == "c"); + return true; +} + +const list<value> lta(const std::string& x) { + return mklist<value>(x.c_str(), (x + x).c_str()); +} + +bool testTreeAssoc() { + const list<value> t = mktree<value>(lta("a"), list<value>(), list<value>()); + 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 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); + 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))); + return true; +} + double fib_aux(double n, double a, double b) { if(n == 0.0) return a; @@ -367,19 +401,31 @@ double fib(double n) { return fib_aux(n, 0.0, 1.0); } -bool testCppPerf() { - struct timeval start; - struct timeval end; - { - gettimeofday(&start, NULL); +struct fibMapPerf { + const bool operator()() const { + list<double> s = seq(0.0, 999.0); + list<double> r = map<double, double>(fib, s); + assert(1000 == length(r)); + return true; + } +}; +struct nestedFibMapPerf { + const lambda<double(const double)> fib; + nestedFibMapPerf(const lambda<double(const double)>& fib) : fib(fib) { + } + const bool operator()() const { list<double> s = seq(0.0, 999.0); list<double> r = map<double, double>(fib, s); assert(1000 == length(r)); + return true; + } +}; - gettimeofday(&end, NULL); - //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); - //std::cout << "Fib cpp function map perf test " << t << " ms" << std::endl; +bool testCppPerf() { + { + const lambda<bool()> fml = fibMapPerf(); + std::cout << "Fibonacci map test " << (time(fml, 1, 1) / 1000) << " ms" << std::endl; } { @@ -396,197 +442,8 @@ bool testCppPerf() { } }; - gettimeofday(&start, NULL); - - list<double> s = seq(0.0, 999.0); - list<double> r = map(lambda<double(double)>(nested::fib), s); - assert(1000 == length(r)); - - gettimeofday(&end, NULL); - //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); - //std::cout << "Fib cpp nested function map perf test " << t << " ms" << std::endl; - } - return true; -} - -bool testAtomicPerf() { - struct timeval start; - struct timeval end; - { - gettimeofday(&start, NULL); - for(int i = 0; i < 10000000;) - i = i + 1; - gettimeofday(&end, NULL); - //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); - //std::cout << "Loop test " << t << " ms" << std::endl; - } - { - gettimeofday(&start, NULL); - for(int i = 0; i < 10000000;) - __sync_add_and_fetch(&i, 1); - gettimeofday(&end, NULL); - //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); - //std::cout << "Loop atomic test " << t << " ms" << std::endl; - } - { - pthread_mutex_t mutex; - pthread_mutex_init(&mutex, NULL); - gettimeofday(&start, NULL); - for(int i = 0; i < 10000000;) { - pthread_mutex_lock(&mutex); - i = i + 1; - pthread_mutex_unlock(&mutex); - } - gettimeofday(&end, NULL); - pthread_mutex_destroy(&mutex); - //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); - //std::cout << "Loop mutex test " << t << " ms" << std::endl; - } - return true; -} - -const int mtsquare(const int x) { - //std::cout << "thread " << threadId() << " mtsquare(" << x << ")\n"; - for(int i = 0; i < 10000000; i++) - ; - return x * x; -} - -bool testWorker() { - worker w(10); - { - const lambda<int()> func = curry(lambda<int(int)> (mtsquare), 2); - assert(submit(w, func) == 4); - } - { - const int max = 10; - - list<future<int> > r; - for(int i = 0; i < max; i++) { - const lambda<int()> func = curry(lambda<int(int)> (mtsquare), i); - r = cons(submit(w, func), r); - } - for(int i = max - 1; i >= 0; i--) { - assert(car(r) == i * i); - r = cdr(r); - } - } - shutdown(w); - return true; -} - -const std::string currencyXML = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200903\" " -"xmlns:t=\"http://tuscany.apache.org/xmlns/sca/1.1\" " -"targetNamespace=\"http://services\" " -"name=\"currency\">" -"<component name=\"CurrencyConverterWebService\">" -"<implementation.java class=\"services.CurrencyConverterImpl\"/>" -"<service name=\"CurrencyConverter\">" -"<binding.ws/>" -"</service>" -"</component>" -"<component name=\"CurrencyConverterWebService2\">" -"<implementation.java class=\"services.CurrencyConverterImpl2\"/>" -"<service name=\"CurrencyConverter2\">" -"<binding.atom/>" -"</service>" -"<property name=\"currency\">US</property>" -"</component>" -"</composite>" -"\n"; - -const std::string customerXML = -"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" -"<customer>" -"<name>jdoe</name>" -"<address><city>san francisco</city><state>ca</state></address>" -"<account><id>1234</id><balance>1000</balance></account>" -"<account><id>6789</id><balance>2000</balance></account>" -"<account><id>4567</id><balance>3000</balance></account>" -"</customer>" -"\n"; - - -const bool isName(const value& token) { - return isTaggedList(token, attribute) && attributeName(token) == "name"; -} - -bool testReadXML() { - { - std::istringstream is(customerXML); - const list<value> c = readXML(streamList(is)); - } - { - std::istringstream is(currencyXML); - const list<value> c = readXML(streamList(is)); - - const value composite = car(c); - assert(isTaggedList(composite, element)); - assert(elementName(composite) == "composite"); - assert(attributeValue(car(filter<value>(isName, elementChildren(composite)))) == std::string("currency")); - } - return true; -} - -std::ostringstream* xmlWriter(const std::string& s, std::ostringstream* os) { - (*os) << s; - return os; -} - -bool testWriteXML() { - { - std::istringstream is(customerXML); - const list<value> c = readXML(streamList(is)); - std::ostringstream os; - writeXML<std::ostringstream*>(xmlWriter, &os, c); - assert(os.str() == customerXML); - } - { - std::istringstream is(currencyXML); - const list<value> c = readXML(streamList(is)); - std::ostringstream os; - writeXML<std::ostringstream*>(xmlWriter, &os, c); - assert(os.str() == currencyXML); - } - return true; -} - -bool testElement() { - { - const list<value> ad = mklist<value>(mklist<value>("city", std::string("san francisco")), mklist<value>("state", std::string("ca"))); - const list<value> ac1 = mklist<value>(mklist<value>("id", std::string("1234")), mklist<value>("balance", 1000)); - const list<value> ac2 = mklist<value>(mklist<value>("id", std::string("6789")), mklist<value>("balance", 2000)); - const list<value> ac3 = mklist<value>(mklist<value>("id", std::string("4567")), mklist<value>("balance", 3000)); - { - const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", std::string("jdoe")), cons<value>("address", ad), mklist<value>("account", mklist<value>(ac1, ac2, ac3)))); - const list<value> e = valuesToElements(c); - const list<value> v = elementsToValues(e); - assert(v == c); - - std::ostringstream os; - writeXML<std::ostringstream*>(xmlWriter, &os, e); - assert(os.str() == customerXML); - } - { - const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", std::string("jdoe")), cons<value>("address", ad), cons<value>("account", ac1), cons<value>("account", ac2), cons<value>("account", ac3))); - const list<value> e = valuesToElements(c); - const list<value> v = elementsToValues(e); - - std::ostringstream os; - writeXML<std::ostringstream*>(xmlWriter, &os, e); - assert(os.str() == customerXML); - } - } - { - std::istringstream is(customerXML); - const list<value> c = readXML(streamList(is)); - const list<value> v = elementsToValues(c); - const list<value> e = valuesToElements(v); - std::ostringstream os; - writeXML<std::ostringstream*>(xmlWriter, &os, e); - assert(os.str() == customerXML); + const lambda<bool()> nfml = nestedFibMapPerf(lambda<double(const double)>(nested::fib)); + std::cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << std::endl; } return true; } @@ -651,8 +508,9 @@ bool testFailableMonad() { assert((m >> success<int, std::string>()) == m); assert(m >> failableF >> failableG == m >> failableH); - failable<int, std::string> ooops = mkfailure<int, std::string>("ooops"); - assert(reason(ooops) == "ooops"); + std::cout << "Failable monad test... "; + failable<int, std::string> ooops = mkfailure<int, std::string>("test"); + assert(reason(ooops) == "test"); assert(ooops >> failableF >> failableG == ooops); return true; } @@ -683,7 +541,7 @@ const state<int, double> stateH(const double v) { } bool testStateMonad() { - const lambda<state<int, double>(double)> r(result<int, double>); + const lambda<state<int, double>(const double)> r(result<int, double>); state<int, double> m = result<int, double>(2.0); assert((m >> stateF)(0) == stateF(2.0)(0)); @@ -697,14 +555,14 @@ bool testStateMonad() { bool testDynLib() { const failable<lib, std::string> dl(dynlib(".libs/libdynlib-test" + dynlibExt)); assert(hasContent(dl)); - const failable<lambda<int(int)>, std::string> sq(dynlambda<int(int)>("csquare", content(dl))); + const failable<lambda<int(const int)>, std::string> sq(dynlambda<int(const int)>("csquare", content(dl))); assert(hasContent(sq)); - lambda<int(int)> l(content(sq)); + lambda<int(const int)> l(content(sq)); assert(l(2) == 4); - const failable<lambda<lambda<int(int)>()>, std::string> sql(dynlambda<lambda<int(int)>()>("csquarel", content(dl))); + const failable<lambda<lambda<int(const int)>()>, std::string> sql(dynlambda<lambda<int(const int)>()>("csquarel", content(dl))); assert(hasContent(sql)); - lambda<lambda<int(int)>()> ll(content(sql)); + lambda<lambda<int(const int)>()> ll(content(sql)); assert(ll()(3) == 9); return true; } @@ -736,12 +594,9 @@ int main() { tuscany::testSeq(); tuscany::testValue(); tuscany::testValueGC(); - tuscany::testElement(); + tuscany::testTree(); + tuscany::testTreeAssoc(); tuscany::testCppPerf(); - tuscany::testAtomicPerf(); - tuscany::testWorker(); - tuscany::testReadXML(); - tuscany::testWriteXML(); tuscany::testIdMonad(); tuscany::testMaybeMonad(); tuscany::testFailableMonad(); diff --git a/sca-cpp/trunk/kernel/list.hpp b/sca-cpp/trunk/kernel/list.hpp index da00a5a40d..88163e63d2 100644 --- a/sca-cpp/trunk/kernel/list.hpp +++ b/sca-cpp/trunk/kernel/list.hpp @@ -26,6 +26,8 @@ * Simple list functions. */ +#include <string> +#include <sstream> #include <iostream> #include "function.hpp" #include "debug.hpp" @@ -35,7 +37,9 @@ namespace tuscany { #ifdef _DEBUG /** - * Debug counters. + * Debug utilities. Counters used to track instances of lists, and + * macro used to write the contents of a list in a string, easier to + * watch in a debugger than the list itself. */ long countLists = 0; long countILists = 0; @@ -59,12 +63,18 @@ bool printListCounters() { return true; } +#define debug_watchList() do { \ + this->watch = watchList(*this); \ + } while (0) + #else #define resetListCounters() #define checkListCounters() true #define printListCounters() +#define debug_watchList(); + #endif @@ -78,18 +88,23 @@ public: list() { debug_inc(countLists); debug_inc(countELists); + debug_watchList(); } - list(const T car, const lambda<list<T> ()>& cdr) : + list(const T car, const lambda<list<T>()>& cdr) : car(car), cdr(cdr) { debug_inc(countLists); debug_inc(countILists); + debug_watchList(); } list(const list& p) : car(p.car), cdr(p.cdr) { debug_inc(countLists); debug_inc(countCLists); +#ifdef _DEBUG + watch = p.watch; +#endif } const list& operator=(const list<T>& p) { @@ -97,6 +112,9 @@ public: return *this; car = p.car; cdr = p.cdr; +#ifdef _DEBUG + watch = p.watch; +#endif return *this; } @@ -118,6 +136,34 @@ public: return cdr() == p.cdr(); } + const bool operator<(const list<T>& p) const { + if(this == &p) + return false; + if (isNil(cdr)) + return !isNil(p.cdr); + if (isNil(p.cdr)) + return false; + if (car < p.car) + return true; + if (car != p.car) + return false; + return cdr() < p.cdr(); + } + + const bool operator>(const list<T>& p) const { + if(this == &p) + return false; + if (isNil(cdr)) + return false; + if (isNil(p.cdr)) + return true; + if (car > p.car) + return true; + if (car != p.car) + return false; + return cdr() > p.cdr(); + } + const bool operator!=(const list<T>& p) const { return !this->operator==(p); } @@ -136,13 +182,33 @@ public: template<typename X> friend const list<X> cdr(const list<X>& p); template<typename X> friend const bool setCar(list<X>& p, const X& car); template<typename X> friend const bool setCdr(list<X>& p, const list<X>& cdr); - template<typename X> friend const bool setCdr(list<X>& p, const lambda<list<X> ()>& cdr); + template<typename X> friend const bool setCdr(list<X>& p, const lambda<list<X>()>& cdr); private: +#ifdef _DEBUG + template<typename X> friend const std::string watchList(const list<X>& p); + std::string watch; +#endif + T car; - lambda<list<T> ()> cdr; + lambda<list<T>()> cdr; }; +#ifdef _DEBUG + +/** + * 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> const std::string watchList(const list<T>& p) { + if(isNil(p)) + return "()"; + std::ostringstream os; + os << "(" << car(p) << " ...)"; + return os.str(); +} +#endif + /** * Returns true if the given list is nil. */ @@ -153,25 +219,25 @@ template<typename T> const bool isNil(const list<T>& p) { /** * Write a list to an output stream. */ +template<typename T> std::ostream& writeHelper(std::ostream& out, const list<T>& l) { + if (isNil(l)) + return out; + out << " " << car(l); + return writeHelper(out, cdr(l)); +} + template<typename T> std::ostream& operator<<(std::ostream& out, const list<T>& l) { if(isNil(l)) return out << "()"; - out << "("; - list<T> ml = l; - while(true) { - out << car(ml); - ml = cdr(ml); - if (isNil(ml)) - break; - out << " "; - } + out << "(" << car(l); + writeHelper<T>(out, cdr(l)); return out << ")"; } /** * Construct a (lazy) list from a value and a lambda function that returns the cdr. */ -template<typename T> const list<T> cons(const T& car, const lambda<list<T> ()>& cdr) { +template<typename T> const list<T> cons(const T& car, const lambda<list<T>()>& cdr) { return list<T> (car, cdr); } @@ -268,7 +334,7 @@ template<typename T> const bool setCdr(list<T>& p, const list<T>& c) { /** * Sets the cdr of a list to a lambda function. */ -template<typename T> const bool setCdr(list<T>& p, const lambda<list<T> ()>& cdr) { +template<typename T> const bool setCdr(list<T>& p, const lambda<list<T>()>& cdr) { p.cdr = cdr; return true; } @@ -289,6 +355,13 @@ template<typename T> const T caddr(const list<T>& p) { } /** + * Returns the car of the cdr of the cdr of the cdr of a list. + */ +template<typename T> const T cadddr(const list<T>& p) { + return car(cdr(cdr(cdr(p)))); +} + +/** * Returns the cdr of a cdr of a list. */ template<typename T> const list<T> cddr(const list<T>& p) { @@ -322,8 +395,8 @@ template<typename T> const int length(const list<T>& p) { */ template<typename T> struct appendCdr { const list<T> a; - const lambda<list<T> ()> fb; - appendCdr(const list<T>& a, const lambda<list<T> ()>& fb) : + const lambda<list<T>()> fb; + appendCdr(const list<T>& a, const lambda<list<T>()>& fb) : a(a), fb(fb) { } const list<T> operator()() const { @@ -331,7 +404,7 @@ template<typename T> struct appendCdr { } }; -template<typename T> const list<T> append(const list<T>&a, const lambda<list<T> ()>& fb) { +template<typename T> const list<T> append(const list<T>&a, const lambda<list<T>()>& fb) { if(isNil(a)) return fb(); @@ -348,7 +421,7 @@ template<typename T> const list<T> append(const list<T>&a, const list<T>& b) { /** * Map a lambda function on a list. */ -template<typename T, typename R> const list<R> map(const lambda<R(T)>& f, const list<T>& p) { +template<typename T, typename R> const list<R> map(const lambda<R(const T)>& f, const list<T>& p) { if(isNil(p)) return list<R> (); return cons(f(car(p)), map(f, cdr(p))); @@ -358,8 +431,8 @@ template<typename T, typename R> const list<R> map(const lambda<R(T)>& f, const * Run a reduce lambda function on a list. */ template<typename T, typename R> struct reduceAccumulate { - const lambda<R(R, T)> f; - reduceAccumulate(const lambda<R(R, T)>& f) : + const lambda<R(const R&, const T&)> f; + reduceAccumulate(const lambda<R(const R, const T)>& f) : f(f) { } R operator()(const R& acc, const list<T>& p) const { @@ -369,13 +442,13 @@ template<typename T, typename R> struct reduceAccumulate { } }; -template<typename T, typename R> const R reduce(const lambda<R(R, T)>& f, const R& initial, const list<T>& p) { +template<typename T, typename R> const R reduce(const lambda<R(const R, const T)>& f, const R& initial, const list<T>& p) { return reduceAccumulate<T, R> (f)(initial, p); } template<typename T, typename R> struct reduceRightAccumulate { - const lambda<R(T, R)> f; - reduceRightAccumulate(const lambda<R(T, R)>& f) : + const lambda<R(const T&, const R&)> f; + reduceRightAccumulate(const lambda<R(const T, const R)>& f) : f(f) { } R operator()(const list<T>& p, const R& acc) const { @@ -385,18 +458,18 @@ template<typename T, typename R> struct reduceRightAccumulate { } }; -template<typename T, typename R> const R reduceRight(const lambda<R(T, R)>& f, const R& initial, const list<T>& p) { +template<typename T, typename R> const R reduceRight(const lambda<R(const T, const R)>& f, const R& initial, const list<T>& p) { return reduceRightAccumulate<T, R> (f)(p, initial); } /** * Run a filter lambda function on a list. */ -template<typename T> const list<T> filter(const lambda<bool(T)>& f, const list<T>& p) { +template<typename T> const list<T> filter(const lambda<bool(const T)>& f, const list<T>& p) { if(isNil(p)) return list<T> (); if(f(car(p))) { - const lambda<list<T> (lambda<bool(T)> , list<T> )> ff(filter<T> ); + const lambda<list<T>(const lambda<bool(const T)>, const list<T>)> ff(filter<T>); return cons(car(p), curry(ff, f, cdr(p))); } return filter(f, cdr(p)); diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp index 31eb390f1c..5449aa38fd 100644 --- a/sca-cpp/trunk/kernel/monad.hpp +++ b/sca-cpp/trunk/kernel/monad.hpp @@ -89,14 +89,14 @@ template<typename V> const id<V> mkunit(const V& v) { return id<V>(v); } -template<typename V> const lambda<id<V>(V)> unit() { +template<typename V> const lambda<id<V>(const V)> unit() { return mkunit<V>; } /** * Bind a function to an identity monad. Pass the value in the monad to the function. */ -template<typename R, typename V> const id<R> operator>>(const id<V>& m, const lambda<id<R>(V)>& f) { +template<typename R, typename V> const id<R> operator>>(const id<V>& m, const lambda<id<R>(const V)>& f) { return f(content(m)); } @@ -164,7 +164,7 @@ template<typename V> const maybe<V> mkjust(const V& v) { return maybe<V>(v); } -template<typename V> const lambda<maybe<V>(V)> just() { +template<typename V> const lambda<maybe<V>(const V)> just() { return mkjust<V>; } @@ -186,7 +186,7 @@ template<typename V> const V content(const maybe<V>& m) { * Bind a function to a maybe monad. Passes the value in the monad to the function * if present, or does nothing if there's no value. */ -template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, const lambda<maybe<R>(V)>& f) { +template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, const lambda<maybe<R>(const V)>& f) { if (!hasContent(m)) return m; return f(content(m)); @@ -274,7 +274,7 @@ template<typename V, typename F> const failable<V, F> mksuccess(const V& v) { return failable<V, F>(v); } -template<typename V, typename F> const lambda<failable<V, F>(V)> success() { +template<typename V, typename F> const lambda<failable<V, F>(const V)> success() { return mksuccess<V, F>; } @@ -286,7 +286,7 @@ template<typename V, typename F> const failable<V, F> mkfailure(const F& f) { return failable<V, F>(false, f); } -template<typename V, typename F> const lambda<failable<V, F>(V)> failure() { +template<typename V, typename F> const lambda<failable<V, F>(const V)> failure() { return mkfailure<V, F>; } @@ -316,7 +316,7 @@ template<typename V, typename F> const F reason(const failable<V, F>& m) { * if present, or does nothing if there's no value and a failure instead. */ template<typename R, typename FR, typename V, typename FV> -const failable<R, FR> operator>>(const failable<V, FV>& m, const lambda<failable<R, FR>(V)>& f) { +const failable<R, FR> operator>>(const failable<V, FV>& m, const lambda<failable<R, FR>(const V)>& f) { if (!hasContent(m)) return m; return f(content(m)); @@ -390,7 +390,7 @@ template<typename S, typename V> const S content(const scp<S, V>& m) { */ template<typename S, typename V> class state { public: - state(const lambda<scp<S, V>(S)>& f) : f(f) { + state(const lambda<scp<S, V>(const S)>& f) : f(f) { } const scp<S, V> operator()(const S& s) const { @@ -415,7 +415,7 @@ public: } private: - const lambda<scp<S, V>(S)> f; + const lambda<scp<S, V>(const S)> f; }; /** @@ -449,7 +449,7 @@ template<typename S, typename V> const state<S, V> result(const V& v) { * A transformer function takes a state and returns an scp pair carrying a content and a * new (transformed) state. */ -template<typename S, typename V> const state<S, V> transformer(const lambda<scp<S, V>(S)>& f) { +template<typename S, typename V> const state<S, V> transformer(const lambda<scp<S, V>(const S)>& f) { return state<S, V>(f); } @@ -459,9 +459,9 @@ template<typename S, typename V> const state<S, V> transformer(const lambda<scp< */ template<typename S, typename A, typename B> struct stateBind { const state<S, A> st; - const lambda<state<S, B>(A)>f; + const lambda<state<S, B>(const A)>f; - stateBind(const state<S, A>& st, const lambda<state<S, B>(A)>& f) : st(st), f(f) { + stateBind(const state<S, A>& st, const lambda<state<S, B>(const A)>& f) : st(st), f(f) { } const scp<S, B> operator()(const S& is) const { @@ -472,7 +472,7 @@ template<typename S, typename A, typename B> struct stateBind { }; template<typename S, typename A, typename B> -const state<S, B> operator>>(const state<S, A>& st, const lambda<state<S, B>(A)>& f) { +const state<S, B> operator>>(const state<S, A>& st, const lambda<state<S, B>(const A)>& f) { return state<S, B>(stateBind<S, A , B>(st, f)); } diff --git a/sca-cpp/trunk/kernel/parallel.hpp b/sca-cpp/trunk/kernel/parallel.hpp index 987d662e23..a94764763a 100644 --- a/sca-cpp/trunk/kernel/parallel.hpp +++ b/sca-cpp/trunk/kernel/parallel.hpp @@ -246,7 +246,7 @@ template<typename R> bool submitFunc(const lambda<R()>& func, const future<R>& f */ template<typename R> const future<R> submit(worker& w, const lambda<R()>& func) { const future<R> fut; - const lambda<bool()> f = curry(lambda<bool(lambda<R()>, future<R>)>(submitFunc<R>), func, fut); + const lambda<bool()> f = curry(lambda<bool(const lambda<R()>, future<R>)>(submitFunc<R>), func, fut); enqueue(w.work, f); return fut; } diff --git a/sca-cpp/trunk/kernel/tree.hpp b/sca-cpp/trunk/kernel/tree.hpp new file mode 100644 index 0000000000..f0c85ff403 --- /dev/null +++ b/sca-cpp/trunk/kernel/tree.hpp @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +#ifndef tuscany_tree_hpp +#define tuscany_tree_hpp + +/** + * Functions to work with trees. + */ + +#include <iostream> +#include <string> +#include "function.hpp" +#include "list.hpp" +#include "monad.hpp" +#include "value.hpp" + +namespace tuscany { + +/** + * Make a tree from a leaf and two branches. + */ +template<typename T> const list<T> mktree(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. + */ +template<typename T> const list<T> assoctree(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)); +} + +/** + * Construct a new tree from a leaf and a tree. + */ +template<typename T> const list<T> constree(const T& e, const list<T>& tree) { + if (isNil(tree)) + return mktree(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))); +} + +/** + * Make a tree from an unordered list of leaves. + */ +template<typename T> const list<T> mktree(const list<T>& l) { + if (isNil(l)) + return l; + return constree(car(l), mktree(cdr(l))); +} + +/** + * Convert a tree to an ordered list of leaves. + */ +template<typename T> const list<T> flatten(const list<T>& tree) { + if (isNil(tree)) + return tree; + return append<T>(flatten<T>(cadr(tree)), cons<T>(car(tree), flatten<T>(caddr(tree)))); +} + +/** + * Sort a list. + */ +template<typename T> const list<T> sort(const list<T>& l) { + return flatten(mktree(l)); +} + +/** + * Make a balanced tree from an ordered list of leaves. + */ +template<typename T> const list<T> btreeHelper(const list<T>& elements, const int n) { + if (n == 0) + return cons<T>(list<T>(), elements); + const int leftSize = (n - 1) / 2; { + const list<T> leftResult = btreeHelper<T>(elements, leftSize); { + const list<T> leftTree = car(leftResult); + const list<T> nonLeftElements = cdr(leftResult); + const int rightSize = n - (leftSize + 1); { + const T thisEntry = car(nonLeftElements); + const list<T> rightResult = btreeHelper<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); + } + } + } + } + } +} + +template<typename T> const list<T> mkbtree(const list<T>& elements) { + return car(btreeHelper<T>(elements, length(elements))); +} + +} + +#endif /* tuscany_tree_hpp */ diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index a99309869f..e767ead74b 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -32,6 +32,7 @@ #include "gc.hpp" #include "function.hpp" #include "list.hpp" +#include "monad.hpp" #include "debug.hpp" namespace tuscany @@ -40,7 +41,9 @@ namespace tuscany #ifdef _DEBUG /** - * Debug counters. + * Debug utilities. Counters used to track instances of values, and + * macro used to write the contents of a value in a string, easier to + * watch in a debugger than the value itself. */ long int countValues = 0; long int countEValues = 0; @@ -64,12 +67,18 @@ bool printValueCounters() { return true; } +#define debug_watchValue() do { \ + this->watch = watchValue(*this); \ + } while (0) + #else #define resetValueCounters() #define checkValueCounters() true #define printValueCounters() +#define debug_watchValue() + #endif class value; @@ -85,6 +94,7 @@ public: type(value::Undefined) { debug_inc(countValues); debug_inc(countEValues); + debug_watchValue(); } value(const value& v) { @@ -113,6 +123,9 @@ public: default: break; } +#ifdef _DEBUG + watch = v.watch; +#endif } const value& operator=(const value& v) { @@ -141,6 +154,9 @@ public: default: break; } +#ifdef _DEBUG + watch = v.watch; +#endif return *this; } @@ -148,70 +164,84 @@ public: debug_dec(countValues); } - value(const lambda<value(list<value>&)>& func) : - type(value::Lambda), data(vdata(func)) { + value(const lambda<value(const list<value>&)>& func) : type(value::Lambda), data(vdata(func)) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const std::string& str) : - type(value::String), data(vdata(result(str))) { + value(const std::string& str) : type(value::String), data(vdata(result(str))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const char* str) : - type(value::Symbol), data(vdata(result(std::string(str)))) { + value(const char* str) : type(value::Symbol), data(vdata(result(std::string(str)))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const list<value>& lst) : - type(value::List), data(vdata(result(lst))) { + value(const list<value>& lst) : type(value::List), data(vdata(result(lst))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const list<list<value> >& l) : - type(value::List), data(vdata(result(listOfValues(l)))) { + value(const list<list<value> >& l) : type(value::List), data(vdata(result(listOfValues(l)))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const double num) : - type(value::Number), data(vdata(result(num))) { + value(const double num) : type(value::Number), data(vdata(result(num))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const int num) : - type(value::Number), data(vdata(result((double)num))) { + value(const int num) : type(value::Number), data(vdata(result((double)num))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const bool boo) : - type(value::Bool), data(vdata(result(boo))) { + value(const bool boo) : type(value::Bool), data(vdata(result(boo))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const char chr) : - type(value::Char), data(vdata(result(chr))) { + value(const char chr) : type(value::Char), data(vdata(result(chr))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const gc_ptr<value> ptr) : - type(value::Ptr), data(vdata(result(ptr))) { + value(const gc_ptr<value> ptr) : type(value::Ptr), data(vdata(result(ptr))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); } - value(const gc_pool_ptr<value> ptr) : - type(value::PoolPtr), data(vdata(result(ptr))) { + value(const gc_pool_ptr<value> ptr) : type(value::PoolPtr), data(vdata(result(ptr))) { debug_inc(countValues); debug_inc(countVValues); + debug_watchValue(); + } + + value(const failable<value, std::string>& m) : type(value::List), + data(vdata(result(hasContent(m)? mklist<value>(content(m)) : mklist<value>(value(), reason(m))))) { + debug_inc(countValues); + debug_inc(countVValues); + debug_watchValue(); + } + + value(const maybe<value>& m) : type(value::List), + data(vdata(result(hasContent(m)? mklist<value>(content(m)) : list<value>()))) { + debug_inc(countValues); + debug_inc(countVValues); + debug_watchValue(); } const bool operator!=(const value& v) const { @@ -221,35 +251,75 @@ public: const bool operator==(const value& v) const { if(this == &v) return true; - if(type != v.type) - return false; switch(type) { case value::Undefined: return true; case value::List: - return lst()() == v.lst()(); + return v.type == value::List && lst()() == v.lst()(); case value::Lambda: - return func() == v.func(); + return v.type == value::Lambda && func() == v.func(); case value::Symbol: - return str()() == v.str()(); + return str()() == (std::string)v; case value::String: - return str()() == v.str()(); + return str()() == (std::string)v; case value::Number: - return num()() == v.num()(); + return num()() == (double)v; case value::Bool: - return boo()() == v.boo()(); + return boo()() == (bool)v; case value::Char: - return chr()() == v.chr()(); + return chr()() == (char)v; case value::Ptr: - return ptr()() == v.ptr()(); + return v.type == value::Ptr && ptr()() == v.ptr()(); case value::PoolPtr: - return poolptr()() == v.poolptr()(); + return v.type == value::PoolPtr && poolptr()() == v.poolptr()(); + default: + return false; + } + } + + const bool operator<(const value& v) const { + if(this == &v) + return false; + switch(type) { + case value::List: + return v.type == value::List && lst()() < v.lst()(); + case value::Symbol: + case value::String: + return str()() < (std::string)v; + return str()() < (std::string)v; + case value::Bool: + return boo()() < (bool)v; + case value::Number: + return num()() < (double)v; + case value::Char: + return chr()() < (char)v; + default: + return false; + } + } + + const bool operator>(const value& v) const { + if(this == &v) + return false; + switch(type) { + case value::List: + return v.type == value::List && lst()() > v.lst()(); + case value::Symbol: + case value::String: + return str()() > (std::string)v; + return str()() > (std::string)v; + case value::Bool: + return boo()() > (bool)v; + case value::Number: + return num()() > (double)v; + case value::Char: + return chr()() > (char)v; default: return false; } } - const value operator()(list<value>& args) const { + const value operator()(const list<value>& args) const { return func()(args); } @@ -355,17 +425,12 @@ public: return listOfListOfValues(lst()()); } - operator const lambda<value(list<value>&)>() const { + operator const lambda<value(const list<value>&)>() const { return func(); } - friend std::ostream& operator<<(std::ostream&, const value&); - - ValueType type; - lambda<char()> data; - private: - template<typename T> lambda<T>& vdata() const { + template<typename T> lambda<T>& vdata() const { return *reinterpret_cast<lambda<T> *> (const_cast<lambda<char()> *> (&data)); } @@ -401,8 +466,8 @@ private: return vdata<list<value>()> (); } - lambda<value(list<value>&)>& func() const { - return vdata<value(list<value>&)> (); + lambda<value(const list<value>&)>& func() const { + return vdata<value(const list<value>&)> (); } const list<value> listOfValues(const list<list<value> >& l) const { @@ -417,8 +482,33 @@ private: return cons<list<value> >(list<value>(car(l)), listOfListOfValues(cdr(l))); } + friend std::ostream& operator<<(std::ostream&, const value&); + friend const value::ValueType type(const value& v); + +#ifdef _DEBUG + friend const std::string watchValue(const value& v); + std::string watch; +#endif + + ValueType type; + lambda<char()> data; }; +#ifdef _DEBUG + +/** + * Debug utility used to write the contents of a value to a string, easier + * to watch than the value itself in a debugger. + */ +const std::string watchValue(const value& v) { + if (v.type == value::List) + return watchList<value>(v); + std::ostringstream os; + os << v; + return os.str(); +} +#endif + /** * Write a value to a stream. */ @@ -444,14 +534,14 @@ std::ostream& operator<<(std::ostream& out, const value& v) { case value::Ptr: { const gc_ptr<value> p = v.ptr()(); if (p == gc_ptr<value>(NULL)) - return out << "pointer::null"; - return out << "pointer::" << *p; + return out << "gc_ptr::null"; + return out << "gc_ptr::" << p; } case value::PoolPtr: { const gc_pool_ptr<value> p = v.poolptr()(); if (p == gc_pool_ptr<value>(NULL)) - return out << "pointer::null"; - return out << "pointer::" << *p; + return out << "pool_ptr::null"; + return out << "pool_ptr::" << p; } default: return out << "undefined"; @@ -468,71 +558,71 @@ const value::ValueType type(const value& v) { /** * Returns true if a value is nil. */ -const bool isNil(const value& value) { - return value.type == value::Undefined; +const bool isNil(const value& v) { + return type(v) == value::Undefined; } /** * Returns true if a value is a lambda. */ -const bool isLambda(const value& value) { - return value.type == value::Lambda; +const bool isLambda(const value& v) { + return type(v) == value::Lambda; } /** * Returns true if a value is a string. */ -const bool isString(const value& value) { - return value.type == value::String; +const bool isString(const value& v) { + return type(v) == value::String; } /** * Returns true if a value is a symbol. */ -const bool isSymbol(const value& value) { - return value.type == value::Symbol; +const bool isSymbol(const value& v) { + return type(v) == value::Symbol; } /** * Returns true if a value is a list. */ -const bool isList(const value& value) { - return value.type == value::List; +const bool isList(const value& v) { + return type(v) == value::List; } /** * Returns true if a value is a number. */ -const bool isNumber(const value& value) { - return value.type == value::Number; +const bool isNumber(const value& v) { + return type(v) == value::Number; } /** * Returns true if a value is a boolean. */ -const bool isBool(const value& value) { - return value.type == value::Bool; +const bool isBool(const value& v) { + return type(v) == value::Bool; } /** * Returns true if a value is a character. */ -const bool isChar(const value& value) { - return value.type == value::Char; +const bool isChar(const value& v) { + return type(v) == value::Char; } /** * Returns true if a value is a pointer. */ -const bool isPtr(const value& value) { - return value.type == value::Ptr; +const bool isPtr(const value& v) { + return type(v) == value::Ptr; } /** * Returns true if a value is a pooled pointer. */ -const bool isPoolPtr(const value& value) { - return value.type == value::PoolPtr; +const bool isPoolPtr(const value& v) { + return type(v) == value::PoolPtr; } /** diff --git a/sca-cpp/trunk/kernel/xml.hpp b/sca-cpp/trunk/kernel/xml.hpp index 4b4bcd098e..eee6e290d8 100644 --- a/sca-cpp/trunk/kernel/xml.hpp +++ b/sca-cpp/trunk/kernel/xml.hpp @@ -315,9 +315,9 @@ const failable<bool, std::string> write(const list<value>& l, const xmlTextWrite */ template<typename R> class XMLWriteContext { public: - XMLWriteContext(const lambda<R(std::string, R)>& reduce, const R& accum) : reduce(reduce), accum(accum) { + XMLWriteContext(const lambda<R(const std::string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) { } - const lambda<R(std::string, R)> reduce; + const lambda<R(const std::string&, const R)> reduce; R accum; }; @@ -333,7 +333,7 @@ template<typename R> int writeCallback(void *context, const char* buffer, int le /** * Convert a list of values to an XML document. */ -template<typename R> const failable<R, std::string> writeXML(const lambda<R(std::string, R)>& reduce, const R& initial, const list<value>& l) { +template<typename R> const failable<R, std::string> writeXML(const lambda<R(const std::string&, const R)>& reduce, const R& initial, const list<value>& l) { XMLWriteContext<R> cx(reduce, initial); xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback<R>, NULL, &cx, NULL); if (out == NULL) diff --git a/sca-cpp/trunk/modules/atom/atom.hpp b/sca-cpp/trunk/modules/atom/atom.hpp index 22489fd1d1..7e2eb66cd2 100644 --- a/sca-cpp/trunk/modules/atom/atom.hpp +++ b/sca-cpp/trunk/modules/atom/atom.hpp @@ -115,7 +115,7 @@ const list<value> entriesElements(const list<value>& l) { * Convert a list of values representing an ATOM entry to an ATOM entry. * The first two values in the list are the entry id and title. */ -template<typename R> const failable<R, std::string> writeATOMEntry(const lambda<R(std::string, R)>& reduce, const R& initial, const list<value>& l) { +template<typename R> const failable<R, std::string> writeATOMEntry(const lambda<R(const std::string&, const R)>& reduce, const R& initial, const list<value>& l) { return writeXML<R>(reduce, initial, mklist<value>(entryElement(l))); } @@ -130,7 +130,7 @@ const failable<list<std::string>, std::string> writeATOMEntry(const list<value>& * Convert a list of values representing an ATOM feed to an ATOM feed. * The first two values in the list are the feed id and title. */ -template<typename R> const failable<R, std::string> writeATOMFeed(const lambda<R(std::string, R)>& reduce, const R& initial, const list<value>& l) { +template<typename R> const failable<R, std::string> writeATOMFeed(const lambda<R(const std::string&, const R)>& reduce, const R& initial, const list<value>& l) { const list<value> f = list<value>() << element << "feed" << (list<value>() << attribute << "xmlns" << "http://www.w3.org/2005/Atom") << (list<value>() << element << "title" << (list<value>() << attribute << "type" << "text") << car(l)) diff --git a/sca-cpp/trunk/modules/http/curl.hpp b/sca-cpp/trunk/modules/http/curl.hpp index fd2e9857d1..85665c2785 100644 --- a/sca-cpp/trunk/modules/http/curl.hpp +++ b/sca-cpp/trunk/modules/http/curl.hpp @@ -35,6 +35,7 @@ #include "value.hpp" #include "element.hpp" #include "monad.hpp" +#include "parallel.hpp" #include "../atom/atom.hpp" #include "../json/json.hpp" @@ -126,9 +127,9 @@ size_t readCallback(void *ptr, size_t size, size_t nmemb, void *data) { */ template<typename R> class CURLWriteContext { public: - CURLWriteContext(const lambda<R(std::string, R)>& reduce, const R& accum) : reduce(reduce), accum(accum) { + CURLWriteContext(const lambda<R(const std::string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) { } - const lambda<R(std::string, R)> reduce; + const lambda<R(const std::string&, const R)> reduce; R accum; }; @@ -162,7 +163,7 @@ curl_slist* headers(curl_slist* cl, const list<std::string>& h) { return headers(curl_slist_append(cl, std::string(car(h)).c_str()), cdr(h)); } -template<typename R> const failable<list<R>, std::string> apply(const list<list<std::string> >& req, const lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, const std::string& verb, const CURLSession& cs) { +template<typename R> const failable<list<R>, std::string> apply(const list<list<std::string> >& req, const lambda<R(const std::string&, const R)>& reduce, const R& initial, const std::string& url, const std::string& verb, const CURLSession& cs) { // Init the curl session CURL* ch = handle(cs); @@ -174,8 +175,6 @@ template<typename R> const failable<list<R>, std::string> apply(const list<list< write(cadr(req), os); const std::string s = os.str(); const int sz = s.length(); - if (sz < 1400) - curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true); // Setup the read, header and write callbacks CURLReadContext rcx(mklist(s)); @@ -187,6 +186,7 @@ template<typename R> const failable<list<R>, std::string> apply(const list<list< CURLWriteContext<R> wcx(reduce, initial); curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, (size_t (*)(void*, size_t, size_t, void*))writeCallback<R>); curl_easy_setopt(ch, CURLOPT_WRITEDATA, &wcx); + curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true); // Set the request headers curl_slist* hl = headers(NULL, car(req)); @@ -291,7 +291,7 @@ const failable<std::string, std::string> contentType(const list<std::string>& h) /** * HTTP GET, return the resource at the given URL. */ -template<typename R> const failable<list<R>, std::string> get(const lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, const CURLSession& ch) { +template<typename R> const failable<list<R>, std::string> get(const lambda<R(const std::string&, const R)>& reduce, const R& initial, const std::string& url, const CURLSession& ch) { debug(url, "http::get::url"); const list<list<std::string> > req = mklist(list<std::string>(), list<std::string>()); return apply(req, reduce, initial, url, "GET", ch); @@ -391,18 +391,18 @@ const failable<value, std::string> del(const std::string& url, const CURLSession * HTTP client proxy function. */ struct proxy { - proxy(const std::string& url, const CURLSession& ch) : url(url), ch(ch) { + proxy(const std::string& url) : url(url) { } const value operator()(const list<value>& args) const { - failable<value, std::string> val = evalExpr(args, url, ch); + CURLSession cs; + failable<value, std::string> val = evalExpr(args, url, cs); if (!hasContent(val)) return value(); return content(val); } const std::string url; - const CURLSession ch; }; } diff --git a/sca-cpp/trunk/modules/json/json.hpp b/sca-cpp/trunk/modules/json/json.hpp index 7d9bba564e..6ce4e3a9a1 100644 --- a/sca-cpp/trunk/modules/json/json.hpp +++ b/sca-cpp/trunk/modules/json/json.hpp @@ -332,10 +332,10 @@ const failable<bool, std::string> writeList(const list<value>& l, JSObject* o, c */ template<typename R> class WriteContext { public: - WriteContext(const lambda<R(std::string, R)>& reduce, const R& accum, const JSONContext& cx) : cx(cx), reduce(reduce), accum(accum) { + WriteContext(const lambda<R(const std::string&, const R)>& reduce, const R& accum, const JSONContext& cx) : cx(cx), reduce(reduce), accum(accum) { } const JSONContext& cx; - const lambda<R(std::string, R)> reduce; + const lambda<R(const std::string&, const R)> reduce; R accum; }; @@ -352,7 +352,7 @@ template<typename R> JSBool writeCallback(const jschar *buf, uint32 len, void *d /** * Convert a list of values to a JSON document. */ -template<typename R> const failable<R, std::string> writeJSON(const lambda<R(std::string, R)>& reduce, const R& initial, const list<value>& l, const JSONContext& cx) { +template<typename R> const failable<R, std::string> writeJSON(const lambda<R(const std::string&, const R)>& reduce, const R& initial, const list<value>& l, const JSONContext& cx) { JSObject* o = JS_NewObject(cx, NULL, NULL, NULL); jsval val = OBJECT_TO_JSVAL(o); const failable<bool, std::string> w = writeList(l, o, cx); |