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
This commit is contained in:
jsdelfino 2009-09-14 05:55:14 +00:00
parent 3703aa37ce
commit 67618c8048
4 changed files with 1193 additions and 0 deletions
cpp/sca/runtime/core/src/tuscany

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */