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:
parent
3703aa37ce
commit
67618c8048
4 changed files with 1193 additions and 0 deletions
cpp/sca/runtime/core/src/tuscany
235
cpp/sca/runtime/core/src/tuscany/function.hpp
Normal file
235
cpp/sca/runtime/core/src/tuscany/function.hpp
Normal 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 */
|
269
cpp/sca/runtime/core/src/tuscany/gc.hpp
Normal file
269
cpp/sca/runtime/core/src/tuscany/gc.hpp
Normal 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 */
|
348
cpp/sca/runtime/core/src/tuscany/list.hpp
Normal file
348
cpp/sca/runtime/core/src/tuscany/list.hpp
Normal 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 */
|
341
cpp/sca/runtime/core/src/tuscany/value.hpp
Normal file
341
cpp/sca/runtime/core/src/tuscany/value.hpp
Normal 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 */
|
Loading…
Add table
Reference in a new issue