summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-12-11 03:51:03 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-12-11 03:51:03 +0000
commitae0b7c0063db6236be2d7cf01ddbf2159f77c98c (patch)
tree2f64d65d018634b8728623e2ca99514541fab8aa /sca-cpp/trunk/kernel
parent1f3796522a078dda5906395ba471d151ad694b6b (diff)
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
Diffstat (limited to 'sca-cpp/trunk/kernel')
-rw-r--r--sca-cpp/trunk/kernel/Makefile.am10
-rw-r--r--sca-cpp/trunk/kernel/config.hpp4
-rw-r--r--sca-cpp/trunk/kernel/dynlib-test.cpp6
-rw-r--r--sca-cpp/trunk/kernel/dynlib.hpp32
-rw-r--r--sca-cpp/trunk/kernel/element.hpp103
-rw-r--r--sca-cpp/trunk/kernel/fstream.hpp132
-rw-r--r--sca-cpp/trunk/kernel/function.hpp114
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp370
-rw-r--r--sca-cpp/trunk/kernel/hash-test.cpp87
-rw-r--r--sca-cpp/trunk/kernel/hash.hpp10
-rw-r--r--sca-cpp/trunk/kernel/kernel-test.cpp528
-rw-r--r--sca-cpp/trunk/kernel/lambda-test.cpp25
-rw-r--r--sca-cpp/trunk/kernel/list.hpp210
-rw-r--r--sca-cpp/trunk/kernel/mem-test.cpp56
-rw-r--r--sca-cpp/trunk/kernel/monad.hpp225
-rw-r--r--sca-cpp/trunk/kernel/parallel-test.cpp84
-rw-r--r--sca-cpp/trunk/kernel/parallel.hpp161
-rw-r--r--sca-cpp/trunk/kernel/perf.hpp22
-rw-r--r--sca-cpp/trunk/kernel/sstream.hpp213
-rw-r--r--sca-cpp/trunk/kernel/stream.hpp91
-rw-r--r--sca-cpp/trunk/kernel/string-test.cpp97
-rw-r--r--sca-cpp/trunk/kernel/string.hpp223
-rw-r--r--sca-cpp/trunk/kernel/tree.hpp16
-rw-r--r--sca-cpp/trunk/kernel/value.hpp371
-rw-r--r--sca-cpp/trunk/kernel/xml-test.cpp235
-rw-r--r--sca-cpp/trunk/kernel/xml.hpp412
-rw-r--r--sca-cpp/trunk/kernel/xsd-test.cpp107
27 files changed, 1769 insertions, 2175 deletions
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<int(const int)> csquarel() {
- return tuscany::lambda<int(const int)>(tuscany::test::cppsquare);
+ const tuscany::lambda<const int(const int)> csquarel() {
+ return tuscany::lambda<const int(const int)>(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<void*>(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<void*> open(const string& name) {
+ void * h = dlopen(c_str(name), RTLD_NOW);
+ return h != NULL? failable<void*>(h) : mkfailure<void*>(string("Could not load library: ") + name + ": " + dlerror());
+ }
+
template<typename S> friend const failable<lambda<S> > dynlambda(const string& name, const lib& l);
- string name;
- failable<void*> h;
- bool owner;
+ const string name;
+ const failable<void*> h;
+ const bool owner;
};
/**
* Find a lambda function in a dynamic library.
*/
-template<typename S> const failable<lambda<S> > dynlambda(const string& name, const lib& l) {
+template<typename S> inline const failable<lambda<S> > dynlambda(const string& name, const lib& l) {
if (!hasContent(l.h))
return mkfailure<lambda<S>>(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<value>(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<value>(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<value>& l) {
+inline const value attributeName(const list<value>& l) {
return cadr(l);
}
/**
* Returns the value of an attribute.
*/
-const value attributeValue(const list<value>& l) {
+inline const value attributeValue(const list<value>& l) {
return caddr(l);
}
/**
* Returns the name of an element.
*/
-const value elementName(const list<value>& l) {
+inline const value elementName(const list<value>& l) {
return cadr(l);
}
/**
* Returns true if an element has children.
*/
-const bool elementHasChildren(const list<value>& l) {
+inline const bool elementHasChildren(const list<value>& l) {
return !isNil(cddr(l));
}
/**
* Returns the children of an element.
*/
-const list<value> elementChildren(const list<value>& l) {
+inline const list<value> elementChildren(const list<value>& l) {
return cddr(l);
}
/**
* Returns true if an element has a value.
*/
-const bool elementHasValue(const list<value>& l) {
+inline const bool elementHasValue(const list<value>& l) {
const list<value> r = reverse(l);
if (isSymbol(car(r)))
return false;
@@ -107,26 +107,26 @@ const bool elementHasValue(const list<value>& l) {
/**
* Returns the value of an element.
*/
-const value elementValue(const list<value>& l) {
+inline const value elementValue(const list<value>& 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<value> l = v;
return (isNil(l) || !isSymbol(car(l)));
}
-const value elementToValue(const value& t) {
+inline const value elementToValue(const value& t) {
const list<value> elementsToValues(const list<value>& e);
// Convert an attribute
if (isTaggedList(t, attribute))
- return mklist<value>(c_str(atsign + attributeName(t)), attributeValue(t));
+ return mklist<value>(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<value> l = v;
@@ -166,7 +166,7 @@ const bool elementToValueIsSymbol(const value& v) {
return true;
}
-const list<value> elementToValueGroupValues(const value& v, const list<value>& l) {
+inline const list<value> elementToValueGroupValues(const value& v, const list<value>& l) {
if (isNil(l) || !elementToValueIsSymbol(v) || !elementToValueIsSymbol(car(l)))
return cons(v, l);
if (car<value>(car(l)) != car<value>(v))
@@ -180,7 +180,7 @@ const list<value> elementToValueGroupValues(const value& v, const list<value>& l
}
-const list<value> elementsToValues(const list<value>& e) {
+inline const list<value> elementsToValues(const list<value>& e) {
if (isNil(e))
return e;
return elementToValueGroupValues(elementToValue(car(e)), elementsToValues(cdr(e)));
@@ -189,13 +189,13 @@ const list<value> elementsToValues(const list<value>& e) {
/**
* Convert a value to an element.
*/
-const value valueToElement(const value& t) {
+inline const value valueToElement(const value& t) {
const list<value> valuesToElements(const list<value>& l);
// Convert a name value pair
if (isList(t) && !isNil((list<value>)t) && isSymbol(car<value>(t))) {
const value n = car<value>(t);
- const value v = isNil(cdr<value>(t))? value() : cadr<value>(t);
+ const value v = isNil(cdr<value>(t))? nilValue : cadr<value>(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<value> valuesToElements(const list<value>& l) {
+inline const list<value> valuesToElements(const list<value>& l) {
if (isNil(l))
return l;
return cons<value>(valueToElement(car(l)), valuesToElements(cdr(l)));
@@ -231,72 +231,51 @@ const list<value> valuesToElements(const list<value>& l) {
* Returns a selector lambda function which can be used to filter
* elements against the given element pattern.
*/
-struct selectorLambda {
- const list<value> select;
- selectorLambda(const list<value>& s) : select(s) {
- }
- const bool evalSelect(const list<value>& s, const list<value> 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<const bool(const value&)> selector(const list<value>& select) {
+ return [select](const value& v) -> const bool {
+ const lambda<const bool(const list<value>&, const list<value>&)> evalSelect = [&evalSelect](const list<value>& s, const list<value>& v) -> const bool {
+ if (isNil(s))
+ return true;
+ if (isNil(v))
+ return false;
+ if (car(s) != car(v))
+ return false;
+ return evalSelect(cdr(s), cdr(v));
+ };
if (!isList(v))
return false;
return evalSelect(select, v);
- }
-};
-
-const lambda<bool(const value&)> selector(const list<value> 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<value>)v) == name;
- }
-};
-
-const value attributeValue(const value& name, const value& l) {
- const list<value> f = filter<value>(filterAttribute(name), list<value>(l));
+inline const value attributeValue(const value& name, const value& l) {
+ const list<value> f = filter<value>([name](const value& v) {
+ return isAttribute(v) && attributeName((list<value>)v) == name;
+ }, list<value>(l));
if (isNil(f))
- return value();
+ return nilValue;
return caddr<value>(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<value>)v) == name;
- }
-};
-
-const value elementChildren(const value& name, const value& l) {
- return filter<value>(filterElement(name), list<value>(l));
+inline const value elementChildren(const value& name, const value& l) {
+ return filter<value>([name](const value& v) {
+ return isElement(v) && elementName((list<value>)v) == name;
+ }, list<value>(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<value> 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<typename V> const bool debugLog(const V& v, const string& msg) {
- gc_scoped_pool p;
+template<typename V> 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<typename V> const bool debugLog(const V& v, const string& msg) {
/**
* Log a debug message and two values.
*/
-template<typename V, typename W> const bool debugLog(const V& v, const W& w, const string& msg) {
- gc_scoped_pool p;
+template<typename V, typename W> 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 <utility>
@@ -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<typename R, typename... P> 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<typename F> class Proxy: public Callable {
+ template<typename F> class Proxy: public Callable<R, P...> {
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>(p)...);
- }
-
- virtual const size_t size() const {
- return sizeof(function);
+ virtual const R operator() (const P&&... p) const noexcept {
+ return function(std::forward<const P&&>(p)...);
}
private:
@@ -123,67 +119,68 @@ template<typename S> class lambda;
template<typename R, typename... P> class lambda<R(P...)> {
public:
- lambda() : callable(0) {
+ inline lambda() noexcept : callable(NULL) {
debug_inc(countLambdas);
debug_inc(countELambdas);
}
- template<typename F> lambda(const F f) {
+ template<typename F> inline lambda(const F f) noexcept : callable(mkproxy<F>(f)) {
debug_inc(countLambdas);
debug_inc(countFLambdas);
+ }
- typedef typename CallableType::template Proxy<F> ProxyType;
- callable = gc_ptr<CallableType>(new (gc_new<ProxyType>()) ProxyType(f));
+ template<typename F> inline lambda(const gc_mutable_ref<F>& r) noexcept : callable(mkproxy<F>(*(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>(p)...);
+ inline const R operator()(const P&... p) const noexcept {
+ return (*callable)(std::forward<const P&&>(p)...);
}
template<typename S> friend ostream& operator<<(ostream&, const lambda<S>&);
- template<typename S> friend const bool isNil(const lambda<S>& l);
+ template<typename S> friend const bool isNil(const lambda<S>& l) noexcept;
private:
typedef Callable<R,P...> CallableType;
- gc_ptr<CallableType> callable;
+ const gc_ptr<CallableType> callable;
+
+ template<typename F> inline gc_ptr<CallableType> mkproxy(const F& f) noexcept {
+ typedef typename CallableType::template Proxy<F> ProxyType;
+ return gc_ptr<CallableType>(new (gc_new<ProxyType>()) ProxyType(f));
+ }
};
-template<typename S> ostream& operator<<(ostream& out, const lambda<S>& l) {
+template<typename S> inline ostream& operator<<(ostream& out, const lambda<S>& l) {
return out << "lambda::" << l.callable;
}
/**
* Return true if a lambda is nil.
*/
-template<typename S> const bool isNil(const lambda<S>& l) {
- return ((void*)l.callable) == 0;
+template<typename S> inline const bool isNil(const lambda<S>& l) noexcept {
+ return (const void*)l.callable == NULL;
}
/**
@@ -191,11 +188,11 @@ template<typename S> const bool isNil(const lambda<S>& l) {
*/
template<typename R, typename T, typename... P> class curried {
public:
- curried(const lambda<R(T, P...)>& f, const T& v): v(v), f(f) {
+ inline curried(const lambda<R(T, P...)>& f, const T& v) noexcept: v(v), f(f) {
}
- const R operator()(P... p) const {
- return f(v, std::forward<P>(p)...);
+ inline const R operator()(const P&... p) const noexcept {
+ return f(v, std::forward<const P&>(p)...);
}
private:
@@ -203,36 +200,29 @@ private:
const lambda<R(T, P...)>f;
};
-template<typename R, typename T, typename... P> const lambda<R(P...)> curry(const lambda<R(T, P...)>& f, const T& t) {
+template<typename R, typename T, typename... P> inline const lambda<const R(P...)> curry(const lambda<R(T, P...)>& f, const T& t) noexcept {
return curried<R, T, P...>(f, t);
}
-template<typename R, typename T, typename U, typename... P> const lambda<R(P...)> curry(const lambda<R(T, U, P...)>& f, const T& t, const U& u) {
+template<typename R, typename T, typename U, typename... P> inline const lambda<R(P...)> curry(const lambda<R(T, U, P...)>& f, const T& t, const U& u) noexcept {
return curry(curry(f, t), u);
}
-template<typename R, typename T, typename U, typename V, typename... P> const lambda<R(P...)> curry(const lambda<R(T, U, V, P...)>& f, const T& t, const U& u, const V& v) {
+template<typename R, typename T, typename U, typename V, typename... P> inline const lambda<R(P...)> curry(const lambda<R(T, U, V, P...)>& 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<typename T> class returnResult {
-public:
- returnResult(const T& v) :
- v(v) {
- }
- const T operator()() const {
- return v;
- }
-private:
- const T v;
-};
-
-template<typename T> const lambda<T()> result(const T& v) {
- return returnResult<T> (v);
+template<typename T> inline const lambda<const T()> result(const T& v) {
+ return [v]()->T { return v; };
}
+/**
+ * Commonly used lambda types.
+ */
+typedef lambda<const bool()> 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<typename T> using gc_ptr = T*;
+
+#else
+
template<typename T> 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<typename T> using gc_mutable_ptr = T*;
+
+#else
+
+template<typename T> 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<apr_pool_t*>(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<typename T> apr_status_t gc_pool_cleanup(void* v) {
+template<typename T> inline apr_status_t gc_pool_cleanup(void* v) {
T* t = (T*)v;
t->~T();
return APR_SUCCESS;
}
-template<typename T> T* gc_new(apr_pool_t* p) {
+template<typename T> 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<T>, apr_pool_cleanup_null) ;
return (T*)(gc_new_ptr);
}
-template<typename T> T* gc_new(const gc_pool& p) {
+template<typename T> inline T* const gc_new(const gc_pool& p) noexcept {
return gc_new<T>(pool(p));
}
-template<typename T> T* gc_new() {
+template<typename T> inline T* const gc_new() noexcept {
return gc_new<T>(gc_current_pool());
}
-template<typename T> apr_status_t gc_pool_acleanup(void* v) {
- size_t* m = static_cast<size_t*>(v);
+template<typename T> 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<typename T> apr_status_t gc_pool_acleanup(void* v) {
return APR_SUCCESS;
}
-template<typename T> T* gc_anew(apr_pool_t* p, size_t n) {
- size_t* gc_anew_ptr = static_cast<size_t*>(apr_palloc(p, sizeof(size_t) + sizeof(T) * n));
+template<typename T> 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<T>, apr_pool_cleanup_null) ;
return (T*)(gc_anew_ptr + 1);
}
-template<typename T> T* gc_anew(const gc_pool& p, size_t n) {
+template<typename T> inline T* const gc_anew(const gc_pool& p, const size_t n) noexcept {
return gc_anew<T>(pool(p), n);
}
-template<typename T> T* gc_anew(size_t n) {
+template<typename T> inline T* const gc_anew(const size_t n) noexcept {
return gc_anew<T>(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<char*>(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<typename T> class gc_mutable_ref {
+public:
+ inline gc_mutable_ref() noexcept : ptr(new (gc_new<T>()) 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>()) 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>()) 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<size_t*>(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<size_t*>(ptr) - 1);
- size_t* rptr = static_cast<size_t*>(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<char*>(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<size_t*>(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<size_t*>(ptr) - 1);
- size_t* rptr = static_cast<size_t*>(mremap(static_cast<size_t*>(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<size_t*>(ptr) - 1);
- munmap(static_cast<size_t*>(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<bool()> crc32 = crc32hashTest(key);
- cout << "crc32hash test " << time(crc32, 5, count) << " ms" << endl;
- const lambda<bool()> times33 = times33hashTest(key);
- cout << "times33hash test " << time(times33, 5, count) << " ms" << endl;
- const lambda<bool()> murmur = murmurhashTest(key);
- cout << "murmurhash test " << time(murmur, 5, count) << " ms" << endl;
- const lambda<bool()> 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 <rse@engelschall.com>
*/
-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 <functional>
#include <assert.h>
#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<int> y = &x;
+ int z = *y + *y;
+ z = z + 1;
+ }
+ return true;
+}
+
+const bool testPtrPerf() {
+ {
+ const gc_scoped_pool gcp;
+ const blambda pp = ptrPerf;
+ cout << "Pointer test " << (time(pp, 5, 10000) / 10000) << " ms" << endl;
+ }
+ {
+ const gc_scoped_pool gcp;
+ const blambda gpp = gcptrPerf;
+ cout << "GC Pointer test " << (time(gpp, 5, 10000) / 10000) << " ms" << endl;
+ }
+ return true;
+}
+
+class incFunctor {
+public:
+ incFunctor(const int i) :
i(i) {
}
const int operator()(const int x) const {
return x + i;
}
+private:
+ const int i;
};
const int square(const int x) {
return x * x;
}
-int mapLambda(lambda<int(const int)> f, int v) {
+const int mapLambda(lambda<const int(const int)> f, int v) {
return f(v);
}
-bool testLambda() {
- const lambda<int(const int)> sq(square);
+const lambda<const int(const int)> mksquare() {
+ return square;
+}
+
+const bool testSizes() {
+ const gc_ptr<int> p(NULL);
+ cout << "sizeof gc_ptr " << sizeof(p) << endl;
+ const lambda<const int(const int)> sq(square);
+ cout << "sizeof C function lambda " << sizeof(sq) << endl;
+ const lambda<const int(const int)> incl(incFunctor(10));
+ cout << "sizeof functor lambda " << sizeof(incl) << endl;
+ const std::function<int(const int)> sqf(square);
+ cout << "sizeof C function std::function " << sizeof(sqf) << endl;
+ const std::function<int(const int)> incf(incFunctor(10));
+ cout << "sizeof functor std::function " << sizeof(incf) << endl;
+ const string s("abcd");
+ cout << "sizeof string " << sizeof(s) << endl;
+ const string v(s);
+ cout << "sizeof val " << sizeof(v) << endl;
+ const list<int> li = cons<int>(2, mklist<int>(3, 4));
+ cout << "sizeof list<int> " << sizeof(li) << endl;
+ const list<string> ls = cons<string>("a", mklist<string>("b", "c"));
+ cout << "sizeof list<string> " << sizeof(ls) << endl;
+ const list<value> lv = cons<value>("a", mklist<value>("b", "c"));
+ cout << "sizeof list<value> " << sizeof(lv) << endl;
+ return true;
+}
+
+const bool testLambda() {
+ const lambda<const int(const int)> sq(square);
assert(sq(2) == 4);
+
+ const lambda<const lambda<const int(const int)>()> mksq(mksquare);
+ assert(mksq()(2) == 4);
+
assert(mapLambda(sq, 2) == 4);
assert(mapLambda(square, 2) == 4);
- const lambda<int(const int)> incf(inc(10));
+ const lambda<const int(const int)> 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<const int(const int)> incl(incl11);
+ assert(incl(1) == 11);
+ assert(mapLambda(incl, 1) == 11);
+ assert(mapLambda(incl11, 1) == 11);
+
+ const lambda<const int(const int)> il(incf);
+ assert(il(1) == 11);
+ const lambda<const int(const int)> sl(square);
+ assert(sl(2) == 4);
+ return true;
+}
+
+int constructCopiable = 0;
+int copyCopiable = 0;
+
+class Copiable {
+public:
+ Copiable() {
+ assert(false);
+ }
+
+ Copiable(const string& s) : s(s) {
+ constructCopiable++;
+ }
+
+ Copiable(const Copiable& c) : s(c.s) {
+ copyCopiable++;
+ }
+
+ Copiable& operator=(const Copiable& c) = delete;
+
+ ~Copiable() {
+ }
+
+ void doit() const {
+ }
+
+private:
+ const string s;
+};
+
+bool testLambdaRef(const Copiable& c) {
+ [&c] { c.doit(); }();
+ return true;
+}
+
+bool testLambdaCopy(const Copiable& c) {
+ [c] { c.doit(); }();
+ return true;
+}
+
+const bool testCopiable() {
+ const Copiable ac = Copiable("assigned");
+ ac.doit();
+ assert(constructCopiable = 1);
+ assert(copyCopiable = 1);
+
+ const Copiable ac2 = []{ return Copiable("returned"); }();
+ ac2.doit();
+ assert(constructCopiable = 2);
+ assert(copyCopiable = 2);
+
+ const Copiable rc = Copiable("captured by ref");
+ testLambdaRef(rc);
+ assert(constructCopiable = 3);
+ assert(copyCopiable = 3);
+
+ const Copiable cc = Copiable("captured by value");
+ testLambdaCopy(cc);
+ assert(constructCopiable = 4);
+ assert(copyCopiable = 5);
- lambda<int(const int)> l;
- l = incf;
- assert(l(1) == 11);
- l = square;
- assert(l(2) == 4);
return true;
}
-bool testLambdaGC() {
+const bool testMutable() {
+ {
+ gc_mutable_ref<string> s = string("aaa");
+ s = "bbb";
+ assert(s == "bbb");
+ }
+ {
+ gc_mutable_ref<string> s;
+ assert(s == "");
+ s = "bbb";
+ assert(s == "bbb");
+ }
+ {
+ gc_mutable_ref<value> v;
+ assert(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<const int(const sint)> mult2 = curry((lambda<const int(const sint, const sint)>)mult, sint(2));
+ assert(6 == mult2(sint(3)));
+ return true;
+}
+
+const bool curryPerf() {
+ const sint a(2);
+ const sint b(3);
+ const lambda<const int(const sint)> mult2 = curry((lambda<const int(const sint, const sint)>)mult, a);
+ for(int i = 0; i < 1000; i++)
+ mult2(b);
+ return true;
+}
+
+class multFunctor {
+public:
+ multFunctor(const sint& a) : a(a) {
+ }
+ const int operator()(const sint& b) const {
+ return a.i * b.i;
+ }
+private:
+ const sint a;
+};
+
+const bool testFunctor() {
+ const lambda<const int(const sint)> mult2 = multFunctor(sint(2));
+ assert(6 == mult2(sint(3)));
+ return true;
+}
+
+const bool functorPerf() {
+ const sint a(2);
+ const sint b(3);
+ const lambda<const int(const sint)> mult2 = lambda<const int(const sint)>(multFunctor(a));
+ for(int i = 0; i < 1000; i++)
+ mult2(b);
+ return true;
+}
+
+const bool test11Lambda() {
+ const sint a(2);
+ assert(6 == [a](const sint& b) { return a.i * b.i; } (sint(3)));
+ return true;
+}
+
+const lambda<const sint(const sint)> multlambda11(const sint& a) {
+ return [a](const sint& b) { return a.i * b.i; };
+}
+
+const bool lambda11Perf() {
+ const sint a(2);
+ const sint b(3);
+ const lambda<const sint(const sint)> mult2 = multlambda11(a);
+ for(int i = 0; i < 1000; i++)
+ mult2(b);
+ return true;
+}
+
+const std::function<sint(const sint&)> multfunction11(const sint& a) {
+ return [a](const sint& b) { return a.i * b.i; };
+}
+
+const bool function11Perf() {
+ const sint a(2);
+ const sint b(3);
+ const std::function<sint(const sint&)> mult2 = multfunction11(a);
+ for(int i = 0; i < 1000; i++)
+ mult2(b);
+ return true;
+}
+
+const bool testFuncPerf() {
+ {
+ const gc_scoped_pool gcp;
+ const blambda cp = curryPerf;
+ cout << "Curry test " << (time(cp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ {
+ const gc_scoped_pool gcp;
+ const blambda fp = functorPerf;
+ cout << "Functor test " << (time(fp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ {
+ const gc_scoped_pool gcp;
+ const blambda lp = lambda11Perf;
+ cout << "Lambda11 test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ {
+ const gc_scoped_pool gcp;
+ const blambda lp = function11Perf;
+ cout << "Function11 test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ return true;
+}
+int countElements = 0;
+
+class Element {
+public:
Element() : i(0) {
countElements++;
}
@@ -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<typename T> const list<T> listPerf(const T& v, const long int i) {
+ if (i == 0)
+ return list<T>();
+ return cons<T>(v, listPerf<T>(v, i -1));
+}
+
+const bool testListPerf() {
+ {
+ const gc_scoped_pool gcp;
+ const blambda lp = []() -> const bool {
+ listPerf<int>(0, 1000);
+ return true;
+ };
+ cout << "List<int> test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ {
+ const gc_scoped_pool gcp;
+ const blambda lp = []() -> const bool {
+ listPerf<string>(string("x"), 1000);
+ return true;
+ };
+ cout << "List<string> test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ {
+ const gc_scoped_pool gcp;
+ const blambda lp = []() -> const bool {
+ listPerf<string>(value("x"), 1000);
+ return true;
+ };
+ cout << "List<value> test " << (time(lp, 5, 1000) / 1000) << " ms" << endl;
+ }
+ return true;
+}
+
+const bool testOut() {
ostringstream os1;
os1 << list<int> ();
assert(str(os1) == "()");
@@ -147,7 +451,7 @@ bool testOut() {
return true;
}
-bool testEquals() {
+const bool testEquals() {
assert(list<int>() == list<int>());
assert(mklist(1, 2) == mklist(1, 2));
assert(list<int>() != mklist(1, 2));
@@ -156,14 +460,14 @@ bool testEquals() {
return true;
}
-bool testLength() {
+const bool testLength() {
assert(0 == length(list<int>()));
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<Complex> 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<int, int>(square, list<int>())));
const list<int> m = map<int, int>(square, mklist(2, 3));
@@ -209,26 +515,26 @@ const int add(const int x, const int y) {
return x + y;
}
-bool testReduce() {
- const lambda<int(const int, const int)> r(add);
+const bool testReduce() {
+ const lambda<const int(const int, const int)> 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<int>(isPositive, mklist(1, -1, 2, -2))) == 1);
assert(cadr(filter<int>(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<int>())));
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<list<string> > l = mklist(mklist<string>("x", "X"), mklist<string>("a", "A"), mklist<string>("y", "Y"), mklist<string>("a", "AA"));
assert(assoc<string>("a", l) == mklist<string>("a", "A"));
assert(isNil(assoc<string>("z", l)));
@@ -261,10 +567,13 @@ bool testAssoc() {
const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
assert(assoc<value>("a", v) == mklist<value>("a", "A"));
+
+ const list<value> v2 = mklist<value>(mklist<value>("x", "X"), "a", mklist<value>("a", "A"), mklist<value>("y", "Y"), mklist<value>("a", "AA"));
+ assert(assoc<value>("a", v2) == mklist<value>("a", "A"));
return true;
}
-bool testZip() {
+const bool testZip() {
const list<string> k = mklist<string>("x", "a", "y", "a");
const list<string> v = mklist<string>("X", "A", "Y", "AA");
const list<list<string> > z = mklist(k, v);
@@ -274,7 +583,7 @@ bool testZip() {
return true;
}
-bool testTokenize() {
+const bool testTokenize() {
assert(tokenize("/", "") == list<string>());
assert(tokenize("/", "aaa") == mklist<string>("aaa"));
assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist<string>("aaa", "bbb", "ccc", "ddd"));
@@ -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<value> x) {
+const value valueSquare(const list<value>& 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<value(const list<value>&)> vl(valueSquare);
- assert(value(vl) == value(vl));
+ lvvlambda vl(valueSquare);
+ //assert(value(vl) == value(vl));
assert(value(mklist<value>(1, 2)) == value(mklist<value>(1, 2)));
const list<value> v = mklist<value>(mklist<value>("x", "X"), mklist<value>("a", "A"), mklist<value>("y", "Y"));
@@ -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<value> t = mktree<value>("a", list<value>(), list<value>());
+const bool testTree() {
+ const list<value> t = mktree<value>("a", nilListValue, nilListValue);
const list<value> ct = constree<value>("d", constree<value>("f", constree<value>("c", constree<value>("e", constree<value>("b", t)))));
const list<value> mt = mktree(mklist<value>("d", "f", "c", "e", "b", "a"));
assert(mt == ct);
@@ -371,8 +680,8 @@ const list<value> lta(const string& x) {
return mklist<value>(c_str(x), c_str(x + x));
}
-bool testTreeAssoc() {
- const list<value> t = mktree<value>(lta("a"), list<value>(), list<value>());
+const bool testTreeAssoc() {
+ const list<value> t = mktree<value>(lta("a"), nilListValue, nilListValue);
const list<value> at = constree<value>(lta("d"), constree<value>(lta("f"), constree<value>(lta("c"), constree<value>(lta("e"), constree<value>(lta("b"), t)))));
const list<value> l = flatten<value>(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<double> s = seq(0.0, 999.0);
- list<double> r = map<double, double>(fib, s);
- assert(1000 == length(r));
- return true;
- }
-};
-
-struct nestedFibMapPerf {
- const lambda<double(const double)> fib;
- nestedFibMapPerf(const lambda<double(const double)>& fib) : fib(fib) {
- }
- const bool operator()() const {
- list<double> s = seq(0.0, 999.0);
- list<double> r = map<double, double>(fib, s);
- assert(1000 == length(r));
- return true;
- }
-};
+const bool fibMapPerf() {
+ const list<double> s = seq(0.0, 999.0);
+ const list<double> r = map<double, double>(fib, s);
+ assert(1000 == length(r));
+ return true;
+}
-bool testCppPerf() {
+const bool testCppPerf() {
{
- const lambda<bool()> 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<const double(const double n)> fib = [](const double n) -> const double {
+ const lambda<const double(const double, const double, const double)> fib_aux = [&fib_aux](double n, double a, double b) -> const double {
+ if(n == 0.0)
+ return a;
+ return fib_aux(n - 1.0, b, a + b);
+ };
+ return fib_aux(n, 0.0, 1.0);
};
- const lambda<bool()> nfml = nestedFibMapPerf(lambda<double(const double)>(nested::fib));
+ const blambda nfml = [fib]() -> const bool {
+ const list<double> s = seq(0.0, 999.0);
+ const list<double> r = map<double, double>(fib, s);
+ assert(1000 == length(r));
+ return true;
+ };
cout << "Nested Fibonacci map test " << (time(nfml, 1, 1) / 1000) << " ms" << endl;
}
return true;
@@ -456,7 +753,7 @@ const id<int> idH(const int v) {
return idF(v) >> idG;
}
-bool testIdMonad() {
+const bool testIdMonad() {
const id<int> m(2);
assert(m >> idF == idF(2));
assert(m >> unit<int>() == m);
@@ -476,7 +773,7 @@ const maybe<int> maybeH(const int v) {
return maybeF(v) >> maybeG;
}
-bool testMaybeMonad() {
+const bool testMaybeMonad() {
const maybe<int> m(2);
assert(m >> maybeF == maybeF(2));
assert((m >> just<int>()) == m);
@@ -498,7 +795,7 @@ const failable<int> failableH(const int v) {
return failableF(v) >> failableG;
}
-bool testFailableMonad() {
+const bool testFailableMonad() {
const failable<int> m(2);
assert(m >> failableF == failableF(2));
assert((m >> success<int, string, int>()) == m);
@@ -515,23 +812,16 @@ bool testFailableMonad() {
assert(rcode(vooops) == 500);
const value v = value(vooops);
- assert(car<value>(v) == value());
+ assert(car<value>(v) == nilValue);
assert(cadr<value>(v) == string("test"));
assert(caddr<value>(v) == value((double)500));
return true;
}
-struct tickInc {
- const double v;
- tickInc(const double v) : v(v) {
- }
- const scp<int, double> operator()(int s) const {
- return scp<int, double>(s + 1, v);
- }
-};
-
const state<int, double> tick(const double v) {
- return transformer<int, double>(tickInc(v));
+ return transformer<int, double>([v](const int s) {
+ return scp<int, double>(s + 1, v);
+ });
}
const state<int, double> stateF(const double v) {
@@ -546,8 +836,8 @@ const state<int, double> stateH(const double v) {
return stateF(v) >> stateG;
}
-bool testStateMonad() {
- const lambda<state<int, double>(const double)> r(result<int, double>);
+const bool testStateMonad() {
+ const lambda<const state<int, double>(const double)> r(result<int, double>);
state<int, double> m = result<int, double>(2.0);
assert((m >> stateF)(0) == stateF(2.0)(0));
@@ -558,30 +848,40 @@ bool testStateMonad() {
return true;
}
-bool testDynLib() {
+const bool testDynLib() {
const lib dl(string("./libdynlib-test") + dynlibExt);
- const failable<lambda<int(const int)> > sq(dynlambda<int(const int)>("csquare", dl));
+ const failable<lambda<const int(const int)> > sq(dynlambda<const int(const int)>("csquare", dl));
assert(hasContent(sq));
- lambda<int(const int)> l(content(sq));
+ lambda<const int(const int)> l(content(sq));
assert(l(2) == 4);
- const failable<lambda<lambda<int(const int)>()> > sql(dynlambda<lambda<int(const int)>()>("csquarel", dl));
+ const failable<lambda<const lambda<const int(const int)>()> > sql(dynlambda<const lambda<const int(const int)>()>("csquarel", dl));
assert(hasContent(sql));
- lambda<lambda<int(const int)>()> ll(content(sql));
+ lambda<const lambda<const int(const int)>()> 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<const int(const int)> 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<const int(const int)> f, int v) {
+const int mapLambda(const lambda<const int(const int)> f, int v) {
return f(v);
}
-bool testLambda() {
+const bool testLambda() {
const lambda<const int(const int)> 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<int(int)> incf = inc(10);
+ const lambda<const int(const int)> incf = inc(10);
assert(incf(1) == 11);
assert(mapLambda(incf, 1) == 11);
assert(mapLambda(inc(10), 1) == 11);
- lambda<const int(const int)> l;
- l = incf;
- assert(l(1) == 11);
- l = square;
- assert(l(2) == 4);
+ const lambda<const int(const int)> il(incf);
+ assert(il(1) == 11);
+ const lambda<const int(const int)> sl(square);
+ assert(sl(2) == 4);
return true;
}
@@ -72,13 +71,13 @@ const double fib_aux(const double n, const double a, const double b) {
}
const bool fibMapPerf() {
- list<double> s = seq(0.0, 4999.0);
- list<double> r = map<double, double>([](const double n)->const double { return fib_aux(n, 0.0, 1.0); }, s);
+ const list<double> s = seq(0.0, 4999.0);
+ const list<double> r = map<double, double>([](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<typename T> class list {
public:
- list() {
+ inline list() : car() {
debug_inc(countLists);
debug_inc(countELists);
debug_watchList();
}
- list(const T car, const lambda<list<T>()>& cdr) : car(car), cdr(cdr) {
+ inline list(const T& car, const lambda<list<T>()>& cdr) : car(car), cdr(cdr) {
debug_inc(countLists);
debug_inc(countILists);
debug_watchList();
}
- list(const list& p) : car(p.car), cdr(p.cdr) {
+ 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<T>& operator=(const list<T>& p) {
- if(this == &p)
- return *this;
- car = p.car;
- cdr = p.cdr;
-#ifdef WANT_MAINTAINER_WATCH
- watch = p.watch;
-#endif
- return *this;
- }
+ list<T>& operator=(const list<T>& p) = delete;
- ~list() {
+ inline ~list() {
debug_dec(countLists);
}
- const bool operator==(const list<T>& p) const {
+ inline const bool operator==(const list<T>& p) const {
if(this == &p)
return true;
if(isNil(cdr))
@@ -140,7 +131,7 @@ public:
return cdr() == p.cdr();
}
- const bool operator<(const list<T>& p) const {
+ inline const bool operator<(const list<T>& p) const {
if(this == &p)
return false;
if (isNil(cdr))
@@ -154,7 +145,7 @@ public:
return cdr() < p.cdr();
}
- const bool operator>(const list<T>& p) const {
+ inline const bool operator>(const list<T>& p) const {
if(this == &p)
return false;
if (isNil(cdr))
@@ -168,11 +159,11 @@ public:
return cdr() > p.cdr();
}
- const bool operator!=(const list<T>& p) const {
+ inline const bool operator!=(const list<T>& p) const {
return !this->operator==(p);
}
- operator const list<list<T> >() const {
+ inline operator const list<list<T> >() const {
return (list<list<T> >)T(*this);
}
@@ -185,9 +176,10 @@ private:
template<typename X> friend const bool isNil(const list<X>& p);
template<typename X> friend const X car(const list<X>& p);
template<typename X> friend const list<X> cdr(const list<X>& p);
+ template<typename X> friend const bool setlist(list<X>& target, const list<X>& l);
- T car;
- lambda<list<T>()> cdr;
+ const T car;
+ const lambda<list<T>()> 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<typename T> const string watchList(const list<T>& p) {
+template<typename T> inline const string watchList(const list<T>& p) {
if(isNil(p))
return "()";
odebugstream os;
@@ -209,21 +201,21 @@ template<typename T> const string watchList(const list<T>& p) {
/**
* Returns true if the given list is nil.
*/
-template<typename T> const bool isNil(const list<T>& p) {
+template<typename T> inline const bool isNil(const list<T>& p) {
return isNil(p.cdr);
}
/**
* Write a list to an output stream.
*/
-template<typename T> ostream& writeHelper(ostream& out, const list<T>& l) {
+template<typename T> inline ostream& writeHelper(ostream& out, const list<T>& l) {
if (isNil(l))
return out;
out << " " << car(l);
return writeHelper(out, cdr(l));
}
-template<typename T> ostream& operator<<(ostream& out, const list<T>& l) {
+template<typename T> inline ostream& operator<<(ostream& out, const list<T>& l) {
if(isNil(l))
return out << "()";
out << "(" << car(l);
@@ -234,74 +226,74 @@ template<typename T> ostream& operator<<(ostream& out, const list<T>& l) {
/**
* Construct a (lazy) list from a value and a lambda function that returns the cdr.
*/
-template<typename T> const list<T> cons(const T& car, const lambda<list<T>()>& cdr) {
+template<typename T> inline const list<T> cons(const T& car, const lambda<const list<T>()>& cdr) {
return list<T> (car, cdr);
}
/**
* Construct a list from a value and a cdr list.
*/
-template<typename T> const list<T> cons(const T& car, const list<T>& cdr) {
+template<typename T> inline const list<T> cons(const T& car, const list<T>& cdr) {
return list<T> (car, result(cdr));
}
/**
* Cons variations for use with the reduce and reduceRight functions.
*/
-template<typename T> const list<T> lcons(const list<T>& cdr, const T& car) {
+template<typename T> inline const list<T> lcons(const list<T>& cdr, const T& car) {
return cons<T>(car, cdr);
}
-template<typename T> const list<T> rcons(const T& car, const list<T>& cdr) {
+template<typename T> inline const list<T> rcons(const T& car, const list<T>& cdr) {
return cons<T>(car, cdr);
}
/**
* Construct a list of one value.
*/
-template<typename T> const list<T> mklist(const T& car) {
+template<typename T> inline const list<T> mklist(const T& car) {
return list<T> (car, result(list<T> ()));
}
/**
* Construct a list of two values.
*/
-template<typename T> const list<T> mklist(const T& a, const T& b) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b) {
return cons(a, mklist(b));
}
/**
* Construct a list of three values.
*/
-template<typename T> const list<T> mklist(const T& a, const T& b, const T& c) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c) {
return cons(a, cons(b, mklist(c)));
}
/**
* Construct a list of four values.
*/
-template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d) {
return cons(a, cons(b, cons(c, mklist(d))));
}
/**
* Construct a list of five values.
*/
-template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e) {
return cons(a, cons(b, cons(c, cons(d, mklist(e)))));
}
/**
* Construct a list of six values.
*/
-template<typename T> const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) {
+template<typename T> inline const list<T> mklist(const T& a, const T& b, const T& c, const T& d, const T& e, const T& f) {
return cons(a, cons(b, cons(c, cons(d, cons(e, mklist(f))))));
}
/**
* Returns the car of a list.
*/
-template<typename T> const T car(const list<T>& p) {
+template<typename T> inline const T car(const list<T>& p) {
// Abort if trying to access the car of a nil list
assertOrFail(!isNil(p.cdr));
return p.car;
@@ -310,159 +302,144 @@ template<typename T> const T car(const list<T>& p) {
/**
* Returns the cdr of a list.
*/
-template<typename T> const list<T> cdr(const list<T>& p) {
+template<typename T> inline const list<T> cdr(const list<T>& p) {
return p.cdr();
}
/**
* Returns the car of the cdr (the 2nd element) of a list.
*/
-template<typename T> const T cadr(const list<T>& p) {
+template<typename T> inline const T cadr(const list<T>& p) {
return car(cdr(p));
}
/**
* Returns the 3rd element of a list.
*/
-template<typename T> const T caddr(const list<T>& p) {
+template<typename T> inline const T caddr(const list<T>& p) {
return car(cdr(cdr(p)));
}
/**
* Returns the 4th element of a list.
*/
-template<typename T> const T cadddr(const list<T>& p) {
+template<typename T> inline const T cadddr(const list<T>& p) {
return car(cdr(cdr(cdr(p))));
}
/**
* Returns the 5th element of a list.
*/
-template<typename T> const T caddddr(const list<T>& p) {
+template<typename T> inline const T caddddr(const list<T>& p) {
return car(cdr(cdr(cdr(cdr(p)))));
}
/**
* Returns the 6th element of a list.
*/
-template<typename T> const T cadddddr(const list<T>& p) {
+template<typename T> inline const T cadddddr(const list<T>& p) {
return car(cdr(cdr(cdr(cdr(cdr(p))))));
}
/**
* Returns the 7th element of a list.
*/
-template<typename T> const T caddddddr(const list<T>& p) {
+template<typename T> inline const T caddddddr(const list<T>& p) {
return car(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
}
/**
* Returns the 8th element of a list.
*/
-template<typename T> const T cadddddddr(const list<T>& p) {
+template<typename T> inline const T cadddddddr(const list<T>& 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<typename T> const list<T> cddr(const list<T>& p) {
+template<typename T> inline const list<T> cddr(const list<T>& p) {
return cdr(cdr(p));
}
/**
* Returns a list of elements from the 4th to the end of a list.
*/
-template<typename T> const list<T> cdddr(const list<T>& p) {
+template<typename T> inline const list<T> cdddr(const list<T>& p) {
return cdr(cdr(cdr(p)));
}
/**
* Returns a list of elements from the 5th to the end of a list.
*/
-template<typename T> const list<T> cddddr(const list<T>& p) {
+template<typename T> inline const list<T> cddddr(const list<T>& p) {
return cdr(cdr(cdr(cdr(p))));
}
/**
* Returns a list of elements from the 6th to the end of a list.
*/
-template<typename T> const list<T> cdddddr(const list<T>& p) {
+template<typename T> inline const list<T> cdddddr(const list<T>& p) {
return cdr(cdr(cdr(cdr(cdr(p)))));
}
/**
* Returns a list of elements from the 7th to the end of a list.
*/
-template<typename T> const list<T> cddddddr(const list<T>& p) {
+template<typename T> inline const list<T> cddddddr(const list<T>& p) {
return cdr(cdr(cdr(cdr(cdr(cdr(p))))));
}
/**
* Returns a list of elements from the 8th to the end of a list.
*/
-template<typename T> const list<T> cdddddddr(const list<T>& p) {
+template<typename T> inline const list<T> cdddddddr(const list<T>& p) {
return cdr(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
}
/**
* Returns the length of a list.
*/
-template<typename T> struct lengthRef {
- const size_t operator()(const size_t c, const list<T>& p) {
+template<typename T> inline const size_t length(const list<T>& p) {
+ const lambda<size_t(const size_t, const list<T>&)> lengthRef = [&lengthRef](const size_t c, const list<T>& p) -> const size_t {
if(isNil(p))
return c;
- return (*this)(c + 1, cdr(p));
- }
-};
-
-template<typename T> const size_t length(const list<T>& p) {
- return lengthRef<T> ()(0, p);
+ return lengthRef(c + 1, cdr(p));
+ };
+ return lengthRef(0, p);
}
/**
* Appends a list and a lambda function returning a list.
*/
-template<typename T> struct appendCdr {
- const list<T> a;
- const lambda<list<T>()> fb;
- appendCdr(const list<T>& a, const lambda<list<T>()>& fb) :
- a(a), fb(fb) {
- }
- const list<T> operator()() const {
- return append(a, fb);
- }
-};
-
-template<typename T> const list<T> append(const list<T>&a, const lambda<list<T>()>& fb) {
+template<typename T> inline const list<T> append(const list<T>&a, const lambda<const list<T>()>& fb) {
if(isNil(a))
return fb();
-
- return cons<T>(car(a), appendCdr<T> (cdr(a), fb));
+ return cons<T>(car(a), [a, fb]() { return append(cdr(a), fb); });
}
/**
* Appends two lists.
*/
-template<typename T> const list<T> append(const list<T>&a, const list<T>& b) {
+template<typename T> inline const list<T> append(const list<T>&a, const list<T>& b) {
return append(a, result(b));
}
/**
* Append a value to a list.
*/
-template<typename T> const list<T> operator+(const list<T>& l, const T& v) {
+template<typename T> inline const list<T> operator+(const list<T>& l, const T& v) {
return append(l, mklist(v));
}
-template<typename T, typename V> const list<T> operator+(const list<T>& l, const V& v) {
+template<typename T, typename V> const list<T> inline operator+(const list<T>& l, const V& v) {
return append(l, mklist<T>(v));
}
/**
* Map a lambda function on a list.
*/
-template<typename T, typename R> const list<R> map(const lambda<R(const T)>& f, const list<T>& p) {
+template<typename T, typename R> inline const list<R> map(const lambda<const R(const T)>& f, const list<T>& p) {
if(isNil(p))
return list<R> ();
return cons(f(car(p)), map(f, cdr(p)));
@@ -471,46 +448,32 @@ template<typename T, typename R> const list<R> map(const lambda<R(const T)>& f,
/**
* Run a reduce lambda function on a list.
*/
-template<typename T, typename R> struct reduceAccumulate {
- const lambda<R(const R&, const T&)> f;
- reduceAccumulate(const lambda<R(const R, const T)>& f) :
- f(f) {
- }
- R operator()(const R& acc, const list<T>& p) const {
+template<typename T, typename R> inline const R reduce(const lambda<const R(const R, const T)>& f, const R& initial, const list<T>& p) {
+ const lambda<const R(const R&, const list<T>&p)> reduceAccumulate = [f, &reduceAccumulate](const R& acc, const list<T>& p) -> R {
if(isNil(p))
return acc;
- return (*this)(f(acc, car(p)), cdr(p));
- }
-};
-
-template<typename T, typename R> const R reduce(const lambda<R(const R, const T)>& f, const R& initial, const list<T>& p) {
- return reduceAccumulate<T, R> (f)(initial, p);
+ return reduceAccumulate(f(acc, car(p)), cdr(p));
+ };
+ return reduceAccumulate(initial, p);
}
-template<typename T, typename R> struct reduceRightAccumulate {
- const lambda<R(const T&, const R&)> f;
- reduceRightAccumulate(const lambda<R(const T, const R)>& f) :
- f(f) {
- }
- R operator()(const list<T>& p, const R& acc) const {
+template<typename T, typename R> inline const R reduceRight(const lambda<const R(const T, const R)>& f, const R& initial, const list<T>& p) {
+ const lambda<const R(const list<T>&p, const R&)> reduceRightAccumulate = [f, &reduceRightAccumulate](const list<T>& p, const R& acc) -> R {
if(isNil(p))
return acc;
- return (*this)(cdr(p), f(car(p), acc));
- }
-};
-
-template<typename T, typename R> const R reduceRight(const lambda<R(const T, const R)>& f, const R& initial, const list<T>& p) {
- return reduceRightAccumulate<T, R> (f)(p, initial);
+ return reduceRightAccumulate(cdr(p), f(car(p), acc));
+ };
+ return reduceRightAccumulate(p, initial);
}
/**
* Run a filter lambda function on a list.
*/
-template<typename T> const list<T> filter(const lambda<bool(const T)>& f, const list<T>& p) {
+template<typename T> inline const list<T> filter(const lambda<const bool(const T)>& f, const list<T>& p) {
if(isNil(p))
return list<T> ();
if(f(car(p))) {
- const lambda<list<T>(const lambda<bool(const T)>, const list<T>)> ff(filter<T>);
+ const lambda<const list<T>(const lambda<const bool(const T)>, const list<T>)> ff(filter<T>);
return cons(car(p), curry(ff, f, cdr(p)));
}
return filter(f, cdr(p));
@@ -519,7 +482,7 @@ template<typename T> const list<T> filter(const lambda<bool(const T)>& f, const
/**
* Returns a list pointing to a member of a list.
*/
-template<typename T> const list<T> member(const T& t, const list<T>& p) {
+template<typename T> inline const list<T> member(const T& t, const list<T>& p) {
if(isNil(p))
return list<T> ();
if(t == car(p))
@@ -530,44 +493,31 @@ template<typename T> const list<T> member(const T& t, const list<T>& p) {
/**
* Reverse a list.
*/
-template<typename T> const list<T> reverseIter(const list<T>& acc, const list<T>& p) {
+template<typename T> inline const list<T> reverseIter(const list<T>& acc, const list<T>& p) {
if(isNil(p))
return acc;
return reverseIter(cons(car(p), acc), cdr(p));
}
-template<typename T> const list<T> reverse(const list<T>& p) {
+template<typename T> inline const list<T> reverse(const list<T>& p) {
return reverseIter(list<T> (), p);
}
-template<typename T> const list<T> seq(const T& start, const T& end);
-
-template<typename T> struct seqGenerate {
- const T start;
- const T end;
- seqGenerate(const T& start, const T&end) :
- start(start), end(end) {
- }
- const list<T> operator()() const {
- return seq<T> (start, end);
- }
-};
-
/**
* Returns a sequence of values between the given bounds.
*/
-template<typename T> const list<T> seq(const T& start, const T& end) {
+template<typename T> inline const list<T> seq(const T& start, const T& end) {
if(start == end)
return mklist(start);
if(start < end)
- return cons<T>(start, seqGenerate<T> (start + 1, end));
- return cons<T>(start, seqGenerate<T> (start - 1, end));
+ return cons<T>(start, [start, end] { return seq<T> (start + 1, end); });
+ return cons<T>(start, [start, end] { return seq<T> (start - 1, end); });
}
/**
* Returns the i-th element of a list.
*/
-template<typename T> const T listRef(const list<T>& l, const size_t i) {
+template<typename T> inline const T listRef(const list<T>& l, const size_t i) {
if (i == 0)
return car(l);
return listRef(cdr(l), i - 1);
@@ -576,7 +526,7 @@ template<typename T> const T listRef(const list<T>& l, const size_t i) {
/**
* Returns the first pair matching a key from a list of key value pairs.
*/
-template<typename T> const list<T> assoc(const T& k, const list<list<T> >& p) {
+template<typename T> inline const list<T> assoc(const T& k, const list<list<T> >& p) {
if(isNil(p))
return list<T> ();
if(k == car(car(p)))
@@ -587,7 +537,7 @@ template<typename T> const list<T> assoc(const T& k, const list<list<T> >& p) {
/**
* Returns a list of lists containing elements from two input lists.
*/
-template<typename T> const list<list<T> > zip(const list<T>& a, const list<T>& b) {
+template<typename T> inline const list<list<T> > zip(const list<T>& a, const list<T>& b) {
if (isNil(a) || isNil(b))
return list<list<T> >();
return cons<list<T> >(mklist<T>(car(a), car(b)), zip(cdr(a), cdr(b)));
@@ -596,19 +546,19 @@ template<typename T> const list<list<T> > zip(const list<T>& a, const list<T>& b
/**
* Converts a list of key value pairs to a list containing the list of keys and the list of values.
*/
-template<typename T> const list<T> unzipKeys(const list<list<T> >& l) {
+template<typename T> inline const list<T> unzipKeys(const list<list<T> >& l) {
if (isNil(l))
return list<T>();
return cons(car(car(l)), unzipKeys(cdr(l)));
}
-template<typename T> const list<T> unzipValues(const list<list<T> >& l) {
+template<typename T> inline const list<T> unzipValues(const list<list<T> >& l) {
if (isNil(l))
return list<T>();
return cons(cadr(car(l)), unzipValues(cdr(l)));
}
-template<typename T> const list<list<T> > unzip(const list<list<T> >& l) {
+template<typename T> inline const list<list<T> > unzip(const list<list<T> >& l) {
return mklist<list<T> >(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>()) 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<bool()> 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<bool()> 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 <execinfo.h>
#include <cxxabi.h>
+#endif
+
#include "function.hpp"
#include "string.hpp"
#include "stream.hpp"
@@ -43,21 +46,16 @@ namespace tuscany
*/
template<typename V> class id {
public:
- id(const V& v) : v(v) {
+ inline id(const V& v) : v(v) {
}
- const id<V>& operator=(const id<V>& m) {
- if(this == &m)
- return *this;
- v = m.v;
- return *this;
- }
+ id<V>& operator=(const id<V>& m) = delete;
- const bool operator!=(const id<V>& m) const {
+ inline const bool operator!=(const id<V>& m) const {
return !this->operator==(m);
}
- const bool operator==(const id<V>& m) const {
+ inline const bool operator==(const id<V>& m) const {
if (&m == this)
return true;
return v == m.v;
@@ -72,7 +70,7 @@ private:
/**
* Write an identity monad to a stream.
*/
-template<typename V> ostream& operator<<(ostream& out, const id<V>& m) {
+template<typename V> inline ostream& operator<<(ostream& out, const id<V>& m) {
out << content(m);
return out;
}
@@ -80,29 +78,29 @@ template<typename V> ostream& operator<<(ostream& out, const id<V>& m) {
/**
* Returns the content of an identity monad.
*/
-template<typename V> const V content(const id<V>& m) {
+template<typename V> inline const V content(const id<V>& m) {
return m.v;
}
/**
* Return an identity monad from a value.
*/
-template<typename V> const id<V> mkunit(const V& v) {
+template<typename V> inline const id<V> mkunit(const V& v) {
return id<V>(v);
}
-template<typename V> const lambda<id<V>(const V)> unit() {
+template<typename V> inline const lambda<const id<V>(const V)> unit() {
return mkunit<V>;
}
/**
* Bind a function to an identity monad. Pass the value in the monad to the function.
*/
-template<typename R, typename V> const id<R> operator>>(const id<V>& m, const lambda<id<R>(const V)>& f) {
+template<typename R, typename V> inline const id<R> operator>>(const id<V>& m, const lambda<const id<R>(const V)>& f) {
return f(content(m));
}
-template<typename R, typename V> const id<R> operator>>(const id<V>& m, const id<R> (* const f)(const V)) {
+template<typename R, typename V> inline const id<R> operator>>(const id<V>& m, const id<R> (* const f)(const V)) {
return f(content(m));
}
@@ -112,26 +110,22 @@ template<typename R, typename V> const id<R> operator>>(const id<V>& m, const id
*/
template<typename V> 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<V>& operator=(const maybe<V>& m) {
- if(this == &m)
- return *this;
- hasv = m.hasv;
- if (hasv)
- v = m.v;
- return *this;
+ inline maybe(const maybe<V>& m) : hasv(m.hasv), v(m.v) {
}
- const bool operator!=(const maybe<V>& m) const {
+ maybe<V>& operator=(const maybe<V>& m) = delete;
+
+ inline const bool operator!=(const maybe<V>& m) const {
return !this->operator==(m);
}
- const bool operator==(const maybe<V>& m) const {
+ inline const bool operator==(const maybe<V>& m) const {
if (this == &m)
return true;
if (!hasv)
@@ -141,7 +135,7 @@ public:
private:
const bool hasv;
- V v;
+ const V v;
template<typename X> friend const bool hasContent(const maybe<X>& m);
template<typename X> friend const X content(const maybe<X>& m);
@@ -150,7 +144,7 @@ private:
/**
* Write a maybe monad to a stream.
*/
-template<typename V> ostream& operator<<(ostream& out, const maybe<V>& m) {
+template<typename V> inline ostream& operator<<(ostream& out, const maybe<V>& m) {
if (!hasContent(m)) {
out << "nothing";
return out;
@@ -162,25 +156,25 @@ template<typename V> ostream& operator<<(ostream& out, const maybe<V>& m) {
/**
* Return a maybe monad with a value in it.
*/
-template<typename V> const maybe<V> mkjust(const V& v) {
+template<typename V> inline const maybe<V> mkjust(const V& v) {
return maybe<V>(v);
}
-template<typename V> const lambda<maybe<V>(const V)> just() {
+template<typename V> inline const lambda<const maybe<V>(const V)> just() {
return mkjust<V>;
}
/**
* Returns true if a maybe monad contains a content.
*/
-template<typename V> const bool hasContent(const maybe<V>& m) {
+template<typename V> inline const bool hasContent(const maybe<V>& m) {
return m.hasv;
}
/**
* Returns the content of a maybe monad.
*/
-template<typename V> const V content(const maybe<V>& m) {
+template<typename V> inline const V content(const maybe<V>& m) {
return m.v;
}
@@ -188,13 +182,13 @@ template<typename V> const V content(const maybe<V>& m) {
* Bind a function to a maybe monad. Passes the value in the monad to the function
* if present, or does nothing if there's no value.
*/
-template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, const lambda<maybe<R>(const V)>& f) {
+template<typename R, typename V> inline const maybe<R> operator>>(const maybe<V>& m, const lambda<const maybe<R>(const V)>& f) {
if (!hasContent(m))
return m;
return f(content(m));
}
-template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, const maybe<R> (* const f)(const V)) {
+template<typename R, typename V> inline const maybe<R> operator>>(const maybe<V>& m, const maybe<R> (* const f)(const V)) {
if (!hasContent(m))
return m;
return f(content(m));
@@ -207,30 +201,22 @@ template<typename R, typename V> const maybe<R> operator>>(const maybe<V>& m, co
*/
template<typename V, typename F = string, typename C = int> 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<V, F, C>& m) : hasv(m.hasv), v(m.v), f(m.f), c(m.c) {
+ inline failable(const failable<V, F, C>& m) : hasv(m.hasv), v(m.v), f(m.f), c(m.c) {
}
- const failable<V, F, C>& operator=(const failable<V, F, C>& m) {
- if (&m == this)
- return *this;
- hasv = m.hasv;
- v = m.v;
- f = m.f;
- c = m.c;
- return *this;
- }
+ failable<V, F, C>& operator=(const failable<V, F, C>& m) = delete;
- const bool operator!=(const failable<V, F, C>& m) const {
+ inline const bool operator!=(const failable<V, F, C>& m) const {
return !this->operator==(m);
}
- const bool operator==(const failable<V, F, C>& m) const {
+ inline const bool operator==(const failable<V, F, C>& 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<typename A, typename B, typename R> friend const bool hasContent(const failable<A, B, R>& m);
@@ -250,16 +236,16 @@ private:
template<typename A, typename B> friend const failable<A, B> mkfailure(const B& f, const int c, const bool log);
template<typename A> friend const failable<A> 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<typename V, typename F, typename C> ostream& operator<<(ostream& out, const failable<V, F, C>& m) {
+template<typename V, typename F, typename C> inline ostream& operator<<(ostream& out, const failable<V, F, C>& m) {
if (!hasContent(m)) {
out << reason(m) << " : " << rcode(m);
return out;
@@ -271,20 +257,22 @@ template<typename V, typename F, typename C> ostream& operator<<(ostream& out, c
/**
* Returns a failable monad with a success value in it.
*/
-template<typename V, typename F, typename C> const failable<V, F, C> mksuccess(const V& v) {
+template<typename V, typename F, typename C> inline const failable<V, F, C> mksuccess(const V& v) {
return failable<V, F, C>(v);
}
-template<typename V, typename F, typename C> const lambda<failable<V, F, C>(const V)> success() {
+template<typename V, typename F, typename C> inline const lambda<const failable<V, F, C>(const V)> success() {
return mksuccess<V, F, C>;
}
+#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<typename V, typename F, typename C> const failable<V, F, C> mkfailure(const F& f, const C& c, const bool log = true) {
+template<typename V, typename F, typename C> inline const failable<V, F, C> 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<typename V, typename F, typename C> const failable<V, F, C> 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<V, F, C>(false, f, c);
}
-template<typename V, typename F> const failable<V, F> mkfailure(const F& f, const int c = -1, const bool log = true) {
+template<typename V, typename F> inline const failable<V, F> mkfailure(const F& f, const int c = -1, const bool log = true) {
return mkfailure<V, F, int>(f, c, log);
}
-template<typename V> const failable<V> mkfailure(const char* f, const int c = -1, const bool log = true) {
+template<typename V> inline const failable<V> mkfailure(const char* f, const int c = -1, const bool log = true) {
return mkfailure<V, string, int>(string(f), c, log);
}
-template<typename V> const failable<V> mkfailure() {
+template<typename V> inline const failable<V> mkfailure() {
return failable<V, string>(false, string(), -1);
}
-template<typename V, typename F, typename C> const lambda<failable<V, F, C>(const V)> failure() {
+template<typename V, typename F, typename C> inline const lambda<const failable<V, F, C>(const V)> failure() {
return mkfailure<V, F, C>;
}
/**
* Convert a failable of a given type to a failable of another type.
*/
-template<typename V, typename F, typename C, typename X> const failable<V, F, C> mkfailure(const failable<X, F, C>& f, const bool log = true) {
+template<typename V, typename F, typename C, typename X> inline const failable<V, F, C> mkfailure(const failable<X, F, C>& f, const bool log = false) {
return mkfailure<V, F, C>(reason(f), rcode(f), log);
}
/**
* Returns true if the monad contains a content.
*/
-template<typename V, typename F, typename C> const bool hasContent(const failable<V, F, C>& m) {
+template<typename V, typename F, typename C> inline const bool hasContent(const failable<V, F, C>& m) {
return m.hasv;
}
/**
* Returns the content of a failable monad.
*/
-template<typename V, typename F, typename C> const V content(const failable<V, F, C>& m) {
+template<typename V, typename F, typename C> inline const V content(const failable<V, F, C>& m) {
return m.v;
}
/**
* Returns the reason for failure of a failable monad.
*/
-template<typename V, typename F, typename C> const F reason(const failable<V, F, C>& m) {
+template<typename V, typename F, typename C> inline const F reason(const failable<V, F, C>& m) {
return m.f;
}
/**
* Returns the reason code for failure of a failable monad.
*/
-template<typename V, typename F, typename C> const C rcode(const failable<V, F, C>& m) {
+template<typename V, typename F, typename C> inline const C rcode(const failable<V, F, C>& m) {
return m.c;
}
@@ -458,14 +452,14 @@ template<typename V, typename F, typename C> const C rcode(const failable<V, F,
* if present, or does nothing if there's no value and a failure instead.
*/
template<typename R, typename FR, typename XR, typename V, typename FV, typename XV>
-const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const lambda<failable<R, FR, XR>(const V)>& f) {
+inline const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const lambda<const failable<R, FR, XR>(const V)>& f) {
if (!hasContent(m))
return m;
return f(content(m));
}
template<typename R, typename FR, typename XR, typename V, typename FV, typename XV>
-const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const failable<R, FR, XR> (* const f)(const V)) {
+inline const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const failable<R, FR, XR> (* const f)(const V)) {
if (!hasContent(m))
return m;
return f(content(m));
@@ -476,30 +470,27 @@ const failable<R, FR, XR> operator>>(const failable<V, FV, XV>& m, const failabl
*/
template<typename S, typename V> 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<S, V>& operator=(const scp<S, V>& p) {
- if(this == &p)
- return *this;
- s = p.s;
- v = p.v;
- return *this;
+ inline scp(const scp<S, V>& p) : s(p.s), v(p.v) {
}
- const bool operator!=(const scp<S, V>& p) const {
+ scp<S, V>& operator=(const scp<S, V>& p) = delete;
+
+ inline const bool operator!=(const scp<S, V>& p) const {
return !this->operator==(p);
}
- const bool operator==(const scp<S, V>& p) const {
+ inline const bool operator==(const scp<S, V>& 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<typename S, typename V> const S scpstate(const scp<S, V>& m) {
+template<typename S, typename V> inline const S scpstate(const scp<S, V>& m) {
return m.s;
}
/**
* Returns the content of a state-content pair.
*/
-template<typename S, typename V> const S content(const scp<S, V>& m) {
+template<typename S, typename V> inline const S content(const scp<S, V>& m) {
return m.v;
}
@@ -532,38 +523,36 @@ template<typename S, typename V> const S content(const scp<S, V>& m) {
*/
template<typename S, typename V> class state {
public:
- state(const lambda<scp<S, V>(const S)>& f) : f(f) {
+ inline state(const lambda<const scp<S, V>(const S)>& f) : f(f) {
}
- const scp<S, V> operator()(const S& s) const {
+ inline const scp<S, V> operator()(const S& s) const {
return f(s);
}
- const state<S, V>& operator=(const state<S, V>& m) {
- if(this == &m)
- return *this;
- f = m.f;
- return *this;
+ inline state(const state<S, V>& m) : f(m.f) {
}
- const bool operator!=(const state<S, V>& m) const {
+ state<S, V>& operator=(const state<S, V>& m) = delete;
+
+ inline const bool operator!=(const state<S, V>& m) const {
return !this->operator==(m);
}
- const bool operator==(const state<S, V>& m) const {
+ inline const bool operator==(const state<S, V>& m) const {
if (this == &m)
return true;
return f == m.f;
}
private:
- const lambda<scp<S, V>(const S)> f;
+ const lambda<const scp<S, V>(const S)> f;
};
/**
* Write a state monad to a stream.
*/
-template<typename S, typename V> ostream& operator<<(ostream& out, const state<S, V>& m) {
+template<typename S, typename V> inline ostream& operator<<(ostream& out, const state<S, V>& m) {
const S s = m;
const V v = m;
out << '(' << s << ' ' << v << ')';
@@ -573,17 +562,10 @@ template<typename S, typename V> ostream& operator<<(ostream& out, const state<S
/**
* Return a state monad carrying a result content.
*/
-template<typename S, typename V> struct returnState {
- const V v;
- returnState(const V& v) : v(v) {
- }
- const scp<S, V> operator()(const S& s) const {
+template<typename S, typename V> inline const state<S, V> result(const V& v) {
+ return state<S, V>([v](const S& s) -> const scp<S, V> {
return scp<S, V>(s, v);
- }
-};
-
-template<typename S, typename V> const state<S, V> result(const V& v) {
- return state<S, V>(returnState<S, V>(v));
+ });
}
/**
@@ -591,7 +573,7 @@ template<typename S, typename V> const state<S, V> result(const V& v) {
* A transformer function takes a state and returns an scp pair carrying a content and a
* new (transformed) state.
*/
-template<typename S, typename V> const state<S, V> transformer(const lambda<scp<S, V>(const S)>& f) {
+template<typename S, typename V> inline const state<S, V> transformer(const lambda<const scp<S, V>(const S)>& f) {
return state<S, V>(f);
}
@@ -599,28 +581,19 @@ template<typename S, typename V> const state<S, V> transformer(const lambda<scp<
* Bind a function to a state monad. The function takes a content and returns a state
* monad carrying a return content.
*/
-template<typename S, typename A, typename B> struct stateBind {
- const state<S, A> st;
- const lambda<state<S, B>(const A)>f;
-
- stateBind(const state<S, A>& st, const lambda<state<S, B>(const A)>& f) : st(st), f(f) {
- }
-
- const scp<S, B> operator()(const S& is) const {
+template<typename S, typename A, typename B>
+inline const state<S, B> operator>>(const state<S, A>& st, const lambda<const state<S, B>(const A)>& f) {
+ const lambda<const scp<S, B>(const S&)> stateBind = [st, f](const S& is) -> const scp<S, B> {
const scp<S, A> iscp = st(is);
const state<S, B> m = f((A)iscp);
return m((S)iscp);
- }
-};
-
-template<typename S, typename A, typename B>
-const state<S, B> operator>>(const state<S, A>& st, const lambda<state<S, B>(const A)>& f) {
- return state<S, B>(stateBind<S, A , B>(st, f));
+ };
+ return state<S, B>(stateBind);
}
template<typename S, typename A, typename B>
-const state<S, B> operator>>(const state<S, A>& st, const state<S, B> (* const f)(const A)) {
- return state<S, B>(stateBind<S, A , B>(st, f));
+inline const state<S, B> operator>>(const state<S, A>& st, const state<S, B> (* const f)(const A)) {
+ return st >> lambda<const state<S, B>(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<int> tlsic() {
- gc_ptr<int> i = new (gc_new<int>()) int();
+ const gc_ptr<int> i = new (gc_new<int>()) int();
*i = 0;
return i;
}
const perthread_ptr<int> 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<bool()> 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<bool()> 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<bool()> 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<bool()> 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<future<int> > submitSquares(worker& w, const int max, const int i) {
if (i == max)
return list<future<int> >();
- const lambda<int()> func = curry(lambda<int(const int)> (mtsquare), i);
+ const lambda<const int()> func = curry(lambda<const int(const int)> (mtsquare), i);
return cons(submit(w, func), submitSquares(w, max, i + 1));
}
@@ -143,7 +117,7 @@ bool checkSquareResults(const list<future<int> > r, int i) {
}
const gc_ptr<unsigned long> tlsvc() {
- gc_ptr<unsigned long> i = new (gc_new<unsigned long>()) unsigned long();
+ const gc_ptr<unsigned long> i = new (gc_new<unsigned long>()) unsigned long();
*i = 0l;
return i;
}
@@ -181,11 +155,11 @@ const bool unblockWorkers(wqueue<bool>& wq, const int n) {
const list<future<long int> > submitTLSSets(worker& w, wqueue<bool>& wq, wqueue<bool>& xq, const int max, const int i) {
if (i == max)
return list<future<long int> >();
- const lambda<long int()> func = curry(lambda<long int(gc_ptr<wqueue<bool>>, gc_ptr<wqueue<bool>>)>(tlsset), (gc_ptr<wqueue<bool>>)&wq, (gc_ptr<wqueue<bool>>)&xq);
+ const lambda<const long int()> func = curry(lambda<const long int(gc_ptr<wqueue<bool>>, gc_ptr<wqueue<bool>>)>(tlsset), (gc_ptr<wqueue<bool>>)&wq, (gc_ptr<wqueue<bool>>)&xq);
return cons(submit(w, func), submitTLSSets(w, wq, xq, max, i + 1));
}
-bool checkTLSSets(const list<future<long int> > s) {
+const bool checkTLSSets(const list<future<long int> > s) {
if (isNil(s))
return true;
assert(car(s) == 0);
@@ -195,22 +169,22 @@ bool checkTLSSets(const list<future<long int> > s) {
const list<future<bool> > submitTLSChecks(worker& w, wqueue<bool>& wq, wqueue<bool>& xq, const int max, const int i) {
if (i == max)
return list<future<bool> >();
- const lambda<bool()> func = curry(lambda<bool(gc_ptr<wqueue<bool>>, gc_ptr<wqueue<bool>>)>(tlscheck), (gc_ptr<wqueue<bool>>)&wq, (gc_ptr<wqueue<bool>>)&xq);
+ const blambda func = curry(lambda<const bool(gc_ptr<wqueue<bool>>, gc_ptr<wqueue<bool>>)>(tlscheck), (gc_ptr<wqueue<bool>>)&wq, (gc_ptr<wqueue<bool>>)&xq);
return cons(submit(w, func), submitTLSChecks(w, wq, xq, max, i + 1));
}
-bool checkTLSResults(const list<future<bool> > r) {
+const bool checkTLSResults(const list<future<bool> > 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<int()> func = curry(lambda<int(const int)> (mtsquare), 2);
+ const lambda<const int()> func = curry(lambda<const int(const int)> (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<typename T> class future {
private:
template<typename X> 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<X> value;
};
- gc_ptr<futureValue<T> > fvalue;
+ const gc_ptr<futureValue<T> > fvalue;
- template<typename X> friend const X get(const future<X>& f);
- template<typename X> friend bool set(const future<X>& f, const X& v);
+ template<typename X> friend const X get(const future<X>& f) noexcept;
+ template<typename X> friend bool set(const future<X>& f, const X& v) noexcept;
public:
- future() : fvalue(new (gc_new<futureValue<T> >()) futureValue<T>()) {
+ inline future() noexcept : fvalue(new (gc_new<futureValue<T> >()) futureValue<T>()) {
}
- ~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<typename T> class wqueue {
public:
- wqueue(size_t max) : max(max), size(0), tail(0), head(0), values(new (gc_anew<T>(max)) T[max]) {
+ inline wqueue(size_t max) noexcept : max(max), size(0), tail(0), head(0), values(new (gc_anew<gc_mutable_ref<T> >(max)) gc_mutable_ref<T>[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<T> values;
+ gc_ptr<gc_mutable_ref<T> > values;
- template<typename X> friend const size_t enqueue(wqueue<X>& q, const X& v);
- template<typename X> friend const X dequeue(wqueue<X>& q);
+ template<typename X> friend const size_t enqueue(wqueue<X>& q, const X& v) noexcept;
+ template<typename X> friend const X dequeue(wqueue<X>& q) noexcept;
};
/**
* Adds an element to the tail of the queue.
*/
-template<typename T> const size_t enqueue(wqueue<T>&q, const T& v) {
+template<typename T> inline const size_t enqueue(wqueue<T>&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<typename T> const size_t enqueue(wqueue<T>&q, const T& v) {
/**
* Returns the element at the head of the queue.
*/
-template<typename T> const T dequeue(wqueue<T>& q) {
+template<typename T> inline const T dequeue(wqueue<T>& q) noexcept {
pthread_mutex_lock(&q.mutex);
while(q.size == 0)
pthread_cond_wait(&q.empty, &q.mutex);
@@ -202,13 +197,13 @@ template<typename T> const T dequeue(wqueue<T>& 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<lambda<bool()> >* work = reinterpret_cast<wqueue<lambda<bool()> >*>(arg);
+ wqueue<blambda >* work = reinterpret_cast<wqueue<blambda >*>(arg);
while(dequeue(*work)())
;
return NULL;
@@ -217,7 +212,7 @@ void *workerThreadFunc(void *arg) {
/**
* Returns a list of worker threads.
*/
-const list<pthread_t> workerThreads(wqueue<lambda<bool()> >& wqueue, const size_t count) {
+inline const list<pthread_t> workerThreads(wqueue<blambda >& wqueue, const size_t count) noexcept {
if (count == 0)
return list<pthread_t>();
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<lambda<bool()> >(max)), threads(workerThreads(work, max)) {
+ inline sharedWorker(size_t max) noexcept : work(wqueue<blambda >(max)), threads(workerThreads(work, max)) {
}
- wqueue<lambda<bool()> > work;
+ wqueue<blambda > work;
const list<pthread_t> threads;
};
public:
- worker(size_t max) : w(*(new (gc_new<sharedWorker>()) sharedWorker(max))) {
+ inline worker(size_t max) noexcept : w(*(new (gc_new<sharedWorker>()) sharedWorker(max))) {
}
- worker(const worker& wk) : w(wk.w) {
+ inline worker(const worker& wk) noexcept : w(wk.w) {
}
private:
sharedWorker& w;
- template<typename X> friend const future<X> submit(worker& w, const lambda<X()>& func);
- friend const bool shutdown(worker& w);
- friend const bool cancel(worker& w);
+ template<typename X> friend const future<X> submit(const worker& w, const lambda<const X()>& 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<typename R> bool submitFunc(const lambda<R()>& func, const future<R>& fut) {
+template<typename R> inline const bool submitFunc(const lambda<const R()>& func, const future<R>& fut) noexcept {
fut = func();
return true;
}
@@ -268,9 +263,9 @@ template<typename R> bool submitFunc(const lambda<R()>& func, const future<R>& f
/**
* Submits work to a worker.
*/
-template<typename R> const future<R> submit(worker& w, const lambda<R()>& func) {
+template<typename R> inline const future<R> submit(const worker& w, const lambda<const R()>& func) noexcept {
const future<R> fut;
- const lambda<bool()> f = curry(lambda<bool(const lambda<R()>, future<R>)>(submitFunc<R>), func, fut);
+ const blambda f = curry(lambda<const bool(const lambda<const R()>, future<R>)>(submitFunc<R>), func, fut);
enqueue(w.w.work, f);
return fut;
}
@@ -278,7 +273,7 @@ template<typename R> const future<R> submit(worker& w, const lambda<R()>& func)
/**
* Enqueues shutdown requests.
*/
-const bool shutdownEnqueue(const list<pthread_t>& threads, wqueue<lambda<bool()> >& work) {
+inline const bool shutdownEnqueue(const list<pthread_t>& threads, wqueue<blambda>& work) noexcept {
if (isNil(threads))
return true;
enqueue(work, result(false));
@@ -288,7 +283,7 @@ const bool shutdownEnqueue(const list<pthread_t>& threads, wqueue<lambda<bool()>
/**
* Waits for shut down threads to terminate.
*/
-const bool shutdownJoin(const list<pthread_t>& threads) {
+inline const bool shutdownJoin(const list<pthread_t>& threads) noexcept {
if (isNil(threads))
return true;
pthread_join(car(threads), NULL);
@@ -298,7 +293,7 @@ const bool shutdownJoin(const list<pthread_t>& 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<pthread_t>& threads) {
+inline const bool cancel(const list<pthread_t>& 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<typename T> class perthread_ptr {
public:
- perthread_ptr() : key(createkey()), owner(true), cl(lambda<gc_ptr<T>()>()), managed(false) {
+ inline perthread_ptr() noexcept : key(createkey()), owner(true), cl(lambda<const gc_ptr<T>()>()), managed(false) {
}
- perthread_ptr(const lambda<gc_ptr<T>()>& cl) : key(createkey()), owner(true), cl(cl), managed(true) {
+ inline perthread_ptr(const lambda<const gc_ptr<T>()>& 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<T>& v) {
+ inline const perthread_ptr& operator=(const gc_ptr<T>& 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<T>& r) const throw() {
+ inline const bool operator==(const gc_ptr<T>& 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<T>& r) const throw() {
+ inline const bool operator!=(const gc_ptr<T>& 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<T>() const {
+ inline operator gc_ptr<T>() 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<T>& v) {
+ inline const bool set(const gc_ptr<T>& v) const noexcept {
pthread_setspecific(key, (T*)v);
return true;
}
- gc_ptr<T> get() const {
- const gc_ptr<T> v = static_cast<T*>(pthread_getspecific(key));
+ inline const gc_ptr<T> get() const noexcept {
+ const gc_ptr<T> v = (T*)(pthread_getspecific(key));
if (v != NULL || !managed)
return v;
const gc_ptr<T> nv = cl();
- pthread_setspecific(key, nv);
+ pthread_setspecific(key, (T*)nv);
return nv;
}
#else
- gc_ptr<gc_ptr<T> > createkey() {
+ inline const gc_ptr<gc_ptr<T> > createkey() noexcept {
return new (gc_new<gc_ptr<T> >()) gc_ptr<T>();
}
- bool deletekey(unused gc_ptr<gc_ptr<T> > k) {
+ inline const bool deletekey(unused gc_ptr<gc_ptr<T> > k) noexcept {
return true;
}
- bool set(const gc_ptr<T>& v) {
+ inline const bool set(const gc_ptr<T>& v) const noexcept {
*key = v;
return true;
}
- gc_ptr<T> get() const {
+ inline const gc_ptr<T> 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<gc_ptr<T> >key;
+ const gc_ptr<gc_ptr<T> >key;
#endif
- bool owner;
- lambda<const gc_ptr<T>()> cl;
- bool managed;
+ const bool owner;
+ const lambda<const gc_ptr<T>()> 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<bool()> f;
- timeLambda(const lambda<bool()>& 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<const bool(const long)> tl = [f](const long count) -> const bool {
for (long i = 0; i < count; i++)
f();
return true;
- }
-};
-
-const double time(const lambda<bool()>& f, const long warmup, const long count) {
- const lambda<bool(long)> tl = timeLambda(f);
- struct timeval start;
- struct timeval end;
+ };
tl(warmup);
gettimeofday(&start, NULL);
@@ -62,13 +56,13 @@ const double time(const lambda<bool()>& 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<string>& l, char* buf) {
+const bool writeList(const list<string>& l, char* const buf) {
if (isNil(l))
return true;
const string c = car(l);
@@ -59,63 +59,108 @@ const bool writeList(const list<string>& 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<string>)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<string>)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<string>)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<string>)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<string>)buf);
+ accumbuf = NULL;
+ accumlen = 0;
+ return true;
}
friend const string str(ostringstream& os);
size_t len;
- list<string> buf;
+ char* accumbuf;
+ size_t accumlen;
+ gc_mutable_ref<list<string> > 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<string> tokenize(const char* sep, const string& str) {
- struct nested {
- static const list<string> tokenize(const char* sep, const size_t slen, const string& str, const size_t start) {
- if (start >= length(str))
- return list<string>();
- 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<string> tokenize(const char* const sep, const string& str) {
+ const lambda<const list<string>(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<string> {
+ if (start >= length(str))
+ return list<string>();
+ 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<string>& l) {
- struct nested {
- static ostringstream& join(const char* sep, const list<string>& 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<string>& l) {
ostringstream os;
- return str(nested::join(sep, l, os));
+ const lambda<ostringstream&(const char* const, const list<string>&, ostringstream&)> join = [&join](const char* const sep, const list<string>& 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<string> operator()() {
+inline const list<string> streamList(istream& is) {
+ const lambda<const list<string>()> ilistRead = [&is, &ilistRead]() -> const list<string> {
char buffer[1024];
const size_t n = read(is, buffer, sizeof(buffer));
if (n ==0)
return list<string>();
- return cons(string(buffer, n), (*this)());
- }
-};
-
-const list<string> 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<string> fragment(list<string> l, size_t max) {
+inline const list<string> fragment(const list<string>& l, const size_t max) {
const string s = car(l);
if (length(s) <= max)
return l;
@@ -250,13 +276,26 @@ const list<string> fragment(list<string> l, size_t max) {
/**
* Write a list of strings to an output stream.
*/
-ostream& write(const list<string>& l, ostream& os) {
+inline ostream& write(const list<string>& 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<string>& 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<typename T> ostream& operator<<(ostream& out, const gc_ptr<T>& p) {
- return out << p.ptr;
+#ifndef WANT_RAW_PTR
+
+/**
+ * Write a pointer.
+ */
+template<typename T> inline ostream& operator<<(ostream& out, const gc_ptr<T>& p) {
+ return out << (T*)p;
+}
+
+/**
+ * Write a mutable pointer.
+ */
+template<typename T> inline ostream& operator<<(ostream& out, const gc_mutable_ptr<T>& p) {
+ return out << (T*)p;
+}
+
+#endif
+
+/**
+ * Write a mutable reference.
+ */
+template<typename T> inline ostream& operator<<(ostream& out, const gc_mutable_ref<T>& r) {
+ return out << (T)r;
}
#ifdef WANT_MAINTAINER_LOG
@@ -159,35 +181,40 @@ template<typename T> ostream& operator<<(ostream& out, const gc_ptr<T>& 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<string> 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<string> pl = list<string>() + "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<bool()> a16 = addStrings(16);
+ const lambda<const blambda(const size_t size)> 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<bool()> a32 =addStrings(32);
+ const blambda a32 =addStrings(32);
cout << "string test " << time(a32, 5, count) << " ms" << endl;
- const lambda<bool()> a256 =addStrings(256);
+ const blambda a256 =addStrings(256);
cout << "string test " << time(a256, 5, count) << " ms" << endl;
- const lambda<bool()> a1024 =addStrings(1024);
+ const blambda a1024 =addStrings(1024);
cout << "string test " << time(a1024, 5, count) << " ms" << endl;
- const lambda<bool()> a4096 =addStrings(4096);
+ const blambda a4096 =addStrings(4096);
cout << "string test " << time(a4096, 5, count) << " ms" << endl;
}
{
- const lambda<bool()> a16 =addStdStrings(16);
+ const lambda<const blambda(const size_t size)> 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<bool()> a32 =addStdStrings(32);
+ const blambda a32 =addStdStrings(32);
cout << "Std string test " << time(a32, 5, count) << " ms" << endl;
- const lambda<bool()> a256 =addStdStrings(256);
+ const blambda a256 =addStdStrings(256);
cout << "Std string test " << time(a256, 5, count) << " ms" << endl;
- const lambda<bool()> a1024 =addStdStrings(1024);
+ const blambda a1024 =addStdStrings(1024);
cout << "Std string test " << time(a1024, 5, count) << " ms" << endl;
- const lambda<bool()> 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<typename T> const list<T> mktree(const T& e, const list<T>& left, const list<T>& right) {
+template<typename T> inline const list<T> mktree(const T& e, const list<T>& left, const list<T>& right) {
return mklist<T>(e, left, right);
}
/**
* Find a leaf with the given key in a tree.
*/
-template<typename T> const list<T> assoctree(const T& k, const list<T>& tree) {
+template<typename T> inline const list<T> assoctree(const T& k, const list<T>& tree) {
if (isNil(tree))
return tree;
if (k == car<T>(car(tree)))
@@ -58,7 +58,7 @@ template<typename T> const list<T> assoctree(const T& k, const list<T>& tree) {
/**
* Construct a new tree from a leaf and a tree.
*/
-template<typename T> const list<T> constree(const T& e, const list<T>& tree) {
+template<typename T> inline const list<T> constree(const T& e, const list<T>& tree) {
if (isNil(tree))
return mktree(e, list<T>(), list<T>());
if (e == car(tree))
@@ -71,7 +71,7 @@ template<typename T> const list<T> constree(const T& e, const list<T>& tree) {
/**
* Make a tree from an unordered list of leaves.
*/
-template<typename T> const list<T> mktree(const list<T>& l) {
+template<typename T> inline const list<T> mktree(const list<T>& l) {
if (isNil(l))
return l;
return constree(car(l), mktree(cdr(l)));
@@ -80,7 +80,7 @@ template<typename T> const list<T> mktree(const list<T>& l) {
/**
* Convert a tree to an ordered list of leaves.
*/
-template<typename T> const list<T> flatten(const list<T>& tree) {
+template<typename T> inline const list<T> flatten(const list<T>& tree) {
if (isNil(tree))
return tree;
return append<T>(flatten<T>(cadr(tree)), cons<T>(car(tree), flatten<T>(caddr(tree))));
@@ -89,14 +89,14 @@ template<typename T> const list<T> flatten(const list<T>& tree) {
/**
* Sort a list.
*/
-template<typename T> const list<T> sort(const list<T>& l) {
+template<typename T> inline const list<T> sort(const list<T>& l) {
return flatten(mktree(l));
}
/**
* Make a balanced tree from an ordered list of leaves.
*/
-template<typename T> const list<T> btreeHelper(const list<T>& elements, const size_t n) {
+template<typename T> inline const list<T> btreeHelper(const list<T>& elements, const size_t n) {
if (n == 0)
return cons<T>(list<T>(), elements);
const size_t leftSize = (n - 1) / 2; {
@@ -116,7 +116,7 @@ template<typename T> const list<T> btreeHelper(const list<T>& elements, const si
}
}
-template<typename T> const list<T> mkbtree(const list<T>& elements) {
+template<typename T> inline const list<T> mkbtree(const list<T>& elements) {
return car(btreeHelper<T>(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<value> nilListValue;
+extern const list<value> nilPairValue;
+extern const value emptyStringValue;
+extern const value trueValue;
+extern const value falseValue;
+
+/**
+ * Common value-based lambda types.
+ */
+typedef lambda<const value(const list<value>&)> lvvlambda;
+typedef lambda<const value(const value&)> vvlambda;
+typedef lambda<const bool(const value&)> vblambda;
+typedef lambda<const value()> 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<list<value> > lst;
+ const string str;
+ const lvvlambda func;
+ const gc_ptr<value> 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<value>& 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<value(const list<value>&)>& 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<value>& lst) : type(value::List), data(vdata(result(lst))) {
+ inline value(const list<value>& l) noexcept : type(value::List), lst(new (gc_new<list<value> >()) list<value>(l)) {
debug_inc(countValues);
debug_inc(countVValues);
debug_watchValue();
}
- value(const list<list<value> >& l) : type(value::List), data(vdata(result(listOfValues(l)))) {
+ inline value(const list<list<value> >& l) noexcept : type(value::List), lst(new (gc_new<list<value> >()) list<value>(listOfValues(l))) {
debug_inc(countValues);
debug_inc(countVValues);
debug_watchValue();
}
- 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<value> ptr) : type(value::Ptr), data(vdata(result(ptr))) {
+ inline value(const gc_ptr<value> p) noexcept : type(value::Ptr), ptr(p) {
debug_inc(countValues);
debug_inc(countVValues);
debug_watchValue();
}
- value(const failable<value>& m) : type(value::List),
- data(vdata(result(hasContent(m)? mklist<value>(content(m)) : rcode(m) == 1? mklist<value>(value(), reason(m)) : mklist<value>(value(), reason(m), rcode(m))))) {
+ inline value(const failable<value>& m) noexcept : type(value::List),
+ lst(new (gc_new<list<value> >()) list<value>(hasContent(m)? mklist<value>(content(m)) :
+ rcode(m) == 1? mklist<value>(nilValue, reason(m)) : mklist<value>(nilValue, reason(m), rcode(m)))) {
debug_inc(countValues);
debug_inc(countVValues);
debug_watchValue();
}
- value(const maybe<value>& m) : type(value::List),
- data(vdata(result(hasContent(m)? mklist<value>(content(m)) : list<value>()))) {
+ inline value(const maybe<value>& m) noexcept : type(value::List),
+ lst(new (gc_new<list<value> >()) list<value>(hasContent(m)? mklist<value>(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<value>& args) const {
- return func()(args);
+ inline const value operator()(const list<value>& 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<value>() const {
- return ptr()();
+ inline operator const gc_ptr<value>() const noexcept {
+ return ptr;
}
- operator const list<value>() const {
- return lst()();
+ inline operator const list<value>() const noexcept {
+ return *lst;
}
- operator const list<list<value> >() const {
- return listOfListOfValues(lst()());
+ inline operator const list<list<value> >() const noexcept {
+ return listOfListOfValues(*lst);
}
- operator const lambda<value(const list<value>&)>() const {
- return func();
+ inline operator const lvvlambda() const noexcept {
+ return func;
}
private:
- template<typename T> lambda<T>& vdata() const {
- return *reinterpret_cast<lambda<T> *> (const_cast<lambda<char()> *> (&data));
- }
-
- template<typename T> const lambda<char()>& vdata(const T& v) const {
- return *reinterpret_cast<const lambda<char()> *> (&v);
- }
-
- lambda<double()>& num() const {
- return vdata<double()> ();
- }
-
- lambda<bool()>& boo() const {
- return vdata<bool()> ();
- }
-
- lambda<gc_ptr<value>()>& ptr() const {
- return vdata<gc_ptr<value>()> ();
- }
-
- lambda<string()>& str() const {
- return vdata<string()> ();
- }
-
- lambda<list<value>()>& lst() const {
- return vdata<list<value>()> ();
- }
-
- lambda<value(const list<value>&)>& func() const {
- return vdata<value(const list<value>&)> ();
- }
-
- const list<value> listOfValues(const list<list<value> >& l) const {
+ inline const list<value> listOfValues(const list<list<value> >& l) const noexcept {
if (isNil(l))
- return list<value>();
+ return nilListValue;
return cons<value>(car(l), listOfValues(cdr(l)));
}
- const list<list<value> > listOfListOfValues(const list<value>& l) const {
+ inline const list<list<value> > listOfListOfValues(const list<value>& l) const noexcept {
if (isNil(l))
return list<list<value> >();
- return cons<list<value> >(list<value>(car(l)), listOfListOfValues(cdr(l)));
+ return cons<list<value> >(car(l).type == value::List? list<value>(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<char()> data;
+ const ValueType type;
+ union {
+ void* mix;
+ const gc_ptr<list<value> > lst;
+ const string str;
+ const lvvlambda func;
+ const gc_ptr<value> ptr;
+ const double num;
+ const bool boo;
+ };
};
+/**
+ * Common value constants.
+ */
+const value nilValue;
+const list<value> nilListValue = list<value>();
+const list<value> nilPairValue = mklist<value>(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<value>(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<value> p = v.ptr()();
- if (p == gc_ptr<value>(NULL))
+ if (v.ptr == gc_ptr<value>(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<value>)exp))
return car((list<value>)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<typename T> const list<value> mkvalues(const list<T>& l) {
+template<typename T> inline const list<value> mkvalues(const list<T>& l) noexcept {
if (isNil(l))
- return list<value>();
+ return nilListValue;
return cons<value>(car(l), mkvalues(cdr(l)));
}
/**
* Convert a list of values to a list of other things.
*/
-template<typename T> const list<T> convertValues(const list<value>& l) {
+template<typename T> inline const list<T> convertValues(const list<value>& l) noexcept {
if (isNil(l))
return list<T>();
return cons<T>(car(l), convertValues<T>(cdr(l)));
@@ -603,7 +586,7 @@ template<typename T> const list<T> convertValues(const list<value>& l) {
/**
* Convert a path string value to a list of values.
*/
-const list<string> pathTokens(const char* p) {
+inline const list<string> pathTokens(const char* const p) noexcept {
if (p == NULL || p[0] == '\0')
return list<string>();
if (p[0] == '/')
@@ -611,23 +594,23 @@ const list<string> pathTokens(const char* p) {
return tokenize("/", p);
}
-const list<value> pathValues(const value& p) {
+inline const list<value> 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<value>& p) {
+inline const value path(const list<value>& 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 <assert.h>
-#include "stream.hpp"
-#include "string.hpp"
-#include "list.hpp"
-#include "value.hpp"
-#include "element.hpp"
-#include "xml.hpp"
-
-namespace tuscany {
-
-const string currencyXML =
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" targetNamespace=\"http://services\" name=\"currency\">\n"
-" <component name=\"CurrencyConverterWebService\">\n"
-" <implementation.java class=\"services.CurrencyConverterImpl\"/>\n"
-" <service name=\"CurrencyConverter\">\n"
-" <binding.ws/>\n"
-" </service>\n"
-" </component>\n"
-" <component name=\"CurrencyConverterWebService2\">\n"
-" <implementation.java class=\"services.CurrencyConverterImpl2\"/>\n"
-" <service name=\"CurrencyConverter2\">\n"
-" <binding.atom/>\n"
-" </service>\n"
-" <property name=\"currency\">US</property>\n"
-" </component>\n"
-"</composite>\n";
-
-const string customerXML =
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<customer>\n"
-" <name>jdoe</name>\n"
-" <address>\n"
-" <city>san francisco</city>\n"
-" <state>ca</state>\n"
-" </address>\n"
-" <account>\n"
-" <id>1234</id>\n"
-" <balance>1000</balance>\n"
-" </account>\n"
-" <account>\n"
-" <id>6789</id>\n"
-" <balance>2000</balance>\n"
-" </account>\n"
-" <account>\n"
-" <id>4567</id>\n"
-" <balance>3000</balance>\n"
-" </account>\n"
-"</customer>\n";
-
-const string abcXML =
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<a>\n"
-" <m>abc</m>\n"
-" <m>def</m>\n"
-" <m>xyz</m>\n"
-" <m>tuv</m>\n"
-"</a>\n";
-
-const string xyzXML =
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<a>\n"
-" <m>\n"
-" <id>123</id>\n"
-" <name>abc</name>\n"
-" </m>\n"
-" <m>\n"
-" <id>234</id>\n"
-" <name>def</name>\n"
-" </m>\n"
-" <m>\n"
-" <id>345</id>\n"
-" <name>xyz</name>\n"
-" </m>\n"
-" <m>\n"
-" <id>456</id>\n"
-" <name>tuv</name>\n"
-" </m>\n"
-"</a>\n";
-
-const bool isName(const value& token) {
- return isTaggedList(token, attribute) && attributeName(token) == "name";
-}
-
-bool testReadXML() {
- {
- istringstream is(customerXML);
- const list<value> c = readXML(streamList(is));
- }
- {
- istringstream is(currencyXML);
- const list<value> c = readXML(streamList(is));
-
- const value composite = car(c);
- assert(isTaggedList(composite, element));
- assert(elementName(composite) == "composite");
- assert(attributeValue(car(filter<value>(isName, elementChildren(composite)))) == string("currency"));
- }
- return true;
-}
-
-ostream* xmlWriter(const string& s, ostream* os) {
- (*os) << s;
- return os;
-}
-
-bool testWriteXML() {
- {
- istringstream is(customerXML);
- const list<value> c = readXML(streamList(is));
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, c);
- assert(str(os) == customerXML);
- }
- {
- istringstream is(currencyXML);
- const list<value> c = readXML(streamList(is));
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, c);
- assert(str(os) == currencyXML);
- }
- return true;
-}
-
-bool testElements() {
- {
- const list<value> ad = mklist<value>(mklist<value>("city", string("san francisco")), mklist<value>("state", string("ca")));
- const list<value> ac1 = mklist<value>(mklist<value>("id", string("1234")), mklist<value>("balance", 1000));
- const list<value> ac2 = mklist<value>(mklist<value>("id", string("6789")), mklist<value>("balance", 2000));
- const list<value> ac3 = mklist<value>(mklist<value>("id", string("4567")), mklist<value>("balance", 3000));
- {
- const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", string("jdoe")), cons<value>("address", ad), mklist<value>("account", mklist<value>(ac1, ac2, ac3))));
- const list<value> e = valuesToElements(c);
- const list<value> v = elementsToValues(e);
- assert(v == c);
-
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, e);
- assert(str(os) == customerXML);
- }
- {
- const list<value> c = mklist<value>(mklist<value>("customer", mklist<value>("name", string("jdoe")), cons<value>("address", ad), cons<value>("account", ac1), cons<value>("account", ac2), cons<value>("account", ac3)));
- const list<value> e = valuesToElements(c);
- const list<value> v = elementsToValues(e);
-
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, e);
- assert(str(os) == customerXML);
- }
- }
- {
- istringstream is(abcXML);
- const list<value> c = readXML(streamList(is));
- const list<value> v = elementsToValues(c);
- const list<value> e = valuesToElements(v);
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, e);
- assert(str(os) == abcXML);
- }
- {
- istringstream is(xyzXML);
- const list<value> c = readXML(streamList(is));
- const list<value> v = elementsToValues(c);
- const list<value> e = valuesToElements(v);
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, e);
- assert(str(os) == xyzXML);
- }
- {
- istringstream is(customerXML);
- const list<value> c = readXML(streamList(is));
- const list<value> v = elementsToValues(c);
- const list<value> e = valuesToElements(v);
- ostringstream os;
- writeXML<ostream*>(xmlWriter, &os, e);
- assert(str(os) == customerXML);
- }
- return true;
-}
-
-bool testValues() {
- {
- const list<value> l = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!")));
- const list<value> e = valuesToElements(l);
- const failable<list<string> > lx = writeXML(e);
- ostringstream os;
- write(content(lx), os);
- istringstream is(str(os));
- const list<value> x = readXML(streamList(is));
- const list<value> 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 <libxml/xmlreader.h>
-#include <libxml/xmlwriter.h>
-#include <libxml/xmlschemas.h>
-#include <libxml/globals.h>
-#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<value>(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<value> readList(const list<value>& listSoFar, XMLReader& reader) {
- const value token = readToken(reader);
- if(isNil(token) || endElement == token)
- return reverse(listSoFar);
- if(startElement == token)
- return readList(cons<value>(readList(mklist(element), reader), listSoFar), reader);
- return readList(cons(token, listSoFar), reader);
-}
-
-/**
- * Read a list of values from a libxml2 XML reader.
- */
-const list<value> read(XMLReader& reader) {
- value nextToken = readToken(reader);
- if (startElement == nextToken)
- return mklist<value>(readList(mklist(element), reader));
- return list<value>();
-}
-
-/**
- * Context passed to the read callback function.
- */
-class XMLReadContext {
-public:
- XMLReadContext(const list<string>& ilist) : ilist(ilist) {
- }
- list<string> ilist;
-};
-
-/**
- * Callback function called by libxml2 to read XML.
- */
-int readCallback(void *context, char* buffer, int len) {
- XMLReadContext& rc = *static_cast<XMLReadContext*>(context);
- if (isNil(rc.ilist))
- return 0;
- const list<string> 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<string>& ls) {
- if (isNil(ls))
- return false;
- return substr(car(ls), 0, 5) == "<?xml";
-}
-
-/**
- * Read a list of values from a list of strings representing an XML document.
- */
-const list<value> readXML(const list<string>& 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<value>();
- 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<value> expandElementValues(const value& n, const list<value>& l) {
- if (isNil(l))
- return l;
- return cons<value>(value(cons<value>(element, cons<value>(n, isList(car(l))? (list<value>)car(l) : mklist(car(l))))), expandElementValues(n, cdr(l)));
-}
-
-const failable<bool> writeList(const list<value>& 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<bool>("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<value> 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<bool>("xmlTextWriterStartElement failed");
-
- // Write its children
- const failable<bool> w = writeList(elementChildren(token), xml);
- if (!hasContent(w))
- return w;
-
- if (xmlTextWriterEndElement(xml) < 0)
- return mkfailure<bool>("xmlTextWriterEndElement failed");
- }
- }
- else {
-
- // Write an element
- if (xmlTextWriterStartElement(xml, (const xmlChar*)c_str(string(elementName(token)))) < 0)
- return mkfailure<bool>("xmlTextWriterStartElement failed");
-
- // Write its children
- const failable<bool> w = writeList(elementChildren(token), xml);
- if (!hasContent(w))
- return w;
-
- if (xmlTextWriterEndElement(xml) < 0)
- return mkfailure<bool>("xmlTextWriterEndElement failed");
- }
- } else {
-
- // Write XML text
- if (xmlTextWriterWriteString(xml, (const xmlChar*)c_str(string(token))) < 0)
- return mkfailure<bool>("xmlTextWriterWriteString failed");
- }
-
- // Go on
- return writeList(cdr(l), xml);
-}
-
-/**
- * Write a list of values to a libxml2 XML writer.
- */
-const failable<bool> write(const list<value>& l, const xmlTextWriterPtr xml, bool xmlTag) {
- if (xmlTag) {
- if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0)
- return mkfailure<bool>("xmlTextWriterStartDocument failed");
- }
-
- const failable<bool> w = writeList(l, xml);
- if (!hasContent(w))
- return w;
-
- if (xmlTag) {
- if (xmlTextWriterEndDocument(xml) < 0)
- return mkfailure<bool>("xmlTextWriterEndDocument failed");
- }
- return true;
-}
-
-/**
- * Context passed to the write callback function.
- */
-template<typename R> class XMLWriteContext {
-public:
- XMLWriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) {
- }
- const lambda<R(const string&, const R)> reduce;
- R accum;
-};
-
-/**
- * Callback function called by libxml2 to write XML out.
- */
-template<typename R> int writeCallback(void *context, const char* buffer, int len) {
- XMLWriteContext<R>& cx = *static_cast<XMLWriteContext<R>*>(context);
- cx.accum = cx.reduce(string(buffer, len), cx.accum);
- return len;
-}
-
-/**
- * Convert a list of values to an XML document.
- */
-template<typename R> const failable<R> writeXML(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l, const bool xmlTag) {
- XMLWriteContext<R> cx(reduce, initial);
- xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback<R>, NULL, &cx, NULL);
- if (out == NULL)
- return mkfailure<R>("xmlOutputBufferCreateIO failed");
- xmlTextWriterPtr xml = xmlNewTextWriter(out);
- if (xml == NULL)
- return mkfailure<R>("xmlNewTextWriter failed");
- xmlTextWriterSetIndent(xml, 1);
-
- const failable<bool> w = write(l, xml, xmlTag);
- xmlFreeTextWriter(xml);
- if (!hasContent(w)) {
- return mkfailure<R>(w);
- }
- return cx.accum;
-}
-
-template<typename R> const failable<R> writeXML(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
- return writeXML(reduce, initial, l, true);
-}
-
-/**
- * Convert a list of values to a list of strings representing an XML document.
- */
-const failable<list<string> > writeXML(const list<value>& l, const bool xmlTag) {
- debug(l, "xml::writeXML");
- const failable<list<string> > ls = writeXML<list<string> >(rcons<string>, list<string>(), l, xmlTag);
- if (!hasContent(ls))
- return ls;
- return reverse(list<string>(content(ls)));
-}
-
-const failable<list<string> > writeXML(const list<value>& 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 <libxml/xmlreader.h>
-#include <libxml/xmlschemas.h>
-
-namespace tuscany {
-
-bool printNode(xmlTextReaderPtr reader) {
- const xmlChar* name = xmlTextReaderConstName(reader);
- if(name == NULL)
- name = (xmlChar *)"<unknown>";
- 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;
-}