diff options
Diffstat (limited to 'cpp/sca')
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/function.hpp | 235 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/gc.hpp | 269 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/list.hpp | 348 | ||||
-rw-r--r-- | cpp/sca/runtime/core/src/tuscany/value.hpp | 341 |
4 files changed, 1193 insertions, 0 deletions
diff --git a/cpp/sca/runtime/core/src/tuscany/function.hpp b/cpp/sca/runtime/core/src/tuscany/function.hpp new file mode 100644 index 0000000000..e0e8889dad --- /dev/null +++ b/cpp/sca/runtime/core/src/tuscany/function.hpp @@ -0,0 +1,235 @@ +/* + * 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_function_hpp +#define tuscany_function_hpp + +/** + * Lambda function type, used to represent service operations. + */ + +#include <iostream> +#include "gc.hpp" + +using std::ostream; + +namespace tuscany { + +/** + * Debug counters. + */ +long int countProxies; +long int countFProxies = 0; +long int countCProxies = 0; +long int countLambdas = 0; +long int countELambdas = 0; +long int countCLambdas = 0; +long int countFLambdas = 0; + +bool resetLambdaCounters() { + countLambdas = countELambdas = countCLambdas = countFLambdas = countProxies = countFProxies = countCProxies = 0; + return true; +} + +bool printLambdaCounters() { + using std::cout; + using std::endl; + cout << "countLambdas " << countLambdas << endl; + cout << "countELambdas " << countELambdas << endl; + cout << "countFLambdas " << countFLambdas << endl; + cout << "countCLambdas " << countCLambdas << endl; + cout << "countProxies " << countProxies << endl; + cout << "countFProxies " << countFProxies << endl; + cout << "countCProxies " << countCProxies << endl; + return true; +} + +/** + * Lambda function type. + */ + +template<typename R, typename... P> class Callable { +public: + unsigned int refCount; + + Callable() : refCount(0) { + } + + virtual const int size() const = 0; + + virtual const R operator()(P... p) const = 0; + + virtual ~Callable() { + } + + unsigned int acquire() { + return ++refCount; + } + + unsigned int release() { + return --refCount; + } + + template<typename F> class Proxy: public Callable { + public: + explicit Proxy(const F& f) : function(f) { + countProxies++; + countFProxies ++; + } + + Proxy(const Proxy& p) : function(p.function) { + countProxies++; + countCProxies ++; + } + + ~Proxy() { + countProxies--; + } + + virtual const R operator() (P... p) const { + return function(std::forward<P>(p)...); + } + + virtual const int size() const { + return sizeof(function); + } + + private: + const F function; + }; + +}; + +template<typename S> class lambda; + +template<typename R, typename... P> class lambda<R(P...)> { +public: + lambda() : callable(0) { + countLambdas++; + countELambdas++; + } + + template<typename F> explicit lambda(const F f) : callable(0) { + typedef typename CallableType::template Proxy<F> ProxyType; + + countLambdas++; + countFLambdas++; + callable = gc_counting_ptr<CallableType>(new ProxyType(f)); + } + + lambda(const lambda& l) { + countLambdas++; + countCLambdas++; + callable = l.callable; + } + + const lambda& operator=(const lambda& l) { + if (this == &l) + return *this; + callable = l.callable; + return *this; + } + + ~lambda() { + countLambdas--; + } + + const bool operator==(const lambda& l) const { + if (this == &l) + return true; + return callable == l.callable; + } + + const bool operator!=(const lambda& l) const { + return !this->operator==(l); + } + + const R operator()(P... p) const { + return (*callable)(std::forward<P>(p)...); + } + + template<typename S> friend ostream& operator<<(ostream&, const lambda<S>&); + +private: + typedef Callable<R,P...> CallableType; + gc_counting_ptr<CallableType> callable; +}; + +template<typename S> ostream& operator<<(ostream& out, const lambda<S>& l) { + return out << "lambda::" << l.callable; +} + +/** + * Creates a lambda function from a pointer to a function. + */ +template<typename R, typename... P> lambda<R(P...)> makeLambda(const R (* const f)(P...)) { + return lambda<R(P...)>(f); +} + +/** + * Curry a lambda function. + */ +template<typename R, typename T, typename... P> class Curried { +private: + const T v; + const lambda<R(T, P...)>f; + +public: + Curried(const lambda<R(T, P...)>& f, const T& v): v(v), f(f) { + } + + const R operator()(P... p) const { + return f(v, std::forward<P>(p)...); + } + +}; + +template<typename R, typename T, typename... P> const lambda<R(P...)> curry(const lambda<R(T, P...)>& f, const T& t) { + return (lambda<R(P...)>)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) { + 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, P...)>& f, const T& t, const U& u, const V& v) { + return curry(curry(curry(f, t), u), v); +} + +/** + * A lambda function that returns the given value. + */ +template<typename T> struct unitReturn { + const T v; + unitReturn(const T& v) : + v(v) { + } + const T operator()() const { + return v; + } +}; + +template<typename T> const lambda<T()> unit(const T& v) { + return lambda<T()> (unitReturn<T> (v)); +} + +} +#endif /* tuscany_function_hpp */ diff --git a/cpp/sca/runtime/core/src/tuscany/gc.hpp b/cpp/sca/runtime/core/src/tuscany/gc.hpp new file mode 100644 index 0000000000..803ec31643 --- /dev/null +++ b/cpp/sca/runtime/core/src/tuscany/gc.hpp @@ -0,0 +1,269 @@ +/* + * 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_gc_hpp +#define tuscany_gc_hpp + +/** + * Garbage collected pointer. + */ + +#include <ostream> + +using std::ostream; + +namespace tuscany +{ + +template<typename T> class gc_ptr { +public: + explicit gc_ptr(T* p = 0) throw() : countingRef(p == 0? 0 : new CountingRef(p)) { + } + + ~gc_ptr() throw() { + release(); + } + + gc_ptr(const gc_ptr& r) throw() : countingRef(r.countingRef) { + acquire(r.countingRef); + } + + gc_ptr& operator=(const gc_ptr& r) throw() { + if(this == &r) + return *this; + acquire(r.countingRef); + release(); + countingRef = r.countingRef; + return *this; + } + + const bool operator==(const gc_ptr& r) const throw() { + if (this == &r) + return true; + if (countingRef == NULL) + return r.countingRef == NULL; + if (r.countingRef == NULL) + return false; + return countingRef-> ptr == r.countingRef->ptr; + } + + const bool operator!=(const gc_ptr& r) const throw() { + return !this->operator ==(r); + } + + T& operator*() const throw() { + return *countingRef->ptr; + } + + T* operator->() const throw() { + return countingRef->ptr; + } + + operator T*() const throw() { + return countingRef->ptr; + } + + template<typename X> friend ostream& operator<<(ostream&, const gc_ptr<X>&); + +private: + struct CountingRef { + T* ptr; + unsigned count; + + CountingRef(T* p) throw() : + ptr(p), count(1) { + } + }* countingRef; + + void acquire(CountingRef* ref) throw() { + if(ref) + ++ref->count; + } + + void release() throw() { + if(countingRef) { + if(--countingRef->count == 0) { + delete countingRef->ptr; + delete countingRef; + } + } + } +}; + +template<typename T> ostream& operator<<(ostream& out, const gc_ptr<T>& p) { + return out << p.countingRef->ptr; +} + +/** + * Garbage collected pointer to an array. + */ +template<typename T> class gc_aptr { +public: + explicit gc_aptr(T* p = 0) throw() : countingRef(p == 0? 0 : new CountingRef(p)) { + } + + ~gc_aptr() throw() { + release(); + } + + gc_aptr(const gc_aptr& r) throw() : countingRef(r.countingRef) { + acquire(r.countingRef); + } + + gc_aptr& operator=(const gc_aptr& r) throw() { + if(this == &r) + return *this; + acquire(r.countingRef); + release(); + countingRef = r.countingRef; + return *this; + } + + const bool operator==(const gc_aptr& r) const throw() { + if (this == &r) + return true; + if (countingRef == NULL) + return r.countingRef == NULL; + if (r.countingRef == NULL) + return false; + return countingRef-> ptr == r.countingRef->ptr; + } + + const bool operator!=(const gc_aptr& r) const throw() { + return !this->operator ==(r); + } + + T& operator*() const throw() { + return *countingRef->ptr; + } + + T* operator->() const throw() { + return countingRef->ptr; + } + + operator T*() const throw() { + return countingRef->ptr; + } + + template<typename X> friend ostream& operator<<(ostream&, const gc_aptr<X>&); + +private: + struct CountingRef { + T* ptr; + unsigned count; + + CountingRef(T* p) throw() : + ptr(p), count(1) { + } + }* countingRef; + + void acquire(CountingRef* ref) throw() { + if(ref) + ++ref->count; + } + + void release() throw() { + if(countingRef) { + if(--countingRef->count == 0) { + delete[] countingRef->ptr; + delete countingRef; + } + } + } +}; + +template<typename T> ostream& operator<<(ostream& out, const gc_aptr<T>& p) { + return out << p.countingRef->ptr; +} + +/** + * Garbage collected pointer to a reference counting object. + */ +template<typename T> class gc_counting_ptr { +public: + explicit gc_counting_ptr(T* p = 0) throw() : ptr(p) { + acquire(p); + } + + ~gc_counting_ptr() throw() { + release(); + } + + gc_counting_ptr(const gc_counting_ptr& r) throw() : ptr(r.ptr) { + acquire(ptr); + } + + gc_counting_ptr& operator=(const gc_counting_ptr& r) throw() { + if(this == &r) + return *this; + acquire(r.ptr); + release(); + ptr = r.ptr; + return *this; + } + + const bool operator==(const gc_counting_ptr& r) const throw() { + if (this == &r) + return true; + return ptr == r.ptr; + } + + const bool operator!=(const gc_counting_ptr& r) const throw() { + return !this->operator ==(r); + } + + T& operator*() const throw() { + return *ptr; + } + + T* operator->() const throw() { + return ptr; + } + + operator T*() const throw() { + return ptr; + } + + template<typename X> friend ostream& operator<<(ostream&, const gc_counting_ptr<X>&); + +private: + T* ptr; + + void acquire(T* p) throw() { + if(p) + p->acquire(); + } + + void release() throw() { + if(ptr) { + if(ptr->release() == 0) { + delete ptr; + } + } + } +}; + +template<typename T> ostream& operator<<(ostream& out, const gc_counting_ptr<T>& p) { + return out << p.ptr; +} + +} +#endif /* tuscany_gc_hpp */ diff --git a/cpp/sca/runtime/core/src/tuscany/list.hpp b/cpp/sca/runtime/core/src/tuscany/list.hpp new file mode 100644 index 0000000000..e180ad6134 --- /dev/null +++ b/cpp/sca/runtime/core/src/tuscany/list.hpp @@ -0,0 +1,348 @@ +/* + * 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_list_hpp +#define tuscany_list_hpp + +/** + * Simple list functions. + */ + +#include <iostream> +#include "function.hpp" + +using std::ostream; + +namespace tuscany { + +long countlists = 0; +long countIlists = 0; +long countClists = 0; +long countElists = 0; + +bool resetlistCounters() { + countlists = countIlists = countClists = countElists = 0; + return true; +} + +bool printlistCounters() { + using std::cout; + using std::endl; + cout << "countlists " << countlists << endl; + cout << "countElists " << countElists << endl; + cout << "countIlists " << countIlists << endl; + cout << "countClists " << countClists << endl; + return true; +} + +/** + * A car/cdr lisp-like pair, base structure to construct lists. + */ + +template<typename T> struct list { + bool nil; + T car; + lambda<list<T> ()> cdr; + + list(const T car, const lambda<list<T> ()> cdr) : + nil(false), car(car), cdr(cdr) { + countlists++; + countIlists++; + } + + list() : + nil(true) { + countlists++; + countElists++; + } + + list(const list& p) : + nil(p.nil), car(p.car), cdr(p.cdr) { + countlists++; + countClists++; + } + + const list& operator=(const list<T>& p) { + if(this == &p) + return *this; + nil = p.nil; + car = p.car; + cdr = p.cdr; + return *this; + } + + ~list() { + countlists--; + } + + const bool operator==(const list<T>& p) const { + if(this == &p) + return true; + if(nil) + return p.nil; + if(p.nil) + return false; + if(!(car == p.car)) + return false; + if(cdr == p.cdr) + return true; + return cdr() == p.cdr(); + } + + const bool operator!=(const list<T>& p) const { + return !this->operator==(p); + } + + template<typename X> friend ostream& operator<<(ostream&, const list<X>&); + +}; + +/** + * Returns true if the given list is nil. + */ +template<typename T> const bool isNil(const list<T>& p) { + return p.nil; +} + +/** + * Write a list to an output stream. + */ +template<typename X> ostream& operator<<(ostream& out, const list<X>& l) { + if(l == list<X> ()) + return out << "()"; + return out << "(" << car(l) << ", " << cdr(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) { + 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) { + return list<T> (car, unit(cdr)); +} + +/** + * Construct a list of one value. + */ +template<typename T> const list<T> makeList(const T& car) { + return list<T> (car, unit(list<T> ())); +} + +/** + * Construct a list of two values. + */ +template<typename T> const list<T> makeList(const T& a, const T& b) { + return cons(a, makeList(b)); +} + +/** + * Construct a list of three values. + */ +template<typename T> const list<T> makeList(const T& a, const T& b, const T& c) { + return cons(a, cons(b, makeList(c))); +} + +/** + * Construct a list of four values. + */ +template<typename T> const list<T> makeList(const T& a, const T& b, const T& c, const T& d) { + return cons(a, cons(b, cons(c, makeList(d)))); +} + +/** + * Returns the car of a list. + */ +template<typename T> const T car(const list<T>& p) { + return p.car; +} + +/** + * Returns the cdr of a list. + */ +template<typename T> list<T> const cdr(const list<T>& p) { + return p.cdr(); +} + +/** + * Returns the car of the cdr of a list. + */ +template<typename T> const T cadr(const list<T>& p) { + return car(cdr(p)); +} + +/** + * Returns the cdr of a cdr of a list. + */ +template<typename T> const list<T> cddr(const list<T>& p) { + return cdr(cdr(p)); +} + +/** + * Returns the length of a list. + */ +template<typename T> struct lengthRef { + const int operator()(const int c, const list<T>& p) { + if(isNil(p)) + return c; + return (*this)(c + 1, cdr(p)); + } +}; + +template<typename T> const int length(const list<T>& p) { + return lengthRef<T> ()(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) { + if(isNil(a)) + return fb(); + + return cons(car(a), lambda<list<T> ()> (appendCdr<T> (cdr(a), fb))); +} + +/** + * Appends two lists. + */ +template<typename T> const list<T> append(const list<T>&a, const list<T>& b) { + return append(a, unit(b)); +} + +/** + * Map a lambda function on a list. + */ +template<typename T, typename R> const list<R> map(const lambda<R(T)>& f, const list<T>& p) { + if(isNil(p)) + return list<R> (); + return cons(f(car(p)), map(f, cdr(p))); +} + +/** + * Run a reduce lambda function on a list. + */ +template<typename T, typename R> struct reduceAccumulate { + const lambda<R(R, T)> f; + reduceAccumulate(const lambda<R(R, T)>& f) : + f(f) { + } + R operator()(const R& acc, const list<T>& p) const { + if(isNil(p)) + return acc; + return (*this)(f(acc, car(p)), cdr(p)); + } +}; + +template<typename T, typename R> const R reduce(const lambda<R(R, T)>& f, const R& initial, const list<T>& p) { + return reduceAccumulate<T, R> (f)(initial, p); +} + +/** + * Run a filter lambda function on a list. + */ +template<typename T> const list<T> filter(const lambda<bool(T)>& f, const list<T>& p) { + if(isNil(p)) + return list<T> (); + if(f(car(p))) { + const lambda<list<T> (lambda<bool(T)> , list<T> )> ff(filter<T> ); + return cons(car(p), curry(ff, f, cdr(p))); + } + return filter(f, cdr(p)); +} + +/** + * Returns a list pointing to a member of a list. + */ +template<typename T> const list<T> member(const T& t, const list<T>& p) { + if(isNil(p)) + return list<T> (); + if(t == car(p)) + return p; + return member(t, cdr(p)); +} + +/** + * Reverse a list. + */ +template<typename T> 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) { + 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) { + if(start == end) + return makeList(start); + if(start < end) + return cons(start, lambda<list<T> ()> (seqGenerate<T> (start + 1, end))); + return cons(start, lambda<list<T> ()> (seqGenerate<T> (start - 1, end))); +} + +/** + * Equivalent of the list assoc function. + */ +template<typename T> const list<T> assoc(const T& k, const list<list<T> >& p) { + if(isNil(p)) + return list<T> (); + if(k == car(car(p))) + return car(p); + return assoc(k, cdr(p)); +} + +} +#endif /* tuscany_list_hpp */ 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 */ |