Documentation updates.

This commit is contained in:
Jason Turner 2009-07-12 03:07:45 +00:00
parent c9e67f2063
commit a70dc12b2a
14 changed files with 649 additions and 81 deletions

View File

@ -1,5 +1,8 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_HPP_
#define CHAISCRIPT_HPP_

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef __bootstrap_hpp
#define __bootstrap_hpp__
@ -15,28 +21,24 @@ namespace dispatchkit
return p1 + p2;
}
template<typename Ret, typename P1, typename P2>
Ret subtract(P1 p1, P2 p2)
{
return p1 - p2;
}
template<typename Ret, typename P1, typename P2>
Ret divide(P1 p1, P2 p2)
{
return p1 / p2;
}
template<typename Ret, typename P1, typename P2>
Ret multiply(P1 p1, P2 p2)
{
return p1 * p2;
}
template<typename Ret, typename P1, typename P2>
Ret modulus(P1 p1, P2 p2)
{
@ -49,16 +51,12 @@ namespace dispatchkit
return (p1 = p2);
}
template<typename P1, typename P2>
bool equals(P1 p1, P2 p2)
{
return p1 == p2;
}
template<typename P1, typename P2>
bool not_equals(P1 p1, P2 p2)
{
@ -102,7 +100,6 @@ namespace dispatchkit
return (p1 /= p2);
}
template<typename P1, typename P2>
P1 &addsequal(P1 &p1, const P2 &p2)
{
@ -115,8 +112,6 @@ namespace dispatchkit
return (p1 -= p2);
}
template<typename P1>
P1 &prefixincrement(P1 &p1)
{
@ -259,18 +254,27 @@ namespace dispatchkit
register_function(s, &divide<T, const T&, const T&>, "/");
}
/**
* Add canonical form of "*" for type T
*/
template<typename T>
void add_oper_multiply(Dispatch_Engine &s)
{
register_function(s, &multiply<T, const T&, const T&>, "*");
}
/**
* Add canonical form of "!=" for type T
*/
template<typename T>
void add_oper_not_equals(Dispatch_Engine &s)
{
register_function(s, &not_equals<const T&, const T&>, "!=");
}
/**
* Add user defined assignment operator for T = U
*/
template<typename T, typename U>
void add_oper_assign_overload(Dispatch_Engine &s)
{
@ -278,6 +282,9 @@ namespace dispatchkit
}
/**
* Add canonical form of "=" for type T
*/
template<typename T>
void add_oper_assign(Dispatch_Engine &s)
{
@ -285,6 +292,9 @@ namespace dispatchkit
}
/**
* Add assignment operator for T = POD.
*/
template<typename T>
void add_oper_assign_pod(Dispatch_Engine &s)
{
@ -292,31 +302,46 @@ namespace dispatchkit
}
/**
* Add canonical form of "<" for type T
*/
template<typename T>
void add_oper_less_than(Dispatch_Engine &s)
{
register_function(s, &less_than<const T&, const T&>, "<");
}
/**
* Add canonical form of ">" for type T
*/
template<typename T>
void add_oper_greater_than(Dispatch_Engine &s)
{
register_function(s, &greater_than<const T&, const T&>, ">");
}
/**
* Add canonical form of "<=" for type T
*/
template<typename T>
void add_oper_less_than_equals(Dispatch_Engine &s)
{
register_function(s, &less_than_equals<const T&, const T&>, "<=");
}
/**
* Add canonical form of ">=" for type T
*/
template<typename T>
void add_oper_greater_than_equals(Dispatch_Engine &s)
{
register_function(s, &greater_than_equals<const T&, const T&>, ">=");
}
/**
* Add user defined comparison operators for T and R.
* Examples: T < R, T == R, etc.
*/
template<typename T, typename R>
void add_opers_comparison_overload(Dispatch_Engine &s)
{
@ -328,12 +353,22 @@ namespace dispatchkit
register_function(s, &greater_than_equals<const T&, const R&>, ">=");
}
/**
* Add canonical forms of all comparison operators for type T
*/
template<typename T>
void add_opers_comparison(Dispatch_Engine &s)
{
add_opers_comparison_overload<T, T>(s);
}
/**
* Add all arithmetic operators that return a type of Ret, taking
* a lhs of T and a rhs of R, when possible.
* examples: Ret = T + R;
* ++T
* T *= R;
*/
template<typename Ret, typename T, typename R>
void add_opers_arithmetic_overload(Dispatch_Engine &s)
{
@ -351,6 +386,10 @@ namespace dispatchkit
register_function(s, &prefixnot<T>, "!");
}
/**
* Add arithmetic assign operators for POD types:
* example: POD *= T, POD /= T
*/
template<typename T>
void add_opers_arithmetic_modify_pod(Dispatch_Engine &s)
{
@ -360,6 +399,11 @@ namespace dispatchkit
register_function(s, &addsequal_pod<T>, "+=");
}
/**
* Add a copy constructor for type T, also creates the standard
* function "clone" for the type. "clone" is a synonym for
* the copy constructor.
*/
template<typename T>
void add_copy_constructor(Dispatch_Engine &s, const std::string &type)
{
@ -367,6 +411,9 @@ namespace dispatchkit
s.register_function(build_constructor<T, const T &>(), "clone");
}
/**
* Add default and copy constructors (including "clone") for type T
*/
template<typename T>
void add_basic_constructors(Dispatch_Engine &s, const std::string &type)
{
@ -374,18 +421,28 @@ namespace dispatchkit
add_copy_constructor<T>(s, type);
}
/**
* Add POD type constructor for type T. ie: T = type(POD)
*/
template<typename T>
void add_construct_pod(Dispatch_Engine &s, const std::string &type)
{
register_function(s, &construct_pod<T>, type);
}
/**
* add user defined single parameter constructor for type T.
* T = type(const U &)
*/
template<typename T, typename U>
void add_constructor_overload(Dispatch_Engine &s, const std::string &type)
{
s.register_function(build_constructor<T, const U &>(), type);
}
/**
* Add canonical forms of all arithmetic operators for type T
*/
template<typename T>
void add_opers_arithmetic(Dispatch_Engine &s)
{
@ -393,15 +450,18 @@ namespace dispatchkit
}
//Built in to_string operator
/**
* to_string function for internal use. Uses ostream operator<<
*/
template<typename Input>
std::string to_string(Input i)
{
return boost::lexical_cast<std::string>(i);
}
/**
* Boolean specialization of internal to_string function
*/
template<> std::string to_string(bool b)
{
if (b)
@ -412,14 +472,20 @@ namespace dispatchkit
}
}
/**
* Internal function for converting from a string to a value
* uses ostream operator >> to perform the conversion
*/
template<typename Input>
Input parse_string(const std::string &i)
{
return boost::lexical_cast<Input>(i);
}
/**
* Add all common functions for a POD type. All operators, and
* common conversions
*/
template<typename T>
void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name)
{
@ -434,12 +500,24 @@ namespace dispatchkit
register_function(s, &parse_string<T>, "to_" + name);
}
/**
* "clone" function for a shared_ptr type. This is used in the case
* where you do not want to make a deep copy of an object during cloning
* but want to instead maintain the shared_ptr. It is needed internally
* for handling of boost::shared_ptr<Proxy_Function> object (that is,
* function variables.
*/
template<typename Type>
boost::shared_ptr<Type> shared_ptr_clone(boost::shared_ptr<Type> f)
{
return f;
}
/**
* Assignment function for shared_ptr objects, does not perform a copy of the
* object pointed to, instead maintains the shared_ptr concept.
* Similar to shared_ptr_clone. Used for Proxy_Function.
*/
template<typename Type>
Boxed_Value ptr_assign(Boxed_Value lhs, boost::shared_ptr<Type> rhs)
{
@ -448,9 +526,15 @@ namespace dispatchkit
return lhs;
}
/**
* Class consisting of only static functions. All default bootstrapping occurs
* from this class.
*/
struct Bootstrap
{
/**
* Function allowing for assignment of an unknown type to any other value
*/
static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs)
{
if (lhs.is_unknown())
@ -471,6 +555,9 @@ namespace dispatchkit
std::cout << s << std::endl;
}
/**
* Add all comparison operators for POD types
*/
static void add_opers_comparison_pod(Dispatch_Engine &s)
{
register_function(s, &equals<Boxed_POD_Value, Boxed_POD_Value>, "==");
@ -481,6 +568,9 @@ namespace dispatchkit
register_function(s, &greater_than_equals<Boxed_POD_Value, Boxed_POD_Value>, ">=");
}
/**
* Add all arithmetic operators for PODs
*/
static void add_opers_arithmetic_pod(Dispatch_Engine &s)
{
register_function(s, &add<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "+");
@ -489,11 +579,17 @@ namespace dispatchkit
register_function(s, &multiply<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "*");
}
/**
* Return true if the two Boxed_Value's share the same internal type
*/
static bool type_match(Boxed_Value l, Boxed_Value r)
{
return l.get_type_info() == r.get_type_info();
}
/**
* return true if the Boxed_Value matches the registered type by name
*/
static bool is_type(const Dispatch_Engine &e, const std::string &type_name, Boxed_Value r)
{
try {
@ -503,6 +599,11 @@ namespace dispatchkit
}
}
/**
* Create a bound function object. The first param is the function to bind
* the remaining parameters are the args to bind into the
* result
*/
static Boxed_Value bind_function(const std::vector<Boxed_Value> &params)
{
if (params.size() < 2)
@ -516,6 +617,10 @@ namespace dispatchkit
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
}
/**
* Returns true if a call can be made that consists of the first parameter
* (the function) with the remaining parameters as its arguments.
*/
static Boxed_Value call_exists(const std::vector<Boxed_Value> &params)
{
if (params.size() < 1)
@ -528,6 +633,9 @@ namespace dispatchkit
return Boxed_Value(f->types_match(std::vector<Boxed_Value>(params.begin() + 1, params.end())));
}
/**
* perform all common bootstrap functions for std::string, void and POD types
*/
static void bootstrap(Dispatch_Engine &s)
{
s.register_type<void>("void");

View File

@ -1,3 +1,16 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
/**
* This file contains utility functions for registration of STL container
* classes. The methodology used is based on the SGI STL concepts.
* http://www.sgi.com/tech/stl/table_of_contents.html
*/
#ifndef __bootstrap_stl_hpp
#define __bootstrap_stl_hpp__
@ -7,6 +20,11 @@
namespace dispatchkit
{
/**
* Input_Range, based on the D concept of ranges.
* \todo Update the Range code to base its capabilities on
* the type_traits of the iterator passed in
*/
template<typename Container>
struct Input_Range
{
@ -52,6 +70,10 @@ namespace dispatchkit
typename Container::iterator m_end;
};
/**
* Add Input_Range support for the given ContainerType
*/
template<typename ContainerType>
void bootstrap_input_range(Dispatch_Engine &system, const std::string &type)
{
@ -75,11 +97,19 @@ namespace dispatchkit
system.register_function(build_constructor<Input_Range<ContainerType>, const Input_Range<ContainerType> &>(), "clone");
}
/**
* Add reversible_container concept to the given ContainerType
* http://www.sgi.com/tech/stl/ReversibleContainer.html
*/
template<typename ContainerType>
void bootstrap_reversible_container(Dispatch_Engine &/*system*/, const std::string &/*type*/)
{
}
/**
* Add random_access_container concept to the given ContainerType
* http://www.sgi.com/tech/stl/RandomAccessContainer.html
*/
template<typename ContainerType>
void bootstrap_random_access_container(Dispatch_Engine &system, const std::string &type)
{
@ -89,19 +119,25 @@ namespace dispatchkit
//In the interest of runtime safety for the system, we prefer the at() method for [] access,
//to throw an exception in an out of bounds condition.
system.register_function(
boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::at)), "[]");
system.register_function(
boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::operator[])), "at");
register_function(system, indexoper(&ContainerType::at), "[]");
register_function(system, indexoper(&ContainerType::operator[]), "at");
}
template<typename Assignable>
/**
* Add assignable concept to the given ContainerType
* http://www.sgi.com/tech/stl/Assignable.html
*/
template<typename ContainerType>
void bootstrap_assignable(Dispatch_Engine &system, const std::string &type)
{
add_basic_constructors<Assignable>(system, type);
add_oper_assign<Assignable>(system);
add_basic_constructors<ContainerType>(system, type);
add_oper_assign<ContainerType>(system);
}
/**
* Add container concept to the given ContainerType
* http://www.sgi.com/tech/stl/Container.html
*/
template<typename ContainerType>
void bootstrap_container(Dispatch_Engine &system, const std::string &type)
{
@ -112,6 +148,10 @@ namespace dispatchkit
register_function(system, &ContainerType::empty, "empty");
}
/**
* Add forward container concept to the given ContainerType
* http://www.sgi.com/tech/stl/ForwardContainer.html
*/
template<typename ContainerType>
void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type)
{
@ -119,12 +159,19 @@ namespace dispatchkit
bootstrap_container<ContainerType>(system, type);
}
/**
* Add default constructable concept to the given Type
* http://www.sgi.com/tech/stl/DefaultConstructible.html
*/
template<typename Type>
void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type)
{
system.register_function(build_constructor<Type>(), type);
}
/**
* Algorithm for inserting at a specific position into a container
*/
template<typename Type>
void insert_at(Type &container, int pos, const typename Type::value_type &v)
{
@ -140,6 +187,9 @@ namespace dispatchkit
container.insert(itr, v);
}
/**
* Algorithm for erasing a specific position from a container
*/
template<typename Type>
void erase_at(Type &container, int pos)
{
@ -155,46 +205,58 @@ namespace dispatchkit
container.erase(itr);
}
template<typename SequenceType>
/**
* Add sequence concept to the given ContainerType
* http://www.sgi.com/tech/stl/Sequence.html
*/
template<typename ContainerType>
void bootstrap_sequence(Dispatch_Engine &system, const std::string &type)
{
bootstrap_forward_container<SequenceType>(system, type);
bootstrap_default_constructible<SequenceType>(system, type);
bootstrap_forward_container<ContainerType>(system, type);
bootstrap_default_constructible<ContainerType>(system, type);
std::string insert_name;
if (typeid(typename SequenceType::value_type) == typeid(Boxed_Value))
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value))
{
insert_name = "insert_ref_at";
} else {
insert_name = "insert_at";
}
register_function(system, &insert_at<SequenceType>, insert_name);
register_function(system, &erase_at<SequenceType>, "erase_at");
register_function(system, &insert_at<ContainerType>, insert_name);
register_function(system, &erase_at<ContainerType>, "erase_at");
}
template<typename SequenceType>
/**
* Add back insertion sequence concept to the given ContainerType
* http://www.sgi.com/tech/stl/BackInsertionSequence.html
*/
template<typename ContainerType>
void bootstrap_back_insertion_sequence(Dispatch_Engine &system, const std::string &type)
{
bootstrap_sequence<SequenceType>(system, type);
bootstrap_sequence<ContainerType>(system, type);
typedef typename SequenceType::reference (SequenceType::*backptr)();
typedef typename ContainerType::reference (ContainerType::*backptr)();
system.register_function(boost::function<typename SequenceType::reference (SequenceType *)>(backptr(&SequenceType::back)), "back");
register_function(system, (backptr(&ContainerType::back)), "back");
std::string push_back_name;
if (typeid(typename SequenceType::value_type) == typeid(Boxed_Value))
if (typeid(typename ContainerType::value_type) == typeid(Boxed_Value))
{
push_back_name = "push_back_ref";
} else {
push_back_name = "push_back";
}
register_function(system, &SequenceType::push_back, push_back_name);
register_function(system, &SequenceType::pop_back, "pop_back");
register_function(system, &ContainerType::push_back, push_back_name);
register_function(system, &ContainerType::pop_back, "pop_back");
}
/**
* Create a vector type with associated concepts
* http://www.sgi.com/tech/stl/Vector.html
*/
template<typename VectorType>
void bootstrap_vector(Dispatch_Engine &system, const std::string &type)
{
@ -203,6 +265,10 @@ namespace dispatchkit
bootstrap_back_insertion_sequence<VectorType>(system, type);
}
/**
* Create a vector type with associated concepts
* http://www.sgi.com/tech/stl/Vector.html
*/
template<typename ContainerType>
void bootstrap_associative_container(Dispatch_Engine &system, const std::string &type)
{
@ -210,6 +276,10 @@ namespace dispatchkit
bootstrap_default_constructible<ContainerType>(system, type);
}
/**
* bootstrap a given PairType
* http://www.sgi.com/tech/stl/pair.html
*/
template<typename PairType>
void bootstrap_pair(Dispatch_Engine &system, const std::string &type)
{
@ -225,6 +295,10 @@ namespace dispatchkit
}
/**
* Add pair associative container concept to the given ContainerType
* http://www.sgi.com/tech/stl/PairAssociativeContainer.html
*/
template<typename ContainerType>
void bootstrap_pair_associative_container(Dispatch_Engine &system, const std::string &type)
{
@ -232,6 +306,10 @@ namespace dispatchkit
bootstrap_pair<typename ContainerType::value_type>(system, type + "_Pair");
}
/**
* Add unique associative container concept to the given ContainerType
* http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
*/
template<typename ContainerType>
void bootstrap_unique_associative_container(Dispatch_Engine &system, const std::string &type)
{
@ -239,6 +317,10 @@ namespace dispatchkit
register_function(system, &ContainerType::count, "count");
}
/**
* Add sorted associative container concept to the given ContainerType
* http://www.sgi.com/tech/stl/SortedAssociativeContainer.html
*/
template<typename ContainerType>
void bootstrap_sorted_associative_container(Dispatch_Engine &system, const std::string &type)
{
@ -250,6 +332,10 @@ namespace dispatchkit
register_function(system, eq_range(&ContainerType::equal_range), "equal_range");
}
/**
* Add unique sorted associative container concept to the given ContainerType
* http://www.sgi.com/tech/stl/UniqueSortedAssociativeContainer.html
*/
template<typename ContainerType>
void bootstrap_unique_sorted_associative_container(Dispatch_Engine &system, const std::string &type)
{
@ -257,6 +343,10 @@ namespace dispatchkit
bootstrap_unique_associative_container<ContainerType>(system, type);
}
/**
* Add a MapType container
* http://www.sgi.com/tech/stl/Map.html
*/
template<typename MapType>
void bootstrap_map(Dispatch_Engine &system, const std::string &type)
{
@ -266,6 +356,10 @@ namespace dispatchkit
bootstrap_pair_associative_container<MapType>(system, type);
}
/**
* Add a String container
* http://www.sgi.com/tech/stl/basic_string.html
*/
template<typename String>
void bootstrap_string(Dispatch_Engine &system, const std::string &type)
{
@ -283,7 +377,6 @@ namespace dispatchkit
register_function(system, find_func(&String::find_first_not_of), "find_first_not_of");
register_function(system, find_func(&String::find_last_not_of), "find_last_not_of");
}
}
#endif

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef __boxed_value_hpp__
#define __boxed_value_hpp__
@ -13,16 +19,32 @@
namespace dispatchkit
{
/**
* Boxed_Value is the main tool of the dispatchkit. It allows
* for boxed / untyped containment of any C++ object. It uses
* boost::any internally but also provides user access the underlying
* stored type information
*/
class Boxed_Value
{
public:
/**
* used for explicitly creating a "void" object
*/
struct Void_Type
{
};
private:
/**
* structure which holds the internal state of a Boxed_Value
*/
struct Data
{
/**
* used to provide type-erased access to the internal boost::shared_ptr
* reference count information
*/
struct Shared_Ptr_Proxy
{
virtual ~Shared_Ptr_Proxy()
@ -33,6 +55,9 @@ namespace dispatchkit
virtual long use_count(boost::any *) = 0;
};
/**
* Typed implementation of the Shared_Ptr_Proxy
*/
template<typename T>
struct Shared_Ptr_Proxy_Impl : Shared_Ptr_Proxy
{
@ -83,6 +108,12 @@ namespace dispatchkit
boost::shared_ptr<Shared_Ptr_Proxy> m_ptr_proxy;
};
/**
* Cache of all created objects in the dispatch kit. Used to return the
* same shared_ptr if the same object is created more than once.
* Also used for acquiring a shared_ptr of a reference object, if the
* value of the shared_ptr is known
*/
struct Object_Cache
{
boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
@ -131,7 +162,6 @@ namespace dispatchkit
if (itr != m_ptrs.end())
{
// std::cout << "Reference wrapper ptr found, using it" << std::endl;
(*data) = (itr->second);
}
@ -163,6 +193,10 @@ namespace dispatchkit
);
}
/**
* Drop objects from the cache where there is only one (ie, our)
* reference to it, so it may be destructed
*/
void cull()
{
std::map<void *, Data >::iterator itr = m_ptrs.begin();
@ -172,22 +206,21 @@ namespace dispatchkit
if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1)
{
std::map<void *, Data >::iterator todel = itr;
// std::cout << "Releasing unique ptr " << std::endl;
++itr;
m_ptrs.erase(todel);
} else {
++itr;
}
}
// std::cout << "References held: " << m_ptrs.size() << std::endl;
}
std::map<void *, Data > m_ptrs;
};
public:
/**
* Basic Boxed_Value constructor
*/
template<typename T>
explicit Boxed_Value(T t)
: m_data(get_object_cache().get(t))
@ -195,11 +228,17 @@ namespace dispatchkit
get_object_cache().cull();
}
/**
* Copy constructor - each copy shares the same data pointer
*/
Boxed_Value(const Boxed_Value &t_so)
: m_data(t_so.m_data)
{
}
/**
* Unknown-type constructor
*/
Boxed_Value()
: m_data(get_object_cache().get())
{
@ -209,20 +248,28 @@ namespace dispatchkit
{
}
/**
* Return a reference to the static global Object_Cache
*/
Object_Cache &get_object_cache()
{
static Object_Cache oc;
return oc;
}
/**
* copy the values stored in rhs.m_data to m_data
* m_data pointers are not shared in this case
*/
Boxed_Value assign(const Boxed_Value &rhs)
{
(*m_data) = (*rhs.m_data);
return *this;
}
/**
* shared data assignment, same as copy construction
*/
Boxed_Value &operator=(const Boxed_Value &rhs)
{
m_data = rhs.m_data;
@ -234,6 +281,9 @@ namespace dispatchkit
return m_data->m_type_info;
}
/**
* return true if the object is uninitialized
*/
bool is_unknown() const
{
return m_data->m_type_info.m_is_unknown;
@ -254,7 +304,11 @@ namespace dispatchkit
};
//cast_help specializations
// Cast_Helper helper classes
/**
* Generic Cast_Helper, for casting to any type
*/
template<typename Result>
struct Cast_Helper
{
@ -271,6 +325,9 @@ namespace dispatchkit
}
};
/**
* Cast_Helper for casting to a const & type
*/
template<typename Result>
struct Cast_Helper<const Result &>
{
@ -287,6 +344,9 @@ namespace dispatchkit
}
};
/**
* Cast_Helper for casting to a const * type
*/
template<typename Result>
struct Cast_Helper<const Result *>
{
@ -303,6 +363,9 @@ namespace dispatchkit
}
};
/**
* Cast_Helper for casting to a * type
*/
template<typename Result>
struct Cast_Helper<Result *>
{
@ -319,6 +382,9 @@ namespace dispatchkit
}
};
/**
* Cast_Helper for casting to a & type
*/
template<typename Result>
struct Cast_Helper<Result &>
{
@ -335,6 +401,9 @@ namespace dispatchkit
}
};
/**
* Cast_Helper for casting to a boost::shared_ptr<> type
*/
template<typename Result>
struct Cast_Helper<typename boost::shared_ptr<Result> >
{
@ -347,6 +416,9 @@ namespace dispatchkit
};
/**
* Cast_Helper for casting to a Boxed_Value type
*/
template<>
struct Cast_Helper<Boxed_Value>
{
@ -358,6 +430,9 @@ namespace dispatchkit
}
};
/**
* Cast_Helper for casting to a const Boxed_Value & type
*/
template<>
struct Cast_Helper<const Boxed_Value &>
{
@ -369,7 +444,10 @@ namespace dispatchkit
}
};
/**
* class that is thrown in the event of a bad_boxed_cast. That is,
* in the case that a Boxed_Value cannot be cast to the desired type
*/
class bad_boxed_cast : public std::bad_cast
{
public:
@ -396,6 +474,11 @@ namespace dispatchkit
std::string m_what;
};
/**
* boxed_cast function for casting a Boxed_Value into a given type
* example:
* int &i = boxed_cast<int &>(boxedvalue);
*/
template<typename Type>
typename Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
{
@ -406,6 +489,10 @@ namespace dispatchkit
}
}
/**
* Object which attempts to convert a Boxed_Value into a generic
* POD type and provide generic POD type operations
*/
struct Boxed_POD_Value
{
Boxed_POD_Value(const Boxed_Value &v)
@ -456,7 +543,6 @@ namespace dispatchkit
}
}
bool operator==(const Boxed_POD_Value &r) const
{
return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i);
@ -533,6 +619,9 @@ namespace dispatchkit
bool m_isfloat;
};
/**
* Cast_Helper for converting from Boxed_Value to Boxed_POD_Value
*/
template<>
struct Cast_Helper<Boxed_POD_Value>
{

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef __dispatchkit_hpp__
#define __dispatchkit_hpp__
@ -19,6 +25,11 @@
namespace dispatchkit
{
/**
* A Proxy_Function implementation that is able to take
* a vector of Proxy_Functions and perform a dispatch on them. It is
* used specifically in the case of dealing with Function object variables
*/
class Dispatch_Function : public Proxy_Function
{
public:
@ -74,6 +85,10 @@ namespace dispatchkit
};
/**
* Main class for the dispatchkit. Handles management
* of the object stack, functions and registered types.
*/
class Dispatch_Engine
{
public:
@ -87,18 +102,27 @@ namespace dispatchkit
m_scopes.push_back(Scope());
}
/**
* Add a new named Proxy_Function to the system
*/
bool register_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &name)
{
return add_function(f, name);
}
/**
* Add a generic, named boost::function() to the system
*/
template<typename Function>
bool register_function(const Function &func, const std::string &name)
{
return add_function(boost::shared_ptr<Proxy_Function>(new Proxy_Function_Impl<Function>(func)), name);
}
/**
* Set the value of an object, by name. If the object
* is not available in the current scope it is created
*/
template<typename Class>
void set_object(const std::string &name, const Class &obj)
{
@ -115,17 +139,26 @@ namespace dispatchkit
add_object(name, obj);
}
/**
* Adds a named object to the current scope
*/
template<typename Class>
void add_object(const std::string &name, const Class &obj)
{
m_scopes.back()[name] = Boxed_Value(obj);
}
/**
* Adds a new scope to the stack
*/
void new_scope()
{
m_scopes.push_back(Scope());
}
/**
* Pops the current scope from the stack
*/
void pop_scope()
{
if (m_scopes.size() > 1)
@ -136,18 +169,30 @@ namespace dispatchkit
}
}
/**
* Returns the current stack
*/
Stack get_stack()
{
return m_scopes;
}
/**
* Swaps out the stack with a new stack
* \returns the old stack
* \param[in] s The new stack
*/
Stack set_stack(Stack s)
{
std::swap(s, m_scopes);
return s;
}
/**
* Searches the current stack for an object of the given name
* includes a special overload for the _ place holder object to
* ensure that it is always in scope.
*/
Boxed_Value get_object(const std::string &name) const
{
if (name == "_")
@ -174,13 +219,18 @@ namespace dispatchkit
}
}
/**
* Registers a new named type
*/
template<typename Type>
void register_type(const std::string &name)
{
m_types.insert(std::make_pair(name, Get_Type_Info<Type>::get()));
}
/**
* Returns the type info for a named type
*/
Type_Info get_type(const std::string &name) const
{
Type_Name_Map::const_iterator itr = m_types.find(name);
@ -193,6 +243,11 @@ namespace dispatchkit
throw std::range_error("Type Not Known");
}
/**
* Returns the registered name of a known type_info object
* compares the "bare_type_info" for the broadest possible
* match
*/
std::string get_type_name(const Type_Info &ti) const
{
for (Type_Name_Map::const_iterator itr = m_types.begin();
@ -208,11 +263,37 @@ namespace dispatchkit
return ti.m_bare_type_info->name();
}
/**
* Return all registered types
*/
std::vector<std::pair<std::string, Type_Info> > get_types() const
{
return std::vector<std::pair<std::string, Type_Info> >(m_types.begin(), m_types.end());
}
/**
* Return a function by name
*/
std::vector<std::pair<std::string, std::multimap<std::string, boost::shared_ptr<Proxy_Function> >::mapped_type> >
get_function(const std::string &t_name) const
{
return get_function_impl(t_name, true);
}
/**
* Get a vector of all registered functions
*/
std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > get_functions() const
{
return std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > >(m_functions.begin(), m_functions.end());
}
private:
/**
* Implementation detail for searching for a function by name.
* Looks for all registered global functions and optionally for an object
* in scope with the same name
*/
std::vector<std::pair<std::string, std::multimap<std::string, boost::shared_ptr<Proxy_Function> >::mapped_type> >
get_function_impl(const std::string &t_name, bool include_objects) const
{
@ -238,18 +319,11 @@ namespace dispatchkit
return funcs;
}
std::vector<std::pair<std::string, std::multimap<std::string, boost::shared_ptr<Proxy_Function> >::mapped_type> >
get_function(const std::string &t_name) const
{
return get_function_impl(t_name, true);
}
std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > get_functions() const
{
return std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > >(m_functions.begin(), m_functions.end());
}
private:
/**
* Implementation detail for adding a function. Returns
* true if the function was added, false if a function with the
* same signature and name already exists.
*/
bool add_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &t_name)
{
std::pair<std::multimap<std::string, boost::shared_ptr<Proxy_Function> >::const_iterator, std::multimap<std::string, boost::shared_ptr<Proxy_Function> >::const_iterator> range
@ -275,16 +349,25 @@ namespace dispatchkit
Boxed_Value m_place_holder;
};
/**
* Dump object info to stdout
*/
void dump_object(Boxed_Value o, const Dispatch_Engine &e)
{
std::cout << e.get_type_name(o.get_type_info()) << std::endl;
}
/**
* Dump type info to stdout
*/
void dump_type(const Type_Info &type, const Dispatch_Engine &e)
{
std::cout << e.get_type_name(type);
}
/**
* Dump function to stdout
*/
void dump_function(const std::pair<const std::string, boost::shared_ptr<Proxy_Function> > &f, const Dispatch_Engine &e)
{
std::vector<Type_Info> params = f.second->get_param_types();
@ -307,12 +390,14 @@ namespace dispatchkit
{
std::cout << ", ";
}
}
std::cout << ") " << std::endl;
}
/**
* Dump all system info to stdout
*/
void dump_system(const Dispatch_Engine &s)
{
std::cout << "Registered Types: " << std::endl;
@ -326,7 +411,6 @@ namespace dispatchkit
std::cout << std::endl;
}
std::cout << std::endl;
std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > funcs = s.get_functions();
@ -339,8 +423,6 @@ namespace dispatchkit
}
std::cout << std::endl;
}
}
#endif

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#define addparam(z,n,text) params.push_back(Boxed_Value(BOOST_PP_CAT(p, n) ));
@ -17,6 +23,10 @@
namespace dispatchkit
{
/**
* Internal helper class for handling the return
* value of a build_function_caller
*/
template<typename Ret>
class Function_Caller_Ret
{
@ -32,6 +42,9 @@ namespace dispatchkit
}
};
/**
* Specialization for void return types
*/
template<>
class Function_Caller_Ret<void>
{
@ -54,6 +67,14 @@ namespace dispatchkit
namespace dispatchkit
{
/**
* Build a function caller that knows how to dispatch on a set of functions
* example:
* boost::function<void (int)> f =
* build_function_caller(dispatchkit.get_function("print"));
* \returns A boost::function object for dispatching
* \param[in] funcs the set of functions to dispatch on.
*/
template<typename FunctionType>
boost::function<FunctionType>
build_function_caller(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs)
@ -62,6 +83,19 @@ namespace dispatchkit
return build_function_caller_helper(p, funcs);
}
/**
* Build a function caller for a particular Proxy_Function object
* useful in the case that a function is being pass out from scripting back
* into code
* example:
* void my_function(boost::shared_ptr<Proxy_Function> f)
* {
* boost::function<void (int)> local_f =
* build_function_caller(f);
* }
* \returns A boost::function object for dispatching
* \param[in] func A function to execute.
*/
template<typename FunctionType>
boost::function<FunctionType>
build_function_caller(boost::shared_ptr<Proxy_Function> func)
@ -71,6 +105,10 @@ namespace dispatchkit
return build_function_caller<FunctionType>(funcs);
}
/**
* Helper for automatically unboxing a Boxed_Value that contains a function object
* and creating a typesafe C++ function caller from it.
*/
template<typename FunctionType>
boost::function<FunctionType>
build_function_caller(const Boxed_Value &bv)
@ -78,7 +116,14 @@ namespace dispatchkit
return build_function_caller<FunctionType>(boxed_cast<boost::shared_ptr<Proxy_Function> >(bv));
}
/**
* Helper for calling script code as if it were native C++ code
* example:
* boost::function<int (int, int)> f = build_functor(chai, "func(x, y){x+y}");
* \return a boost::function representing the passed in script
* \param[in] e ScriptEngine to build the script execution from
* \param[in] script Script code to build a function from
*/
template<typename FunctionType, typename ScriptEngine>
boost::function<FunctionType> build_functor(ScriptEngine &e, const std::string &script)
{
@ -92,6 +137,9 @@ namespace dispatchkit
namespace dispatchkit
{
/**
* used internally for unwrapping a function call's types
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
Ret function_caller(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs
BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
@ -103,6 +151,9 @@ namespace dispatchkit
return Function_Caller_Ret<Ret>().call(funcs, params);
}
/**
* used internally for unwrapping a function call's types
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param)) >
build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs)

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#ifndef BOOST_PP_IS_ITERATING
@ -18,12 +24,22 @@
namespace dispatchkit
{
/**
* A constructor function, used for creating a new object
* of a given type with a given set of params
*/
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::shared_ptr<Class> constructor( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) )
{
return boost::shared_ptr<Class>(new Class( BOOST_PP_ENUM_PARAMS(n, p) ));
}
/**
* Helper function for build a constructor function
* example:
* dispatchengine.register_function(build_constructor<MyClass, int, const std::string&>, "MyClass");
* \todo See if it is possible to make this not be a variadic function
*/
template<typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
boost::function<boost::shared_ptr<Class> (BOOST_PP_ENUM_PARAMS(n, Param))> build_constructor()
{

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#define gettypeinfo(z,n,text) ti.push_back(Get_Type_Info<Param ## n>::get());
@ -22,7 +28,9 @@
namespace dispatchkit
{
// handle_return implementations
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<typename Ret>
struct Handle_Return
{
@ -32,6 +40,9 @@ namespace dispatchkit
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<typename Ret>
struct Handle_Return<Ret &>
{
@ -41,6 +52,9 @@ namespace dispatchkit
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<Boxed_Value>
{
@ -50,6 +64,9 @@ namespace dispatchkit
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<Boxed_Value &>
{
@ -59,6 +76,9 @@ namespace dispatchkit
}
};
/**
* Used internally for handling a return value from a Proxy_Function call
*/
template<>
struct Handle_Return<void>
{
@ -69,7 +89,14 @@ namespace dispatchkit
}
};
/**
* Helper for building a list of parameters for calling a Proxy_Function
* it does automatic conversion to Boxed_Value types via operator<<
*
* example usage:
* Boxed_Value retval = dispatch(dispatchengine.get_function("+"),
* dispatchkit::Param_List_Builder() << 5 << 6);
*/
struct Param_List_Builder
{
Param_List_Builder &operator<<(const Boxed_Value &so)
@ -93,6 +120,10 @@ namespace dispatchkit
std::vector<Boxed_Value> objects;
};
/**
* Exception thrown when there is a mismatch in number of
* parameters during Proxy_Function execution
*/
struct arity_error : std::range_error
{
arity_error(int t_got, int t_expected)
@ -105,7 +136,6 @@ namespace dispatchkit
int got;
int expected;
};
}
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
@ -114,6 +144,14 @@ namespace dispatchkit
namespace dispatchkit
{
/**
* Pure virtual base class for all Proxy_Function implementations
* Proxy_Functions are a type erasure of type safe C++
* function calls. At runtime parameter types are expected to be
* tested against passed in types.
* Dispatch_Engine only knows how to work with Proxy_Function, no other
* function classes.
*/
class Proxy_Function
{
public:
@ -125,6 +163,9 @@ namespace dispatchkit
virtual std::string annotation() const = 0;
};
/**
* Exception thrown if a function's guard fails to execute
*/
class guard_error : public std::runtime_error
{
public:
@ -136,6 +177,10 @@ namespace dispatchkit
{ }
};
/**
* A Proxy_Function implementation that is not type safe, the called function
* is expecting a vector<Boxed_Value> that it works with how it chooses.
*/
class Dynamic_Proxy_Function : public Proxy_Function
{
public:
@ -225,10 +270,20 @@ namespace dispatchkit
boost::shared_ptr<Proxy_Function> m_guard;
};
/**
* An object used by Bound_Function to represent "_" parameters
* of a binding. This allows for unbound parameters during bind.
*/
struct Placeholder_Object
{
};
/**
* An implementation of Proxy_Function that takes a Proxy_Function
* and substitutes bound parameters into the parameter list
* at runtime, when call() is executed.
* it is used for bind(function, param1, _, param2) style calls
*/
class Bound_Function : public Proxy_Function
{
public:
@ -291,7 +346,6 @@ namespace dispatchkit
break;
}
}
return args;
}
@ -305,12 +359,16 @@ namespace dispatchkit
return "";
}
private:
boost::shared_ptr<Proxy_Function> m_f;
std::vector<Boxed_Value> m_args;
};
/**
* The standard typesafe function call implementation of Proxy_Function
* It takes a boost::function<> object and performs runtime
* type checking of Boxed_Value parameters, in a type safe manner
*/
template<typename Func>
class Proxy_Function_Impl : public Proxy_Function
{
@ -352,11 +410,16 @@ namespace dispatchkit
return "";
}
private:
Func m_f;
};
/**
* Exception thrown in the case that a multi method dispatch fails
* because no matching function was found
* at runtime due to either an arity_error, a guard_error or a bad_boxed_cast
* exception
*/
struct dispatch_error : std::runtime_error
{
dispatch_error() throw()
@ -367,6 +430,11 @@ namespace dispatchkit
virtual ~dispatch_error() throw() {}
};
/**
* Take a vector of functions and a vector of parameters. Attempt to execute
* each function against the set of parameters, in order, until a matching
* function is found or throw dispatch_error if no matching function is found
*/
Boxed_Value dispatch(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs,
const std::vector<Boxed_Value> &plist)
{
@ -385,7 +453,6 @@ namespace dispatchkit
//try again
}
}
throw dispatch_error();
}
}
@ -396,7 +463,10 @@ namespace dispatchkit
namespace dispatchkit
{
/**
* Used by Proxy_Function_Impl to return a list of all param types
* it contains.
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
std::vector<Type_Info> build_param_type_list(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &)
{
@ -408,6 +478,12 @@ namespace dispatchkit
return ti;
}
/**
* Used by Proxy_Function_Impl to perform typesafe execution of a function.
* The function attempts to unbox each paramter to the expected type.
* if any unboxing fails the execution of the function fails and
* the bad_boxed_cast is passed up to the caller.
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
Boxed_Value call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
const std::vector<Boxed_Value> &params)
@ -420,6 +496,11 @@ namespace dispatchkit
}
}
/**
* Used by Proxy_Function_Impl to determine if it is equivalent to another
* Proxy_Function_Impl object. This function is primarly used to prevent
* registration of two functions with the exact same signatures
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
bool compare_types(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &,
const std::vector<Boxed_Value> &params)
@ -440,8 +521,6 @@ namespace dispatchkit
return true;
}
}
}
#endif

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#include <boost/preprocessor.hpp>
#ifndef BOOST_PP_IS_ITERATING
@ -10,12 +16,20 @@
namespace dispatchkit
{
/**
* Helper function for register_member function
*/
template<typename T, typename Class>
T &get_member(T Class::* m, Class *obj)
{
return obj->*m;
}
/**
* Automatically create a get_member helper function for an object
* to allow for runtime dispatched access to public data members
* for example, the case of std::pair<>::first and std::pair<>::second
*/
template<typename T, typename Class>
void register_member(Dispatch_Engine &s, T Class::* m, const std::string &name)
{
@ -33,18 +47,27 @@ namespace dispatchkit
namespace dispatchkit
{
/**
* Register a global function of n parameters with name
*/
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
void register_function(Dispatch_Engine &s, Ret (*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name)
{
s.register_function(boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))>(f), name);
}
/**
* Register a class method of n parameters with name
*/
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
void register_function(Dispatch_Engine &s, Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param)), const std::string &name)
{
s.register_function(boost::function<Ret (Class* BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, Param))>(f), name);
}
/**
* Register a const class method of n parameters with name
*/
template<typename Ret, typename Class BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param)>
void register_function(Dispatch_Engine &s, Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const, const std::string &name)
{

View File

@ -1,3 +1,9 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef __type_info_hpp__
#define __type_info_hpp__
@ -12,6 +18,9 @@
namespace dispatchkit
{
/**
* compile time deduced information about a type
*/
struct Type_Info
{
Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
@ -68,6 +77,9 @@ namespace dispatchkit
bool m_is_unknown;
};
/**
* Helper used to create a Type_Info object
*/
template<typename T>
struct Get_Type_Info
{

View File

@ -1,5 +1,8 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_ENGINE_HPP_
#define CHAISCRIPT_ENGINE_HPP_

View File

@ -1,5 +1,8 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_EVAL_HPP_
#define CHAISCRIPT_EVAL_HPP_

View File

@ -1,5 +1,8 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_PARSER_HPP_
#define CHAISCRIPT_PARSER_HPP_

View File

@ -1,5 +1,8 @@
// This file is distributed under the BSD License.
// See LICENSE.TXT for details.
// Copyright 2009, Jonathan Turner (jonathan.d.turner@gmail.com)
// and Jason Turner (lefticus@gmail.com)
// http://www.chaiscript.com
#ifndef CHAISCRIPT_PRELUDE_HPP_
#define CHAISCRIPT_PRELUDE_HPP_