From 67618c80483e01793351b20cbbbc5a56a6a8f016 Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Mon, 14 Sep 2009 05:55:14 +0000 Subject: Utility functions and headers used by the sample store app, function objects, lists and strawman pointer utils. Started to implement a generic value holder object that can help exchange data with scripting components. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@814481 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/sca/runtime/core/src/tuscany/function.hpp | 235 +++++++++++++++++ cpp/sca/runtime/core/src/tuscany/gc.hpp | 269 ++++++++++++++++++++ cpp/sca/runtime/core/src/tuscany/list.hpp | 348 ++++++++++++++++++++++++++ cpp/sca/runtime/core/src/tuscany/value.hpp | 341 +++++++++++++++++++++++++ 4 files changed, 1193 insertions(+) create mode 100644 cpp/sca/runtime/core/src/tuscany/function.hpp create mode 100644 cpp/sca/runtime/core/src/tuscany/gc.hpp create mode 100644 cpp/sca/runtime/core/src/tuscany/list.hpp create mode 100644 cpp/sca/runtime/core/src/tuscany/value.hpp (limited to 'cpp') 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 +#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 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 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)...); + } + + virtual const int size() const { + return sizeof(function); + } + + private: + const F function; + }; + +}; + +template class lambda; + +template class lambda { +public: + lambda() : callable(0) { + countLambdas++; + countELambdas++; + } + + template explicit lambda(const F f) : callable(0) { + typedef typename CallableType::template Proxy ProxyType; + + countLambdas++; + countFLambdas++; + callable = gc_counting_ptr(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)...); + } + + template friend ostream& operator<<(ostream&, const lambda&); + +private: + typedef Callable CallableType; + gc_counting_ptr callable; +}; + +template ostream& operator<<(ostream& out, const lambda& l) { + return out << "lambda::" << l.callable; +} + +/** + * Creates a lambda function from a pointer to a function. + */ +template lambda makeLambda(const R (* const f)(P...)) { + return lambda(f); +} + +/** + * Curry a lambda function. + */ +template class Curried { +private: + const T v; + const lambdaf; + +public: + Curried(const lambda& f, const T& v): v(v), f(f) { + } + + const R operator()(P... p) const { + return f(v, std::forward

