summaryrefslogtreecommitdiffstats
path: root/cpp/sca
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/sca')
-rw-r--r--cpp/sca/runtime/core/src/tuscany/function.hpp235
-rw-r--r--cpp/sca/runtime/core/src/tuscany/gc.hpp269
-rw-r--r--cpp/sca/runtime/core/src/tuscany/list.hpp348
-rw-r--r--cpp/sca/runtime/core/src/tuscany/value.hpp341
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 */