diff options
Diffstat (limited to '')
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/value.hpp | 341 |
1 files changed, 341 insertions, 0 deletions
diff --git a/cpp/sca/runtime/core/src/tuscany/value.hpp b/cpp/sca/runtime/core/src/tuscany/value.hpp new file mode 100644 index 0000000000..e92a9178ca --- /dev/null +++ b/cpp/sca/runtime/core/src/tuscany/value.hpp @@ -0,0 +1,341 @@ +/* + * 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_value_hpp +#define tuscany_value_hpp + +/** + * Generic value type. + */ + +#include <string> +#include <ostream> +#include "gc.hpp" +#include "function.hpp" +#include "list.hpp" + +using std::string; +using std::ostream; +using std::cout; +using std::endl; + +namespace tuscany +{ + +long int countValues = 0; +long int countEValues = 0; +long int countCValues = 0; +long int countVValues = 0; + +bool resetValueCounters() { + countValues = countEValues = countCValues = countVValues = 0; + return true; +} + +bool printValueCounters() { + using std::cout; + using std::endl; + cout << "countValues " << countValues << endl; + cout << "countEValues " << countEValues << endl; + cout << "countCValues " << countCValues << endl; + cout << "countVValues " << countVValues << endl; + return true; +} + +class Value; + +class Value { +public: + + enum ValueType { + Undefined, Symbol, String, List, Number, Boolean, Character, Lambda + }; + + Value() : + type(Value::Undefined) { + countValues++; + countEValues++; + } + + Value(const Value& v) { + countValues++; + 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::Boolean: + boo() = v.boo(); + case Value::Character: + chr() = v.chr(); + default: + break; + } + } + + 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::Boolean: + boo() = v.boo(); + case Value::Character: + chr() = v.chr(); + default: + break; + } + return *this; + } + + virtual ~Value() { + countValues--; + } + + Value(const lambda<Value(list<Value>&)>& func) : + type(Value::Lambda), data(vdata(func)) { + countValues++; + countVValues++; + } + + Value(const string& str) : + type(Value::String), data(vdata(unit(str))) { + countValues++; + countVValues++; + } + + Value(const char* str) : + type(Value::Symbol), data(vdata(unit(string(str)))) { + countValues++; + countVValues++; + } + + Value(const list<Value>& lst) : + type(Value::List), data(vdata(unit(lst))) { + countValues++; + countVValues++; + } + + Value(const double num) : + type(Value::Number), data(vdata(unit(num))) { + countValues++; + countVValues++; + } + + Value(const int num) : + type(Value::Number), data(vdata(unit((double)num))) { + countValues++; + countVValues++; + } + + Value(const bool boo) : + type(Value::Boolean), data(vdata(unit(boo))) { + countValues++; + countVValues++; + } + + Value(const char chr) : + type(Value::Character), data(vdata(unit(chr))) { + countValues++; + countVValues++; + } + + const bool operator!=(const Value& v) const { + return !this->operator==(v); + } + + const bool operator==(const Value& v) const { + if(this == &v) + return true; + if(type != v.type) + return false; + switch(type) { + case Value::Undefined: + return true; + case Value::List: + return lst()() == v.lst()(); + case Value::Lambda: + return func() == v.func(); + case Value::Symbol: + return str()() == v.str()(); + case Value::String: + return str()() == v.str()(); + case Value::Number: + return num()() == v.num()(); + case Value::Boolean: + return boo()() == v.boo()(); + case Value::Character: + return chr()() == v.chr()(); + default: + return false; + } + } + + const Value operator()(list<Value>& args) const { + return func()(args); + } + + operator string() const { + return str()(); + } + + operator double() const { + return num()(); + } + + operator int() const { + return num()(); + } + + operator bool() const { + return boo()(); + } + + operator char() const { + return chr()(); + } + + operator list<Value>() const { + return lst()(); + } + + operator lambda<Value(list<Value>&)>() const { + return func(); + } + + friend ostream& operator<<(ostream&, const Value&); + + ValueType type; + lambda<char()> data; + +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<char()>& chr() const { + return vdata<char()> (); + } + + lambda<string()>& str() const { + return vdata<string()> (); + } + + lambda<list<Value>()>& lst() const { + return vdata<list<Value>()> (); + } + + lambda<Value(list<Value>&)>& func() const { + return vdata<Value(list<Value>&)> (); + } + +}; + +ostream& operator<<(ostream& out, const Value& v) { + switch(v.type) { + case Value::List: + return out << "List::" << v.lst()(); + case Value::Lambda: + return out << "Lambda::" << v.func(); + case Value::Symbol: + return out << "Symbol::" << v.str()(); + case Value::String: + return out << "String::" << '\'' << v.str()() << '\''; + case Value::Number: + return out << "Number::" << v.num()(); + case Value::Boolean: + if(v.boo()()) + return out << "Boolean::" << "true"; + else + return out << "Boolean::" << "false"; + case Value::Character: + return out << "Character::" << v.chr()(); + default: + return out << "Undefined"; + } +} + +const bool isNull(const Value& value) { + return value.type == Value::Undefined; +} + +const bool isString(const Value& value) { + return value.type == Value::String; +} + +const bool isSymbol(const Value& value) { + return value.type == Value::Symbol; +} + +const bool isList(const Value& value) { + return value.type == Value::List; +} + +const bool isNumber(const Value& value) { + return value.type == Value::Number; +} + +const bool isBoolean(const Value& value) { + return value.type == Value::Boolean; +} + +const bool isCharacter(const Value& value) { + return value.type == Value::Character; +} + +const bool isTaggedList(const Value& exp, Value tag) { + if(isList(exp)) + return car((list<Value> )exp) == tag; + return false; +} + +} +#endif /* tuscany_value_hpp */ |