(p)...); + } + +}; + +template const lambda curry(const lambda& f, const T& t) { + return (lambda)Curried(f, t); +} + +template const lambda curry(const lambda& f, const T& t, const U& u) { + return curry(curry(f, t), u); +} + +template const lambda curry(const lambda& 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 struct unitReturn { + const T v; + unitReturn(const T& v) : + v(v) { + } + const T operator()() const { + return v; + } +}; + +template const lambda unit(const T& v) { + return lambda (unitReturn (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 + +using std::ostream; + +namespace tuscany +{ + +template 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 friend ostream& operator<<(ostream&, const gc_ptr&); + +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 ostream& operator<<(ostream& out, const gc_ptr& p) { + return out << p.countingRef->ptr; +} + +/** + * Garbage collected pointer to an array. + */ +template 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 friend ostream& operator<<(ostream&, const gc_aptr&); + +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 ostream& operator<<(ostream& out, const gc_aptr& p) { + return out << p.countingRef->ptr; +} + +/** + * Garbage collected pointer to a reference counting object. + */ +template 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 friend ostream& operator<<(ostream&, const gc_counting_ptr&); + +private: + T* ptr; + + void acquire(T* p) throw() { + if(p) + p->acquire(); + } + + void release() throw() { + if(ptr) { + if(ptr->release() == 0) { + delete ptr; + } + } + } +}; + +template ostream& operator<<(ostream& out, const gc_counting_ptr& 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 +#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 struct list { + bool nil; + T car; + lambda ()> cdr; + + list(const T car, const lambda ()> 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& p) { + if(this == &p) + return *this; + nil = p.nil; + car = p.car; + cdr = p.cdr; + return *this; + } + + ~list() { + countlists--; + } + + const bool operator==(const list& 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& p) const { + return !this->operator==(p); + } + + template friend ostream& operator<<(ostream&, const list&); + +}; + +/** + * Returns true if the given list is nil. + */ +template const bool isNil(const list& p) { + return p.nil; +} + +/** + * Write a list to an output stream. + */ +template ostream& operator<<(ostream& out, const list& l) { + if(l == list ()) + return out << "()"; + return out << "(" << car(l) << ", " << cdr(l) << ")"; +} + +/** + * Construct a (lazy) list from a value and a lambda function that returns the cdr. + */ +template const list cons(const T& car, const lambda ()>& cdr) { + return list (car, cdr); +} + +/** + * Construct a list from a value and a cdr list. + */ +template const list cons(const T& car, const list& cdr) { + return list (car, unit(cdr)); +} + +/** + * Construct a list of one value. + */ +template const list makeList(const T& car) { + return list (car, unit(list ())); +} + +/** + * Construct a list of two values. + */ +template const list makeList(const T& a, const T& b) { + return cons(a, makeList(b)); +} + +/** + * Construct a list of three values. + */ +template const list makeList(const T& a, const T& b, const T& c) { + return cons(a, cons(b, makeList(c))); +} + +/** + * Construct a list of four values. + */ +template const list 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 const T car(const list& p) { + return p.car; +} + +/** + * Returns the cdr of a list. + */ +template list const cdr(const list& p) { + return p.cdr(); +} + +/** + * Returns the car of the cdr of a list. + */ +template const T cadr(const list& p) { + return car(cdr(p)); +} + +/** + * Returns the cdr of a cdr of a list. + */ +template const list cddr(const list& p) { + return cdr(cdr(p)); +} + +/** + * Returns the length of a list. + */ +template struct lengthRef { + const int operator()(const int c, const list& p) { + if(isNil(p)) + return c; + return (*this)(c + 1, cdr(p)); + } +}; + +template const int length(const list& p) { + return lengthRef ()(0, p); +} + +/** + * Appends a list and a lambda function returning a list. + */ +template struct appendCdr { + const list a; + const lambda ()> fb; + appendCdr(const list& a, const lambda ()>& fb) : + a(a), fb(fb) { + } + const list operator()() const { + return append(a, fb); + } +}; + +template const list append(const list&a, const lambda ()>& fb) { + if(isNil(a)) + return fb(); + + return cons(car(a), lambda ()> (appendCdr (cdr(a), fb))); +} + +/** + * Appends two lists. + */ +template const list append(const list&a, const list& b) { + return append(a, unit(b)); +} + +/** + * Map a lambda function on a list. + */ +template const list map(const lambda& f, const list& p) { + if(isNil(p)) + return list (); + return cons(f(car(p)), map(f, cdr(p))); +} + +/** + * Run a reduce lambda function on a list. + */ +template struct reduceAccumulate { + const lambda f; + reduceAccumulate(const lambda& f) : + f(f) { + } + R operator()(const R& acc, const list& p) const { + if(isNil(p)) + return acc; + return (*this)(f(acc, car(p)), cdr(p)); + } +}; + +template const R reduce(const lambda& f, const R& initial, const list& p) { + return reduceAccumulate (f)(initial, p); +} + +/** + * Run a filter lambda function on a list. + */ +template const list filter(const lambda& f, const list& p) { + if(isNil(p)) + return list (); + if(f(car(p))) { + const lambda (lambda , list )> ff(filter ); + 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 const list member(const T& t, const list& p) { + if(isNil(p)) + return list (); + if(t == car(p)) + return p; + return member(t, cdr(p)); +} + +/** + * Reverse a list. + */ +template const list reverseIter(const list& acc, const list& p) { + if(isNil(p)) + return acc; + return reverseIter(cons(car(p), acc), cdr(p)); +} + +template const list reverse(const list& p) { + return reverseIter(list (), p); +} + +template const list seq(const T& start, const T& end); + +template struct seqGenerate { + const T start; + const T end; + seqGenerate(const T& start, const T&end) : + start(start), end(end) { + } + const list operator()() const { + return seq (start, end); + } +}; + +/** + * Returns a sequence of values between the given bounds. + */ +template const list seq(const T& start, const T& end) { + if(start == end) + return makeList(start); + if(start < end) + return cons(start, lambda ()> (seqGenerate (start + 1, end))); + return cons(start, lambda ()> (seqGenerate (start - 1, end))); +} + +/** + * Equivalent of the list assoc function. + */ +template const list assoc(const T& k, const list >& p) { + if(isNil(p)) + return list (); + 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 +#include +#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&)>& 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& 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& 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() const { + return lst()(); + } + + operator lambda&)>() const { + return func(); + } + + friend ostream& operator<<(ostream&, const Value&); + + ValueType type; + lambda data; + +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& chr() const { + return vdata (); + } + + lambda& str() const { + return vdata (); + } + + lambda()>& lst() const { + return vdata()> (); + } + + lambda&)>& func() const { + return vdata&)> (); + } + +}; + +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 )exp) == tag; + return false; +} + +} +#endif /* tuscany_value_hpp */ -- cgit v1.2.3