From ae0b7c0063db6236be2d7cf01ddbf2159f77c98c Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Tue, 11 Dec 2012 03:51:03 +0000 Subject: Port kernel to C++11 and refactor some of the core modules. Convert functors to lambdas, and add C++ const, noexcept and inline annotations to get more efficient generated code. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1419985 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/kernel/value.hpp | 371 ++++++++++++++++++++--------------------- 1 file changed, 184 insertions(+), 187 deletions(-) (limited to 'sca-cpp/trunk/kernel/value.hpp') diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index 206fe8b32b..60fb29070c 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -50,16 +50,16 @@ long int countEValues = 0; long int countCValues = 0; long int countVValues = 0; -bool resetValueCounters() { +inline const bool resetValueCounters() { countValues = countEValues = countCValues = countVValues = 0; return true; } -bool checkValueCounters() { +inline const bool checkValueCounters() { return countValues == 0; } -bool printValueCounters() { +inline const bool printValueCounters() { cout << "countValues " << countValues << endl; cout << "countEValues " << countEValues << endl; cout << "countCValues " << countCValues << endl; @@ -92,7 +92,28 @@ bool printValueCounters() { #endif +/** + * Common value constants. + */ class value; +extern const value nilValue; +extern const list nilListValue; +extern const list nilPairValue; +extern const value emptyStringValue; +extern const value trueValue; +extern const value falseValue; + +/** + * Common value-based lambda types. + */ +typedef lambda&)> lvvlambda; +typedef lambda vvlambda; +typedef lambda vblambda; +typedef lambda vlambda; + +/** + * Generic value type class. + */ class value { public: @@ -101,346 +122,309 @@ public: Nil, Symbol, String, List, Number, Bool, Lambda, Ptr }; - value() : type(value::Nil) { + typedef union { + const void* mix; + const gc_ptr > lst; + const string str; + const lvvlambda func; + const gc_ptr ptr; + const double num; + const bool boo; + } ValueMix; + + inline value() noexcept : type(value::Nil) { debug_inc(countValues); debug_inc(countEValues); debug_watchValue(); } - value(const value& v) { + inline value(const value& v) noexcept : type(v.type) { debug_inc(countValues); debug_inc(countCValues); - type = v.type; - switch(type) { - case value::List: - lst() = v.lst(); - case value::Lambda: - func() = v.func(); - case value::Symbol: - str() = v.str(); - case value::String: - str() = v.str(); - case value::Number: - num() = v.num(); - case value::Bool: - boo() = v.boo(); - case value::Ptr: - ptr() = v.ptr(); - default: - break; - } + memcpy((void*)&mix, (void*)&v.mix, sizeof(ValueMix)); #ifdef WANT_MAINTAINER_WATCH watch = v.watch; #endif } - virtual ~value() { + inline value(const gc_mutable_ref& r) noexcept : type(((value*)r)->type) { + debug_inc(countValues); + debug_inc(countCValues); + memcpy((void*)&mix, (void*)&(((value*)r)->mix), sizeof(ValueMix)); +#ifdef WANT_MAINTAINER_WATCH + watch = v.watch; +#endif + } + + inline virtual ~value() noexcept { debug_dec(countValues); } - value(const lambda&)>& func) : type(value::Lambda), data(vdata(func)) { + inline value(const lvvlambda& f) noexcept : type(value::Lambda), func(f) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const string& str) : type(value::String), data(vdata(result(str))) { + inline value(const string& s) noexcept : type(value::String), str(s) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const char* str) : type(value::Symbol), data(vdata(result(string(str)))) { + inline value(const char* s) noexcept : type(value::Symbol), str(s) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const list& lst) : type(value::List), data(vdata(result(lst))) { + inline value(const list& l) noexcept : type(value::List), lst(new (gc_new >()) list(l)) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const list >& l) : type(value::List), data(vdata(result(listOfValues(l)))) { + inline value(const list >& l) noexcept : type(value::List), lst(new (gc_new >()) list(listOfValues(l))) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const double num) : type(value::Number), data(vdata(result(num))) { + inline value(const double d) noexcept : type(value::Number), num(d) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const int num) : type(value::Number), data(vdata(result((double)num))) { + inline value(const int i) noexcept : type(value::Number), num((double)i) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const bool boo) : type(value::Bool), data(vdata(result(boo))) { + inline value(const bool b) noexcept : type(value::Bool), boo(b) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const gc_ptr ptr) : type(value::Ptr), data(vdata(result(ptr))) { + inline value(const gc_ptr p) noexcept : type(value::Ptr), ptr(p) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const failable& m) : type(value::List), - data(vdata(result(hasContent(m)? mklist(content(m)) : rcode(m) == 1? mklist(value(), reason(m)) : mklist(value(), reason(m), rcode(m))))) { + inline value(const failable& m) noexcept : type(value::List), + lst(new (gc_new >()) list(hasContent(m)? mklist(content(m)) : + rcode(m) == 1? mklist(nilValue, reason(m)) : mklist(nilValue, reason(m), rcode(m)))) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - value(const maybe& m) : type(value::List), - data(vdata(result(hasContent(m)? mklist(content(m)) : list()))) { + inline value(const maybe& m) noexcept : type(value::List), + lst(new (gc_new >()) list(hasContent(m)? mklist(content(m)) : nilListValue)) { debug_inc(countValues); debug_inc(countVValues); debug_watchValue(); } - const value& operator=(const value& v) { - if(this == &v) - return *this; - type = v.type; - switch(type) { - case value::List: - lst() = v.lst(); - case value::Lambda: - func() = v.func(); - case value::Symbol: - str() = v.str(); - case value::String: - str() = v.str(); - case value::Number: - num() = v.num(); - case value::Bool: - boo() = v.boo(); - case value::Ptr: - ptr() = v.ptr(); - default: - break; - } -#ifdef WANT_MAINTAINER_WATCH - watch = v.watch; -#endif - return *this; - } + value& operator=(const value& v) = delete; - const bool operator!=(const value& v) const { + inline const bool operator!=(const value& v) const noexcept { return !this->operator==(v); } - const bool operator==(const value& v) const { + inline const bool operator==(const value& v) const noexcept { if(this == &v) return true; switch(type) { case value::Nil: return v.type == value::Nil; case value::List: - return v.type == value::List && lst()() == v.lst()(); + return v.type == value::List && *lst == *v.lst; case value::Lambda: - return v.type == value::Lambda && func() == v.func(); + return v.type == value::Lambda && func == v.func; case value::Symbol: case value::String: - return str()() == (string)v; + return (v.type == value::Symbol || v.type == value::String) && str == v.str; case value::Number: - return num()() == (double)v; + return v.type == value::Number && num == v.num; case value::Bool: - return boo()() == (bool)v; + return v.type == value::Bool && boo == v.boo; case value::Ptr: - return v.type == value::Ptr && ptr()() == v.ptr()(); + return v.type == value::Ptr && ptr == v.ptr; default: return false; } } - const bool operator<(const value& v) const { + inline const bool operator<(const value& v) const noexcept { if(this == &v) return false; switch(type) { case value::List: - return v.type == value::List && lst()() < v.lst()(); + return v.type == value::List && *lst < *v.lst; case value::Symbol: case value::String: - return str()() < (string)v; + return (v.type == value::Symbol || v.type == value::String) && str < v.str; case value::Bool: - return boo()() < (bool)v; + return v.type == value::Bool && boo < v.boo; case value::Number: - return num()() < (double)v; + return v.type == value::Number && num < v.num; default: return false; } } - const bool operator>(const value& v) const { + inline const bool operator>(const value& v) const noexcept { if(this == &v) return false; switch(type) { case value::List: - return v.type == value::List && lst()() > v.lst()(); + return v.type == value::List && *lst > *v.lst; case value::Symbol: case value::String: - return str()() > (string)v; + return (v.type == value::Symbol || v.type == value::String) && str > v.str; case value::Bool: - return boo()() > (bool)v; + return v.type == value::Bool && boo > v.boo; case value::Number: - return num()() > (double)v; + return v.type == value::Number && num > v.num; default: return false; } } - const value operator()(const list& args) const { - return func()(args); + inline const value operator()(const list& args) const noexcept { + return func(args); } - operator const string() const { + inline operator const string() const noexcept { switch(type) { case value::Symbol: case value::String: - return str()(); + return str; case value::Number: { ostringstream os; - os << num()(); + os << num; return tuscany::str(os); } case value::Bool: - return boo()()? trueString : falseString; + return boo? trueString : falseString; default: return emptyString; } } - operator const double() const { + inline operator const double() const noexcept { switch(type) { case value::Symbol: case value::String: - return atof(c_str(str()())); + return atof(c_str(str)); case value::Number: - return (double)num()(); + return (double)num; case value::Bool: - return boo()()? 1.0 : 0.0; + return boo? 1.0 : 0.0; default: return 0.0; } } - operator const int() const { + inline operator const int() const noexcept { switch(type) { case value::Symbol: case value::String: - return atoi(c_str(str()())); + return atoi(c_str(str)); case value::Number: - return (int)num()(); + return (int)num; case value::Bool: - return boo()()? 1 : 0; + return boo? 1 : 0; default: return 0; } } - operator const bool() const { + inline operator const bool() const noexcept { switch(type) { case value::Symbol: case value::String: - return str()() == string("true"); + return str == trueString; case value::Number: - return (int)num()() != 0; + return num != 0.0; case value::Bool: - return boo()(); + return boo; default: - return 0; + return false; } } - operator const gc_ptr() const { - return ptr()(); + inline operator const gc_ptr() const noexcept { + return ptr; } - operator const list() const { - return lst()(); + inline operator const list() const noexcept { + return *lst; } - operator const list >() const { - return listOfListOfValues(lst()()); + inline operator const list >() const noexcept { + return listOfListOfValues(*lst); } - operator const lambda&)>() const { - return func(); + inline operator const lvvlambda() const noexcept { + return func; } private: - template lambda& vdata() const { - return *reinterpret_cast *> (const_cast *> (&data)); - } - - template const lambda& vdata(const T& v) const { - return *reinterpret_cast *> (&v); - } - - lambda& num() const { - return vdata (); - } - - lambda& boo() const { - return vdata (); - } - - lambda()>& ptr() const { - return vdata()> (); - } - - lambda& str() const { - return vdata (); - } - - lambda()>& lst() const { - return vdata()> (); - } - - lambda&)>& func() const { - return vdata&)> (); - } - - const list listOfValues(const list >& l) const { + inline const list listOfValues(const list >& l) const noexcept { if (isNil(l)) - return list(); + return nilListValue; return cons(car(l), listOfValues(cdr(l))); } - const list > listOfListOfValues(const list& l) const { + inline const list > listOfListOfValues(const list& l) const noexcept { if (isNil(l)) return list >(); - return cons >(list(car(l)), listOfListOfValues(cdr(l))); + return cons >(car(l).type == value::List? list(car(l)) : nilPairValue, listOfListOfValues(cdr(l))); } - friend ostream& operator<<(ostream&, const value&); - friend const value::ValueType type(const value& v); + friend ostream& operator<<(ostream&, const value&) noexcept; + friend const value::ValueType type(const value& v) noexcept; + friend const bool setvalue(value& target, const value& v); #ifdef WANT_MAINTAINER_WATCH friend const string watchValue(const value& v); string watch; #endif - ValueType type; - lambda data; + const ValueType type; + union { + void* mix; + const gc_ptr > lst; + const string str; + const lvvlambda func; + const gc_ptr ptr; + const double num; + const bool boo; + }; }; +/** + * Common value constants. + */ +const value nilValue; +const list nilListValue = list(); +const list nilPairValue = mklist(nilValue, nilValue); +const value emptyStringValue(emptyString); +const value trueValue(true); +const value falseValue(false); + #ifdef WANT_MAINTAINER_WATCH /** * Debug utility used to write the contents of a value to a string, easier * to watch than the value itself in a debugger. */ -const string watchValue(const value& v) { +inline const string watchValue(const value& v) { if (v.type == value::List) return watchList(v); odebugstream os; @@ -453,7 +437,7 @@ const string watchValue(const value& v) { /** * Write an escape string to a buffer. */ -const char* escapestr(const char* s, char* buf) { +inline const char* escapestr(const char* const s, char* const buf) noexcept { if (*s == '\0') { *buf = '\0'; return buf; @@ -470,7 +454,7 @@ const char* escapestr(const char* s, char* buf) { /** * Write an escaped string value to a stream. */ -ostream& escvwrite(const string& str, ostream& out) { +inline ostream& escvwrite(const string& str, ostream& out) noexcept { char* buf = gc_cnew(length(str) * 2 + 1); escapestr(c_str(str), buf); out << buf; @@ -480,30 +464,29 @@ ostream& escvwrite(const string& str, ostream& out) { /** * Write a value to a stream. */ -ostream& operator<<(ostream& out, const value& v) { +inline ostream& operator<<(ostream& out, const value& v) noexcept { switch(v.type) { case value::List: - return out << v.lst()(); + return out << *v.lst; case value::Lambda: - return out << "lambda::" << v.func(); + return out << "lambda::" << v.func; case value::Symbol: - return out << v.str()(); + return out << v.str; case value::String: out << '\"'; - escvwrite(v.str()(), out); + escvwrite(v.str, out); return out << '\"'; case value::Number: - return out << v.num()(); + return out << v.num; case value::Bool: - if(v.boo()()) - return out << "true"; + if(v.boo) + return out << trueString; else - return out << "false"; + return out << falseString; case value::Ptr: { - const gc_ptr p = v.ptr()(); - if (p == gc_ptr(NULL)) + if (v.ptr == gc_ptr(NULL)) return out << "gc_ptr::null"; - return out << "gc_ptr::" << p; + return out << "gc_ptr::" << v.ptr; } default: return out << "nil"; @@ -513,70 +496,70 @@ ostream& operator<<(ostream& out, const value& v) { /** * Returns the type of a value. */ -const value::ValueType type(const value& v) { +inline const value::ValueType type(const value& v) noexcept { return v.type; } /** * Returns true if a value is nil. */ -const bool isNil(const value& v) { +inline const bool isNil(const value& v) noexcept { return type(v) == value::Nil; } /** * Returns true if a value is a lambda. */ -const bool isLambda(const value& v) { +inline const bool isLambda(const value& v) noexcept { return type(v) == value::Lambda; } /** * Returns true if a value is a string. */ -const bool isString(const value& v) { +inline const bool isString(const value& v) noexcept { return type(v) == value::String; } /** * Returns true if a value is a symbol. */ -const bool isSymbol(const value& v) { +inline const bool isSymbol(const value& v) noexcept { return type(v) == value::Symbol; } /** * Returns true if a value is a list. */ -const bool isList(const value& v) { +inline const bool isList(const value& v) noexcept { return type(v) == value::List; } /** * Returns true if a value is a number. */ -const bool isNumber(const value& v) { +inline const bool isNumber(const value& v) noexcept { return type(v) == value::Number; } /** * Returns true if a value is a boolean. */ -const bool isBool(const value& v) { +inline const bool isBool(const value& v) noexcept { return type(v) == value::Bool; } /** * Returns true if a value is a pointer. */ -const bool isPtr(const value& v) { +inline const bool isPtr(const value& v) noexcept { return type(v) == value::Ptr; } /** * Returns true if a value is a tagged list. */ -const bool isTaggedList(const value& exp, value tag) { +inline const bool isTaggedList(const value& exp, const value& tag) noexcept { if(isList(exp) && !isNil((list)exp)) return car((list)exp) == tag; return false; @@ -585,16 +568,16 @@ const bool isTaggedList(const value& exp, value tag) { /** * Make a list of values from a list of other things. */ -template const list mkvalues(const list& l) { +template inline const list mkvalues(const list& l) noexcept { if (isNil(l)) - return list(); + return nilListValue; return cons(car(l), mkvalues(cdr(l))); } /** * Convert a list of values to a list of other things. */ -template const list convertValues(const list& l) { +template inline const list convertValues(const list& l) noexcept { if (isNil(l)) return list(); return cons(car(l), convertValues(cdr(l))); @@ -603,7 +586,7 @@ template const list convertValues(const list& l) { /** * Convert a path string value to a list of values. */ -const list pathTokens(const char* p) { +inline const list pathTokens(const char* const p) noexcept { if (p == NULL || p[0] == '\0') return list(); if (p[0] == '/') @@ -611,23 +594,23 @@ const list pathTokens(const char* p) { return tokenize("/", p); } -const list pathValues(const value& p) { +inline const list pathValues(const value& p) noexcept { return mkvalues(pathTokens(c_str(p))); } /** * Convert a path represented as a list of values to a string value. */ -const value path(const list& p) { +inline const value path(const list& p) noexcept { if (isNil(p)) - return ""; - return string("/") + car(p) + path(cdr(p)); + return emptyString; + return string("/") + (string)car(p) + (string)path(cdr(p)); } /** * Make a uuid value. */ -const value mkuuid() { +inline const value mkuuid() noexcept { apr_uuid_t id; apr_uuid_get(&id); char buf[APR_UUID_FORMATTED_LENGTH]; @@ -638,19 +621,33 @@ const value mkuuid() { /** * Make a random alphanumeric value. */ -const int intrand() { +inline const int intrand() noexcept { const apr_uint64_t now = apr_time_now(); srand((unsigned int)(((now >> 32) ^ now) & 0xffffffff)); return rand() & 0x0FFFF; } -const value mkrand() { +inline const value mkrand() noexcept { char buf[32]; - const char* an = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + const char* const an = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; for (int i =0; i < 32; i++) buf[i] = an[intrand() % 62]; return value(string(buf, 32)); } +/** + * Set a value. Use with moderation. + */ +inline const bool setvalue(value& target, const value& v) { + if (&target == &v) + return true; +#ifdef WANT_MAINTAINER_WATCH + memcpy(&target.watch, &v.watch, sizeof(string)); +#endif + memcpy((void*)&target.type, (void*)&v.type, sizeof(value::ValueType)); + memcpy((void*)&target.mix, (void*)&v.mix, sizeof(value::ValueMix)); + return true; +} + } #endif /* tuscany_value_hpp */ -- cgit v1.2.3