From ae0b7c0063db6236be2d7cf01ddbf2159f77c98c Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Tue, 11 Dec 2012 03:51:03 +0000 Subject: Port kernel to C++11 and refactor some of the core modules. Convert functors to lambdas, and add C++ const, noexcept and inline annotations to get more efficient generated code. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1419985 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/kernel/Makefile.am | 10 +- sca-cpp/trunk/kernel/config.hpp | 4 +- sca-cpp/trunk/kernel/dynlib-test.cpp | 6 +- sca-cpp/trunk/kernel/dynlib.hpp | 32 +- sca-cpp/trunk/kernel/element.hpp | 103 +++---- sca-cpp/trunk/kernel/fstream.hpp | 132 +++++---- sca-cpp/trunk/kernel/function.hpp | 114 ++++--- sca-cpp/trunk/kernel/gc.hpp | 370 ++++++++++++++++------- sca-cpp/trunk/kernel/hash-test.cpp | 87 ++---- sca-cpp/trunk/kernel/hash.hpp | 10 +- sca-cpp/trunk/kernel/kernel-test.cpp | 528 ++++++++++++++++++++++++++------- sca-cpp/trunk/kernel/lambda-test.cpp | 25 +- sca-cpp/trunk/kernel/list.hpp | 210 +++++-------- sca-cpp/trunk/kernel/mem-test.cpp | 56 ++-- sca-cpp/trunk/kernel/monad.hpp | 225 +++++++------- sca-cpp/trunk/kernel/parallel-test.cpp | 84 ++---- sca-cpp/trunk/kernel/parallel.hpp | 161 +++++----- sca-cpp/trunk/kernel/perf.hpp | 22 +- sca-cpp/trunk/kernel/sstream.hpp | 213 +++++++------ sca-cpp/trunk/kernel/stream.hpp | 91 ++++-- sca-cpp/trunk/kernel/string-test.cpp | 97 +++--- sca-cpp/trunk/kernel/string.hpp | 223 ++++++++------ sca-cpp/trunk/kernel/tree.hpp | 16 +- sca-cpp/trunk/kernel/value.hpp | 371 ++++++++++++----------- sca-cpp/trunk/kernel/xml-test.cpp | 235 --------------- sca-cpp/trunk/kernel/xml.hpp | 412 ------------------------- sca-cpp/trunk/kernel/xsd-test.cpp | 107 ------- 27 files changed, 1769 insertions(+), 2175 deletions(-) delete mode 100644 sca-cpp/trunk/kernel/xml-test.cpp delete mode 100644 sca-cpp/trunk/kernel/xml.hpp delete mode 100644 sca-cpp/trunk/kernel/xsd-test.cpp (limited to 'sca-cpp/trunk/kernel') diff --git a/sca-cpp/trunk/kernel/Makefile.am b/sca-cpp/trunk/kernel/Makefile.am index e6a7fdb2b3..47c65a1889 100644 --- a/sca-cpp/trunk/kernel/Makefile.am +++ b/sca-cpp/trunk/kernel/Makefile.am @@ -37,14 +37,8 @@ mem_test_SOURCES = mem-test.cpp parallel_test_SOURCES = parallel-test.cpp -xml_test_SOURCES = xml-test.cpp -xml_test_LDFLAGS = -lxml2 - -xsd_test_SOURCES = xsd-test.cpp -xsd_test_LDFLAGS = -lxml2 - hash_test_SOURCES = hash-test.cpp -noinst_PROGRAMS = string-test kernel-test lambda-test hash-test mem-test parallel-test xml-test xsd-test -TESTS = string-test kernel-test lambda-test hash-test mem-test parallel-test xml-test +noinst_PROGRAMS = string-test kernel-test lambda-test hash-test mem-test parallel-test +TESTS = string-test kernel-test lambda-test hash-test mem-test parallel-test diff --git a/sca-cpp/trunk/kernel/config.hpp b/sca-cpp/trunk/kernel/config.hpp index 944b9629e7..e6af54552b 100644 --- a/sca-cpp/trunk/kernel/config.hpp +++ b/sca-cpp/trunk/kernel/config.hpp @@ -93,12 +93,12 @@ namespace tuscany #ifdef WANT_MAINTAINER_COUNTERS -bool debug_inc(long int& c) { +const bool debug_inc(long int& c) { c++; return true; } -bool debug_dec(long int& c) { +const bool debug_dec(long int& c) { c--; return true; } diff --git a/sca-cpp/trunk/kernel/dynlib-test.cpp b/sca-cpp/trunk/kernel/dynlib-test.cpp index 419fa29db5..c7f0e6238d 100644 --- a/sca-cpp/trunk/kernel/dynlib-test.cpp +++ b/sca-cpp/trunk/kernel/dynlib-test.cpp @@ -28,7 +28,7 @@ namespace tuscany { namespace test { - const int cppsquare(int x) { + const int cppsquare(const int x) { return x * x; } @@ -41,8 +41,8 @@ extern "C" { return tuscany::test::cppsquare(x); } - const tuscany::lambda csquarel() { - return tuscany::lambda(tuscany::test::cppsquare); + const tuscany::lambda csquarel() { + return tuscany::lambda(tuscany::test::cppsquare); } } diff --git a/sca-cpp/trunk/kernel/dynlib.hpp b/sca-cpp/trunk/kernel/dynlib.hpp index 69359b4dae..ea6b50bacb 100644 --- a/sca-cpp/trunk/kernel/dynlib.hpp +++ b/sca-cpp/trunk/kernel/dynlib.hpp @@ -48,27 +48,18 @@ const string dynlibExt(".so"); */ class lib { public: - lib() : h(NULL), owner(false) { + inline lib() : h(NULL), owner(false) { } - lib(const string& name) : name(name), h(dlopen(c_str(name), RTLD_NOW)), owner(true) { - if (h == NULL) - h = mkfailure(string("Could not load library: ") + name + ": " + dlerror()); + inline lib(const string& name) : name(name), h(open(name)), owner(true) { } - lib(const lib& l) : name(l.name), h(l.h), owner(false) { + inline lib(const lib& l) : name(l.name), h(l.h), owner(false) { } - const lib& operator=(const lib& l) { - if(this == &l) - return *this; - name = l.name; - h = l.h; - owner = false; - return *this; - } + lib& operator=(const lib& l) = delete; - ~lib() { + inline ~lib() { if (!owner) return; if (!hasContent(h) || content(h) == NULL) @@ -77,17 +68,22 @@ public: } private: + const failable open(const string& name) { + void * h = dlopen(c_str(name), RTLD_NOW); + return h != NULL? failable(h) : mkfailure(string("Could not load library: ") + name + ": " + dlerror()); + } + template friend const failable > dynlambda(const string& name, const lib& l); - string name; - failable h; - bool owner; + const string name; + const failable h; + const bool owner; }; /** * Find a lambda function in a dynamic library. */ -template const failable > dynlambda(const string& name, const lib& l) { +template inline const failable > dynlambda(const string& name, const lib& l) { if (!hasContent(l.h)) return mkfailure>(l.h); const void* s = dlsym(content(l.h), c_str(name)); diff --git a/sca-cpp/trunk/kernel/element.hpp b/sca-cpp/trunk/kernel/element.hpp index 27b5af8691..9ae1e632cb 100644 --- a/sca-cpp/trunk/kernel/element.hpp +++ b/sca-cpp/trunk/kernel/element.hpp @@ -42,7 +42,7 @@ const string atsign("@"); /** * Returns true if a value is an element. */ -bool isElement(const value& v) { +inline const bool isElement(const value& v) { if (!isList(v) || isNil(v) || element != car(v)) return false; return true; @@ -51,7 +51,7 @@ bool isElement(const value& v) { /** * Returns true if a value is an attribute. */ -bool isAttribute(const value& v) { +inline const bool isAttribute(const value& v) { if (!isList(v) || isNil(v) || attribute != car(v)) return false; return true; @@ -60,42 +60,42 @@ bool isAttribute(const value& v) { /** * Returns the name of an attribute. */ -const value attributeName(const list& l) { +inline const value attributeName(const list& l) { return cadr(l); } /** * Returns the value of an attribute. */ -const value attributeValue(const list& l) { +inline const value attributeValue(const list& l) { return caddr(l); } /** * Returns the name of an element. */ -const value elementName(const list& l) { +inline const value elementName(const list& l) { return cadr(l); } /** * Returns true if an element has children. */ -const bool elementHasChildren(const list& l) { +inline const bool elementHasChildren(const list& l) { return !isNil(cddr(l)); } /** * Returns the children of an element. */ -const list elementChildren(const list& l) { +inline const list elementChildren(const list& l) { return cddr(l); } /** * Returns true if an element has a value. */ -const bool elementHasValue(const list& l) { +inline const bool elementHasValue(const list& l) { const list r = reverse(l); if (isSymbol(car(r))) return false; @@ -107,26 +107,26 @@ const bool elementHasValue(const list& l) { /** * Returns the value of an element. */ -const value elementValue(const list& l) { +inline const value elementValue(const list& l) { return car(reverse(l)); } /** * Convert an element to a value. */ -const bool elementToValueIsList(const value& v) { +inline const bool elementToValueIsList(const value& v) { if (!isList(v)) return false; const list l = v; return (isNil(l) || !isSymbol(car(l))); } -const value elementToValue(const value& t) { +inline const value elementToValue(const value& t) { const list elementsToValues(const list& e); // Convert an attribute if (isTaggedList(t, attribute)) - return mklist(c_str(atsign + attributeName(t)), attributeValue(t)); + return mklist(c_str(atsign + (string)attributeName(t)), attributeValue(t)); // Convert an element if (isTaggedList(t, element)) { @@ -155,7 +155,7 @@ const value elementToValue(const value& t) { /** * Convert a list of elements to a list of values. */ -const bool elementToValueIsSymbol(const value& v) { +inline const bool elementToValueIsSymbol(const value& v) { if (!isList(v)) return false; const list l = v; @@ -166,7 +166,7 @@ const bool elementToValueIsSymbol(const value& v) { return true; } -const list elementToValueGroupValues(const value& v, const list& l) { +inline const list elementToValueGroupValues(const value& v, const list& l) { if (isNil(l) || !elementToValueIsSymbol(v) || !elementToValueIsSymbol(car(l))) return cons(v, l); if (car(car(l)) != car(v)) @@ -180,7 +180,7 @@ const list elementToValueGroupValues(const value& v, const list& l } -const list elementsToValues(const list& e) { +inline const list elementsToValues(const list& e) { if (isNil(e)) return e; return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e))); @@ -189,13 +189,13 @@ const list elementsToValues(const list& e) { /** * Convert a value to an element. */ -const value valueToElement(const value& t) { +inline const value valueToElement(const value& t) { const list valuesToElements(const list& l); // Convert a name value pair if (isList(t) && !isNil((list)t) && isSymbol(car(t))) { const value n = car(t); - const value v = isNil(cdr(t))? value() : cadr(t); + const value v = isNil(cdr(t))? nilValue : cadr(t); // Convert a single value to an attribute or an element if (!isList(v)) { @@ -221,7 +221,7 @@ const value valueToElement(const value& t) { /** * Convert a list of values to a list of elements. */ -const list valuesToElements(const list& l) { +inline const list valuesToElements(const list& l) { if (isNil(l)) return l; return cons(valueToElement(car(l)), valuesToElements(cdr(l))); @@ -231,72 +231,51 @@ const list valuesToElements(const list& l) { * Returns a selector lambda function which can be used to filter * elements against the given element pattern. */ -struct selectorLambda { - const list select; - selectorLambda(const list& s) : select(s) { - } - const bool evalSelect(const list& s, const list v) const { - if (isNil(s)) - return true; - if (isNil(v)) - return false; - if (car(s) != car(v)) - return false; - return evalSelect(cdr(s), cdr(v)); - } - const bool operator()(const value& v) const { +inline const lambda selector(const list& select) { + return [select](const value& v) -> const bool { + const lambda&, const list&)> evalSelect = [&evalSelect](const list& s, const list& 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); - } -}; - -const lambda selector(const list s) { - return selectorLambda(s); + }; } /** * Returns the value of the attribute with the given name. */ -struct filterAttribute { - const value name; - filterAttribute(const value& n) : name(n) { - } - const bool operator()(const value& v) const { - return isAttribute(v) && attributeName((list)v) == name; - } -}; - -const value attributeValue(const value& name, const value& l) { - const list f = filter(filterAttribute(name), list(l)); +inline const value attributeValue(const value& name, const value& l) { + const list f = filter([name](const value& v) { + return isAttribute(v) && attributeName((list)v) == name; + }, list(l)); if (isNil(f)) - return value(); + return nilValue; return caddr(car(f)); } /** * Returns child elements with the given name. */ -struct filterElement { - const value name; - filterElement(const value& n) : name(n) { - } - const bool operator()(const value& v) const { - return isElement(v) && elementName((list)v) == name; - } -}; - -const value elementChildren(const value& name, const value& l) { - return filter(filterElement(name), list(l)); +inline const value elementChildren(const value& name, const value& l) { + return filter([name](const value& v) { + return isElement(v) && elementName((list)v) == name; + }, list(l)); } /** * Return the child element with the given name. */ -const value elementChild(const value& name, const value& l) { +inline const value elementChild(const value& name, const value& l) { const list f = elementChildren(name, l); if (isNil(f)) - return value(); + return nilValue; return car(f); } diff --git a/sca-cpp/trunk/kernel/fstream.hpp b/sca-cpp/trunk/kernel/fstream.hpp index 4f7f5152aa..1ed1487707 100644 --- a/sca-cpp/trunk/kernel/fstream.hpp +++ b/sca-cpp/trunk/kernel/fstream.hpp @@ -69,24 +69,18 @@ namespace tuscany { */ class ofstream : public ostream { public: - ofstream(const string& path) : file(fopen(c_str(path), "wb")), owner(true) { + inline ofstream(const string& path) : file(fopen(c_str(path), "wb")), owner(true) { } - ofstream(FILE* file) : file(file), owner(false) { + inline ofstream(FILE* const file) : file(file), owner(false) { } - ofstream(const ofstream& os) : file(os.file), owner(false) { + inline ofstream(const ofstream& os) : file(os.file), owner(false) { } - const ofstream& operator=(const ofstream& os) { - if(this == &os) - return *this; - file = os.file; - owner = false; - return *this; - } + ofstream& operator=(const ofstream& os) = delete; - ~ofstream() { + inline ~ofstream() { if (!owner) return; if (file == NULL) @@ -94,11 +88,11 @@ public: fclose(file); } - const bool fail() { + inline const bool fail() { return file == NULL; } - ofstream& vprintf(const char* fmt, ...) { + inline ofstream& vprintf(const char* const fmt, ...) { va_list args; va_start (args, fmt); vfprintf (file, fmt, args); @@ -106,19 +100,24 @@ public: return *this; } - ofstream& write(const string& s) { + inline ofstream& write(const string& s) { fwrite(c_str(s), 1, length(s), file); return *this; } - ofstream& flush() { + inline ofstream& write(const char c) { + fwrite(&c, 1, 1, file); + return *this; + } + + inline ofstream& flush() { fflush(file); return *this; } private: - FILE* file; - bool owner; + FILE* const file; + const bool owner; }; /* @@ -126,24 +125,18 @@ private: */ class ifstream : public istream { public: - ifstream(const string& path) : file(fopen(c_str(path), "rb")), owner(true) { + inline ifstream(const string& path) : file(fopen(c_str(path), "rb")), owner(true) { } - ifstream(FILE* file) : file(file), owner(false) { + inline ifstream(FILE* const file) : file(file), owner(false) { } - ifstream(const ifstream& is) : file(is.file), owner(false) { + inline ifstream(const ifstream& is) : file(is.file), owner(false) { } - const ifstream& operator=(const ifstream& is) { - if(this == &is) - return *this; - file = is.file; - owner = false; - return *this; - } + ifstream& operator=(const ifstream& is) = delete; - ~ifstream() { + inline ~ifstream() { if (!owner) return; if (file == NULL) @@ -151,23 +144,23 @@ public: fclose(file); } - const size_t read(void* buf, size_t size) { + inline const size_t read(void* const buf, const size_t size) { return fread(buf, 1, size, file); } - const bool eof() { + inline const bool eof() { return feof(file); } - const bool fail() { + inline const bool fail() { return file == NULL; } - const int get() { + inline const int get() { return fgetc(file); } - const int peek() { + inline const int peek() { int c = fgetc(file); if (c == -1) return c; @@ -176,8 +169,8 @@ public: } private: - FILE* file; - bool owner; + FILE* const file; + const bool owner; }; /** @@ -198,24 +191,24 @@ ifstream cin(stdin); */ class loghstream : public ostream { public: - loghstream(const int level) : level(level), len(0) { + inline loghstream(const int level) : level(level), len(0) { } - ~loghstream() { + inline ~loghstream() { } - ostream& vprintf(const char* fmt, ...) { + inline ostream& vprintf(const char* const fmt, ...) { va_list args; - va_start (args, fmt); + va_start(args, fmt); const int l = vsnprintf(buf + len, (sizeof(buf) - 1) - len, fmt, args); - va_end (args); + va_end(args); len += l; if (len > (int)(sizeof(buf) - 1)) len = sizeof(buf) - 1; return *this; } - ostream& write(const string& s) { + inline ostream& write(const string& s) { if (s != "\n") return this->vprintf("%s", c_str(s)); buf[len] = '\0'; @@ -224,14 +217,23 @@ public: return *this; } - ostream& flush() { + inline ostream& write(const char c) { + if (c != '\n') + return this->vprintf("%c", c); + buf[len] = '\0'; + ap_log_error(NULL, 0, -1, level, 0, ap_server_conf, "%s", buf); + len = 0; + return *this; + } + + inline ostream& flush() { return *this; } private: const int level; int len; - char buf[2049]; + char buf[513]; }; /** @@ -259,11 +261,11 @@ loghstream cdebug(APLOG_DEBUG); /** * Format the current time. */ -const string logTime() { +inline const string logTime() { struct timeval tv; gettimeofday(&tv, NULL); const time_t t = tv.tv_sec; - const tm* lt = localtime(&t); + const tm* const lt = localtime(&t); char ft[32]; strftime(ft, 20, "%a %b %d %H:%M:%S", lt); sprintf(ft + 19, ".%06lu ", (unsigned long)tv.tv_usec); @@ -276,16 +278,16 @@ const string logTime() { */ class logfstream : public ostream { public: - logfstream(FILE* file, const string& type) : file(file), type(type), head(false) { + inline logfstream(FILE* const file, const string& type) : file(file), type(type), head(false) { } - logfstream(const logfstream& os) : file(os.file), type(os.type), head(os.head) { + inline logfstream(const logfstream& os) : file(os.file), type(os.type), head(os.head) { } - ~logfstream() { + inline ~logfstream() { } - ostream& vprintf(const char* fmt, ...) { + inline ostream& vprintf(const char* const fmt, ...) { whead(); va_list args; va_start (args, fmt); @@ -294,7 +296,7 @@ public: return *this; } - ostream& write(const string& s) { + inline ostream& write(const string& s) { whead(); fwrite(c_str(s), 1, length(s), file); if (s == "\n") @@ -302,17 +304,25 @@ public: return *this; } - ostream& flush() { + inline ostream& write(const char c) { + whead(); + fwrite(&c, 1, 1, file); + if (c == '\n') + head = false; + return *this; + } + + inline ostream& flush() { fflush(file); return *this; } private: - FILE* file; + FILE* const file; const string type; bool head; - const unsigned long tid() const { + inline const unsigned long tid() const { #ifdef WANT_THREADS return (unsigned long)pthread_self(); #else @@ -320,7 +330,7 @@ private: #endif } - ostream& whead() { + inline ostream& whead() { if (head) return *this; head = true; @@ -348,7 +358,7 @@ logfstream cdebug(stderr, "debug"); bool debug_isLoggingSet = false; bool debug_isLoggingEnv = false; -const bool debug_isLogging() { +inline const bool debug_isLogging() { if (debug_isLoggingSet) return debug_isLoggingEnv; debug_isLoggingEnv = getenv("TUSCANY_DEBUG_LOG") != NULL; @@ -366,8 +376,8 @@ const bool debug_isLogging() { /** * Log a debug message. */ -const bool debugLog(const string& msg) { - gc_scoped_pool p; +inline const bool debugLog(const string& msg) { + const gc_scoped_pool p; cdebug << msg << endl; return true; } @@ -375,8 +385,8 @@ const bool debugLog(const string& msg) { /** * Log a debug message and a value. */ -template const bool debugLog(const V& v, const string& msg) { - gc_scoped_pool p; +template inline const bool debugLog(const V& v, const string& msg) { + const gc_scoped_pool p; cdebug << msg << ": " << v << endl; return true; } @@ -384,8 +394,8 @@ template const bool debugLog(const V& v, const string& msg) { /** * Log a debug message and two values. */ -template const bool debugLog(const V& v, const W& w, const string& msg) { - gc_scoped_pool p; +template inline const bool debugLog(const V& v, const W& w, const string& msg) { + const gc_scoped_pool p; cdebug << msg << ": " << v << " : " << w << endl; return true; } diff --git a/sca-cpp/trunk/kernel/function.hpp b/sca-cpp/trunk/kernel/function.hpp index 60117dab98..0a88cf51d9 100644 --- a/sca-cpp/trunk/kernel/function.hpp +++ b/sca-cpp/trunk/kernel/function.hpp @@ -23,7 +23,9 @@ #define tuscany_function_hpp /** - * Lambda function type. + * Lambda function type that enforces pass by ref and constant parameters, + * allocates memory only as needed and using an APR memory pool, is about + * 2 times faster than std::function and between 1/4 and 1/6 of its size. */ #include @@ -46,16 +48,16 @@ long int countELambdas = 0; long int countCLambdas = 0; long int countFLambdas = 0; -bool resetLambdaCounters() { +inline const bool resetLambdaCounters() { countLambdas = countELambdas = countCLambdas = countFLambdas = countProxies = countFProxies = countCProxies = 0; return true; } -bool checkLambdaCounters() { +inline const bool checkLambdaCounters() { return countLambdas == 0; } -bool printLambdaCounters() { +inline const bool printLambdaCounters() { cout << "countLambdas " << countLambdas << endl; cout << "countELambdas " << countELambdas << endl; cout << "countFLambdas " << countFLambdas << endl; @@ -80,38 +82,32 @@ bool printLambdaCounters() { template class Callable { public: - Callable() { + inline Callable() noexcept { } - virtual const size_t size() const = 0; - - virtual const R operator()(P... p) const = 0; + virtual const R operator()(const P&&... p) const noexcept = 0; - virtual ~Callable() { + inline virtual ~Callable() noexcept { } - template class Proxy: public Callable { + template class Proxy: public Callable { public: - Proxy(const F& f) : function(f) { + inline Proxy(const F& f) noexcept : function(f) { debug_inc(countProxies); debug_inc(countFProxies); } - Proxy(const Proxy& p) : function(p.function) { + inline Proxy(const Proxy& p) noexcept : function(p.function) { debug_inc(countProxies); debug_inc(countCProxies); } - ~Proxy() { + inline ~Proxy() noexcept { debug_dec(countProxies); } - virtual const R operator() (P... p) const { - return function(std::forward

(p)...); - } - - virtual const size_t size() const { - return sizeof(function); + virtual const R operator() (const P&&... p) const noexcept { + return function(std::forward(p)...); } private: @@ -123,67 +119,68 @@ template class lambda; template class lambda { public: - lambda() : callable(0) { + inline lambda() noexcept : callable(NULL) { debug_inc(countLambdas); debug_inc(countELambdas); } - template lambda(const F f) { + template inline lambda(const F f) noexcept : callable(mkproxy(f)) { debug_inc(countLambdas); debug_inc(countFLambdas); + } - typedef typename CallableType::template Proxy ProxyType; - callable = gc_ptr(new (gc_new()) ProxyType(f)); + template inline lambda(const gc_mutable_ref& r) noexcept : callable(mkproxy(*(F*)r)) { + debug_inc(countLambdas); + debug_inc(countFLambdas); } - lambda(const lambda& l) { + inline lambda(const lambda& l) noexcept : callable(l.callable) { debug_inc(countLambdas); debug_inc(countCLambdas); - callable = l.callable; } - const lambda& operator=(const lambda& l) { - if (this == &l) - return *this; - callable = l.callable; - return *this; - } + lambda& operator=(const lambda& l) = delete; - ~lambda() { + inline ~lambda() noexcept { debug_dec(countLambdas); } - const bool operator==(const lambda& l) const { + inline const bool operator==(const lambda& l) const noexcept { if (this == &l) return true; - return callable == l.callable; + return false; } - const bool operator!=(const lambda& l) const { + inline const bool operator!=(const lambda& l) const noexcept { return !this->operator==(l); } - const R operator()(P... p) const { - return (*callable)(std::forward

(p)...); + inline const R operator()(const P&... p) const noexcept { + return (*callable)(std::forward(p)...); } template friend ostream& operator<<(ostream&, const lambda&); - template friend const bool isNil(const lambda& l); + template friend const bool isNil(const lambda& l) noexcept; private: typedef Callable CallableType; - gc_ptr callable; + const gc_ptr callable; + + template inline gc_ptr mkproxy(const F& f) noexcept { + typedef typename CallableType::template Proxy ProxyType; + return gc_ptr(new (gc_new()) ProxyType(f)); + } }; -template ostream& operator<<(ostream& out, const lambda& l) { +template inline ostream& operator<<(ostream& out, const lambda& l) { return out << "lambda::" << l.callable; } /** * Return true if a lambda is nil. */ -template const bool isNil(const lambda& l) { - return ((void*)l.callable) == 0; +template inline const bool isNil(const lambda& l) noexcept { + return (const void*)l.callable == NULL; } /** @@ -191,11 +188,11 @@ template const bool isNil(const lambda& l) { */ template class curried { public: - curried(const lambda& f, const T& v): v(v), f(f) { + inline curried(const lambda& f, const T& v) noexcept: v(v), f(f) { } - const R operator()(P... p) const { - return f(v, std::forward

(p)...); + inline const R operator()(const P&... p) const noexcept { + return f(v, std::forward(p)...); } private: @@ -203,36 +200,29 @@ private: const lambdaf; }; -template const lambda curry(const lambda& f, const T& t) { +template inline const lambda curry(const lambda& f, const T& t) noexcept { return curried(f, t); } -template const lambda curry(const lambda& f, const T& t, const U& u) { +template inline const lambda curry(const lambda& f, const T& t, const U& u) noexcept { return curry(curry(f, t), u); } -template const lambda curry(const lambda& f, const T& t, const U& u, const V& v) { +template inline const lambda curry(const lambda& f, const T& t, const U& u, const V& v) noexcept { return curry(curry(curry(f, t), u), v); } /** * A lambda function that returns the given value. */ -template class returnResult { -public: - returnResult(const T& v) : - v(v) { - } - const T operator()() const { - return v; - } -private: - const T v; -}; - -template const lambda result(const T& v) { - return returnResult (v); +template inline const lambda result(const T& v) { + return [v]()->T { return v; }; } +/** + * Commonly used lambda types. + */ +typedef lambda blambda; + } #endif /* tuscany_function_hpp */ diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp index 32ad8160cc..7853c551dc 100644 --- a/sca-cpp/trunk/kernel/gc.hpp +++ b/sca-cpp/trunk/kernel/gc.hpp @@ -49,7 +49,7 @@ namespace tuscany /** * Force a core dump on assertion violation. */ -bool assertOrFail(const bool expr) { +inline const bool assertOrFail(const bool expr) { if (!expr) abort(); return true; @@ -64,63 +64,135 @@ bool assertOrFail(const bool expr) { /** * Pointer to a value. */ +#ifdef WANT_RAW_PTR + +template using gc_ptr = T*; + +#else + template class gc_ptr { public: - gc_ptr(T* ptr = NULL) throw() : ptr(ptr) { + inline gc_ptr(T* const ptr = NULL) noexcept : ptr(ptr) { + } + + inline ~gc_ptr() noexcept { + } + + inline gc_ptr(const gc_ptr& r) noexcept : ptr(r.ptr) { + } + + gc_ptr& operator=(const gc_ptr& r) = delete; + + inline const bool operator==(const gc_ptr& r) const noexcept { + if (this == &r) + return true; + return ptr == r.ptr; + } + + inline const bool operator==(const T* const p) const noexcept { + return ptr == p; + } + + inline const bool operator!=(const gc_ptr& r) const noexcept { + return !this->operator==(r); + } + + inline const bool operator!=(const T* const p) const noexcept { + return !this->operator==(p); + } + + inline T& operator*() const noexcept { + return *ptr; + } + + inline T* const operator->() const noexcept { + return ptr; + } + + inline operator T* const () const noexcept { + return ptr; + } + +private: + T* const ptr; +}; + +#endif + +/** + * Mutable pointer to an immutable value. + */ +#ifdef WANT_RAW_PTR + +template using gc_mutable_ptr = T*; + +#else + +template class gc_mutable_ptr { +public: + inline gc_mutable_ptr(T* const ptr = NULL) noexcept : ptr(ptr) { } - ~gc_ptr() throw() { + inline ~gc_mutable_ptr() noexcept { } - gc_ptr(const gc_ptr& r) throw() : ptr(r.ptr) { + inline gc_mutable_ptr(const gc_mutable_ptr& r) noexcept : ptr(r.ptr) { } - gc_ptr& operator=(const gc_ptr& r) throw() { - if(this == &r) + inline gc_mutable_ptr& operator=(T* const p) noexcept { + ptr = p; + return *this; + } + + inline gc_mutable_ptr& operator=(const gc_mutable_ptr& r) noexcept { + if (this == &r) return *this; ptr = r.ptr; return *this; } - const bool operator==(const gc_ptr& r) const throw() { + inline const bool operator==(const gc_mutable_ptr& r) const noexcept { if (this == &r) return true; return ptr == r.ptr; } - const bool operator==(T* p) const throw() { + inline const bool operator==(T* const p) const noexcept { return ptr == p; } - const bool operator!=(const gc_ptr& r) const throw() { + inline const bool operator!=(const gc_mutable_ptr& r) const noexcept { return !this->operator==(r); } - const bool operator!=(T* p) const throw() { + inline const bool operator!=(T* const p) const noexcept { return !this->operator==(p); } - T& operator*() const throw() { + inline T& operator*() const noexcept { return *ptr; } - T* operator->() const throw() { + inline T* const operator->() const noexcept { return ptr; } - operator T*() const throw() { + inline operator T* const () const noexcept { return ptr; } +private: T* ptr; }; +#endif + /** * Initialize APR. */ class gc_apr_context_t { public: - gc_apr_context_t() { + inline gc_apr_context_t() { apr_initialize(); } } gc_apr_context; @@ -130,36 +202,31 @@ public: */ class gc_pool { public: - gc_pool() : apr_pool(NULL) { + inline gc_pool() noexcept : apr_pool(NULL) { } - gc_pool(apr_pool_t* p) : apr_pool(p) { + inline gc_pool(apr_pool_t* const p) noexcept : apr_pool(p) { } - gc_pool(const gc_pool& pool) : apr_pool(pool.apr_pool) { + inline gc_pool(const gc_pool& pool) noexcept : apr_pool(pool.apr_pool) { } - gc_pool& operator=(const gc_pool& pool) { - if (this == &pool) - return *this; - apr_pool = pool.apr_pool; - return *this; - } + gc_pool& operator=(const gc_pool& pool) = delete; private: - friend apr_pool_t* pool(const gc_pool& pool); + friend apr_pool_t* pool(const gc_pool& pool) noexcept; friend class gc_global_pool_t; friend class gc_child_pool; friend class gc_local_pool; friend class gc_scoped_pool; - apr_pool_t* apr_pool; + apr_pool_t* const apr_pool; }; /** * Return the APR pool used by a gc_pool. */ -apr_pool_t* pool(const gc_pool& pool) { +inline apr_pool_t* pool(const gc_pool& pool) noexcept { return pool.apr_pool; } @@ -168,35 +235,51 @@ apr_pool_t* pool(const gc_pool& pool) { */ #ifdef WANT_THREADS +#ifdef __clang__ + class gc_pool_stack_t { public: - gc_pool_stack_t() { - int rc = pthread_key_create(&key, NULL); - assertOrFail(rc == 0); + inline gc_pool_stack_t() noexcept : key(mkkey()) { } - operator apr_pool_t*() const { - return static_cast(pthread_getspecific(key)); + inline operator apr_pool_t*() const noexcept { + return (apr_pool_t*)pthread_getspecific(key); } - const gc_pool_stack_t& operator=(apr_pool_t* p) { + inline const gc_pool_stack_t& operator=(apr_pool_t* p) noexcept { pthread_setspecific(key, p); return *this; } private: pthread_key_t key; + + pthread_key_t mkkey() { + pthread_key_t k; + int rc = pthread_key_create(&k, NULL); + assertOrFail(rc == 0); + return k; + } + } gc_pool_stack; #else + +__thread apr_pool_t* gc_pool_stack = NULL; + +#endif + +#else + apr_pool_t* gc_pool_stack = NULL; + #endif /** * Push a pool onto the stack. */ -apr_pool_t* gc_push_pool(apr_pool_t* pool) { - apr_pool_t* p = gc_pool_stack; +inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept { + apr_pool_t* const p = gc_pool_stack; gc_pool_stack = pool; return p; } @@ -204,8 +287,8 @@ apr_pool_t* gc_push_pool(apr_pool_t* pool) { /** * Pop a pool from the stack. */ -apr_pool_t* gc_pop_pool(apr_pool_t* pool) { - apr_pool_t* p = gc_pool_stack; +inline apr_pool_t* const gc_pop_pool(apr_pool_t* pool) noexcept { + apr_pool_t* const p = gc_pool_stack; gc_pool_stack = pool; return p; } @@ -213,16 +296,17 @@ apr_pool_t* gc_pop_pool(apr_pool_t* pool) { /** * Return the current memory pool. */ -apr_pool_t* gc_current_pool() { - apr_pool_t* p = gc_pool_stack; +inline apr_pool_t* const gc_current_pool() noexcept { + apr_pool_t* const p = gc_pool_stack; if (p != NULL) return p; // Create a parent pool for the current thread - apr_pool_create(&p, NULL); - assertOrFail(p != NULL); - gc_push_pool(p); - return p; + apr_pool_t* pp; + apr_pool_create(&pp, NULL); + assertOrFail(pp != NULL); + gc_push_pool(pp); + return pp; } /** @@ -231,25 +315,23 @@ apr_pool_t* gc_current_pool() { class gc_child_pool : public gc_pool { public: - gc_child_pool() : gc_pool(NULL), owner(true) { - apr_pool_create(&apr_pool, gc_current_pool()); - assertOrFail(apr_pool != NULL); + inline gc_child_pool() noexcept : gc_pool(mkpool()), owner(true) { } - gc_child_pool(const gc_child_pool& p) : gc_pool(p.apr_pool), owner(false) { - } - - const gc_child_pool& operator=(const gc_child_pool& p) { - if(this == &p) - return *this; - apr_pool = p.apr_pool; - owner = false; - return *this; + inline gc_child_pool(const gc_child_pool& p) noexcept : gc_pool(p.apr_pool), owner(false) { } + gc_child_pool& operator=(const gc_child_pool& p) = delete; private: - bool owner; + const bool owner; + + apr_pool_t* const mkpool() { + apr_pool_t* p; + apr_pool_create(&p, gc_current_pool()); + assertOrFail(p != NULL); + return p; + } }; /** @@ -258,29 +340,28 @@ private: class gc_local_pool : public gc_pool { public: - gc_local_pool() : gc_pool(NULL), owner(true) { - apr_pool_create(&apr_pool, gc_current_pool()); - assertOrFail(apr_pool != NULL); + inline gc_local_pool() noexcept : gc_pool(mkpool()), owner(true) { } - ~gc_local_pool() { + inline ~gc_local_pool() noexcept { if (owner) apr_pool_destroy(apr_pool); } - gc_local_pool(const gc_local_pool& p) : gc_pool(p.apr_pool), owner(false) { + inline gc_local_pool(const gc_local_pool& p) noexcept : gc_pool(p.apr_pool), owner(false) { } - const gc_local_pool& operator=(const gc_local_pool& p) { - if(this == &p) - return *this; - apr_pool = p.apr_pool; - owner = false; - return *this; - } + gc_local_pool& operator=(const gc_local_pool& p) = delete; private: - bool owner; + const bool owner; + + apr_pool_t* const mkpool() { + apr_pool_t* p; + apr_pool_create(&p, gc_current_pool()); + assertOrFail(p != NULL); + return p; + } }; /** @@ -290,66 +371,64 @@ private: class gc_scoped_pool : public gc_pool { public: - gc_scoped_pool() : gc_pool(NULL), prev(gc_current_pool()), owner(true) { - apr_pool_create(&apr_pool, prev); - assertOrFail(apr_pool != NULL); + inline gc_scoped_pool() noexcept : gc_pool(mkpool()), prev(gc_current_pool()), owner(true) { gc_push_pool(apr_pool); } - gc_scoped_pool(apr_pool_t* p) : gc_pool(p), prev(gc_current_pool()), owner(false) { + inline gc_scoped_pool(apr_pool_t* p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) { gc_push_pool(apr_pool); } - ~gc_scoped_pool() { + inline ~gc_scoped_pool() noexcept { if (owner) apr_pool_destroy(apr_pool); gc_pop_pool(prev); } - gc_scoped_pool(const gc_scoped_pool& p) : gc_pool(p.apr_pool), prev(p.prev), owner(false) { + inline gc_scoped_pool(const gc_scoped_pool& p) noexcept : gc_pool(p.apr_pool), prev(p.prev), owner(false) { } - const gc_scoped_pool& operator=(const gc_scoped_pool& p) { - if(this == &p) - return *this; - apr_pool = p.apr_pool; - prev = p.prev; - owner = false; - return *this; - } + gc_scoped_pool& operator=(const gc_scoped_pool& p) = delete; private: - apr_pool_t* prev; - bool owner; + apr_pool_t* const prev; + const bool owner; + + apr_pool_t* const mkpool() { + apr_pool_t* p; + apr_pool_create(&p, gc_current_pool()); + assertOrFail(p != NULL); + return p; + } }; /** * Allocates a pointer to an object allocated from a memory pool and * register a cleanup callback for it. */ -template apr_status_t gc_pool_cleanup(void* v) { +template inline apr_status_t gc_pool_cleanup(void* v) { T* t = (T*)v; t->~T(); return APR_SUCCESS; } -template T* gc_new(apr_pool_t* p) { +template inline T* const gc_new(apr_pool_t* const p) noexcept { void* gc_new_ptr = apr_palloc(p, sizeof(T)); assertOrFail(gc_new_ptr != NULL); apr_pool_cleanup_register(p, gc_new_ptr, gc_pool_cleanup, apr_pool_cleanup_null) ; return (T*)(gc_new_ptr); } -template T* gc_new(const gc_pool& p) { +template inline T* const gc_new(const gc_pool& p) noexcept { return gc_new(pool(p)); } -template T* gc_new() { +template inline T* const gc_new() noexcept { return gc_new(gc_current_pool()); } -template apr_status_t gc_pool_acleanup(void* v) { - size_t* m = static_cast(v); +template inline apr_status_t gc_pool_acleanup(void* v) { + size_t* m = (size_t*)v; size_t n = *m; T* t = (T*)(m + 1); for (size_t i = 0; i < n; i++, t++) @@ -357,40 +436,101 @@ template apr_status_t gc_pool_acleanup(void* v) { return APR_SUCCESS; } -template T* gc_anew(apr_pool_t* p, size_t n) { - size_t* gc_anew_ptr = static_cast(apr_palloc(p, sizeof(size_t) + sizeof(T) * n)); +template inline T* const gc_anew(apr_pool_t* const p, const size_t n) noexcept { + size_t* const gc_anew_ptr = (size_t*)apr_palloc(p, sizeof(size_t) + sizeof(T) * n); assertOrFail(gc_anew_ptr != NULL); *gc_anew_ptr = n; apr_pool_cleanup_register(p, gc_anew_ptr, gc_pool_acleanup, apr_pool_cleanup_null) ; return (T*)(gc_anew_ptr + 1); } -template T* gc_anew(const gc_pool& p, size_t n) { +template inline T* const gc_anew(const gc_pool& p, const size_t n) noexcept { return gc_anew(pool(p), n); } -template T* gc_anew(size_t n) { +template inline T* const gc_anew(const size_t n) noexcept { return gc_anew(gc_current_pool(), n); } /** * Allocate an array of chars. */ -char* gc_cnew(apr_pool_t* p, size_t n) { - char* gc_cnew_ptr = static_cast(apr_palloc(p, n)); +inline char* const gc_cnew(apr_pool_t* const p, const size_t n) noexcept { + char* const gc_cnew_ptr = (char*)apr_palloc(p, n); assertOrFail(gc_cnew_ptr != NULL); return gc_cnew_ptr; } -char* gc_cnew(size_t n) { +inline char* const gc_cnew(const size_t n) noexcept { return gc_cnew(gc_current_pool(), n); } +/** + * Mutable reference to an immutable value. + */ +template class gc_mutable_ref { +public: + inline gc_mutable_ref() noexcept : ptr(new (gc_new()) T()) { + } + + inline ~gc_mutable_ref() noexcept { + } + + inline gc_mutable_ref(const gc_mutable_ref& r) noexcept : ptr(r.ptr) { + } + + inline gc_mutable_ref(const T& v) noexcept : ptr(new (gc_new()) T(v)) { + } + + inline gc_mutable_ref& operator=(const gc_mutable_ref& r) noexcept { + if (this == &r) + return *this; + ptr = r.ptr; + return *this; + } + + inline gc_mutable_ref& operator=(const T& v) noexcept { + ptr = new (gc_new()) T(v); + return *this; + } + + inline const bool operator==(const gc_mutable_ref& r) const noexcept { + if (this == &r) + return true; + if (ptr == r.ptr) + return true; + return *ptr == *r.ptr; + } + + inline const bool operator==(const T& v) const noexcept { + return *ptr == v; + } + + inline const bool operator!=(const gc_mutable_ref& r) const noexcept { + return !this->operator==(r); + } + + inline const bool operator!=(const T& v) const noexcept { + return !this->operator==(v); + } + + inline operator T&() const noexcept { + return *ptr; + } + + inline operator T* const () const noexcept { + return ptr; + } + +private: + T* ptr; +}; + /** * Pool based equivalent of the standard malloc function. */ -void* gc_pool_malloc(size_t n) { - size_t* ptr = static_cast(apr_palloc(gc_current_pool(), sizeof(size_t) + n)); +inline void* gc_pool_malloc(size_t n) { + size_t* ptr = (size_t*)apr_palloc(gc_current_pool(), sizeof(size_t) + n); assertOrFail(ptr != NULL); *ptr = n; return ptr + 1; @@ -399,9 +539,9 @@ void* gc_pool_malloc(size_t n) { /** * Pool based equivalent of the standard realloc function. */ -void* gc_pool_realloc(void* ptr, size_t n) { - size_t size = *(static_cast(ptr) - 1); - size_t* rptr = static_cast(apr_palloc(gc_current_pool(), sizeof(size_t) + n)); +inline void* gc_pool_realloc(void* ptr, size_t n) { + size_t size = *(((size_t*)ptr) - 1); + size_t* rptr = (size_t*)apr_palloc(gc_current_pool(), sizeof(size_t) + n); assertOrFail(rptr != NULL); *rptr = n; memcpy(rptr + 1, ptr, size < n? size : n); @@ -411,15 +551,15 @@ void* gc_pool_realloc(void* ptr, size_t n) { /** * Pool based equivalent of the standard free function. */ -void gc_pool_free(unused void* ptr) { +inline void gc_pool_free(unused void* ptr) { // Memory allocated from a pool is freed when the pool is freed } /** * Pool based equivalent of the standard strdup function. */ -char* gc_pool_strdup(const char* str) { - char* dptr = static_cast(gc_pool_malloc(strlen(str) + 1)); +inline char* gc_pool_strdup(const char* str) { + char* dptr = (char*)gc_pool_malloc(strlen(str) + 1); assertOrFail(dptr != NULL); strcpy(dptr, str); return dptr; @@ -434,9 +574,9 @@ char* gc_pool_strdup(const char* str) { /** * Mmap based equivalent of the standard malloc function. */ -void* gc_mmap_malloc(size_t n, unused const void* caller) { +inline void* gc_mmap_malloc(size_t n, unused const void* caller) { //printf("gc_mmap_malloc %d", n); - size_t* ptr = static_cast(mmap(NULL, sizeof(size_t) + n, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); + size_t* ptr = (size_t*)mmap(NULL, sizeof(size_t) + n, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); assertOrFail(ptr != NULL); *ptr = n; //printf(" %p\n", ptr + 1); @@ -446,12 +586,12 @@ void* gc_mmap_malloc(size_t n, unused const void* caller) { /** * Mmap based equivalent of the standard realloc function. */ -void* gc_mmap_realloc(void* ptr, size_t n, const void* caller) { +inline void* gc_mmap_realloc(void* ptr, size_t n, const void* caller) { if (ptr == NULL) return gc_mmap_malloc(n, caller);; //printf("gc_mmap_realloc %p %d", ptr, n); - size_t size = *(static_cast(ptr) - 1); - size_t* rptr = static_cast(mremap(static_cast(ptr) - 1, sizeof(size_t) + size, sizeof(size_t) + n, MREMAP_MAYMOVE, NULL)); + size_t size = *(((size_t*)ptr) - 1); + size_t* rptr = (size_t*)mremap(((size_t*)ptr) - 1, sizeof(size_t) + size, sizeof(size_t) + n, MREMAP_MAYMOVE, NULL); assertOrFail(rptr != NULL); *rptr = n; //printf(" %p\n", rptr + 1); @@ -461,18 +601,18 @@ void* gc_mmap_realloc(void* ptr, size_t n, const void* caller) { /** * Mmap based equivalent of the standard free function. */ -void gc_mmap_free(void* ptr, unused const void* caller) { +inline void gc_mmap_free(void* ptr, unused const void* caller) { //printf("gc_mmap_free %p\n", ptr); if (ptr == NULL) return; - size_t size = *(static_cast(ptr) - 1); - munmap(static_cast(ptr) - 1, sizeof(size_t) + size); + size_t size = *(((size_t*)ptr) - 1); + munmap(((size_t*)ptr) - 1, sizeof(size_t) + size); } /** * Mmap based equivalent of the standard memalign function. */ -void* gc_mmap_memalign(unused size_t alignment, size_t n, unused const void* caller) { +inline void* gc_mmap_memalign(unused size_t alignment, size_t n, unused const void* caller) { //printf("gc_mmap_memalign %d %d\n", alignment, n); return gc_mmap_malloc(n, caller); } @@ -480,7 +620,7 @@ void* gc_mmap_memalign(unused size_t alignment, size_t n, unused const void* cal /** * Install the mmap based memory allocation functions. */ -void gc_mmap_init_hook(void) { +inline void gc_mmap_init_hook(void) { __malloc_hook = gc_mmap_malloc; __realloc_hook = gc_mmap_realloc; __free_hook = gc_mmap_free; diff --git a/sca-cpp/trunk/kernel/hash-test.cpp b/sca-cpp/trunk/kernel/hash-test.cpp index 4e6a3654e5..a012cd5ee7 100644 --- a/sca-cpp/trunk/kernel/hash-test.cpp +++ b/sca-cpp/trunk/kernel/hash-test.cpp @@ -30,89 +30,64 @@ namespace tuscany { -bool testCrc32hash() { +const bool testCrc32hash() { const string key("This is a test key"); - unsigned int h = crc32hash(c_str(key), length(key)); + const unsigned int h = crc32hash(c_str(key), length(key)); assert(h != 0); return true; } -bool testTimes33hash() { +const bool testTimes33hash() { const string key("This is a test key"); - unsigned int h = times33hash(c_str(key), length(key)); + const unsigned int h = times33hash(c_str(key), length(key)); assert(h != 0); return true; } -bool testMurmurhash() { +const bool testMurmurhash() { const string key("This is a test key"); - unsigned int h = murmurhash(c_str(key), length(key)); + const unsigned int h = murmurhash(c_str(key), length(key)); assert(h != 0); return true; } -bool testPortablemurmurhash() { +const bool testPortablemurmurhash() { const string key("This is a test key"); - unsigned int h = portablemurmurhash(c_str(key), length(key)); + const unsigned int h = portablemurmurhash(c_str(key), length(key)); assert(h != 0); return true; } -struct crc32hashTest { - const string key; - crc32hashTest(const string& key) : key(key) { - } - bool operator()() const { - unsigned int h = crc32hash(c_str(key), length(key)); +const bool testHashPerf() { + const string key("This is a test key"); + const int count = 100000; + + const blambda crc32 = [key]() -> const bool { + const unsigned int h = crc32hash(c_str(key), length(key)); assert(h != 0); return true; - } -}; - -struct times33hashTest { - const string key; - times33hashTest(const string& key) : key(key) { - } - bool operator()() const { - unsigned int h = times33hash(c_str(key), length(key)); + }; + cout << "crc32hash test " << time(crc32, 5, count) << " ms" << endl; + + const blambda times33 = [key]() -> const bool { + const unsigned int h = times33hash(c_str(key), length(key)); assert(h != 0); return true; - } -}; - -struct murmurhashTest { - const string key; - murmurhashTest(const string& key) : key(key) { - } - bool operator()() const { - unsigned int h = murmurhash(c_str(key), length(key)); + }; + cout << "times33hash test " << time(times33, 5, count) << " ms" << endl; + + const blambda murmur = [key]() -> const bool { + const unsigned int h = murmurhash(c_str(key), length(key)); assert(h != 0); return true; - } -}; - -struct portablemurmurhashTest { - const string key; - portablemurmurhashTest(const string& key) : key(key) { - } - bool operator()() const { - unsigned int h = portablemurmurhash(c_str(key), length(key)); + }; + cout << "murmurhash test " << time(murmur, 5, count) << " ms" << endl; + + const blambda portablemurmur = [key]() -> const bool { + const unsigned int h = portablemurmurhash(c_str(key), length(key)); assert(h != 0); return true; - } -}; - -bool testHashPerf() { - const string key("This is a test key"); - const int count = 100000; - - const lambda crc32 = crc32hashTest(key); - cout << "crc32hash test " << time(crc32, 5, count) << " ms" << endl; - const lambda times33 = times33hashTest(key); - cout << "times33hash test " << time(times33, 5, count) << " ms" << endl; - const lambda murmur = murmurhashTest(key); - cout << "murmurhash test " << time(murmur, 5, count) << " ms" << endl; - const lambda portablemurmur = portablemurmurhashTest(key); + }; cout << "portable murmurhash test " << time(portablemurmur, 5, count) << " ms" << endl; return true; @@ -121,7 +96,7 @@ bool testHashPerf() { } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; tuscany::testCrc32hash(); diff --git a/sca-cpp/trunk/kernel/hash.hpp b/sca-cpp/trunk/kernel/hash.hpp index 993511e3c2..9e80c977fe 100644 --- a/sca-cpp/trunk/kernel/hash.hpp +++ b/sca-cpp/trunk/kernel/hash.hpp @@ -43,7 +43,7 @@ namespace tuscany * tree at contrib/ltree/crc32.[ch] and from FreeBSD at * src/usr.bin/cksum/crc32.c. */ -const unsigned int crc32hash(const char* data, const size_t len) { +inline const unsigned int crc32hash(const char* const data, const size_t len) { return (unsigned int)apr_memcache_hash_default(NULL, data, len); } @@ -89,7 +89,7 @@ const unsigned int crc32hash(const char* data, const size_t len) { * * -- Ralf S. Engelschall */ -const unsigned int times33hash(const char* data, const size_t len) { +inline const unsigned int times33hash(const char* const data, const size_t len) { apr_ssize_t l = len; return apr_hashfunc_default(data, &l); } @@ -107,7 +107,7 @@ const unsigned int times33hash(const char* data, const size_t len) { * Passes Bob Jenkin's frog.c torture-test. No collisions possible for 4 byte * keys, no small 1 to 7 bit differentials. */ -const unsigned int murmurhash(const char* key, const size_t klen) { +inline const unsigned int murmurhash(const char* const key, const size_t klen) { unsigned int len = (unsigned int)klen; const unsigned int seed = 0; @@ -153,7 +153,7 @@ const unsigned int murmurhash(const char* key, const size_t klen) { * An endian and alignment neutral, but half the speed, version of * the murmur hash. */ -const unsigned int portablemurmurhash(const char* key, const size_t klen) { +inline const unsigned int portablemurmurhash(const char* const key, const size_t klen) { unsigned int len = (unsigned int)klen; const unsigned int seed = 0; @@ -199,7 +199,7 @@ const unsigned int portablemurmurhash(const char* key, const size_t klen) { return h; } -const unsigned int hashselect(const unsigned int hash, const unsigned int max) { +inline const unsigned int hashselect(const unsigned int hash, const unsigned int max) { return hash % max; } diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp index 4d2ca2ba81..0e2a14246a 100644 --- a/sca-cpp/trunk/kernel/kernel-test.cpp +++ b/sca-cpp/trunk/kernel/kernel-test.cpp @@ -23,6 +23,7 @@ * Test kernel functions. */ +#include #include #include "string.hpp" #include "sstream.hpp" @@ -36,58 +37,324 @@ namespace tuscany { -struct inc { - int i; - inc(int i) : +const bool ptrPerf() { + int x = 1; + for (int i = 0; i < 10000; i++) { + int* const y = &x; + int z = *y + *y; + z = z + 1; + } + return true; +} + +const bool gcptrPerf() { + int x = 1; + for (int i = 0; i < 10000; i++) { + const gc_ptr y = &x; + int z = *y + *y; + z = z + 1; + } + return true; +} + +const bool testPtrPerf() { + { + const gc_scoped_pool gcp; + const blambda pp = ptrPerf; + cout << "Pointer test " << (time(pp, 5, 10000) / 10000) << " ms" << endl; + } + { + const gc_scoped_pool gcp; + const blambda gpp = gcptrPerf; + cout << "GC Pointer test " << (time(gpp, 5, 10000) / 10000) << " ms" << endl; + } + return true; +} + +class incFunctor { +public: + incFunctor(const int i) : i(i) { } const int operator()(const int x) const { return x + i; } +private: + const int i; }; const int square(const int x) { return x * x; } -int mapLambda(lambda f, int v) { +const int mapLambda(lambda f, int v) { return f(v); } -bool testLambda() { - const lambda sq(square); +const lambda mksquare() { + return square; +} + +const bool testSizes() { + const gc_ptr p(NULL); + cout << "sizeof gc_ptr " << sizeof(p) << endl; + const lambda sq(square); + cout << "sizeof C function lambda " << sizeof(sq) << endl; + const lambda incl(incFunctor(10)); + cout << "sizeof functor lambda " << sizeof(incl) << endl; + const std::function sqf(square); + cout << "sizeof C function std::function " << sizeof(sqf) << endl; + const std::function incf(incFunctor(10)); + cout << "sizeof functor std::function " << sizeof(incf) << endl; + const string s("abcd"); + cout << "sizeof string " << sizeof(s) << endl; + const string v(s); + cout << "sizeof val " << sizeof(v) << endl; + const list li = cons(2, mklist(3, 4)); + cout << "sizeof list " << sizeof(li) << endl; + const list ls = cons("a", mklist("b", "c")); + cout << "sizeof list " << sizeof(ls) << endl; + const list lv = cons("a", mklist("b", "c")); + cout << "sizeof list " << sizeof(lv) << endl; + return true; +} + +const bool testLambda() { + const lambda sq(square); assert(sq(2) == 4); + + const lambda()> mksq(mksquare); + assert(mksq()(2) == 4); + assert(mapLambda(sq, 2) == 4); assert(mapLambda(square, 2) == 4); - const lambda incf(inc(10)); + const lambda incf(incFunctor(10)); assert(incf(1) == 11); assert(mapLambda(incf, 1) == 11); - assert(mapLambda(inc(10), 1) == 11); + assert(mapLambda(incFunctor(10), 1) == 11); + + const int base = 10; + auto incl11 = [base](const int i) { return base + i; }; + const lambda incl(incl11); + assert(incl(1) == 11); + assert(mapLambda(incl, 1) == 11); + assert(mapLambda(incl11, 1) == 11); + + const lambda il(incf); + assert(il(1) == 11); + const lambda sl(square); + assert(sl(2) == 4); + return true; +} + +int constructCopiable = 0; +int copyCopiable = 0; + +class Copiable { +public: + Copiable() { + assert(false); + } + + Copiable(const string& s) : s(s) { + constructCopiable++; + } + + Copiable(const Copiable& c) : s(c.s) { + copyCopiable++; + } + + Copiable& operator=(const Copiable& c) = delete; + + ~Copiable() { + } + + void doit() const { + } + +private: + const string s; +}; + +bool testLambdaRef(const Copiable& c) { + [&c] { c.doit(); }(); + return true; +} + +bool testLambdaCopy(const Copiable& c) { + [c] { c.doit(); }(); + return true; +} + +const bool testCopiable() { + const Copiable ac = Copiable("assigned"); + ac.doit(); + assert(constructCopiable = 1); + assert(copyCopiable = 1); + + const Copiable ac2 = []{ return Copiable("returned"); }(); + ac2.doit(); + assert(constructCopiable = 2); + assert(copyCopiable = 2); + + const Copiable rc = Copiable("captured by ref"); + testLambdaRef(rc); + assert(constructCopiable = 3); + assert(copyCopiable = 3); + + const Copiable cc = Copiable("captured by value"); + testLambdaCopy(cc); + assert(constructCopiable = 4); + assert(copyCopiable = 5); - lambda l; - l = incf; - assert(l(1) == 11); - l = square; - assert(l(2) == 4); return true; } -bool testLambdaGC() { +const bool testMutable() { + { + gc_mutable_ref s = string("aaa"); + s = "bbb"; + assert(s == "bbb"); + } + { + gc_mutable_ref s; + assert(s == ""); + s = "bbb"; + assert(s == "bbb"); + } + { + gc_mutable_ref v; + assert(isNil((value)v)); + v = 1; + assert(v == 1); + } + return true; +} + +const bool testLambdaGC() { resetLambdaCounters(); { - gc_scoped_pool gc; + const gc_scoped_pool gcp; testLambda(); } assert(checkLambdaCounters()); return true; } -int countElements = 0; +class sint { +public: + sint(const int i) : i(i) { + } + const int i; + char b[4]; +}; -struct Element { - int i; +const int mult(const sint& a, const sint& b) { + return a.i * b.i; +} + +const bool testCurry() { + const lambda mult2 = curry((lambda)mult, sint(2)); + assert(6 == mult2(sint(3))); + return true; +} + +const bool curryPerf() { + const sint a(2); + const sint b(3); + const lambda mult2 = curry((lambda)mult, a); + for(int i = 0; i < 1000; i++) + mult2(b); + return true; +} + +class multFunctor { +public: + multFunctor(const sint& a) : a(a) { + } + const int operator()(const sint& b) const { + return a.i * b.i; + } +private: + const sint a; +}; + +const bool testFunctor() { + const lambda mult2 = multFunctor(sint(2)); + assert(6 == mult2(sint(3))); + return true; +} + +const bool functorPerf() { + const sint a(2); + const sint b(3); + const lambda mult2 = lambda(multFunctor(a)); + for(int i = 0; i < 1000; i++) + mult2(b); + return true; +} + +const bool test11Lambda() { + const sint a(2); + assert(6 == [a](const sint& b) { return a.i * b.i; } (sint(3))); + return true; +} + +const lambda multlambda11(const sint& a) { + return [a](const sint& b) { return a.i * b.i; }; +} + +const bool lambda11Perf() { + const sint a(2); + const sint b(3); + const lambda mult2 = multlambda11(a); + for(int i = 0; i < 1000; i++) + mult2(b); + return true; +} + +const std::function multfunction11(const sint& a) { + return [a](const sint& b) { return a.i * b.i; }; +} + +const bool function11Perf() { + const sint a(2); + const sint b(3); + const std::function mult2 = multfunction11(a); + for(int i = 0; i < 1000; i++) + mult2(b); + return true; +} + +const bool testFuncPerf() { + { + const gc_scoped_pool gcp; + const blambda cp = curryPerf; + cout << "Curry test " << (time(cp, 5, 1000) / 1000) << " ms" << endl; + } + { + const gc_scoped_pool gcp; + const blambda fp = functorPerf; + cout << "Functor test " << (time(fp, 5, 1000) / 1000) << " ms" << endl; + } + { + const gc_scoped_pool gcp; + const blambda lp = lambda11Perf; + cout << "Lambda11 test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; + } + { + const gc_scoped_pool gcp; + const blambda lp = function11Perf; + cout << "Function11 test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; + } + return true; +} +int countElements = 0; + +class Element { +public: Element() : i(0) { countElements++; } @@ -107,13 +374,16 @@ struct Element { const bool operator==(const Element& o) const { return o.i == i; } + + int i; }; + ostream& operator<<(ostream& out, const Element& v) { out << v.i ; return out; } -bool testCons() { +const bool testCons() { assert(car(cons(2, mklist(3))) == 2); assert(car(cdr(cons(2, mklist(3)))) == 3); assert(isNil(cdr(cdr(cons(2, mklist(3)))))); @@ -122,12 +392,12 @@ bool testCons() { return true; } -bool testListGC() { +const bool testListGC() { resetLambdaCounters(); resetListCounters(); countElements = 0; { - gc_scoped_pool gc; + const gc_scoped_pool gcp; testCons(); } assert(checkLambdaCounters()); @@ -136,7 +406,41 @@ bool testListGC() { return true; } -bool testOut() { +template const list listPerf(const T& v, const long int i) { + if (i == 0) + return list(); + return cons(v, listPerf(v, i -1)); +} + +const bool testListPerf() { + { + const gc_scoped_pool gcp; + const blambda lp = []() -> const bool { + listPerf(0, 1000); + return true; + }; + cout << "List test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; + } + { + const gc_scoped_pool gcp; + const blambda lp = []() -> const bool { + listPerf(string("x"), 1000); + return true; + }; + cout << "List test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; + } + { + const gc_scoped_pool gcp; + const blambda lp = []() -> const bool { + listPerf(value("x"), 1000); + return true; + }; + cout << "List test " << (time(lp, 5, 1000) / 1000) << " ms" << endl; + } + return true; +} + +const bool testOut() { ostringstream os1; os1 << list (); assert(str(os1) == "()"); @@ -147,7 +451,7 @@ bool testOut() { return true; } -bool testEquals() { +const bool testEquals() { assert(list() == list()); assert(mklist(1, 2) == mklist(1, 2)); assert(list() != mklist(1, 2)); @@ -156,14 +460,14 @@ bool testEquals() { return true; } -bool testLength() { +const bool testLength() { assert(0 == length(list())); assert(1 == length(mklist(1))); assert(2 == length(cons(1, mklist(2)))); return true; } -bool testAppend() { +const bool testAppend() { assert(car(append(mklist(1), mklist(2))) == 1); assert(car(cdr(append(mklist(1), mklist(2)))) == 2); assert(car(cdr(cdr(append(mklist(1), mklist(2, 3))))) == 3); @@ -173,21 +477,23 @@ bool testAppend() { return true; } -struct Complex { - int x; - int y; - Complex() { +class Complex { +public: + Complex() : x(0), y(0) { } - Complex(int x, int y) : - x(x), y(y) { + Complex(const int x, const int y) : x(x), y(y) { } + + const int x; + const int y; }; + ostream& operator<<(ostream& out, const Complex& v) { out << "[" << v.x << ":" << v.y << "]"; return out; } -bool testComplex() { +const bool testComplex() { const list p = mklist(Complex(1, 2), Complex(3, 4)); assert(car(p).x == 1); assert(car(cdr(p)).x == 3); @@ -195,7 +501,7 @@ bool testComplex() { return true; } -bool testMap() { +const bool testMap() { assert(isNil(map(square, list()))); const list m = map(square, mklist(2, 3)); @@ -209,26 +515,26 @@ const int add(const int x, const int y) { return x + y; } -bool testReduce() { - const lambda r(add); +const bool testReduce() { + const lambda r(add); assert(reduce(r, 0, mklist(1, 2, 3)) == 6); return true; } -bool isPositive(const int x) { +const bool isPositive(const int x) { if(x >= 0) return true; else return false; } -bool testFilter() { +const bool testFilter() { assert(car(filter(isPositive, mklist(1, -1, 2, -2))) == 1); assert(cadr(filter(isPositive, mklist(1, -1, 2, -2))) == 2); return true; } -bool testMember() { +const bool testMember() { assert(isNil(member(4, mklist(1, 2, 3)))); assert(car(member(1, mklist(1, 2, 3))) == 1); assert(car(member(2, mklist(1, 2, 3))) == 2); @@ -236,14 +542,14 @@ bool testMember() { return true; } -bool testReverse() { +const bool testReverse() { assert(isNil(reverse(list()))); assert(car(reverse(mklist(1, 2, 3))) == 3); assert(cadr(reverse(mklist(1, 2, 3))) == 2); return true; } -bool testListRef() { +const bool testListRef() { assert(listRef(mklist(1), 0) == 1); assert(listRef(mklist(1, 2, 3), 0) == 1); assert(listRef(mklist(1, 2, 3), 1) == 2); @@ -251,7 +557,7 @@ bool testListRef() { return true; } -bool testAssoc() { +const bool testAssoc() { const list > l = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", l) == mklist("a", "A")); assert(isNil(assoc("z", l))); @@ -261,10 +567,13 @@ bool testAssoc() { const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", v) == mklist("a", "A")); + + const list v2 = mklist(mklist("x", "X"), "a", mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); + assert(assoc("a", v2) == mklist("a", "A")); return true; } -bool testZip() { +const bool testZip() { const list k = mklist("x", "a", "y", "a"); const list v = mklist("X", "A", "Y", "AA"); const list > z = mklist(k, v); @@ -274,7 +583,7 @@ bool testZip() { return true; } -bool testTokenize() { +const bool testTokenize() { assert(tokenize("/", "") == list()); assert(tokenize("/", "aaa") == mklist("aaa")); assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist("aaa", "bbb", "ccc", "ddd")); @@ -292,11 +601,11 @@ bool testTokenize() { return true; } -double testSeqMap(double x) { +const double testSeqMap(const double x) { return x; } -double testSeqReduce(unused double v, double accum) { +double testSeqReduce(unused const double v, const double accum) { return accum + 1.0; } @@ -316,16 +625,16 @@ bool testSeq() { return true; } -value valueSquare(list x) { +const value valueSquare(const list& x) { return (int)car(x) * (int)car(x); } -bool testValue() { - assert(value(true) == value(true)); +const bool testValue() { + assert(value(true) == trueValue); assert(value(1) == value(1)); assert(value("abcd") == value("abcd")); - lambda&)> vl(valueSquare); - assert(value(vl) == value(vl)); + lvvlambda vl(valueSquare); + //assert(value(vl) == value(vl)); assert(value(mklist(1, 2)) == value(mklist(1, 2))); const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y")); @@ -339,12 +648,12 @@ bool testValue() { return true; } -bool testValueGC() { +const bool testValueGC() { resetLambdaCounters(); resetListCounters(); resetValueCounters(); { - gc_scoped_pool gc; + const gc_scoped_pool gcp; testValue(); } assert(checkValueCounters()); @@ -353,8 +662,8 @@ bool testValueGC() { return true; } -bool testTree() { - const list t = mktree("a", list(), list()); +const bool testTree() { + const list t = mktree("a", nilListValue, nilListValue); const list ct = constree("d", constree("f", constree("c", constree("e", constree("b", t))))); const list mt = mktree(mklist("d", "f", "c", "e", "b", "a")); assert(mt == ct); @@ -371,8 +680,8 @@ const list lta(const string& x) { return mklist(c_str(x), c_str(x + x)); } -bool testTreeAssoc() { - const list t = mktree(lta("a"), list(), list()); +const bool testTreeAssoc() { + const list t = mktree(lta("a"), nilListValue, nilListValue); const list at = constree(lta("d"), constree(lta("f"), constree(lta("c"), constree(lta("e"), constree(lta("b"), t))))); const list l = flatten(at); assert(length(l) == 6); @@ -387,58 +696,46 @@ bool testTreeAssoc() { return true; } -double fib_aux(double n, double a, double b) { +const double fib_aux(const double n, const double a, const double b) { if(n == 0.0) return a; return fib_aux(n - 1.0, b, a + b); } -double fib(double n) { +const double fib(const double n) { return fib_aux(n, 0.0, 1.0); } -struct fibMapPerf { - const bool operator()() const { - list s = seq(0.0, 999.0); - list r = map(fib, s); - assert(1000 == length(r)); - return true; - } -}; - -struct nestedFibMapPerf { - const lambda fib; - nestedFibMapPerf(const lambda& fib) : fib(fib) { - } - const bool operator()() const { - list s = seq(0.0, 999.0); - list r = map(fib, s); - assert(1000 == length(r)); - return true; - } -}; +const bool fibMapPerf() { + const list s = seq(0.0, 999.0); + const list r = map(fib, s); + assert(1000 == length(r)); + return true; +} -bool testCppPerf() { +const bool testCppPerf() { { - const lambda fml = fibMapPerf(); + const gc_scoped_pool gcp; + const blambda fml = fibMapPerf; cout << "Fibonacci map test " << (time(fml, 1, 1) / 1000) << " ms" << endl; } { - struct nested { - static double fib(double n) { - struct nested { - static double fib_aux(double n, double a, double b) { - if(n == 0.0) - return a; - return fib_aux(n - 1.0, b, a + b); - } - }; - return nested::fib_aux(n, 0.0, 1.0); - } + const lambda fib = [](const double n) -> const double { + const lambda fib_aux = [&fib_aux](double n, double a, double b) -> const double { + if(n == 0.0) + return a; + return fib_aux(n - 1.0, b, a + b); + }; + return fib_aux(n, 0.0, 1.0); }; - const lambda nfml = nestedFibMapPerf(lambda(nested::fib)); + const blambda nfml = [fib]() -> const bool { + const list s = seq(0.0, 999.0); + const list r = map(fib, s); + assert(1000 == length(r)); + return true; + }; cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << endl; } return true; @@ -456,7 +753,7 @@ const id idH(const int v) { return idF(v) >> idG; } -bool testIdMonad() { +const bool testIdMonad() { const id m(2); assert(m >> idF == idF(2)); assert(m >> unit() == m); @@ -476,7 +773,7 @@ const maybe maybeH(const int v) { return maybeF(v) >> maybeG; } -bool testMaybeMonad() { +const bool testMaybeMonad() { const maybe m(2); assert(m >> maybeF == maybeF(2)); assert((m >> just()) == m); @@ -498,7 +795,7 @@ const failable failableH(const int v) { return failableF(v) >> failableG; } -bool testFailableMonad() { +const bool testFailableMonad() { const failable m(2); assert(m >> failableF == failableF(2)); assert((m >> success()) == m); @@ -515,23 +812,16 @@ bool testFailableMonad() { assert(rcode(vooops) == 500); const value v = value(vooops); - assert(car(v) == value()); + assert(car(v) == nilValue); assert(cadr(v) == string("test")); assert(caddr(v) == value((double)500)); return true; } -struct tickInc { - const double v; - tickInc(const double v) : v(v) { - } - const scp operator()(int s) const { - return scp(s + 1, v); - } -}; - const state tick(const double v) { - return transformer(tickInc(v)); + return transformer([v](const int s) { + return scp(s + 1, v); + }); } const state stateF(const double v) { @@ -546,8 +836,8 @@ const state stateH(const double v) { return stateF(v) >> stateG; } -bool testStateMonad() { - const lambda(const double)> r(result); +const bool testStateMonad() { + const lambda(const double)> r(result); state m = result(2.0); assert((m >> stateF)(0) == stateF(2.0)(0)); @@ -558,30 +848,40 @@ bool testStateMonad() { return true; } -bool testDynLib() { +const bool testDynLib() { const lib dl(string("./libdynlib-test") + dynlibExt); - const failable > sq(dynlambda("csquare", dl)); + const failable > sq(dynlambda("csquare", dl)); assert(hasContent(sq)); - lambda l(content(sq)); + lambda l(content(sq)); assert(l(2) == 4); - const failable()> > sql(dynlambda()>("csquarel", dl)); + const failable()> > sql(dynlambda()>("csquarel", dl)); assert(hasContent(sql)); - lambda()> ll(content(sql)); + lambda()> ll(content(sql)); assert(ll()(3) == 9); return true; } + } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; + tuscany::testSizes(); + tuscany::testCopiable(); + tuscany::testMutable(); + tuscany::testPtrPerf(); tuscany::testLambda(); tuscany::testLambdaGC(); + tuscany::testCurry(); + tuscany::testFunctor(); + tuscany::test11Lambda(); + tuscany::testFuncPerf(); tuscany::testCons(); tuscany::testListGC(); + tuscany::testListPerf(); tuscany::testOut(); tuscany::testEquals(); tuscany::testLength(); diff --git a/sca-cpp/trunk/kernel/lambda-test.cpp b/sca-cpp/trunk/kernel/lambda-test.cpp index 05a16c2eb8..81f17a57b0 100644 --- a/sca-cpp/trunk/kernel/lambda-test.cpp +++ b/sca-cpp/trunk/kernel/lambda-test.cpp @@ -34,7 +34,7 @@ namespace tuscany { #ifdef HAS_CXX0X_LAMBDAS const lambda inc(const int i) { - return [=](const int x)->const int { + return [i](const int x)->const int { return x + i; }; } @@ -43,27 +43,26 @@ const int square(const int x) { return x * x; } -int mapLambda(const lambda f, int v) { +const int mapLambda(const lambda f, int v) { return f(v); } -bool testLambda() { +const bool testLambda() { const lambda sq = square; assert(sq(2) == 4); assert(mapLambda(square, 2) == 4); assert(mapLambda(sq, 2) == 4); assert(mapLambda([](const int x)->const int { return x * x; }, 2) == 4); - const lambda incf = inc(10); + const lambda incf = inc(10); assert(incf(1) == 11); assert(mapLambda(incf, 1) == 11); assert(mapLambda(inc(10), 1) == 11); - lambda l; - l = incf; - assert(l(1) == 11); - l = square; - assert(l(2) == 4); + const lambda il(incf); + assert(il(1) == 11); + const lambda sl(square); + assert(sl(2) == 4); return true; } @@ -72,13 +71,13 @@ const double fib_aux(const double n, const double a, const double b) { } const bool fibMapPerf() { - list s = seq(0.0, 4999.0); - list r = map([](const double n)->const double { return fib_aux(n, 0.0, 1.0); }, s); + const list s = seq(0.0, 4999.0); + const list r = map([](const double n)->const double { return fib_aux(n, 0.0, 1.0); }, s); assert(5000 == length(r)); return true; } -bool testCppPerf() { +const bool testCppPerf() { cout << "Fibonacci map test " << (time([]()->const bool { return fibMapPerf(); }, 1, 1) / 5000) << " ms" << endl; return true; } @@ -87,7 +86,7 @@ bool testCppPerf() { } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; #ifdef HAS_CXX0X_LAMBDAS diff --git a/sca-cpp/trunk/kernel/list.hpp b/sca-cpp/trunk/kernel/list.hpp index d3736de62c..16a0649fe9 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; -bool resetListCounters() { +inline const bool resetListCounters() { countLists = countILists = countCLists = countELists = 0; return true; } -bool checkListCounters() { +inline const bool checkListCounters() { return countLists == 0; } -bool printListCounters() { +inline const bool printListCounters() { cout << "countLists " << countLists << endl; cout << "countELists " << countELists << endl; cout << "countILists " << countILists << endl; @@ -91,19 +91,19 @@ bool printListCounters() { template class list { public: - list() { + inline list() : car() { debug_inc(countLists); debug_inc(countELists); debug_watchList(); } - list(const T car, const lambda()>& cdr) : car(car), cdr(cdr) { + inline list(const T& car, const lambda()>& cdr) : car(car), cdr(cdr) { debug_inc(countLists); debug_inc(countILists); debug_watchList(); } - list(const list& p) : car(p.car), cdr(p.cdr) { + inline list(const list& p) : car(p.car), cdr(p.cdr) { debug_inc(countLists); debug_inc(countCLists); #ifdef WANT_MAINTAINER_WATCH @@ -111,22 +111,13 @@ public: #endif } - const list& operator=(const list& p) { - if(this == &p) - return *this; - car = p.car; - cdr = p.cdr; -#ifdef WANT_MAINTAINER_WATCH - watch = p.watch; -#endif - return *this; - } + list& operator=(const list& p) = delete; - ~list() { + inline ~list() { debug_dec(countLists); } - const bool operator==(const list& p) const { + inline const bool operator==(const list& p) const { if(this == &p) return true; if(isNil(cdr)) @@ -140,7 +131,7 @@ public: return cdr() == p.cdr(); } - const bool operator<(const list& p) const { + inline const bool operator<(const list& p) const { if(this == &p) return false; if (isNil(cdr)) @@ -154,7 +145,7 @@ public: return cdr() < p.cdr(); } - const bool operator>(const list& p) const { + inline const bool operator>(const list& p) const { if(this == &p) return false; if (isNil(cdr)) @@ -168,11 +159,11 @@ public: return cdr() > p.cdr(); } - const bool operator!=(const list& p) const { + inline const bool operator!=(const list& p) const { return !this->operator==(p); } - operator const list >() const { + inline operator const list >() const { return (list >)T(*this); } @@ -185,9 +176,10 @@ private: template friend const bool isNil(const list& p); template friend const X car(const list& p); template friend const list cdr(const list& p); + template friend const bool setlist(list& target, const list& l); - T car; - lambda()> cdr; + const T car; + const lambda()> cdr; }; #ifdef WANT_MAINTAINER_WATCH @@ -196,7 +188,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 const string watchList(const list& p) { +template inline const string watchList(const list& p) { if(isNil(p)) return "()"; odebugstream os; @@ -209,21 +201,21 @@ template const string watchList(const list& p) { /** * Returns true if the given list is nil. */ -template const bool isNil(const list& p) { +template inline const bool isNil(const list& p) { return isNil(p.cdr); } /** * Write a list to an output stream. */ -template ostream& writeHelper(ostream& out, const list& l) { +template inline ostream& writeHelper(ostream& out, const list& l) { if (isNil(l)) return out; out << " " << car(l); return writeHelper(out, cdr(l)); } -template ostream& operator<<(ostream& out, const list& l) { +template inline ostream& operator<<(ostream& out, const list& l) { if(isNil(l)) return out << "()"; out << "(" << car(l); @@ -234,74 +226,74 @@ template ostream& operator<<(ostream& out, const list& l) { /** * Construct a (lazy) list from a value and a lambda function that returns the cdr. */ -template const list cons(const T& car, const lambda()>& cdr) { +template inline const list cons(const T& car, const lambda()>& cdr) { return list (car, cdr); } /** * Construct a list from a value and a cdr list. */ -template const list cons(const T& car, const list& cdr) { +template inline const list cons(const T& car, const list& cdr) { return list (car, result(cdr)); } /** * Cons variations for use with the reduce and reduceRight functions. */ -template const list lcons(const list& cdr, const T& car) { +template inline const list lcons(const list& cdr, const T& car) { return cons(car, cdr); } -template const list rcons(const T& car, const list& cdr) { +template inline const list rcons(const T& car, const list& cdr) { return cons(car, cdr); } /** * Construct a list of one value. */ -template const list mklist(const T& car) { +template inline const list mklist(const T& car) { return list (car, result(list ())); } /** * Construct a list of two values. */ -template const list mklist(const T& a, const T& b) { +template inline const list mklist(const T& a, const T& b) { return cons(a, mklist(b)); } /** * Construct a list of three values. */ -template const list mklist(const T& a, const T& b, const T& c) { +template inline const list mklist(const T& a, const T& b, const T& c) { return cons(a, cons(b, mklist(c))); } /** * Construct a list of four values. */ -template const list mklist(const T& a, const T& b, const T& c, const T& d) { +template inline const list mklist(const T& a, const T& b, const T& c, const T& d) { return cons(a, cons(b, cons(c, mklist(d)))); } /** * Construct a list of five values. */ -template const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e) { +template inline const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e) { return cons(a, cons(b, cons(c, cons(d, mklist(e))))); } /** * Construct a list of six values. */ -template const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) { +template inline const list mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) { return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f)))))); } /** * Returns the car of a list. */ -template const T car(const list& p) { +template inline const T car(const list& p) { // Abort if trying to access the car of a nil list assertOrFail(!isNil(p.cdr)); return p.car; @@ -310,159 +302,144 @@ template const T car(const list& p) { /** * Returns the cdr of a list. */ -template const list cdr(const list& p) { +template inline const list cdr(const list& p) { return p.cdr(); } /** * Returns the car of the cdr (the 2nd element) of a list. */ -template const T cadr(const list& p) { +template inline const T cadr(const list& p) { return car(cdr(p)); } /** * Returns the 3rd element of a list. */ -template const T caddr(const list& p) { +template inline const T caddr(const list& p) { return car(cdr(cdr(p))); } /** * Returns the 4th element of a list. */ -template const T cadddr(const list& p) { +template inline const T cadddr(const list& p) { return car(cdr(cdr(cdr(p)))); } /** * Returns the 5th element of a list. */ -template const T caddddr(const list& p) { +template inline const T caddddr(const list& p) { return car(cdr(cdr(cdr(cdr(p))))); } /** * Returns the 6th element of a list. */ -template const T cadddddr(const list& p) { +template inline const T cadddddr(const list& p) { return car(cdr(cdr(cdr(cdr(cdr(p)))))); } /** * Returns the 7th element of a list. */ -template const T caddddddr(const list& p) { +template inline const T caddddddr(const list& p) { return car(cdr(cdr(cdr(cdr(cdr(cdr(p))))))); } /** * Returns the 8th element of a list. */ -template const T cadddddddr(const list& p) { +template inline const T cadddddddr(const list& p) { 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 const list cddr(const list& p) { +template inline const list cddr(const list& p) { return cdr(cdr(p)); } /** * Returns a list of elements from the 4th to the end of a list. */ -template const list cdddr(const list& p) { +template inline const list cdddr(const list& p) { return cdr(cdr(cdr(p))); } /** * Returns a list of elements from the 5th to the end of a list. */ -template const list cddddr(const list& p) { +template inline const list cddddr(const list& p) { return cdr(cdr(cdr(cdr(p)))); } /** * Returns a list of elements from the 6th to the end of a list. */ -template const list cdddddr(const list& p) { +template inline const list cdddddr(const list& p) { return cdr(cdr(cdr(cdr(cdr(p))))); } /** * Returns a list of elements from the 7th to the end of a list. */ -template const list cddddddr(const list& p) { +template inline const list cddddddr(const list& p) { return cdr(cdr(cdr(cdr(cdr(cdr(p)))))); } /** * Returns a list of elements from the 8th to the end of a list. */ -template const list cdddddddr(const list& p) { +template inline const list cdddddddr(const list& p) { return cdr(cdr(cdr(cdr(cdr(cdr(cdr(p))))))); } /** * Returns the length of a list. */ -template struct lengthRef { - const size_t operator()(const size_t c, const list& p) { +template inline const size_t length(const list& p) { + const lambda&)> lengthRef = [&lengthRef](const size_t c, const list& p) -> const size_t { if(isNil(p)) return c; - return (*this)(c + 1, cdr(p)); - } -}; - -template const size_t length(const list& p) { - return lengthRef ()(0, p); + return lengthRef(c + 1, cdr(p)); + }; + return lengthRef(0, p); } /** * Appends a list and a lambda function returning a list. */ -template struct appendCdr { - const list a; - const lambda()> fb; - appendCdr(const list& a, const lambda()>& fb) : - a(a), fb(fb) { - } - const list operator()() const { - return append(a, fb); - } -}; - -template const list append(const list&a, const lambda()>& fb) { +template inline const list append(const list&a, const lambda()>& fb) { if(isNil(a)) return fb(); - - return cons(car(a), appendCdr (cdr(a), fb)); + return cons(car(a), [a, fb]() { return append(cdr(a), fb); }); } /** * Appends two lists. */ -template const list append(const list&a, const list& b) { +template inline const list append(const list&a, const list& b) { return append(a, result(b)); } /** * Append a value to a list. */ -template const list operator+(const list& l, const T& v) { +template inline const list operator+(const list& l, const T& v) { return append(l, mklist(v)); } -template const list operator+(const list& l, const V& v) { +template const list inline operator+(const list& l, const V& v) { return append(l, mklist(v)); } /** * Map a lambda function on a list. */ -template const list map(const lambda& f, const list& p) { +template inline const list map(const lambda& f, const list& p) { if(isNil(p)) return list (); return cons(f(car(p)), map(f, cdr(p))); @@ -471,46 +448,32 @@ template const list map(const lambda& f, /** * Run a reduce lambda function on a list. */ -template struct reduceAccumulate { - const lambda f; - reduceAccumulate(const lambda& f) : - f(f) { - } - R operator()(const R& acc, const list& p) const { +template inline const R reduce(const lambda& f, const R& initial, const list& p) { + const lambda&p)> reduceAccumulate = [f, &reduceAccumulate](const R& acc, const list& p) -> R { if(isNil(p)) return acc; - return (*this)(f(acc, car(p)), cdr(p)); - } -}; - -template const R reduce(const lambda& f, const R& initial, const list& p) { - return reduceAccumulate (f)(initial, p); + return reduceAccumulate(f(acc, car(p)), cdr(p)); + }; + return reduceAccumulate(initial, p); } -template struct reduceRightAccumulate { - const lambda f; - reduceRightAccumulate(const lambda& f) : - f(f) { - } - R operator()(const list& p, const R& acc) const { +template inline const R reduceRight(const lambda& f, const R& initial, const list& p) { + const lambda&p, const R&)> reduceRightAccumulate = [f, &reduceRightAccumulate](const list& p, const R& acc) -> R { if(isNil(p)) return acc; - return (*this)(cdr(p), f(car(p), acc)); - } -}; - -template const R reduceRight(const lambda& f, const R& initial, const list& p) { - return reduceRightAccumulate (f)(p, initial); + return reduceRightAccumulate(cdr(p), f(car(p), acc)); + }; + return reduceRightAccumulate(p, initial); } /** * Run a filter lambda function on a list. */ -template const list filter(const lambda& f, const list& p) { +template inline const list filter(const lambda& f, const list& p) { if(isNil(p)) return list (); if(f(car(p))) { - const lambda(const lambda, const list)> ff(filter); + const lambda(const lambda, const list)> ff(filter); return cons(car(p), curry(ff, f, cdr(p))); } return filter(f, cdr(p)); @@ -519,7 +482,7 @@ template const list filter(const lambda& f, const /** * Returns a list pointing to a member of a list. */ -template const list member(const T& t, const list& p) { +template inline const list member(const T& t, const list& p) { if(isNil(p)) return list (); if(t == car(p)) @@ -530,44 +493,31 @@ template const list member(const T& t, const list& p) { /** * Reverse a list. */ -template const list reverseIter(const list& acc, const list& p) { +template inline const list reverseIter(const list& acc, const list& p) { if(isNil(p)) return acc; return reverseIter(cons(car(p), acc), cdr(p)); } -template const list reverse(const list& p) { +template inline const list reverse(const list& p) { return reverseIter(list (), p); } -template const list seq(const T& start, const T& end); - -template struct seqGenerate { - const T start; - const T end; - seqGenerate(const T& start, const T&end) : - start(start), end(end) { - } - const list operator()() const { - return seq (start, end); - } -}; - /** * Returns a sequence of values between the given bounds. */ -template const list seq(const T& start, const T& end) { +template inline const list seq(const T& start, const T& end) { if(start == end) return mklist(start); if(start < end) - return cons(start, seqGenerate (start + 1, end)); - return cons(start, seqGenerate (start - 1, end)); + return cons(start, [start, end] { return seq (start + 1, end); }); + return cons(start, [start, end] { return seq (start - 1, end); }); } /** * Returns the i-th element of a list. */ -template const T listRef(const list& l, const size_t i) { +template inline const T listRef(const list& l, const size_t i) { if (i == 0) return car(l); return listRef(cdr(l), i - 1); @@ -576,7 +526,7 @@ template const T listRef(const list& l, const size_t i) { /** * Returns the first pair matching a key from a list of key value pairs. */ -template const list assoc(const T& k, const list >& p) { +template inline const list assoc(const T& k, const list >& p) { if(isNil(p)) return list (); if(k == car(car(p))) @@ -587,7 +537,7 @@ template const list assoc(const T& k, const list >& p) { /** * Returns a list of lists containing elements from two input lists. */ -template const list > zip(const list& a, const list& b) { +template inline const list > zip(const list& a, const list& b) { if (isNil(a) || isNil(b)) return list >(); return cons >(mklist(car(a), car(b)), zip(cdr(a), cdr(b))); @@ -596,19 +546,19 @@ template const list > zip(const list& a, const list& b /** * Converts a list of key value pairs to a list containing the list of keys and the list of values. */ -template const list unzipKeys(const list >& l) { +template inline const list unzipKeys(const list >& l) { if (isNil(l)) return list(); return cons(car(car(l)), unzipKeys(cdr(l))); } -template const list unzipValues(const list >& l) { +template inline const list unzipValues(const list >& l) { if (isNil(l)) return list(); return cons(cadr(car(l)), unzipValues(cdr(l))); } -template const list > unzip(const list >& l) { +template inline const list > unzip(const list >& l) { return mklist >(unzipKeys(l), unzipValues(l)); } diff --git a/sca-cpp/trunk/kernel/mem-test.cpp b/sca-cpp/trunk/kernel/mem-test.cpp index 668dabe749..2072da9f68 100644 --- a/sca-cpp/trunk/kernel/mem-test.cpp +++ b/sca-cpp/trunk/kernel/mem-test.cpp @@ -43,7 +43,7 @@ public: maxElements = countElements; } - Element(int i) : i(i) { + Element(const int i) : i(i) { countElements++; if (countElements > maxElements) maxElements = countElements; @@ -66,7 +66,7 @@ public: private: friend ostream& operator<<(ostream& out, const Element& v); - int i; + const int i; char c[20]; }; @@ -75,14 +75,14 @@ ostream& operator<<(ostream& out, const Element& v) { return out; } -bool poolAlloc(Element** p, const int count) { +const bool poolAlloc(Element** const p, const int count) { if (count == 0) return true; p[count - 1] = new (gc_new()) Element(); return poolAlloc(p, count - 1); }; -bool poolFree(Element** p, const int count) { +bool poolFree(Element** const p, const int count) { if (count == 0) return true; // Do nothing to free the element, but cycle through them just @@ -90,21 +90,14 @@ bool poolFree(Element** p, const int count) { return poolFree(p, count - 1); }; -struct poolAllocPerf { - const int n; - Element** p; - poolAllocPerf(const int n) : n(n), p(new Element*[n]) { - } - const bool operator()() const { - gc_scoped_pool gc; - poolAlloc(p, n); - return true; - } -}; - -bool testPoolAllocPerf() { +const bool testPoolAllocPerf() { const int count = 10000; - const lambda pl = poolAllocPerf(count); + Element** const elements = new Element*[count]; + const blambda pl = [elements, count]() -> const bool { + const gc_scoped_pool gc; + poolAlloc(elements, count); + return true; + }; maxElements = 0; cout << "Memory pool alloc test " << (time(pl, 1, 1) / count) << " ms" << endl; assert(countElements == 0); @@ -112,35 +105,28 @@ bool testPoolAllocPerf() { return true; } -bool stdAlloc(Element** p, const int count) { +const bool stdAlloc(Element** const p, const int count) { if (count == 0) return true; p[count - 1] = new Element(); return stdAlloc(p, count - 1); }; -bool stdFree(Element** p, const int count) { +const bool stdFree(Element** const p, const int count) { if (count == 0) return true; delete p[count -1]; return stdFree(p, count - 1); }; -struct stdAllocPerf { - const int n; - Element** p; - stdAllocPerf(const int n) : n(n), p(new Element*[n]) { - } - const bool operator()() const { - stdAlloc(p, n); - stdFree(p, n); - return true; - } -}; - -bool testStdAllocPerf() { +const bool testStdAllocPerf() { const int count = 10000; - const lambda sl = stdAllocPerf(count); + Element** const elements = new Element*[count]; + const blambda sl = [elements, count]() -> const bool { + stdAlloc(elements, count); + stdFree(elements, count); + return true; + }; maxElements = 0; cout << "Memory standard alloc test " << (time(sl, 1, 1) / count) << " ms" << endl; assert(countElements == 0); @@ -151,7 +137,7 @@ bool testStdAllocPerf() { } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; tuscany::testPoolAllocPerf(); diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp index b67e92ad79..de79780e7a 100644 --- a/sca-cpp/trunk/kernel/monad.hpp +++ b/sca-cpp/trunk/kernel/monad.hpp @@ -26,8 +26,11 @@ * Simple monad implementations. */ +#ifdef WANT_MAINTAINER_BACKTRACE #include #include +#endif + #include "function.hpp" #include "string.hpp" #include "stream.hpp" @@ -43,21 +46,16 @@ namespace tuscany */ template class id { public: - id(const V& v) : v(v) { + inline id(const V& v) : v(v) { } - const id& operator=(const id& m) { - if(this == &m) - return *this; - v = m.v; - return *this; - } + id& operator=(const id& m) = delete; - const bool operator!=(const id& m) const { + inline const bool operator!=(const id& m) const { return !this->operator==(m); } - const bool operator==(const id& m) const { + inline const bool operator==(const id& m) const { if (&m == this) return true; return v == m.v; @@ -72,7 +70,7 @@ private: /** * Write an identity monad to a stream. */ -template ostream& operator<<(ostream& out, const id& m) { +template inline ostream& operator<<(ostream& out, const id& m) { out << content(m); return out; } @@ -80,29 +78,29 @@ template ostream& operator<<(ostream& out, const id& m) { /** * Returns the content of an identity monad. */ -template const V content(const id& m) { +template inline const V content(const id& m) { return m.v; } /** * Return an identity monad from a value. */ -template const id mkunit(const V& v) { +template inline const id mkunit(const V& v) { return id(v); } -template const lambda(const V)> unit() { +template inline const lambda(const V)> unit() { return mkunit; } /** * Bind a function to an identity monad. Pass the value in the monad to the function. */ -template const id operator>>(const id& m, const lambda(const V)>& f) { +template inline const id operator>>(const id& m, const lambda(const V)>& f) { return f(content(m)); } -template const id operator>>(const id& m, const id (* const f)(const V)) { +template inline const id operator>>(const id& m, const id (* const f)(const V)) { return f(content(m)); } @@ -112,26 +110,22 @@ template const id operator>>(const id& m, const id */ template class maybe { public: - maybe(const V& v) : hasv(true), v(v) { + inline maybe(const V& v) : hasv(true), v(v) { } - maybe() : hasv(false) { + inline maybe() : hasv(false), v() { } - const maybe& operator=(const maybe& m) { - if(this == &m) - return *this; - hasv = m.hasv; - if (hasv) - v = m.v; - return *this; + inline maybe(const maybe& m) : hasv(m.hasv), v(m.v) { } - const bool operator!=(const maybe& m) const { + maybe& operator=(const maybe& m) = delete; + + inline const bool operator!=(const maybe& m) const { return !this->operator==(m); } - const bool operator==(const maybe& m) const { + inline const bool operator==(const maybe& m) const { if (this == &m) return true; if (!hasv) @@ -141,7 +135,7 @@ public: private: const bool hasv; - V v; + const V v; template friend const bool hasContent(const maybe& m); template friend const X content(const maybe& m); @@ -150,7 +144,7 @@ private: /** * Write a maybe monad to a stream. */ -template ostream& operator<<(ostream& out, const maybe& m) { +template inline ostream& operator<<(ostream& out, const maybe& m) { if (!hasContent(m)) { out << "nothing"; return out; @@ -162,25 +156,25 @@ template ostream& operator<<(ostream& out, const maybe& m) { /** * Return a maybe monad with a value in it. */ -template const maybe mkjust(const V& v) { +template inline const maybe mkjust(const V& v) { return maybe(v); } -template const lambda(const V)> just() { +template inline const lambda(const V)> just() { return mkjust; } /** * Returns true if a maybe monad contains a content. */ -template const bool hasContent(const maybe& m) { +template inline const bool hasContent(const maybe& m) { return m.hasv; } /** * Returns the content of a maybe monad. */ -template const V content(const maybe& m) { +template inline const V content(const maybe& m) { return m.v; } @@ -188,13 +182,13 @@ template const V content(const maybe& 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 const maybe operator>>(const maybe& m, const lambda(const V)>& f) { +template inline const maybe operator>>(const maybe& m, const lambda(const V)>& f) { if (!hasContent(m)) return m; return f(content(m)); } -template const maybe operator>>(const maybe& m, const maybe (* const f)(const V)) { +template inline const maybe operator>>(const maybe& m, const maybe (* const f)(const V)) { if (!hasContent(m)) return m; return f(content(m)); @@ -207,30 +201,22 @@ template const maybe operator>>(const maybe& m, co */ template class failable { public: - failable() : hasv(false), c(-1) { + inline failable() : hasv(false), v(), c(-1) { } - failable(const V& v) : hasv(true), v(v), c(-1) { + inline failable(const V& v) : hasv(true), v(v), c(-1) { } - failable(const failable& m) : hasv(m.hasv), v(m.v), f(m.f), c(m.c) { + inline failable(const failable& m) : hasv(m.hasv), v(m.v), f(m.f), c(m.c) { } - const failable& operator=(const failable& m) { - if (&m == this) - return *this; - hasv = m.hasv; - v = m.v; - f = m.f; - c = m.c; - return *this; - } + failable& operator=(const failable& m) = delete; - const bool operator!=(const failable& m) const { + inline const bool operator!=(const failable& m) const { return !this->operator==(m); } - const bool operator==(const failable& m) const { + inline const bool operator==(const failable& m) const { if (this == &m) return true; if (!hasv) @@ -239,7 +225,7 @@ public: } private: - failable(const bool hasv, const F& f, const C& c) : hasv(hasv), f(f), c(c) { + inline failable(const bool hasv, const F& f, const C& c) : hasv(hasv), v(), f(f), c(c) { } template friend const bool hasContent(const failable& m); @@ -250,16 +236,16 @@ private: template friend const failable mkfailure(const B& f, const int c, const bool log); template friend const failable mkfailure(); - bool hasv; - V v; - F f; - C c; + const bool hasv; + const V v; + const F f; + const C c; }; /** * Write a failable monad to a stream. */ -template ostream& operator<<(ostream& out, const failable& m) { +template inline ostream& operator<<(ostream& out, const failable& m) { if (!hasContent(m)) { out << reason(m) << " : " << rcode(m); return out; @@ -271,20 +257,22 @@ template ostream& operator<<(ostream& out, c /** * Returns a failable monad with a success value in it. */ -template const failable mksuccess(const V& v) { +template inline const failable mksuccess(const V& v) { return failable(v); } -template const lambda(const V)> success() { +template inline const lambda(const V)> success() { return mksuccess; } +#ifdef WANT_MAINTAINER_BACKTRACE + /** * Demangle a C++ function name. */ -const string demangleFrame(const char* fun) { +inline const string demangleFrame(const char* fun) { int status; - char* name = abi::__cxa_demangle(fun, 0, 0, &status); + char* const name = abi::__cxa_demangle(fun, 0, 0, &status); if (name == NULL) return fun; const string s = name; @@ -295,12 +283,12 @@ const string demangleFrame(const char* fun) { /** * Format a backtrace frame. */ -const char* formatFrameFile(const char* file) { - const char* s = strrchr(file, '/'); +inline const char* const formatFrameFile(const char* const file) { + const char* const s = strrchr(file, '/'); return s == NULL? file : s + 1; } -const string formatFrame(const char* symbol) { +inline const string formatFrame(const char* const symbol) { #ifdef __clang__ // Mac OS X CLang/LLVM stack frame format // 0 kernel-test 0x000000010d440179 _ZN7tuscany9mkfailureINS_5valueENS_6stringEiEEKNS_8failableIT_T0_T1_EERKS5_RKS6_b + 265 @@ -349,7 +337,7 @@ const string formatFrame(const char* symbol) { /** * Log backtrace frames. */ -const bool logFrames(char** symbols, const int frames, const bool log) { +inline const bool logFrames(char** const symbols, const int frames, const bool log) { if (frames == 0) return true; #ifdef WANT_MAINTAINER_LOG @@ -364,26 +352,30 @@ const bool logFrames(char** symbols, const int frames, const bool log) { /** * Log a backtrace. */ -const bool logBacktrace(void** callstack, const int frames, const bool log) { +inline const bool logBacktrace(void** const callstack, const int frames, const bool log) { char** symbols = backtrace_symbols(callstack, frames); logFrames(symbols, frames, log); free(symbols); return true; } +#endif + /** * Returns a failable monad with a failure in it. */ -template const failable mkfailure(const F& f, const C& c, const bool log = true) { +template inline const failable mkfailure(const F& f, const C& c, const bool log = true) { #ifdef WANT_MAINTAINER_LOG if (!log) { // Log the failure debug(f, "failable::mkfailure"); +#ifdef WANT_MAINTAINER_BACKTRACE // Log the call stack void* callstack[16]; const int frames = backtrace(callstack, 16); logBacktrace(callstack, frames, log); +#endif } #endif if (log) { @@ -393,63 +385,65 @@ template const failable mkfailure(c // Log the failure cfailure << "failable::mkfailure: " << f << " : " << c << endl; +#ifdef WANT_MAINTAINER_BACKTRACE // Print the call stack void* callstack[16]; const int frames = backtrace(callstack, 16); logBacktrace(callstack, frames, log); +#endif } } return failable(false, f, c); } -template const failable mkfailure(const F& f, const int c = -1, const bool log = true) { +template inline const failable mkfailure(const F& f, const int c = -1, const bool log = true) { return mkfailure(f, c, log); } -template const failable mkfailure(const char* f, const int c = -1, const bool log = true) { +template inline const failable mkfailure(const char* f, const int c = -1, const bool log = true) { return mkfailure(string(f), c, log); } -template const failable mkfailure() { +template inline const failable mkfailure() { return failable(false, string(), -1); } -template const lambda(const V)> failure() { +template inline const lambda(const V)> failure() { return mkfailure; } /** * Convert a failable of a given type to a failable of another type. */ -template const failable mkfailure(const failable& f, const bool log = true) { +template inline const failable mkfailure(const failable& f, const bool log = false) { return mkfailure(reason(f), rcode(f), log); } /** * Returns true if the monad contains a content. */ -template const bool hasContent(const failable& m) { +template inline const bool hasContent(const failable& m) { return m.hasv; } /** * Returns the content of a failable monad. */ -template const V content(const failable& m) { +template inline const V content(const failable& m) { return m.v; } /** * Returns the reason for failure of a failable monad. */ -template const F reason(const failable& m) { +template inline const F reason(const failable& m) { return m.f; } /** * Returns the reason code for failure of a failable monad. */ -template const C rcode(const failable& m) { +template inline const C rcode(const failable& m) { return m.c; } @@ -458,14 +452,14 @@ template const C rcode(const failable -const failable operator>>(const failable& m, const lambda(const V)>& f) { +inline const failable operator>>(const failable& m, const lambda(const V)>& f) { if (!hasContent(m)) return m; return f(content(m)); } template -const failable operator>>(const failable& m, const failable (* const f)(const V)) { +inline const failable operator>>(const failable& m, const failable (* const f)(const V)) { if (!hasContent(m)) return m; return f(content(m)); @@ -476,30 +470,27 @@ const failable operator>>(const failable& m, const failabl */ template class scp { public: - scp(const S& s, const V& v) : s(s), v(v) { + inline scp(const S& s, const V& v) : s(s), v(v) { } - operator const S() const { + inline operator const S() const { return s; } - operator const V() const { + inline operator const V() const { return v; } - const scp& operator=(const scp& p) { - if(this == &p) - return *this; - s = p.s; - v = p.v; - return *this; + inline scp(const scp& p) : s(p.s), v(p.v) { } - const bool operator!=(const scp& p) const { + scp& operator=(const scp& p) = delete; + + inline const bool operator!=(const scp& p) const { return !this->operator==(p); } - const bool operator==(const scp& p) const { + inline const bool operator==(const scp& p) const { if (this == &p) return true; return s == p.s && v == p.v; @@ -516,14 +507,14 @@ private: /** * Returns the state of a state-content pair. */ -template const S scpstate(const scp& m) { +template inline const S scpstate(const scp& m) { return m.s; } /** * Returns the content of a state-content pair. */ -template const S content(const scp& m) { +template inline const S content(const scp& m) { return m.v; } @@ -532,38 +523,36 @@ template const S content(const scp& m) { */ template class state { public: - state(const lambda(const S)>& f) : f(f) { + inline state(const lambda(const S)>& f) : f(f) { } - const scp operator()(const S& s) const { + inline const scp operator()(const S& s) const { return f(s); } - const state& operator=(const state& m) { - if(this == &m) - return *this; - f = m.f; - return *this; + inline state(const state& m) : f(m.f) { } - const bool operator!=(const state& m) const { + state& operator=(const state& m) = delete; + + inline const bool operator!=(const state& m) const { return !this->operator==(m); } - const bool operator==(const state& m) const { + inline const bool operator==(const state& m) const { if (this == &m) return true; return f == m.f; } private: - const lambda(const S)> f; + const lambda(const S)> f; }; /** * Write a state monad to a stream. */ -template ostream& operator<<(ostream& out, const state& m) { +template inline ostream& operator<<(ostream& out, const state& m) { const S s = m; const V v = m; out << '(' << s << ' ' << v << ')'; @@ -573,17 +562,10 @@ template ostream& operator<<(ostream& out, const state struct returnState { - const V v; - returnState(const V& v) : v(v) { - } - const scp operator()(const S& s) const { +template inline const state result(const V& v) { + return state([v](const S& s) -> const scp { return scp(s, v); - } -}; - -template const state result(const V& v) { - return state(returnState(v)); + }); } /** @@ -591,7 +573,7 @@ template const state result(const V& v) { * A transformer function takes a state and returns an scp pair carrying a content and a * new (transformed) state. */ -template const state transformer(const lambda(const S)>& f) { +template inline const state transformer(const lambda(const S)>& f) { return state(f); } @@ -599,28 +581,19 @@ template const state transformer(const lambda struct stateBind { - const state st; - const lambda(const A)>f; - - stateBind(const state& st, const lambda(const A)>& f) : st(st), f(f) { - } - - const scp operator()(const S& is) const { +template +inline const state operator>>(const state& st, const lambda(const A)>& f) { + const lambda(const S&)> stateBind = [st, f](const S& is) -> const scp { const scp iscp = st(is); const state m = f((A)iscp); return m((S)iscp); - } -}; - -template -const state operator>>(const state& st, const lambda(const A)>& f) { - return state(stateBind(st, f)); + }; + return state(stateBind); } template -const state operator>>(const state& st, const state (* const f)(const A)) { - return state(stateBind(st, f)); +inline const state operator>>(const state& st, const state (* const f)(const A)) { + return st >> lambda(const A)>(f); } } diff --git a/sca-cpp/trunk/kernel/parallel-test.cpp b/sca-cpp/trunk/kernel/parallel-test.cpp index 28e484d42b..895bb91eb8 100644 --- a/sca-cpp/trunk/kernel/parallel-test.cpp +++ b/sca-cpp/trunk/kernel/parallel-test.cpp @@ -35,84 +35,58 @@ namespace tuscany { int inci = 0; -struct incPerf { - incPerf() { - } - const bool operator()() const { - inci = inci + 1; - return true; - } -}; - const gc_ptr tlsic() { - gc_ptr i = new (gc_new()) int(); + const gc_ptr i = new (gc_new()) int(); *i = 0; return i; } const perthread_ptr tlsi(tlsic); -struct tlsPerf { - tlsPerf() { - } - const bool operator()() const { - *tlsi = *tlsi + 1; - return true; - } -}; - #ifdef WANT_THREADS int addi = 0; - -struct addAndFetchPerf { - addAndFetchPerf() { - } - const bool operator()() const { - __sync_add_and_fetch(&addi, 1); - return true; - } -}; - int muxi = 0; -struct mutexPerf { - pthread_mutex_t* mutex; - mutexPerf(pthread_mutex_t* mutex) : mutex(mutex) { - } - const bool operator()() const { - pthread_mutex_lock(mutex); - muxi = muxi + 1; - pthread_mutex_unlock(mutex); - return true; - } -}; - #endif -bool testAtomicPerf() { +const bool testAtomicPerf() { const int count = 100000; { - const lambda l = incPerf(); + const blambda l = []() -> const bool { + inci = inci + 1; + return true; + }; cout << "Non-atomic inc test " << time(l, 1000, count) << " ms" << endl; assert(inci == count + 1000); } #ifdef WANT_THREADS { - const lambda l = addAndFetchPerf(); + const blambda l = []() -> const bool { + __sync_add_and_fetch(&addi, 1); + return true; + }; cout << "Atomic inc test " << time(l, 1000, count) << " ms" << endl; assert(addi == count + 1000); } { pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); - const lambda l = mutexPerf(&mutex); + const blambda l = [&mutex]() -> const bool { + pthread_mutex_lock(&mutex); + muxi = muxi + 1; + pthread_mutex_unlock(&mutex); + return true; + }; cout << "Locked inc test " << time(l, 1000, count) << " ms" << endl; assert(muxi == count + 1000); pthread_mutex_destroy(&mutex); } #endif { - const lambda l = tlsPerf(); + const blambda l = []() -> const bool { + *tlsi = *tlsi + 1; + return true; + }; cout << "Thread local inc test " << time(l, 1000, count) << " ms" << endl; assert(*tlsi == count + 1000); } @@ -130,7 +104,7 @@ const int mtsquare(const int x) { const list > submitSquares(worker& w, const int max, const int i) { if (i == max) return list >(); - const lambda func = curry(lambda (mtsquare), i); + const lambda func = curry(lambda (mtsquare), i); return cons(submit(w, func), submitSquares(w, max, i + 1)); } @@ -143,7 +117,7 @@ bool checkSquareResults(const list > r, int i) { } const gc_ptr tlsvc() { - gc_ptr i = new (gc_new()) unsigned long(); + const gc_ptr i = new (gc_new()) unsigned long(); *i = 0l; return i; } @@ -181,11 +155,11 @@ const bool unblockWorkers(wqueue& wq, const int n) { const list > submitTLSSets(worker& w, wqueue& wq, wqueue& xq, const int max, const int i) { if (i == max) return list >(); - const lambda func = curry(lambda>, gc_ptr>)>(tlsset), (gc_ptr>)&wq, (gc_ptr>)&xq); + const lambda func = curry(lambda>, gc_ptr>)>(tlsset), (gc_ptr>)&wq, (gc_ptr>)&xq); return cons(submit(w, func), submitTLSSets(w, wq, xq, max, i + 1)); } -bool checkTLSSets(const list > s) { +const bool checkTLSSets(const list > s) { if (isNil(s)) return true; assert(car(s) == 0); @@ -195,22 +169,22 @@ bool checkTLSSets(const list > s) { const list > submitTLSChecks(worker& w, wqueue& wq, wqueue& xq, const int max, const int i) { if (i == max) return list >(); - const lambda func = curry(lambda>, gc_ptr>)>(tlscheck), (gc_ptr>)&wq, (gc_ptr>)&xq); + const blambda func = curry(lambda>, gc_ptr>)>(tlscheck), (gc_ptr>)&wq, (gc_ptr>)&xq); return cons(submit(w, func), submitTLSChecks(w, wq, xq, max, i + 1)); } -bool checkTLSResults(const list > r) { +const bool checkTLSResults(const list > r) { if (isNil(r)) return true; assert(car(r) == true); return checkTLSResults(cdr(r)); } -bool testWorker() { +const bool testWorker() { const int max = 100; worker w(max); { - const lambda func = curry(lambda (mtsquare), 2); + const lambda func = curry(lambda (mtsquare), 2); assert(submit(w, func) == 4); } { @@ -245,7 +219,7 @@ bool testWorker() { } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; tuscany::testAtomicPerf(); diff --git a/sca-cpp/trunk/kernel/parallel.hpp b/sca-cpp/trunk/kernel/parallel.hpp index 3be4d3bc8e..8b01bb819f 100644 --- a/sca-cpp/trunk/kernel/parallel.hpp +++ b/sca-cpp/trunk/kernel/parallel.hpp @@ -39,7 +39,7 @@ namespace tuscany { /** * Returns the current process id. */ -unsigned long processId() { +inline const unsigned long processId() noexcept { return (unsigned long)getpid(); } @@ -48,7 +48,7 @@ unsigned long processId() { /** * Returns the current thread id. */ -unsigned long threadId() { +inline const unsigned long threadId() noexcept{ return (unsigned long)pthread_self(); } @@ -60,20 +60,20 @@ template class future { private: template class futureValue { public: - futureValue() : hasValue(false) { + inline futureValue() noexcept : hasValue(false) { pthread_mutex_init(&valueMutex, NULL); pthread_cond_init(&valueCond, NULL); } - futureValue(const futureValue& fv) : valueMutex(fv.valueMutex), valueCond(fv.valueCond), hasValue(fv.hasValue), value(fv.value) { + inline futureValue(const futureValue& fv) noexcept : valueMutex(fv.valueMutex), valueCond(fv.valueCond), hasValue(fv.hasValue), value(fv.value) { } - ~futureValue() { + inline ~futureValue() noexcept { //pthread_mutex_destroy(&valueMutex); //pthread_cond_destroy(&valueCond); } - bool set(const T& v) { + inline const bool set(const T& v) noexcept { pthread_mutex_lock(&valueMutex); if(hasValue) { pthread_mutex_unlock(&valueMutex); @@ -86,7 +86,7 @@ private: return true; } - const T get() { + inline const T get() noexcept { pthread_mutex_lock(&valueMutex); while(!hasValue) { pthread_cond_wait(&valueCond, &valueMutex); @@ -100,37 +100,32 @@ private: pthread_mutex_t valueMutex; pthread_cond_t valueCond; bool hasValue; - X value; + gc_mutable_ref value; }; - gc_ptr > fvalue; + const gc_ptr > fvalue; - template friend const X get(const future& f); - template friend bool set(const future& f, const X& v); + template friend const X get(const future& f) noexcept; + template friend bool set(const future& f, const X& v) noexcept; public: - future() : fvalue(new (gc_new >()) futureValue()) { + inline future() noexcept : fvalue(new (gc_new >()) futureValue()) { } - ~future() { + inline ~future() noexcept { } - future(const future& f) : fvalue(f.fvalue) { + inline future(const future& f) noexcept : fvalue(f.fvalue) { } - const future& operator=(const future& f) { - if (&f == this) - return *this; - fvalue = f.fvalue; - return *this; - } + const future& operator=(const future& f) = delete; - const future& operator=(const T& v) const { + inline const future& operator=(const T& v) const noexcept { fvalue->set(v); return *this; } - operator const T() const { + inline operator const T() const noexcept { return fvalue->get(); } }; @@ -140,16 +135,16 @@ public: */ template class wqueue { public: - wqueue(size_t max) : max(max), size(0), tail(0), head(0), values(new (gc_anew(max)) T[max]) { + inline wqueue(size_t max) noexcept : max(max), size(0), tail(0), head(0), values(new (gc_anew >(max)) gc_mutable_ref[max]) { pthread_mutex_init(&mutex, NULL); pthread_cond_init(&full, NULL); pthread_cond_init(&empty, NULL); } - wqueue(const wqueue& wq) : max(wq.max), size(wq.size), tail(wq.tail), head(wq.head), mutex(wq.mutex), full(wq.full), empty(wq.empty), values(wq.values) { + inline wqueue(const wqueue& wq) noexcept : max(wq.max), size(wq.size), tail(wq.tail), head(wq.head), mutex(wq.mutex), full(wq.full), empty(wq.empty), values(wq.values) { } - ~wqueue() { + inline ~wqueue() { //pthread_mutex_destroy(&mutex); //pthread_cond_destroy(&full); //pthread_cond_destroy(&empty); @@ -163,16 +158,16 @@ private: pthread_mutex_t mutex; pthread_cond_t full; pthread_cond_t empty; - gc_ptr values; + gc_ptr > values; - template friend const size_t enqueue(wqueue& q, const X& v); - template friend const X dequeue(wqueue& q); + template friend const size_t enqueue(wqueue& q, const X& v) noexcept; + template friend const X dequeue(wqueue& q) noexcept; }; /** * Adds an element to the tail of the queue. */ -template const size_t enqueue(wqueue&q, const T& v) { +template inline const size_t enqueue(wqueue&q, const T& v) noexcept { pthread_mutex_lock(&q.mutex); while(q.size == q.max) pthread_cond_wait(&q.full, &q.mutex); @@ -187,7 +182,7 @@ template const size_t enqueue(wqueue&q, const T& v) { /** * Returns the element at the head of the queue. */ -template const T dequeue(wqueue& q) { +template inline const T dequeue(wqueue& q) noexcept { pthread_mutex_lock(&q.mutex); while(q.size == 0) pthread_cond_wait(&q.empty, &q.mutex); @@ -202,13 +197,13 @@ template const T dequeue(wqueue& q) { /** * The worker thread function. */ -void *workerThreadFunc(void *arg) { +inline void* workerThreadFunc(void* arg) noexcept { int ost; pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ost); int ot; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &ot); - wqueue >* work = reinterpret_cast >*>(arg); + wqueue* work = reinterpret_cast*>(arg); while(dequeue(*work)()) ; return NULL; @@ -217,7 +212,7 @@ void *workerThreadFunc(void *arg) { /** * Returns a list of worker threads. */ -const list workerThreads(wqueue >& wqueue, const size_t count) { +inline const list workerThreads(wqueue& wqueue, const size_t count) noexcept { if (count == 0) return list(); pthread_t thread; @@ -235,32 +230,32 @@ private: // copies of the queue and thread pool when a worker is copied class sharedWorker { public: - sharedWorker(size_t max) : work(wqueue >(max)), threads(workerThreads(work, max)) { + inline sharedWorker(size_t max) noexcept : work(wqueue(max)), threads(workerThreads(work, max)) { } - wqueue > work; + wqueue work; const list threads; }; public: - worker(size_t max) : w(*(new (gc_new()) sharedWorker(max))) { + inline worker(size_t max) noexcept : w(*(new (gc_new()) sharedWorker(max))) { } - worker(const worker& wk) : w(wk.w) { + inline worker(const worker& wk) noexcept : w(wk.w) { } private: sharedWorker& w; - template friend const future submit(worker& w, const lambda& func); - friend const bool shutdown(worker& w); - friend const bool cancel(worker& w); + template friend const future submit(const worker& w, const lambda& func) noexcept; + friend const bool shutdown(const worker& w) noexcept; + friend const bool cancel(const worker& w) noexcept; }; /** * Function used to wrap work submitted to a worker. */ -template bool submitFunc(const lambda& func, const future& fut) { +template inline const bool submitFunc(const lambda& func, const future& fut) noexcept { fut = func(); return true; } @@ -268,9 +263,9 @@ template bool submitFunc(const lambda& func, const future& f /** * Submits work to a worker. */ -template const future submit(worker& w, const lambda& func) { +template inline const future submit(const worker& w, const lambda& func) noexcept { const future fut; - const lambda f = curry(lambda, future)>(submitFunc), func, fut); + const blambda f = curry(lambda, future)>(submitFunc), func, fut); enqueue(w.w.work, f); return fut; } @@ -278,7 +273,7 @@ template const future submit(worker& w, const lambda& func) /** * Enqueues shutdown requests. */ -const bool shutdownEnqueue(const list& threads, wqueue >& work) { +inline const bool shutdownEnqueue(const list& threads, wqueue& work) noexcept { if (isNil(threads)) return true; enqueue(work, result(false)); @@ -288,7 +283,7 @@ const bool shutdownEnqueue(const list& threads, wqueue /** * Waits for shut down threads to terminate. */ -const bool shutdownJoin(const list& threads) { +inline const bool shutdownJoin(const list& threads) noexcept { if (isNil(threads)) return true; pthread_join(car(threads), NULL); @@ -298,7 +293,7 @@ const bool shutdownJoin(const list& threads) { /** * Shutdown a worker. */ -const bool shutdown(worker& w) { +inline const bool shutdown(const worker& w) noexcept { shutdownEnqueue(w.w.threads, w.w.work); shutdownJoin(w.w.threads); return true; @@ -307,14 +302,14 @@ const bool shutdown(worker& w) { /** * Cancel a worker. */ -const bool cancel(const list& threads) { +inline const bool cancel(const list& threads) noexcept { if (isNil(threads)) return true; pthread_cancel(car(threads)); return cancel(cdr(threads)); } -const bool cancel(worker& w) { +inline const bool cancel(const worker& w) noexcept { cancel(w.w.threads); return true; } @@ -324,7 +319,7 @@ const bool cancel(worker& w) { /** * Returns the current thread id. */ -unsigned long threadId() { +inline const unsigned long threadId() noexcept { return 0; } @@ -335,114 +330,106 @@ unsigned long threadId() { */ template class perthread_ptr { public: - perthread_ptr() : key(createkey()), owner(true), cl(lambda()>()), managed(false) { + inline perthread_ptr() noexcept : key(createkey()), owner(true), cl(lambda()>()), managed(false) { } - perthread_ptr(const lambda()>& cl) : key(createkey()), owner(true), cl(cl), managed(true) { + inline perthread_ptr(const lambda()>& cl) noexcept : key(createkey()), owner(true), cl(cl), managed(true) { } - ~perthread_ptr() { + inline ~perthread_ptr() noexcept { if (owner) deletekey(key); } - perthread_ptr(const perthread_ptr& c) : key(c.key), owner(false), cl(c.cl), managed(c.managed) { + inline perthread_ptr(const perthread_ptr& c) noexcept : key(c.key), owner(false), cl(c.cl), managed(c.managed) { } - perthread_ptr& operator=(const perthread_ptr& r) throw() { - if(this == &r) - return *this; - key = r.key; - owner = false; - cl = r.cl; - managed = r.managed; - return *this; - } + perthread_ptr& operator=(const perthread_ptr& r) = delete; - const perthread_ptr& operator=(const gc_ptr& v) { + inline const perthread_ptr& operator=(const gc_ptr& v) const noexcept { set(v); return *this; } - const perthread_ptr& operator=(T* v) { + inline const perthread_ptr& operator=(T* const v) const noexcept { set(v); return *this; } - const bool operator==(const gc_ptr& r) const throw() { + inline const bool operator==(const gc_ptr& r) const noexcept { return get() == r; } - const bool operator==(T* p) const throw() { + inline const bool operator==(const T* const p) const noexcept { return get() == p; } - const bool operator!=(const gc_ptr& r) const throw() { + inline const bool operator!=(const gc_ptr& r) const noexcept { return !this->operator==(r); } - const bool operator!=(T* p) const throw() { + inline const bool operator!=(const T* const p) const noexcept { return !this->operator==(p); } - T& operator*() const throw() { + inline T& operator*() const noexcept { return *get(); } - T* operator->() const throw() { + inline T* const operator->() const noexcept { return get(); } - operator gc_ptr() const { + inline operator gc_ptr() const { return get(); } - operator T*() const { + inline operator T* const () const { return get(); } private: #ifdef WANT_THREADS - pthread_key_t createkey() { + inline const pthread_key_t createkey() noexcept { pthread_key_t k; pthread_key_create(&k, NULL); return k; } - bool deletekey(pthread_key_t k) { + inline const bool deletekey(pthread_key_t k) noexcept { pthread_key_delete(k); return true; } - bool set(const gc_ptr& v) { + inline const bool set(const gc_ptr& v) const noexcept { pthread_setspecific(key, (T*)v); return true; } - gc_ptr get() const { - const gc_ptr v = static_cast(pthread_getspecific(key)); + inline const gc_ptr get() const noexcept { + const gc_ptr v = (T*)(pthread_getspecific(key)); if (v != NULL || !managed) return v; const gc_ptr nv = cl(); - pthread_setspecific(key, nv); + pthread_setspecific(key, (T*)nv); return nv; } #else - gc_ptr > createkey() { + inline const gc_ptr > createkey() noexcept { return new (gc_new >()) gc_ptr(); } - bool deletekey(unused gc_ptr > k) { + inline const bool deletekey(unused gc_ptr > k) noexcept { return true; } - bool set(const gc_ptr& v) { + inline const bool set(const gc_ptr& v) const noexcept { *key = v; return true; } - gc_ptr get() const { + inline const gc_ptr get() const noexcept { if (*key != NULL || !managed) return *key; *key = cl(); @@ -452,14 +439,14 @@ private: #endif #ifdef WANT_THREADS - pthread_key_t key; + const pthread_key_t key; #else - gc_ptr >key; + const gc_ptr >key; #endif - bool owner; - lambda()> cl; - bool managed; + const bool owner; + const lambda()> cl; + const bool managed; }; } diff --git a/sca-cpp/trunk/kernel/perf.hpp b/sca-cpp/trunk/kernel/perf.hpp index 04aad06664..07c586ce7c 100644 --- a/sca-cpp/trunk/kernel/perf.hpp +++ b/sca-cpp/trunk/kernel/perf.hpp @@ -37,21 +37,15 @@ namespace tuscany /** * Measure the time required to perform a function in msec. */ -struct timeLambda { - const lambda f; - timeLambda(const lambda& f) : f(f) { - } - bool operator()(const long count) const { +inline const double time(const blambda& f, const long warmup, const long count) { + struct timeval start; + struct timeval end; + + const lambda tl = [f](const long count) -> const bool { for (long i = 0; i < count; i++) f(); return true; - } -}; - -const double time(const lambda& f, const long warmup, const long count) { - const lambda tl = timeLambda(f); - struct timeval start; - struct timeval end; + }; tl(warmup); gettimeofday(&start, NULL); @@ -62,13 +56,13 @@ const double time(const lambda& f, const long warmup, const long count) return (double)t / (double)count; } -const unsigned long timems() { +inline const unsigned long timems() { struct timeval t; gettimeofday(&t, NULL); return (unsigned long)(t.tv_sec * 1000 + t.tv_usec / 1000); } -const unsigned long timens() { +inline const unsigned long timens() { struct timeval t; gettimeofday(&t, NULL); return (unsigned long)(t.tv_sec * 1000000000 + t.tv_usec * 1000); diff --git a/sca-cpp/trunk/kernel/sstream.hpp b/sca-cpp/trunk/kernel/sstream.hpp index 17fd28b48b..dbdc7414a1 100644 --- a/sca-cpp/trunk/kernel/sstream.hpp +++ b/sca-cpp/trunk/kernel/sstream.hpp @@ -38,14 +38,14 @@ namespace tuscany { /** * Instrumentable memcpy. */ -void* stream_memcpy(void* t, const void* s, const size_t n) { +inline void* stream_memcpy(void* t, const void* s, const size_t n) { return memcpy(t, s, n); } /** * Write a list of strings into a buffer. */ -const bool writeList(const list& l, char* buf) { +const bool writeList(const list& l, char* const buf) { if (isNil(l)) return true; const string c = car(l); @@ -59,63 +59,108 @@ const bool writeList(const list& l, char* buf) { */ class ostringstream : public ostream { public: - ostringstream() : len(0) { + inline ostringstream() : len(0), accumbuf(NULL), accumlen(0), buf() { } - ~ostringstream() { + inline ~ostringstream() { } - ostringstream(const ostringstream& os) { - len = os.len; - buf = os.buf; + inline ostringstream(const ostringstream& os) : len(os.len), accumbuf(os.accumbuf), accumlen(os.accumlen), buf(os.buf) { } - ostringstream& vprintf(const char* fmt, ...) { + inline ostringstream& vprintf(const char* const fmt, ...) { va_list args; - string s; va_start (args, fmt); - s.len = vsnprintf(NULL, 0, fmt, args); - s.buf = gc_cnew(s.len + 1); + const size_t l = vsnprintf(NULL, 0, fmt, args); + if (l <= 256) { + char c[256]; + va_start (args, fmt); + vsnprintf(c, l + 1, fmt, args); + va_end (args); + accumulate(c, l); + return *this; + } + spill(); + char* const sbuf = gc_cnew(l + 1); va_start (args, fmt); - vsnprintf(s.buf, s.len + 1, fmt, args); - buf = cons(s, buf); - len += s.len; + vsnprintf(sbuf, l + 1, fmt, args); va_end (args); + buf = cons(string(sbuf, l, false), (const list)buf); + len += l; return *this; } - ostringstream& write(const string& s) { - buf = cons(s, buf); + inline ostringstream& write(const string& s) { + if (s.len <= 256) { + accumulate(s.buf, s.len); + return *this; + } + spill(); + buf = cons(s, (const list)buf); len += s.len; return *this; } - ostringstream& flush() { + inline ostringstream& write(const char c) { + accumulate(&c, 1); + return *this; + } + + inline ostringstream& flush() { + spill(); return *this; } private: - const string str() { - if (isNil(buf)) - return string(); - string s; - s.len = len; - s.buf = gc_cnew(s.len + 1); - writeList(buf, s.buf + len); - s.buf[s.len] = '\0'; - return s; + inline const string str() { + spill(); + if (isNil((const list)buf)) + return emptyString; + char* const sbuf = gc_cnew(len + 1); + writeList(buf, sbuf + len); + sbuf[len] = '\0'; + return string(sbuf, len, false); + } + + inline const bool accumulate(const char* const c, const size_t l) { + if (accumbuf == NULL) + accumbuf = gc_cnew(65); + for(size_t i = 0; i < l; i++) { + accumbuf[accumlen] = c[i]; + accumlen++; + if (accumlen == 64) { + accumbuf[accumlen] = '\0'; + buf = cons(string(accumbuf, accumlen, false), (const list)buf); + accumbuf = i < l? gc_cnew(65) : NULL; + accumlen = 0; + } + } + accumbuf[accumlen] = '\0'; + len += l; + return true; + } + + inline const bool spill() { + if (accumbuf == NULL) + return true; + buf = cons(string(accumbuf, accumlen), (const list)buf); + accumbuf = NULL; + accumlen = 0; + return true; } friend const string str(ostringstream& os); size_t len; - list buf; + char* accumbuf; + size_t accumlen; + gc_mutable_ref > buf; }; /** * Return a string representation of a stream. */ -const string str(ostringstream& os) { +inline const string str(ostringstream& os) { return os.str(); } @@ -124,23 +169,16 @@ const string str(ostringstream& os) { */ class istringstream : public istream { public: - istringstream(const string& s) { - cur = 0; - const size_t slen = length(s); - len = slen; - buf = c_str(s); - } - - ~istringstream() { + inline istringstream(const string& s) : len(length(s)), cur(0), buf(c_str(s)) { + } + + inline ~istringstream() { } - istringstream(const istringstream& is) { - len = is.len; - cur = is.cur; - buf = is.buf; + inline istringstream(const istringstream& is) : len(is.len), cur(is.cur), buf(is.buf) { } - const size_t read(void* b, size_t size) { + inline const size_t read(void* const b, const size_t size) { const size_t n = len - cur; if (n == 0) return 0; @@ -154,30 +192,28 @@ public: return n; } - const bool eof() { + inline const bool eof() { return cur == len; } - const bool fail() { + inline const bool fail() { return false; } - const int get() { - if (eof()) + inline const int get() { + if (cur == len) return -1; - const int c = buf[cur]; - cur += 1; - return c; + return buf[cur++]; } - const int peek() { - if (eof()) + inline const int peek() { + if (cur == len) return -1; return buf[cur]; } private: - size_t len; + const size_t len; size_t cur; const char* buf; }; @@ -185,62 +221,52 @@ private: /** * Tokenize a string into a list of strings. */ -const list tokenize(const char* sep, const string& str) { - struct nested { - static const list tokenize(const char* sep, const size_t slen, const string& str, const size_t start) { - if (start >= length(str)) - return list(); - const size_t i = find(str, sep, start); - if (i == length(str)) - return mklist(string(substr(str, start))); - return cons(string(substr(str, start, i - start)), tokenize(sep, slen, str, i + slen)); - } +inline const list tokenize(const char* const sep, const string& str) { + const lambda(const char* const, const size_t, const string&, const size_t)> tokenize = [&tokenize](const char* const sep, const size_t slen, const string& str, const size_t start) -> const list { + if (start >= length(str)) + return list(); + const size_t i = find(str, sep, start); + if (i == length(str)) + return mklist(string(substr(str, start))); + return cons(string(substr(str, start, i - start)), tokenize(sep, slen, str, i + slen)); }; - return nested::tokenize(sep, strlen(sep), str, 0); + return tokenize(sep, strlen(sep), str, 0); } /** * Join a list of strings into a single string. */ -const string join(const char* sep, const list& l) { - struct nested { - static ostringstream& join(const char* sep, const list& l, ostringstream& os) { - if (isNil(l)) - return os; - os << car(l); - if (!isNil(cdr(l))) - os << sep; - return join(sep, cdr(l), os); - } - }; +inline const string join(const char* const sep, const list& l) { ostringstream os; - return str(nested::join(sep, l, os)); + const lambda&, ostringstream&)> join = [&join](const char* const sep, const list& l, ostringstream& os) -> ostringstream& { + if (isNil(l)) + return os; + os << car(l); + if (!isNil(cdr(l))) + os << sep; + return join(sep, cdr(l), os); + }; + return str(join(sep, l, os)); } /** * Returns a lazy list view of an input stream. */ -struct ilistRead{ - istream &is; - ilistRead(istream& is) : is(is) { - } - const list operator()() { +inline const list streamList(istream& is) { + const lambda()> ilistRead = [&is, &ilistRead]() -> const list { char buffer[1024]; const size_t n = read(is, buffer, sizeof(buffer)); if (n ==0) return list(); - return cons(string(buffer, n), (*this)()); - } -}; - -const list streamList(istream& is) { - return ilistRead(is)(); + return cons(string(buffer, n), ilistRead()); + }; + return ilistRead(); } /** * Fragment the first element of a list of strings to fit the given max length. */ -const list fragment(list l, size_t max) { +inline const list fragment(const list& l, const size_t max) { const string s = car(l); if (length(s) <= max) return l; @@ -250,13 +276,26 @@ const list fragment(list l, size_t max) { /** * Write a list of strings to an output stream. */ -ostream& write(const list& l, ostream& os) { +inline ostream& write(const list& l, ostream& os) { if(isNil(l)) return os; os << car(l); return write(cdr(l), os); } +/** + * Convert a list of strings to a string. + */ +inline const string write(const list& l) { + if (isNil(l)) + return emptyString; + if (isNil(cdr(l))) + return car(l); + ostringstream os; + write(l, os); + return str(os); +} + } #endif /* tuscany_sstream_hpp */ diff --git a/sca-cpp/trunk/kernel/stream.hpp b/sca-cpp/trunk/kernel/stream.hpp index 8ccfed948f..e59e6a4ef5 100644 --- a/sca-cpp/trunk/kernel/stream.hpp +++ b/sca-cpp/trunk/kernel/stream.hpp @@ -38,66 +38,67 @@ namespace tuscany { */ class ostream { public: - virtual ostream& vprintf(const char* fmt, ...) = 0; + virtual ostream& vprintf(const char* const fmt, ...) = 0; virtual ostream& write(const string& s) = 0; + virtual ostream& write(const char c) = 0; virtual ostream& flush() = 0; }; /** * Flush a stream. */ -ostream& flush(ostream& os) { +inline ostream& flush(ostream& os) { return os.flush(); } /** * Write simple values to a stream. */ -ostream& operator<<(ostream& os, const char* v) { +inline ostream& operator<<(ostream& os, const char* const v) { return os.vprintf("%s", v); } -ostream& operator<<(ostream& os, const unsigned char* v) { +inline ostream& operator<<(ostream& os, const unsigned char* const v) { return os.vprintf("%s", v); } -ostream& operator<<(ostream& os, const char v) { - return os.vprintf("%c", v); +inline ostream& operator<<(ostream& os, const char v) { + return os.write(v); } -ostream& operator<<(ostream& os, const int v) { +inline ostream& operator<<(ostream& os, const int v) { return os.vprintf("%d", v); } -ostream& operator<<(ostream& os, const unsigned int v) { +inline ostream& operator<<(ostream& os, const unsigned int v) { return os.vprintf("%u", v); } -ostream& operator<<(ostream& os, const long int v) { +inline ostream& operator<<(ostream& os, const long int v) { return os.vprintf("%ld", v); } -ostream& operator<<(ostream& os, const long unsigned int v) { +inline ostream& operator<<(ostream& os, const long unsigned int v) { return os.vprintf("%lu", v); } -ostream& operator<<(ostream& os, const double v) { +inline ostream& operator<<(ostream& os, const double v) { return os.vprintf("%.10g", v); } -ostream& operator<<(ostream& os, const void* v) { +inline ostream& operator<<(ostream& os, const void* const v) { return os.vprintf("%p", v); } -ostream& operator<<(ostream& os, const string& v) { +inline ostream& operator<<(ostream& os, const string& v) { return os.write(v); } class stream_endl { } endl; -ostream& operator<<(ostream& os, unused const stream_endl e) { - os.write("\n"); +inline ostream& operator<<(ostream& os, unused const stream_endl e) { + os.write('\n'); return os.flush(); } @@ -106,7 +107,7 @@ ostream& operator<<(ostream& os, unused const stream_endl e) { */ class istream { public: - virtual const size_t read(void* buf, size_t size) = 0; + virtual const size_t read(void* const buf, const size_t size) = 0; virtual const bool eof() = 0; virtual const bool fail() = 0; virtual const int get() = 0; @@ -116,40 +117,61 @@ public: /** * Read from an input stream. */ -const size_t read(istream& is, void * buf, size_t size) { +inline const size_t read(istream& is, void* const buf, const size_t size) { return is.read(buf, size); } /** * Return true if the end of an input stream has been reached. */ -const bool eof(istream& is) { +inline const bool eof(istream& is) { return is.eof(); } /** * Return true if an input stream can't be accessed. */ -const bool fail(istream& is) { +inline const bool fail(istream& is) { return is.fail(); } /** * Read a character from a stream. */ -const int get(istream& is) { +inline const int get(istream& is) { return is.get(); } /** * Peek a character from a stream. */ -const int peek(istream& is) { +inline const int peek(istream& is) { return is.peek(); } -template ostream& operator<<(ostream& out, const gc_ptr& p) { - return out << p.ptr; +#ifndef WANT_RAW_PTR + +/** + * Write a pointer. + */ +template inline ostream& operator<<(ostream& out, const gc_ptr& p) { + return out << (T*)p; +} + +/** + * Write a mutable pointer. + */ +template inline ostream& operator<<(ostream& out, const gc_mutable_ptr& p) { + return out << (T*)p; +} + +#endif + +/** + * Write a mutable reference. + */ +template inline ostream& operator<<(ostream& out, const gc_mutable_ref& r) { + return out << (T)r; } #ifdef WANT_MAINTAINER_LOG @@ -159,35 +181,40 @@ template ostream& operator<<(ostream& out, const gc_ptr& p) { */ class odebugstream : public ostream { public: - odebugstream() { + inline odebugstream() : buf() { } - odebugstream& vprintf(const char* fmt, ...) { + inline odebugstream& vprintf(const char* const fmt, ...) { va_list args; string s; va_start (args, fmt); - s.len = vsnprintf(NULL, 0, fmt, args); - s.buf = gc_cnew(s.len + 1); + const size_t slen = vsnprintf(NULL, 0, fmt, args); + char* const sbuf = gc_cnew(slen + 1); va_start (args, fmt); - vsnprintf(s.buf, s.len + 1, fmt, args); - buf = buf + s; + vsnprintf(sbuf, slen + 1, fmt, args); + buf = buf + string(sbuf, slen, false); va_end (args); return *this; } - odebugstream& write(const string& s) { + inline odebugstream& write(const string& s) { buf = buf + s; return *this; } - odebugstream& flush() { + inline odebugstream& write(const char c) { + buf = buf + c; + return *this; + } + + inline odebugstream& flush() { return *this; } private: friend const string str(odebugstream& os); - string buf; + gc_mutable_ref buf; }; const string str(odebugstream& os) { diff --git a/sca-cpp/trunk/kernel/string-test.cpp b/sca-cpp/trunk/kernel/string-test.cpp index b6f016b294..66716c96b5 100644 --- a/sca-cpp/trunk/kernel/string-test.cpp +++ b/sca-cpp/trunk/kernel/string-test.cpp @@ -32,15 +32,15 @@ namespace tuscany { -bool testCopies() { +const bool testCopies() { resetStringCopyCounters(); - string x("abcd"); + const string x("abcd"); assert(checkStringCopyCounters(1)); resetStringCopyCounters(); - string y = string("abcd"); + const string y = string("abcd"); assert(checkStringCopyCounters(1)); resetStringCopyCounters(); - unused string z = y; + unused const string z = y; assert(checkStringCopyCounters(0)); resetStringCopyCounters(); const list pl = list() + "abcd" + "efgh"; @@ -51,7 +51,7 @@ bool testCopies() { return true; } -bool testString() { +const bool testString() { const string s("abcd"); assert(length(s) == 4); assert(!strcmp(c_str(s), "abcd")); @@ -89,12 +89,19 @@ bool testString() { return true; } -bool testStream() { +const bool testStream() { ostringstream os; os << "ab" << "cd"; - cout << str(os) << endl; assert(str(os) == "abcd"); + ostringstream bos; + bos << "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"; + bos << "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"; + cout << str(bos) << endl; + assert(str(bos) == + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"); + ostringstream cs; cs << "\'"; assert(str(cs) == "\'"); @@ -113,69 +120,65 @@ bool testStream() { return true; } -std::string stdAdd(std::string& x, std::string& y) { +const std::string stdAdd(const std::string& x, const std::string& y) { return x + y; } -string add(string& x, string& y) { +const string add(const string& x, const string& y) { return x + y; } char charBuffer[16385]; -struct addStrings{ - const size_t size; - addStrings(const size_t size) : size(size) { - } - bool operator()() const { - const size_t sz = size / 4; - string x(charBuffer, sz); - string y(charBuffer, sz); - assert(length(add(x, y)) == sz * 2); - return true; - } -}; - -struct addStdStrings{ - const size_t size; - addStdStrings(const size_t size) : size(size) { - } - bool operator()() const { - const size_t sz = size / 4; - std::string x(charBuffer, sz); - std::string y(charBuffer, sz); - assert(stdAdd(x, y).length() == (unsigned int)(sz * 2)); - return true; - } -}; - -bool testStringPerf() { +const bool testStringPerf() { memset(charBuffer, 'A', 16384); charBuffer[16384] = '\0'; const int count = 10000; { - const lambda a16 = addStrings(16); + const lambda addStrings = [](const size_t size) -> const blambda { + const blambda l = [size]() -> const bool { + const size_t sz = size / 4; + const string x(charBuffer, sz); + const string y(charBuffer, sz); + assert(length(add(x, y)) == sz * 2); + return true; + }; + return l; + }; + + const blambda a16 = addStrings(16); cout << "string test " << time(a16, 5, count) << " ms" << endl; - const lambda a32 =addStrings(32); + const blambda a32 =addStrings(32); cout << "string test " << time(a32, 5, count) << " ms" << endl; - const lambda a256 =addStrings(256); + const blambda a256 =addStrings(256); cout << "string test " << time(a256, 5, count) << " ms" << endl; - const lambda a1024 =addStrings(1024); + const blambda a1024 =addStrings(1024); cout << "string test " << time(a1024, 5, count) << " ms" << endl; - const lambda a4096 =addStrings(4096); + const blambda a4096 =addStrings(4096); cout << "string test " << time(a4096, 5, count) << " ms" << endl; } { - const lambda a16 =addStdStrings(16); + const lambda addStdStrings = [](const size_t size) -> const blambda { + const blambda l = [size]() -> const bool { + const size_t sz = size / 4; + const std::string x(charBuffer, sz); + const std::string y(charBuffer, sz); + assert(stdAdd(x, y).length() == (unsigned int)(sz * 2)); + return true; + }; + return l; + }; + + const blambda a16 =addStdStrings(16); cout << "Std string test " << time(a16, 5, count) << " ms" << endl; - const lambda a32 =addStdStrings(32); + const blambda a32 =addStdStrings(32); cout << "Std string test " << time(a32, 5, count) << " ms" << endl; - const lambda a256 =addStdStrings(256); + const blambda a256 =addStdStrings(256); cout << "Std string test " << time(a256, 5, count) << " ms" << endl; - const lambda a1024 =addStdStrings(1024); + const blambda a1024 =addStdStrings(1024); cout << "Std string test " << time(a1024, 5, count) << " ms" << endl; - const lambda a4096 =addStdStrings(4096); + const blambda a4096 =addStdStrings(4096); cout << "Std string test " << time(a4096, 5, count) << " ms" << endl; } @@ -185,7 +188,7 @@ bool testStringPerf() { } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; tuscany::testCopies(); diff --git a/sca-cpp/trunk/kernel/string.hpp b/sca-cpp/trunk/kernel/string.hpp index e726a61b84..4d27ce84d7 100644 --- a/sca-cpp/trunk/kernel/string.hpp +++ b/sca-cpp/trunk/kernel/string.hpp @@ -41,16 +41,16 @@ namespace tuscany { */ long countStringCopies = 0; -bool resetStringCopyCounters() { +inline const bool resetStringCopyCounters() { countStringCopies = 0; return true; } -bool checkStringCopyCounters(long c) { +inline const bool checkStringCopyCounters(long c) { return countStringCopies == c; } -bool printStringCopyCounters() { +inline const bool printStringCopyCounters() { printf("countStringCopies %ld\n", countStringCopies); return true; } @@ -66,13 +66,19 @@ bool printStringCopyCounters() { /** * Instrumented memcpy. */ -void* string_memcpy(void* t, const void* s, const size_t n) { #ifdef WANT_MAINTAINER_COUNTERS + +inline void* string_memcpy(void* t, const void* s, const size_t n) { countStringCopies += 1; -#endif return memcpy(t, s, n); } +#else + +#define string_memcpy(t, s, n) memcpy(t, s, n) + +#endif + char stringEmptyBuffer[1] = { '\0' }; /** @@ -80,56 +86,27 @@ char stringEmptyBuffer[1] = { '\0' }; */ class string { public: - string() : len(0) { - buf = stringEmptyBuffer; + inline string() noexcept : len(0), buf(stringEmptyBuffer) { } - string(const char* s) { - len = strlen(s); - if (len == 0) { - buf = stringEmptyBuffer; - return; - } - buf = gc_cnew(len + 1); - string_memcpy(buf, s, len + 1); + inline string(const char* const s) noexcept : len(strlen(s)), buf(mksbuf(s, len)) { } - string(const char* s, const size_t n) { - len = n; - if (len == 0) { - buf = stringEmptyBuffer; - return; - } - buf = gc_cnew(len + 1); - string_memcpy(buf, s, len); - buf[len] = '\0'; + inline string(const char* const s, const size_t n) noexcept : len(n), buf(mksbuf(s, n)) { } - string(const size_t n, const char c) { - len = n; - if (len == 0) { - buf = stringEmptyBuffer; - return; - } - buf = gc_cnew(len + 1); - memset(buf, c, n); - buf[len] = '\0'; + inline string(const char* const s, const size_t n, const bool copy) noexcept : len(n), buf(mksbuf(s, n, copy)) { } - string(const string& s) { - len = s.len; - buf = s.buf; + inline string(const size_t n, const char c) noexcept : len(n), buf(mkcbuf(c, n)) { } - const string& operator=(const string& s) { - if (&s == this) - return *this; - len = s.len; - buf = s.buf; - return *this; + inline string(const string& s) noexcept : len(s.len), buf(s.buf) { } - const bool operator==(const string& s) const { + string& operator=(const string& s) = delete; + + inline const bool operator==(const string& s) const noexcept { if (len != s.len) return false; if (buf == s.buf) @@ -137,21 +114,21 @@ public: return memcmp(buf, s.buf, len) == 0; } - const bool operator!=(const string& s) const { + inline const bool operator!=(const string& s) const noexcept { return !(*this == s); } - const bool operator==(const char* s) const { + inline const bool operator==(const char* const s) const noexcept { if (buf == s) return true; return strcmp(buf, s) == 0; } - const bool operator!=(const char* s) const { + inline const bool operator!=(const char* const s) const noexcept { return !(*this == s); } - const bool operator<(const string& s) const { + inline const bool operator<(const string& s) const noexcept { const size_t n = len < s.len? len : s.len; const int c = memcmp(buf, s.buf, n); if (c < 0) @@ -161,9 +138,9 @@ public: return false; } - const bool operator>(const string& s) const { + inline const bool operator>(const string& s) const noexcept { const size_t n = len < s.len? len : s.len; - int c = memcmp(buf, s.buf, n); + const int c = memcmp(buf, s.buf, n); if (c > 0) return true; if (c == 0) @@ -176,91 +153,137 @@ private: friend class odebugstream; #endif friend class ostringstream; - friend const string operator+(const string& a, const string& b); - friend const string operator+(const string& a, const char* b); - friend const size_t length(const string& s); - friend const char* c_str(const string& s); - friend const size_t find(const string& s1, const char* s2, const size_t start); - friend const string substr(const string& s, const size_t pos, const size_t n); - - size_t len; - char* buf; + friend const string operator+(const string& a, const string& b) noexcept; + friend const string operator+(const string& a, const char* const b) noexcept; + friend const string operator+(const string& a, const char c) noexcept; + friend const size_t length(const string& s) noexcept; + friend const char* const c_str(const string& s) noexcept; + friend const size_t find(const string& s1, const char* const s2, const size_t start) noexcept; + friend const string substr(const string& s, const size_t pos, const size_t n) noexcept; + friend const bool setstring(string& target, const string& s); + + const size_t len; + const char* const buf; + + const char* const mkbuf(const size_t n) { + if (n == 0) + return stringEmptyBuffer; + char* const b = gc_cnew(n + 1); + b[n] = '\0'; + return b; + } + + const char* const mksbuf(const char* const s, const size_t n) { + if (n == 0) + return stringEmptyBuffer; + char* const b = gc_cnew(n + 1); + string_memcpy(b, s, n); + b[n] = '\0'; + return b; + } + + const char* const mksbuf(const char* const s, const size_t n, const bool copy) { + if (!copy) + return s; + if (n == 0) + return stringEmptyBuffer; + char* const b = gc_cnew(n + 1); + string_memcpy(b, s, n); + b[n] = '\0'; + return b; + } + + const char* const mkcbuf(const char c, const size_t n) { + if (n == 0) + return stringEmptyBuffer; + char* const b = gc_cnew(n + 1); + memset(b, c, n); + b[n] = '\0'; + return b; + } }; /** * Adds two strings. */ -const string operator+(const string& a, const string& b) { - string s; - s.len = a.len + b.len; - s.buf = gc_cnew(s.len + 1); - string_memcpy(s.buf, a.buf, a.len); - string_memcpy(s.buf + a.len, b.buf, b.len); - s.buf[s.len] = '\0'; - return s; +inline const string operator+(const string& sa, const string& sb) noexcept { + const size_t n = sa.len + sb.len; + char* const b = gc_cnew(n + 1); + string_memcpy(b, sa.buf, sa.len); + string_memcpy(b + sa.len, sb.buf, sb.len); + b[n] = '\0'; + return string(b, n, false); } -const string operator+(const string& a, const char* b) { - string s; - const size_t blen = strlen(b); - s.len = a.len + blen; - s.buf = gc_cnew(s.len + 1); - string_memcpy(s.buf, a.buf, a.len); - string_memcpy(s.buf + a.len, b, blen); - s.buf[s.len] = '\0'; - return s; +inline const string operator+(const string& sa, const char* const sb) noexcept { + const size_t bn = strlen(sb); + const size_t n = sa.len + bn; + char* const b = gc_cnew(n + 1); + string_memcpy(b, sa.buf, sa.len); + string_memcpy(b + sa.len, sb, bn); + b[n] = '\0'; + return string(b, n, false); +} + +inline const string operator+(const string& sa, const char c) noexcept { + const size_t n = sa.len + 1; + char* const b = gc_cnew(n + 1); + string_memcpy(b, sa.buf, sa.len); + b[n - 1] = c; + b[n] = '\0'; + return string(b, n, false); } /** * Returns the length of a string. */ -const size_t length(const string& s) { +inline const size_t length(const string& s) noexcept { return s.len; } /** * Returns a string as a C zero terminated string. */ -const char* c_str(const string& s) { +inline const char* const c_str(const string& s) noexcept { return s.buf; } /** * Find the first occurrence of string s2 in s1, starting at the given position. */ -const size_t find(const string& s1, const char* s2, const size_t start) { +inline const size_t find(const string& s1, const char* const s2, const size_t start) noexcept { if (start >= s1.len) return s1.len; - const char *f = strstr(s1.buf + start, s2); + const char* const f = strstr(s1.buf + start, s2); if (f == NULL) return s1.len; return f - s1.buf; } -const size_t find(const string& s1, const char* s2) { +inline const size_t find(const string& s1, const char* const s2) noexcept { return find(s1, s2, 0); } /** * Return true if string s1 contains s2. */ -const bool contains(const string& s1, const char* s2) { +inline const bool contains(const string& s1, const char* const s2) noexcept { return find(s1, s2) != length(s1); } /** * Find the first occurence of any character from a string in a string. */ -const size_t find_first_of(const string& s1, const string& s2) { +inline const size_t find_first_of(const string& s1, const string& s2) noexcept { return strcspn(c_str(s1), c_str(s2)); } /** * Find the first occurence of a character in a string. */ -const size_t find(const string& s, const char c) { - const char* cs = c_str(s); - const char* f = strchr(cs, c); +inline const size_t find(const string& s, const char c) noexcept { + const char* const cs = c_str(s); + const char* const f = strchr(cs, c); if (f == NULL) return length(s); return f - cs; @@ -269,9 +292,9 @@ const size_t find(const string& s, const char c) { /** * Find the last occurence of a character in a string. */ -const size_t find_last(const string& s, const char c) { - const char* cs = c_str(s); - const char* f = strrchr(cs, c); +inline const size_t find_last(const string& s, const char c) noexcept { + const char* const cs = c_str(s); + const char* const f = strrchr(cs, c); if (f == NULL) return length(s); return f - cs; @@ -280,7 +303,7 @@ const size_t find_last(const string& s, const char c) { /** * Return a substring of a string. */ -const string substr(const string& s, const size_t pos, const size_t n) { +inline const string substr(const string& s, const size_t pos, const size_t n) noexcept { if (pos >= s.len) return string(); if (pos + n > s.len) @@ -288,17 +311,29 @@ const string substr(const string& s, const size_t pos, const size_t n) { return string(s.buf + pos, n); } -const string substr(const string& s, const size_t pos) { +inline const string substr(const string& s, const size_t pos) noexcept { return substr(s, pos, length(s)); } /** - * Common string constants. + * Set a string. Use with moderation. */ +/* +inline const bool setstring(string& target, const string& s) { + if (&target == &s) + return true; + memcpy((void*)&target.len, (void*)&s.len, sizeof(size_t)); + memcpy((void*)&target.buf, (void*)&s.buf, sizeof(char*)); + return true; +} +*/ -string trueString("true"); -string falseString("false"); -string emptyString(""); +/** + * Common string constants. + */ +const string trueString("true"); +const string falseString("false"); +const string emptyString(""); } diff --git a/sca-cpp/trunk/kernel/tree.hpp b/sca-cpp/trunk/kernel/tree.hpp index 89a131c324..44af09fa64 100644 --- a/sca-cpp/trunk/kernel/tree.hpp +++ b/sca-cpp/trunk/kernel/tree.hpp @@ -38,14 +38,14 @@ namespace tuscany { /** * Make a tree from a leaf and two branches. */ -template const list mktree(const T& e, const list& left, const list& right) { +template inline const list mktree(const T& e, const list& left, const list& right) { return mklist(e, left, right); } /** * Find a leaf with the given key in a tree. */ -template const list assoctree(const T& k, const list& tree) { +template inline const list assoctree(const T& k, const list& tree) { if (isNil(tree)) return tree; if (k == car(car(tree))) @@ -58,7 +58,7 @@ template const list assoctree(const T& k, const list& tree) { /** * Construct a new tree from a leaf and a tree. */ -template const list constree(const T& e, const list& tree) { +template inline const list constree(const T& e, const list& tree) { if (isNil(tree)) return mktree(e, list(), list()); if (e == car(tree)) @@ -71,7 +71,7 @@ template const list constree(const T& e, const list& tree) { /** * Make a tree from an unordered list of leaves. */ -template const list mktree(const list& l) { +template inline const list mktree(const list& l) { if (isNil(l)) return l; return constree(car(l), mktree(cdr(l))); @@ -80,7 +80,7 @@ template const list mktree(const list& l) { /** * Convert a tree to an ordered list of leaves. */ -template const list flatten(const list& tree) { +template inline const list flatten(const list& tree) { if (isNil(tree)) return tree; return append(flatten(cadr(tree)), cons(car(tree), flatten(caddr(tree)))); @@ -89,14 +89,14 @@ template const list flatten(const list& tree) { /** * Sort a list. */ -template const list sort(const list& l) { +template inline const list sort(const list& l) { return flatten(mktree(l)); } /** * Make a balanced tree from an ordered list of leaves. */ -template const list btreeHelper(const list& elements, const size_t n) { +template inline const list btreeHelper(const list& elements, const size_t n) { if (n == 0) return cons(list(), elements); const size_t leftSize = (n - 1) / 2; { @@ -116,7 +116,7 @@ template const list btreeHelper(const list& elements, const si } } -template const list mkbtree(const list& elements) { +template inline const list mkbtree(const list& elements) { return car(btreeHelper(elements, length(elements))); } diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index 206fe8b32b..60fb29070c 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -50,16 +50,16 @@ long int countEValues = 0; long int countCValues = 0; long int countVValues = 0; -bool resetValueCounters() { +inline const bool resetValueCounters() { countValues = countEValues = countCValues = countVValues = 0; return true; } -bool checkValueCounters() { +inline const bool checkValueCounters() { return countValues == 0; } -bool printValueCounters() { +inline const bool printValueCounters() { cout << "countValues " << countValues << endl; cout << "countEValues " << countEValues << endl; cout << "countCValues " << countCValues << endl; @@ -92,7 +92,28 @@ bool printValueCounters() { #endif +/** + * Common value constants. + */ class value; +extern const value nilValue; +extern const list nilListValue; +extern const list nilPairValue; +extern const value emptyStringValue; +extern const value trueValue; +extern const value falseValue; + +/** + * Common value-based lambda types. + */ +typedef lambda&)> lvvlambda; +typedef lambda vvlambda; +typedef lambda vblambda; +typedef lambda vlambda; + +/** + * Generic value type class. + */ class value { public: @@ -101,346 +122,309 @@ public: Nil, Symbol, String, List, Number, Bool, Lambda, Ptr }; - value() : type(value::Nil) { + typedef union { + const void* mix; + const gc_ptr > lst; + const string str; + const lvvlambda func; + const gc_ptr ptr; + const double num; + const bool boo; + } ValueMix; + + inline value() noexcept : type(value::Nil) { debug_inc(countValues); debug_inc(countEValues); debug_watchValue(); } - value(const value& v) { + inline value(const value& v) noexcept : type(v.type) { debug_inc(countValues); debug_inc(countCValues); - type = v.type; - switch(type) { - case value::List: - lst() = v.lst(); - case value::Lambda: - func() = v.func(); - case value::Symbol: - str() = v.str(); - case value::String: - str() = v.str(); - case value::Number: - num() = v.num(); - case value::Bool: - boo() = v.boo(); - case value::Ptr: - ptr() = v.ptr(); - default: - break; - } + memcpy((void*)&mix, (void*)&v.mix, sizeof(ValueMix)); #ifdef WANT_MAINTAINER_WATCH watch = v.watch; #endif } - virtual ~value() { + inline value(const gc_mutable_ref& r) noexcept : type(((value*)r)->type) { + debug_inc(countValues); + debug_inc(countCValues); + memcpy((void*)&mix, (void*)&(((value*)r)->mix), sizeof(ValueMix)); +#ifdef WANT_MAINTAINER_WATCH + watch = v.watch; +#endif + } + + inline virtual ~value() noexcept { debug_dec(countValues); } - value(const lambda&)>& func) : type(value::Lambda), data(vdata(func)) { + inline value(const lvvlambda& f) noexcept : type(value::Lambda), func(f) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const string& str) : type(value::String), data(vdata(result(str))) { + inline value(const string& s) noexcept : type(value::String), str(s) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const char* str) : type(value::Symbol), data(vdata(result(string(str)))) { + inline value(const char* s) noexcept : type(value::Symbol), str(s) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const list& lst) : type(value::List), data(vdata(result(lst))) { + inline value(const list& l) noexcept : type(value::List), lst(new (gc_new >()) list(l)) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const list >& l) : type(value::List), data(vdata(result(listOfValues(l)))) { + inline value(const list >& l) noexcept : type(value::List), lst(new (gc_new >()) list(listOfValues(l))) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const double num) : type(value::Number), data(vdata(result(num))) { + inline value(const double d) noexcept : type(value::Number), num(d) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const int num) : type(value::Number), data(vdata(result((double)num))) { + inline value(const int i) noexcept : type(value::Number), num((double)i) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const bool boo) : type(value::Bool), data(vdata(result(boo))) { + inline value(const bool b) noexcept : type(value::Bool), boo(b) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const gc_ptr ptr) : type(value::Ptr), data(vdata(result(ptr))) { + inline value(const gc_ptr p) noexcept : type(value::Ptr), ptr(p) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const failable& m) : type(value::List), - data(vdata(result(hasContent(m)? mklist(content(m)) : rcode(m) == 1? mklist(value(), reason(m)) : mklist(value(), reason(m), rcode(m))))) { + inline value(const failable& m) noexcept : type(value::List), + lst(new (gc_new >()) list(hasContent(m)? mklist(content(m)) : + rcode(m) == 1? mklist(nilValue, reason(m)) : mklist(nilValue, reason(m), rcode(m)))) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const maybe& m) : type(value::List), - data(vdata(result(hasContent(m)? mklist(content(m)) : list()))) { + inline value(const maybe& m) noexcept : type(value::List), + lst(new (gc_new >()) list(hasContent(m)? mklist(content(m)) : nilListValue)) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - const value& operator=(const value& v) { - if(this == &v) - return *this; - type = v.type; - switch(type) { - case value::List: - lst() = v.lst(); - case value::Lambda: - func() = v.func(); - case value::Symbol: - str() = v.str(); - case value::String: - str() = v.str(); - case value::Number: - num() = v.num(); - case value::Bool: - boo() = v.boo(); - case value::Ptr: - ptr() = v.ptr(); - default: - break; - } -#ifdef WANT_MAINTAINER_WATCH - watch = v.watch; -#endif - return *this; - } + value& operator=(const value& v) = delete; - const bool operator!=(const value& v) const { + inline const bool operator!=(const value& v) const noexcept { return !this->operator==(v); } - const bool operator==(const value& v) const { + inline const bool operator==(const value& v) const noexcept { if(this == &v) return true; switch(type) { case value::Nil: return v.type == value::Nil; case value::List: - return v.type == value::List && lst()() == v.lst()(); + return v.type == value::List && *lst == *v.lst; case value::Lambda: - return v.type == value::Lambda && func() == v.func(); + return v.type == value::Lambda && func == v.func; case value::Symbol: case value::String: - return str()() == (string)v; + return (v.type == value::Symbol || v.type == value::String) && str == v.str; case value::Number: - return num()() == (double)v; + return v.type == value::Number && num == v.num; case value::Bool: - return boo()() == (bool)v; + return v.type == value::Bool && boo == v.boo; case value::Ptr: - return v.type == value::Ptr && ptr()() == v.ptr()(); + return v.type == value::Ptr && ptr == v.ptr; default: return false; } } - const bool operator<(const value& v) const { + inline const bool operator<(const value& v) const noexcept { if(this == &v) return false; switch(type) { case value::List: - return v.type == value::List && lst()() < v.lst()(); + return v.type == value::List && *lst < *v.lst; case value::Symbol: case value::String: - return str()() < (string)v; + return (v.type == value::Symbol || v.type == value::String) && str < v.str; case value::Bool: - return boo()() < (bool)v; + return v.type == value::Bool && boo < v.boo; case value::Number: - return num()() < (double)v; + return v.type == value::Number && num < v.num; default: return false; } } - const bool operator>(const value& v) const { + inline const bool operator>(const value& v) const noexcept { if(this == &v) return false; switch(type) { case value::List: - return v.type == value::List && lst()() > v.lst()(); + return v.type == value::List && *lst > *v.lst; case value::Symbol: case value::String: - return str()() > (string)v; + return (v.type == value::Symbol || v.type == value::String) && str > v.str; case value::Bool: - return boo()() > (bool)v; + return v.type == value::Bool && boo > v.boo; case value::Number: - return num()() > (double)v; + return v.type == value::Number && num > v.num; default: return false; } } - const value operator()(const list& args) const { - return func()(args); + inline const value operator()(const list& args) const noexcept { + return func(args); } - operator const string() const { + inline operator const string() const noexcept { switch(type) { case value::Symbol: case value::String: - return str()(); + return str; case value::Number: { ostringstream os; - os << num()(); + os << num; return tuscany::str(os); } case value::Bool: - return boo()()? trueString : falseString; + return boo? trueString : falseString; default: return emptyString; } } - operator const double() const { + inline operator const double() const noexcept { switch(type) { case value::Symbol: case value::String: - return atof(c_str(str()())); + return atof(c_str(str)); case value::Number: - return (double)num()(); + return (double)num; case value::Bool: - return boo()()? 1.0 : 0.0; + return boo? 1.0 : 0.0; default: return 0.0; } } - operator const int() const { + inline operator const int() const noexcept { switch(type) { case value::Symbol: case value::String: - return atoi(c_str(str()())); + return atoi(c_str(str)); case value::Number: - return (int)num()(); + return (int)num; case value::Bool: - return boo()()? 1 : 0; + return boo? 1 : 0; default: return 0; } } - operator const bool() const { + inline operator const bool() const noexcept { switch(type) { case value::Symbol: case value::String: - return str()() == string("true"); + return str == trueString; case value::Number: - return (int)num()() != 0; + return num != 0.0; case value::Bool: - return boo()(); + return boo; default: - return 0; + return false; } } - operator const gc_ptr() const { - return ptr()(); + inline operator const gc_ptr() const noexcept { + return ptr; } - operator const list() const { - return lst()(); + inline operator const list() const noexcept { + return *lst; } - operator const list >() const { - return listOfListOfValues(lst()()); + inline operator const list >() const noexcept { + return listOfListOfValues(*lst); } - operator const lambda&)>() const { - return func(); + inline operator const lvvlambda() const noexcept { + return func; } private: - template lambda& vdata() const { - return *reinterpret_cast *> (const_cast *> (&data)); - } - - template const lambda& vdata(const T& v) const { - return *reinterpret_cast *> (&v); - } - - lambda& num() const { - return vdata (); - } - - lambda& boo() const { - return vdata (); - } - - lambda()>& ptr() const { - return vdata()> (); - } - - lambda& str() const { - return vdata (); - } - - lambda()>& lst() const { - return vdata()> (); - } - - lambda&)>& func() const { - return vdata&)> (); - } - - const list listOfValues(const list >& l) const { + inline const list listOfValues(const list >& l) const noexcept { if (isNil(l)) - return list(); + return nilListValue; return cons(car(l), listOfValues(cdr(l))); } - const list > listOfListOfValues(const list& l) const { + inline const list > listOfListOfValues(const list& l) const noexcept { if (isNil(l)) return list >(); - return cons >(list(car(l)), listOfListOfValues(cdr(l))); + return cons >(car(l).type == value::List? list(car(l)) : nilPairValue, listOfListOfValues(cdr(l))); } - friend ostream& operator<<(ostream&, const value&); - friend const value::ValueType type(const value& v); + 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); #ifdef WANT_MAINTAINER_WATCH friend const string watchValue(const value& v); string watch; #endif - ValueType type; - lambda data; + const ValueType type; + union { + void* mix; + const gc_ptr > lst; + const string str; + const lvvlambda func; + const gc_ptr ptr; + const double num; + const bool boo; + }; }; +/** + * Common value constants. + */ +const value nilValue; +const list nilListValue = list(); +const list nilPairValue = mklist(nilValue, nilValue); +const value emptyStringValue(emptyString); +const value trueValue(true); +const value falseValue(false); + #ifdef WANT_MAINTAINER_WATCH /** * Debug utility used to write the contents of a value to a string, easier * to watch than the value itself in a debugger. */ -const string watchValue(const value& v) { +inline const string watchValue(const value& v) { if (v.type == value::List) return watchList(v); odebugstream os; @@ -453,7 +437,7 @@ const string watchValue(const value& v) { /** * Write an escape string to a buffer. */ -const char* escapestr(const char* s, char* buf) { +inline const char* escapestr(const char* const s, char* const buf) noexcept { if (*s == '\0') { *buf = '\0'; return buf; @@ -470,7 +454,7 @@ const char* escapestr(const char* s, char* buf) { /** * Write an escaped string value to a stream. */ -ostream& escvwrite(const string& str, ostream& out) { +inline ostream& escvwrite(const string& str, ostream& out) noexcept { char* buf = gc_cnew(length(str) * 2 + 1); escapestr(c_str(str), buf); out << buf; @@ -480,30 +464,29 @@ ostream& escvwrite(const string& str, ostream& out) { /** * Write a value to a stream. */ -ostream& operator<<(ostream& out, const value& v) { +inline ostream& operator<<(ostream& out, const value& v) noexcept { switch(v.type) { case value::List: - return out << v.lst()(); + return out << *v.lst; case value::Lambda: - return out << "lambda::" << v.func(); + return out << "lambda::" << v.func; case value::Symbol: - return out << v.str()(); + return out << v.str; case value::String: out << '\"'; - escvwrite(v.str()(), out); + escvwrite(v.str, out); return out << '\"'; case value::Number: - return out << v.num()(); + return out << v.num; case value::Bool: - if(v.boo()()) - return out << "true"; + if(v.boo) + return out << trueString; else - return out << "false"; + return out << falseString; case value::Ptr: { - const gc_ptr p = v.ptr()(); - if (p == gc_ptr(NULL)) + if (v.ptr == gc_ptr(NULL)) return out << "gc_ptr::null"; - return out << "gc_ptr::" << p; + return out << "gc_ptr::" << v.ptr; } default: return out << "nil"; @@ -513,70 +496,70 @@ ostream& operator<<(ostream& out, const value& v) { /** * Returns the type of a value. */ -const value::ValueType type(const value& v) { +inline const value::ValueType type(const value& v) noexcept { return v.type; } /** * Returns true if a value is nil. */ -const bool isNil(const value& v) { +inline const bool isNil(const value& v) noexcept { return type(v) == value::Nil; } /** * Returns true if a value is a lambda. */ -const bool isLambda(const value& v) { +inline const bool isLambda(const value& v) noexcept { return type(v) == value::Lambda; } /** * Returns true if a value is a string. */ -const bool isString(const value& v) { +inline const bool isString(const value& v) noexcept { return type(v) == value::String; } /** * Returns true if a value is a symbol. */ -const bool isSymbol(const value& v) { +inline const bool isSymbol(const value& v) noexcept { return type(v) == value::Symbol; } /** * Returns true if a value is a list. */ -const bool isList(const value& v) { +inline const bool isList(const value& v) noexcept { return type(v) == value::List; } /** * Returns true if a value is a number. */ -const bool isNumber(const value& v) { +inline const bool isNumber(const value& v) noexcept { return type(v) == value::Number; } /** * Returns true if a value is a boolean. */ -const bool isBool(const value& v) { +inline const bool isBool(const value& v) noexcept { return type(v) == value::Bool; } /** * Returns true if a value is a pointer. */ -const bool isPtr(const value& v) { +inline const bool isPtr(const value& v) noexcept { return type(v) == value::Ptr; } /** * Returns true if a value is a tagged list. */ -const bool isTaggedList(const value& exp, value tag) { +inline const bool isTaggedList(const value& exp, const value& tag) noexcept { if(isList(exp) && !isNil((list)exp)) return car((list)exp) == tag; return false; @@ -585,16 +568,16 @@ const bool isTaggedList(const value& exp, value tag) { /** * Make a list of values from a list of other things. */ -template const list mkvalues(const list& l) { +template inline const list mkvalues(const list& l) noexcept { if (isNil(l)) - return list(); + return nilListValue; return cons(car(l), mkvalues(cdr(l))); } /** * Convert a list of values to a list of other things. */ -template const list convertValues(const list& l) { +template inline const list convertValues(const list& l) noexcept { if (isNil(l)) return list(); return cons(car(l), convertValues(cdr(l))); @@ -603,7 +586,7 @@ template const list convertValues(const list& l) { /** * Convert a path string value to a list of values. */ -const list pathTokens(const char* p) { +inline const list pathTokens(const char* const p) noexcept { if (p == NULL || p[0] == '\0') return list(); if (p[0] == '/') @@ -611,23 +594,23 @@ const list pathTokens(const char* p) { return tokenize("/", p); } -const list pathValues(const value& p) { +inline const list pathValues(const value& p) noexcept { return mkvalues(pathTokens(c_str(p))); } /** * Convert a path represented as a list of values to a string value. */ -const value path(const list& p) { +inline const value path(const list& p) noexcept { if (isNil(p)) - return ""; - return string("/") + car(p) + path(cdr(p)); + return emptyString; + return string("/") + (string)car(p) + (string)path(cdr(p)); } /** * Make a uuid value. */ -const value mkuuid() { +inline const value mkuuid() noexcept { apr_uuid_t id; apr_uuid_get(&id); char buf[APR_UUID_FORMATTED_LENGTH]; @@ -638,19 +621,33 @@ const value mkuuid() { /** * Make a random alphanumeric value. */ -const int intrand() { +inline const int intrand() noexcept { const apr_uint64_t now = apr_time_now(); srand((unsigned int)(((now >> 32) ^ now) & 0xffffffff)); return rand() & 0x0FFFF; } -const value mkrand() { +inline const value mkrand() noexcept { char buf[32]; - const char* an = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + const char* const an = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; for (int i =0; i < 32; i++) buf[i] = an[intrand() % 62]; return value(string(buf, 32)); } +/** + * Set a value. Use with moderation. + */ +inline const bool setvalue(value& target, const value& v) { + if (&target == &v) + return true; +#ifdef WANT_MAINTAINER_WATCH + memcpy(&target.watch, &v.watch, sizeof(string)); +#endif + memcpy((void*)&target.type, (void*)&v.type, sizeof(value::ValueType)); + memcpy((void*)&target.mix, (void*)&v.mix, sizeof(value::ValueMix)); + return true; +} + } #endif /* tuscany_value_hpp */ diff --git a/sca-cpp/trunk/kernel/xml-test.cpp b/sca-cpp/trunk/kernel/xml-test.cpp deleted file mode 100644 index 0523cc74a6..0000000000 --- a/sca-cpp/trunk/kernel/xml-test.cpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -/** - * Test XML handling functions. - */ - -#include -#include "stream.hpp" -#include "string.hpp" -#include "list.hpp" -#include "value.hpp" -#include "element.hpp" -#include "xml.hpp" - -namespace tuscany { - -const string currencyXML = -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" US\n" -" \n" -"\n"; - -const string customerXML = -"\n" -"\n" -" jdoe\n" -"

\n" -" san francisco\n" -" ca\n" -"
\n" -" \n" -" 1234\n" -" 1000\n" -" \n" -" \n" -" 6789\n" -" 2000\n" -" \n" -" \n" -" 4567\n" -" 3000\n" -" \n" -"\n"; - -const string abcXML = -"\n" -"\n" -" abc\n" -" def\n" -" xyz\n" -" tuv\n" -"\n"; - -const string xyzXML = -"\n" -"\n" -" \n" -" 123\n" -" abc\n" -" \n" -" \n" -" 234\n" -" def\n" -" \n" -" \n" -" 345\n" -" xyz\n" -" \n" -" \n" -" 456\n" -" tuv\n" -" \n" -"\n"; - -const bool isName(const value& token) { - return isTaggedList(token, attribute) && attributeName(token) == "name"; -} - -bool testReadXML() { - { - istringstream is(customerXML); - const list c = readXML(streamList(is)); - } - { - istringstream is(currencyXML); - const list c = readXML(streamList(is)); - - const value composite = car(c); - assert(isTaggedList(composite, element)); - assert(elementName(composite) == "composite"); - assert(attributeValue(car(filter(isName, elementChildren(composite)))) == string("currency")); - } - return true; -} - -ostream* xmlWriter(const string& s, ostream* os) { - (*os) << s; - return os; -} - -bool testWriteXML() { - { - istringstream is(customerXML); - const list c = readXML(streamList(is)); - ostringstream os; - writeXML(xmlWriter, &os, c); - assert(str(os) == customerXML); - } - { - istringstream is(currencyXML); - const list c = readXML(streamList(is)); - ostringstream os; - writeXML(xmlWriter, &os, c); - assert(str(os) == currencyXML); - } - return true; -} - -bool testElements() { - { - const list ad = mklist(mklist("city", string("san francisco")), mklist("state", string("ca"))); - const list ac1 = mklist(mklist("id", string("1234")), mklist("balance", 1000)); - const list ac2 = mklist(mklist("id", string("6789")), mklist("balance", 2000)); - const list ac3 = mklist(mklist("id", string("4567")), mklist("balance", 3000)); - { - const list c = mklist(mklist("customer", mklist("name", string("jdoe")), cons("address", ad), mklist("account", mklist(ac1, ac2, ac3)))); - const list e = valuesToElements(c); - const list v = elementsToValues(e); - assert(v == c); - - ostringstream os; - writeXML(xmlWriter, &os, e); - assert(str(os) == customerXML); - } - { - const list c = mklist(mklist("customer", mklist("name", string("jdoe")), cons("address", ad), cons("account", ac1), cons("account", ac2), cons("account", ac3))); - const list e = valuesToElements(c); - const list v = elementsToValues(e); - - ostringstream os; - writeXML(xmlWriter, &os, e); - assert(str(os) == customerXML); - } - } - { - istringstream is(abcXML); - const list c = readXML(streamList(is)); - const list v = elementsToValues(c); - const list e = valuesToElements(v); - ostringstream os; - writeXML(xmlWriter, &os, e); - assert(str(os) == abcXML); - } - { - istringstream is(xyzXML); - const list c = readXML(streamList(is)); - const list v = elementsToValues(c); - const list e = valuesToElements(v); - ostringstream os; - writeXML(xmlWriter, &os, e); - assert(str(os) == xyzXML); - } - { - istringstream is(customerXML); - const list c = readXML(streamList(is)); - const list v = elementsToValues(c); - const list e = valuesToElements(v); - ostringstream os; - writeXML(xmlWriter, &os, e); - assert(str(os) == customerXML); - } - return true; -} - -bool testValues() { - { - const list l = mklist(list() + "ns1:echoString" + (list() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list() + "text" + string("Hello World!"))); - const list e = valuesToElements(l); - const failable > lx = writeXML(e); - ostringstream os; - write(content(lx), os); - istringstream is(str(os)); - const list x = readXML(streamList(is)); - const list v = elementsToValues(x); - assert(v == l); - } - return true; -} - -} - -int main() { - tuscany::gc_scoped_pool p; - tuscany::cout << "Testing..." << tuscany::endl; - - tuscany::testReadXML(); - tuscany::testWriteXML(); - tuscany::testElements(); - tuscany::testValues(); - - tuscany::cout << "OK" << tuscany::endl; - - return 0; -} diff --git a/sca-cpp/trunk/kernel/xml.hpp b/sca-cpp/trunk/kernel/xml.hpp deleted file mode 100644 index d00a2905fb..0000000000 --- a/sca-cpp/trunk/kernel/xml.hpp +++ /dev/null @@ -1,412 +0,0 @@ -/* - * 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_xml_hpp -#define tuscany_xml_hpp - -/** - * XML read/write functions. - */ - -#include -#include -#include -#include -#include "string.hpp" -#include "list.hpp" -#include "stream.hpp" -#include "value.hpp" -#include "element.hpp" -#include "monad.hpp" - -namespace tuscany { - -/** - * APR-based memory management functions. - */ - - -/** - * Initializes the libxml2 library. - */ -class XMLParser { -public: - XMLParser() { - debug("xml::XMLParser"); - xmlMemSetup(gc_pool_free, gc_pool_malloc, gc_pool_realloc, gc_pool_strdup); - xmlInitParser(); - } - - ~XMLParser() { - } -} xmlParser; - -/** - * Encapsulates a libxml2 xmlTextReader and its state. - */ -class XMLReader { -public: - enum TokenType { - None = 0, Element = 1, Attribute = 2, Text = 3, EndElement = 15, Identifier = 100, End = 101 - }; - - XMLReader(xmlTextReaderPtr xml) : xml(xml), owner(true), tokenType(None), isEmptyElement(false), hasValue(false), hasAttributes(false) { - debug("xml::XMLReader::xml"); - xmlTextReaderSetParserProp(xml, XML_PARSER_DEFAULTATTRS, 1); - xmlTextReaderSetParserProp(xml, XML_PARSER_SUBST_ENTITIES, 1); - } - - XMLReader(const XMLReader& r) : xml(r.xml), owner(false), tokenType(r.tokenType), isEmptyElement(r.isEmptyElement), hasValue(r.hasValue), hasAttributes(r.hasAttributes) { - debug("xml::XMLReader::copy"); - } - - const XMLReader& operator=(const XMLReader& r) { - debug("xml::XMLReader::operator="); - if(this == &r) - return *this; - xml = r.xml; - owner = false; - tokenType = r.tokenType; - isEmptyElement = r.isEmptyElement; - hasValue = r.hasValue; - hasAttributes = r.hasAttributes; - return *this; - } - - ~XMLReader() { - if (!owner) - return; - xmlTextReaderClose(xml); - xmlFreeTextReader(xml); - } - - /** - * Read the next XML token and return its type. - */ - int read() { - if (tokenType == End) - return tokenType; - if (tokenType == Element) { - isEmptyElement = xmlTextReaderIsEmptyElement(xml); - hasAttributes = xmlTextReaderHasAttributes(xml); - return tokenType = Identifier; - } - if (tokenType == Identifier && hasAttributes && xmlTextReaderMoveToFirstAttribute(xml) == 1) - return tokenType = Attribute; - if (tokenType == Attribute && xmlTextReaderMoveToNextAttribute(xml) == 1) - return tokenType = Attribute; - if (isEmptyElement && (tokenType == Identifier || tokenType == Attribute)) - return tokenType = EndElement; - if (!xmlTextReaderRead(xml)) - return tokenType = End; - return tokenType = xmlTextReaderNodeType(xml); - } - - operator xmlTextReaderPtr() const { - return xml; - } - -private: - xmlTextReaderPtr xml; - bool owner; - int tokenType; - bool isEmptyElement; - bool hasValue; - bool hasAttributes; -}; - -/** - * Constants used to tag XML tokens. - */ -const value endElement("<"); -const value startElement(">"); - -/** - * Read an XML identifier. - */ -const value readIdentifier(XMLReader& reader) { - const char* name = (const char*)xmlTextReaderConstName(reader); - return name; -} - -/** - * Read XML text. - */ -const value readText(XMLReader& reader) { - const char *val = (const char*)xmlTextReaderConstValue(reader); - return string(val); -} - -/** - * Read an XML attribute. - */ -const value readAttribute(XMLReader& reader) { - const char *name = (const char*)xmlTextReaderConstName(reader); - const char *val = (const char*)xmlTextReaderConstValue(reader); - return mklist(attribute, name, string(val)); -} - -/** - * Read an XML token. - */ -const value readToken(XMLReader& reader) { - const int tokenType = reader.read(); - if (tokenType == XMLReader::None || tokenType == XMLReader::End) - return value(); - if (tokenType == XMLReader::Element) - return startElement; - if (tokenType == XMLReader::Identifier) - return readIdentifier(reader); - if (tokenType == XMLReader::Attribute) - return readAttribute(reader); - if (tokenType == XMLReader::Text) - return readText(reader); - if (tokenType == XMLReader::EndElement) - return endElement; - return readToken(reader); -} - -/** - * Read a list of values from XML tokens. - */ -const list readList(const list& listSoFar, XMLReader& reader) { - const value token = readToken(reader); - if(isNil(token) || endElement == token) - return reverse(listSoFar); - if(startElement == token) - return readList(cons(readList(mklist(element), reader), listSoFar), reader); - return readList(cons(token, listSoFar), reader); -} - -/** - * Read a list of values from a libxml2 XML reader. - */ -const list read(XMLReader& reader) { - value nextToken = readToken(reader); - if (startElement == nextToken) - return mklist(readList(mklist(element), reader)); - return list(); -} - -/** - * Context passed to the read callback function. - */ -class XMLReadContext { -public: - XMLReadContext(const list& ilist) : ilist(ilist) { - } - list ilist; -}; - -/** - * Callback function called by libxml2 to read XML. - */ -int readCallback(void *context, char* buffer, int len) { - XMLReadContext& rc = *static_cast(context); - if (isNil(rc.ilist)) - return 0; - const list f(fragment(rc.ilist, len)); - const string s(car(f)); - rc.ilist = cdr(f); - memcpy(buffer, c_str(s), length(s)); - return (int)length(s); -} - -/** - * Return true if a list of strings contains an XML document. - */ -const bool isXML(const list& ls) { - if (isNil(ls)) - return false; - return substr(car(ls), 0, 5) == " readXML(const list& ilist) { - debug(ilist, "xml::readXML"); - XMLReadContext cx(ilist); - xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &cx, NULL, NULL, XML_PARSE_NONET | XML_PARSE_NODICT); - if (xml == NULL) - return list(); - XMLReader reader(xml); - return read(reader); -} - -/** - * Default encoding used to write XML documents. - */ -const char* encoding = "UTF-8"; - - -/** - * Write a list of XML element or attribute tokens. - */ -const list expandElementValues(const value& n, const list& l) { - if (isNil(l)) - return l; - return cons(value(cons(element, cons(n, isList(car(l))? (list)car(l) : mklist(car(l))))), expandElementValues(n, cdr(l))); -} - -const failable writeList(const list& l, const xmlTextWriterPtr xml) { - if (isNil(l)) - return true; - - // Write an attribute - const value token(car(l)); - if (isTaggedList(token, attribute)) { - if (xmlTextWriterWriteAttribute(xml, (const xmlChar*)c_str(string(attributeName(token))), (const xmlChar*)c_str(string(attributeValue(token)))) < 0) - return mkfailure("xmlTextWriterWriteAttribute failed"); - - } else if (isTaggedList(token, element)) { - - // Write an element containing a value - if (elementHasValue(token)) { - const value v = elementValue(token); - if (isList(v)) { - - // Write an element per entry in a list of values - const list e = expandElementValues(elementName(token), v); - writeList(e, xml); - - } else { - - // Write an element with a single value - if (xmlTextWriterStartElement(xml, (const xmlChar*)c_str(string(elementName(token)))) < 0) - return mkfailure("xmlTextWriterStartElement failed"); - - // Write its children - const failable w = writeList(elementChildren(token), xml); - if (!hasContent(w)) - return w; - - if (xmlTextWriterEndElement(xml) < 0) - return mkfailure("xmlTextWriterEndElement failed"); - } - } - else { - - // Write an element - if (xmlTextWriterStartElement(xml, (const xmlChar*)c_str(string(elementName(token)))) < 0) - return mkfailure("xmlTextWriterStartElement failed"); - - // Write its children - const failable w = writeList(elementChildren(token), xml); - if (!hasContent(w)) - return w; - - if (xmlTextWriterEndElement(xml) < 0) - return mkfailure("xmlTextWriterEndElement failed"); - } - } else { - - // Write XML text - if (xmlTextWriterWriteString(xml, (const xmlChar*)c_str(string(token))) < 0) - return mkfailure("xmlTextWriterWriteString failed"); - } - - // Go on - return writeList(cdr(l), xml); -} - -/** - * Write a list of values to a libxml2 XML writer. - */ -const failable write(const list& l, const xmlTextWriterPtr xml, bool xmlTag) { - if (xmlTag) { - if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0) - return mkfailure("xmlTextWriterStartDocument failed"); - } - - const failable w = writeList(l, xml); - if (!hasContent(w)) - return w; - - if (xmlTag) { - if (xmlTextWriterEndDocument(xml) < 0) - return mkfailure("xmlTextWriterEndDocument failed"); - } - return true; -} - -/** - * Context passed to the write callback function. - */ -template class XMLWriteContext { -public: - XMLWriteContext(const lambda& reduce, const R& accum) : reduce(reduce), accum(accum) { - } - const lambda reduce; - R accum; -}; - -/** - * Callback function called by libxml2 to write XML out. - */ -template int writeCallback(void *context, const char* buffer, int len) { - XMLWriteContext& cx = *static_cast*>(context); - cx.accum = cx.reduce(string(buffer, len), cx.accum); - return len; -} - -/** - * Convert a list of values to an XML document. - */ -template const failable writeXML(const lambda& reduce, const R& initial, const list& l, const bool xmlTag) { - XMLWriteContext cx(reduce, initial); - xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback, NULL, &cx, NULL); - if (out == NULL) - return mkfailure("xmlOutputBufferCreateIO failed"); - xmlTextWriterPtr xml = xmlNewTextWriter(out); - if (xml == NULL) - return mkfailure("xmlNewTextWriter failed"); - xmlTextWriterSetIndent(xml, 1); - - const failable w = write(l, xml, xmlTag); - xmlFreeTextWriter(xml); - if (!hasContent(w)) { - return mkfailure(w); - } - return cx.accum; -} - -template const failable writeXML(const lambda& reduce, const R& initial, const list& l) { - return writeXML(reduce, initial, l, true); -} - -/** - * Convert a list of values to a list of strings representing an XML document. - */ -const failable > writeXML(const list& l, const bool xmlTag) { - debug(l, "xml::writeXML"); - const failable > ls = writeXML >(rcons, list(), l, xmlTag); - if (!hasContent(ls)) - return ls; - return reverse(list(content(ls))); -} - -const failable > writeXML(const list& l) { - return writeXML(l, true); -} - -} -#endif /* tuscany_xml_hpp */ diff --git a/sca-cpp/trunk/kernel/xsd-test.cpp b/sca-cpp/trunk/kernel/xsd-test.cpp deleted file mode 100644 index fbd2ee6dca..0000000000 --- a/sca-cpp/trunk/kernel/xsd-test.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -/** - * Test validation of a composite file against an SCDL schema. - */ - -#include "string.hpp" -#include "fstream.hpp" -#include -#include - -namespace tuscany { - -bool printNode(xmlTextReaderPtr reader) { - const xmlChar* name = xmlTextReaderConstName(reader); - if(name == NULL) - name = (xmlChar *)""; - const xmlChar* value = xmlTextReaderConstValue(reader); - cerr << xmlTextReaderDepth(reader) << " " << xmlTextReaderNodeType(reader) << " " << name << " " - << xmlTextReaderIsEmptyElement(reader) << " " << xmlTextReaderHasValue(reader); - if(value == NULL) - cerr << endl; - else - cerr << value << endl; - return true; -} - -int xmlRead(void *context, char* buffer, int len) { - return (int)fread(buffer, 1, len, (FILE*)context); -} - -int xmlClose(void *context) { - fclose((FILE*)context); - return 0; -} - -bool readFile(const char*xsdfilename, const char *filename) { - cout << "Loading schema " << xsdfilename << endl; - const xmlDocPtr xsddoc = xmlReadFile(xsdfilename, NULL, XML_PARSE_NONET); - const xmlSchemaParserCtxtPtr xsdctx = xmlSchemaNewDocParserCtxt(xsddoc); - const xmlSchemaPtr xsd = xmlSchemaParse(xsdctx); - const xmlSchemaValidCtxtPtr validctx = xmlSchemaNewValidCtxt(xsd); - - cout << "Reading file " << filename << endl; - FILE* file = fopen(filename, "r"); - if (file != NULL) { - const xmlTextReaderPtr reader = xmlReaderForIO(xmlRead, xmlClose, file, filename, NULL, XML_PARSE_NONET); - xmlTextReaderSetParserProp(reader, XML_PARSER_DEFAULTATTRS, 1); - xmlTextReaderSetParserProp(reader, XML_PARSER_SUBST_ENTITIES, 1); - - if(reader != NULL) { - xmlTextReaderSchemaValidateCtxt(reader, validctx, 0); - - int rc; - while((rc = xmlTextReaderRead(reader)) == 1) { - printNode(reader); - } - if(xmlTextReaderIsValid(reader) != 1) - cout << "Could not validate document" << endl; - xmlFreeTextReader(reader); - if(rc != 0) - cout << "Could not parse document" << endl; - } else - cout << "Could not create parser" << endl; - } else - cout << "Could not open document" << endl; - - xmlSchemaFreeValidCtxt(validctx); - xmlSchemaFree(xsd); - xmlSchemaFreeParserCtxt(xsdctx); - - return true; -} - -} - -int main(int argc, char **argv) { - tuscany::cout << "Testing..." << tuscany::endl; - if(argc != 3) - return 1; - - tuscany::readFile(argv[1], argv[2]); - - xmlCleanupParser(); - - tuscany::cout << "OK" << tuscany::endl; - return 0; -} -- cgit v1.2.3