Documentation updates.
This commit is contained in:
parent
c9e67f2063
commit
a70dc12b2a
@ -1,5 +1,8 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See LICENSE.TXT for details.
|
// 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_
|
#ifndef CHAISCRIPT_HPP_
|
||||||
#define CHAISCRIPT_HPP_
|
#define CHAISCRIPT_HPP_
|
||||||
|
@ -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
|
#ifndef __bootstrap_hpp
|
||||||
#define __bootstrap_hpp__
|
#define __bootstrap_hpp__
|
||||||
|
|
||||||
@ -15,28 +21,24 @@ namespace dispatchkit
|
|||||||
return p1 + p2;
|
return p1 + p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
template<typename Ret, typename P1, typename P2>
|
||||||
Ret subtract(P1 p1, P2 p2)
|
Ret subtract(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
return p1 - p2;
|
return p1 - p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
template<typename Ret, typename P1, typename P2>
|
||||||
Ret divide(P1 p1, P2 p2)
|
Ret divide(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
return p1 / p2;
|
return p1 / p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
template<typename Ret, typename P1, typename P2>
|
||||||
Ret multiply(P1 p1, P2 p2)
|
Ret multiply(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
return p1 * p2;
|
return p1 * p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Ret, typename P1, typename P2>
|
template<typename Ret, typename P1, typename P2>
|
||||||
Ret modulus(P1 p1, P2 p2)
|
Ret modulus(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
@ -49,16 +51,12 @@ namespace dispatchkit
|
|||||||
return (p1 = p2);
|
return (p1 = p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
template<typename P1, typename P2>
|
||||||
bool equals(P1 p1, P2 p2)
|
bool equals(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
return p1 == p2;
|
return p1 == p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
template<typename P1, typename P2>
|
||||||
bool not_equals(P1 p1, P2 p2)
|
bool not_equals(P1 p1, P2 p2)
|
||||||
{
|
{
|
||||||
@ -102,7 +100,6 @@ namespace dispatchkit
|
|||||||
return (p1 /= p2);
|
return (p1 /= p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename P1, typename P2>
|
template<typename P1, typename P2>
|
||||||
P1 &addsequal(P1 &p1, const P2 &p2)
|
P1 &addsequal(P1 &p1, const P2 &p2)
|
||||||
{
|
{
|
||||||
@ -115,8 +112,6 @@ namespace dispatchkit
|
|||||||
return (p1 -= p2);
|
return (p1 -= p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename P1>
|
template<typename P1>
|
||||||
P1 &prefixincrement(P1 &p1)
|
P1 &prefixincrement(P1 &p1)
|
||||||
{
|
{
|
||||||
@ -259,18 +254,27 @@ namespace dispatchkit
|
|||||||
register_function(s, ÷<T, const T&, const T&>, "/");
|
register_function(s, ÷<T, const T&, const T&>, "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of "*" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_multiply(Dispatch_Engine &s)
|
void add_oper_multiply(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &multiply<T, const T&, const T&>, "*");
|
register_function(s, &multiply<T, const T&, const T&>, "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of "!=" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_not_equals(Dispatch_Engine &s)
|
void add_oper_not_equals(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, ¬_equals<const T&, const T&>, "!=");
|
register_function(s, ¬_equals<const T&, const T&>, "!=");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add user defined assignment operator for T = U
|
||||||
|
*/
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
void add_oper_assign_overload(Dispatch_Engine &s)
|
void add_oper_assign_overload(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -278,6 +282,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of "=" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_assign(Dispatch_Engine &s)
|
void add_oper_assign(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -285,6 +292,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add assignment operator for T = POD.
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_assign_pod(Dispatch_Engine &s)
|
void add_oper_assign_pod(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -292,31 +302,46 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of "<" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_less_than(Dispatch_Engine &s)
|
void add_oper_less_than(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &less_than<const T&, const T&>, "<");
|
register_function(s, &less_than<const T&, const T&>, "<");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of ">" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_greater_than(Dispatch_Engine &s)
|
void add_oper_greater_than(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &greater_than<const T&, const T&>, ">");
|
register_function(s, &greater_than<const T&, const T&>, ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of "<=" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_less_than_equals(Dispatch_Engine &s)
|
void add_oper_less_than_equals(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &less_than_equals<const T&, const T&>, "<=");
|
register_function(s, &less_than_equals<const T&, const T&>, "<=");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical form of ">=" for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_oper_greater_than_equals(Dispatch_Engine &s)
|
void add_oper_greater_than_equals(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &greater_than_equals<const T&, const T&>, ">=");
|
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>
|
template<typename T, typename R>
|
||||||
void add_opers_comparison_overload(Dispatch_Engine &s)
|
void add_opers_comparison_overload(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -328,12 +353,22 @@ namespace dispatchkit
|
|||||||
register_function(s, &greater_than_equals<const T&, const R&>, ">=");
|
register_function(s, &greater_than_equals<const T&, const R&>, ">=");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical forms of all comparison operators for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_opers_comparison(Dispatch_Engine &s)
|
void add_opers_comparison(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
add_opers_comparison_overload<T, T>(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>
|
template<typename Ret, typename T, typename R>
|
||||||
void add_opers_arithmetic_overload(Dispatch_Engine &s)
|
void add_opers_arithmetic_overload(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -351,6 +386,10 @@ namespace dispatchkit
|
|||||||
register_function(s, &prefixnot<T>, "!");
|
register_function(s, &prefixnot<T>, "!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add arithmetic assign operators for POD types:
|
||||||
|
* example: POD *= T, POD /= T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_opers_arithmetic_modify_pod(Dispatch_Engine &s)
|
void add_opers_arithmetic_modify_pod(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -360,6 +399,11 @@ namespace dispatchkit
|
|||||||
register_function(s, &addsequal_pod<T>, "+=");
|
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>
|
template<typename T>
|
||||||
void add_copy_constructor(Dispatch_Engine &s, const std::string &type)
|
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");
|
s.register_function(build_constructor<T, const T &>(), "clone");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add default and copy constructors (including "clone") for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_basic_constructors(Dispatch_Engine &s, const std::string &type)
|
void add_basic_constructors(Dispatch_Engine &s, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -374,18 +421,28 @@ namespace dispatchkit
|
|||||||
add_copy_constructor<T>(s, type);
|
add_copy_constructor<T>(s, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add POD type constructor for type T. ie: T = type(POD)
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_construct_pod(Dispatch_Engine &s, const std::string &type)
|
void add_construct_pod(Dispatch_Engine &s, const std::string &type)
|
||||||
{
|
{
|
||||||
register_function(s, &construct_pod<T>, 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>
|
template<typename T, typename U>
|
||||||
void add_constructor_overload(Dispatch_Engine &s, const std::string &type)
|
void add_constructor_overload(Dispatch_Engine &s, const std::string &type)
|
||||||
{
|
{
|
||||||
s.register_function(build_constructor<T, const U &>(), type);
|
s.register_function(build_constructor<T, const U &>(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add canonical forms of all arithmetic operators for type T
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void add_opers_arithmetic(Dispatch_Engine &s)
|
void add_opers_arithmetic(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
@ -393,15 +450,18 @@ namespace dispatchkit
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to_string function for internal use. Uses ostream operator<<
|
||||||
//Built in to_string operator
|
*/
|
||||||
template<typename Input>
|
template<typename Input>
|
||||||
std::string to_string(Input i)
|
std::string to_string(Input i)
|
||||||
{
|
{
|
||||||
return boost::lexical_cast<std::string>(i);
|
return boost::lexical_cast<std::string>(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean specialization of internal to_string function
|
||||||
|
*/
|
||||||
template<> std::string to_string(bool b)
|
template<> std::string to_string(bool b)
|
||||||
{
|
{
|
||||||
if (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>
|
template<typename Input>
|
||||||
Input parse_string(const std::string &i)
|
Input parse_string(const std::string &i)
|
||||||
{
|
{
|
||||||
return boost::lexical_cast<Input>(i);
|
return boost::lexical_cast<Input>(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all common functions for a POD type. All operators, and
|
||||||
|
* common conversions
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void bootstrap_pod_type(Dispatch_Engine &s, const std::string &name)
|
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);
|
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>
|
template<typename Type>
|
||||||
boost::shared_ptr<Type> shared_ptr_clone(boost::shared_ptr<Type> f)
|
boost::shared_ptr<Type> shared_ptr_clone(boost::shared_ptr<Type> f)
|
||||||
{
|
{
|
||||||
return 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>
|
template<typename Type>
|
||||||
Boxed_Value ptr_assign(Boxed_Value lhs, boost::shared_ptr<Type> rhs)
|
Boxed_Value ptr_assign(Boxed_Value lhs, boost::shared_ptr<Type> rhs)
|
||||||
{
|
{
|
||||||
@ -448,9 +526,15 @@ namespace dispatchkit
|
|||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class consisting of only static functions. All default bootstrapping occurs
|
||||||
|
* from this class.
|
||||||
|
*/
|
||||||
struct Bootstrap
|
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)
|
static Boxed_Value unknown_assign(Boxed_Value lhs, Boxed_Value rhs)
|
||||||
{
|
{
|
||||||
if (lhs.is_unknown())
|
if (lhs.is_unknown())
|
||||||
@ -471,6 +555,9 @@ namespace dispatchkit
|
|||||||
std::cout << s << std::endl;
|
std::cout << s << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add all comparison operators for POD types
|
||||||
|
*/
|
||||||
static void add_opers_comparison_pod(Dispatch_Engine &s)
|
static void add_opers_comparison_pod(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &equals<Boxed_POD_Value, Boxed_POD_Value>, "==");
|
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>, ">=");
|
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)
|
static void add_opers_arithmetic_pod(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
register_function(s, &add<Boxed_Value, Boxed_POD_Value, Boxed_POD_Value>, "+");
|
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>, "*");
|
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)
|
static bool type_match(Boxed_Value l, Boxed_Value r)
|
||||||
{
|
{
|
||||||
return l.get_type_info() == r.get_type_info();
|
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)
|
static bool is_type(const Dispatch_Engine &e, const std::string &type_name, Boxed_Value r)
|
||||||
{
|
{
|
||||||
try {
|
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> ¶ms)
|
static Boxed_Value bind_function(const std::vector<Boxed_Value> ¶ms)
|
||||||
{
|
{
|
||||||
if (params.size() < 2)
|
if (params.size() < 2)
|
||||||
@ -516,6 +617,10 @@ namespace dispatchkit
|
|||||||
std::vector<Boxed_Value>(params.begin() + 1, params.end()))));
|
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> ¶ms)
|
static Boxed_Value call_exists(const std::vector<Boxed_Value> ¶ms)
|
||||||
{
|
{
|
||||||
if (params.size() < 1)
|
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())));
|
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)
|
static void bootstrap(Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
s.register_type<void>("void");
|
s.register_type<void>("void");
|
||||||
|
@ -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
|
#ifndef __bootstrap_stl_hpp
|
||||||
#define __bootstrap_stl_hpp__
|
#define __bootstrap_stl_hpp__
|
||||||
|
|
||||||
@ -7,6 +20,11 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
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>
|
template<typename Container>
|
||||||
struct Input_Range
|
struct Input_Range
|
||||||
{
|
{
|
||||||
@ -52,6 +70,10 @@ namespace dispatchkit
|
|||||||
typename Container::iterator m_end;
|
typename Container::iterator m_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Input_Range support for the given ContainerType
|
||||||
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
void bootstrap_input_range(Dispatch_Engine &system, const std::string &type)
|
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");
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_reversible_container(Dispatch_Engine &/*system*/, const std::string &/*type*/)
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_random_access_container(Dispatch_Engine &system, const std::string &type)
|
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,
|
//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.
|
//to throw an exception in an out of bounds condition.
|
||||||
system.register_function(
|
register_function(system, indexoper(&ContainerType::at), "[]");
|
||||||
boost::function<typename ContainerType::reference (ContainerType *, int)>(indexoper(&ContainerType::at)), "[]");
|
register_function(system, indexoper(&ContainerType::operator[]), "at");
|
||||||
system.register_function(
|
|
||||||
boost::function<typename ContainerType::reference (ContainerType *, int)>(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)
|
void bootstrap_assignable(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
add_basic_constructors<Assignable>(system, type);
|
add_basic_constructors<ContainerType>(system, type);
|
||||||
add_oper_assign<Assignable>(system);
|
add_oper_assign<ContainerType>(system);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add container concept to the given ContainerType
|
||||||
|
* http://www.sgi.com/tech/stl/Container.html
|
||||||
|
*/
|
||||||
template<typename ContainerType>
|
template<typename ContainerType>
|
||||||
void bootstrap_container(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_container(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -112,6 +148,10 @@ namespace dispatchkit
|
|||||||
register_function(system, &ContainerType::empty, "empty");
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_forward_container(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -119,12 +159,19 @@ namespace dispatchkit
|
|||||||
bootstrap_container<ContainerType>(system, type);
|
bootstrap_container<ContainerType>(system, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add default constructable concept to the given Type
|
||||||
|
* http://www.sgi.com/tech/stl/DefaultConstructible.html
|
||||||
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_default_constructible(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
system.register_function(build_constructor<Type>(), type);
|
system.register_function(build_constructor<Type>(), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Algorithm for inserting at a specific position into a container
|
||||||
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void insert_at(Type &container, int pos, const typename Type::value_type &v)
|
void insert_at(Type &container, int pos, const typename Type::value_type &v)
|
||||||
{
|
{
|
||||||
@ -140,6 +187,9 @@ namespace dispatchkit
|
|||||||
container.insert(itr, v);
|
container.insert(itr, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Algorithm for erasing a specific position from a container
|
||||||
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void erase_at(Type &container, int pos)
|
void erase_at(Type &container, int pos)
|
||||||
{
|
{
|
||||||
@ -155,46 +205,58 @@ namespace dispatchkit
|
|||||||
container.erase(itr);
|
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)
|
void bootstrap_sequence(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
bootstrap_forward_container<SequenceType>(system, type);
|
bootstrap_forward_container<ContainerType>(system, type);
|
||||||
bootstrap_default_constructible<SequenceType>(system, type);
|
bootstrap_default_constructible<ContainerType>(system, type);
|
||||||
|
|
||||||
std::string insert_name;
|
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";
|
insert_name = "insert_ref_at";
|
||||||
} else {
|
} else {
|
||||||
insert_name = "insert_at";
|
insert_name = "insert_at";
|
||||||
}
|
}
|
||||||
|
|
||||||
register_function(system, &insert_at<SequenceType>, insert_name);
|
register_function(system, &insert_at<ContainerType>, insert_name);
|
||||||
register_function(system, &erase_at<SequenceType>, "erase_at");
|
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)
|
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;
|
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";
|
push_back_name = "push_back_ref";
|
||||||
} else {
|
} else {
|
||||||
push_back_name = "push_back";
|
push_back_name = "push_back";
|
||||||
}
|
}
|
||||||
|
|
||||||
register_function(system, &SequenceType::push_back, push_back_name);
|
register_function(system, &ContainerType::push_back, push_back_name);
|
||||||
register_function(system, &SequenceType::pop_back, "pop_back");
|
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>
|
template<typename VectorType>
|
||||||
void bootstrap_vector(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_vector(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -203,6 +265,10 @@ namespace dispatchkit
|
|||||||
bootstrap_back_insertion_sequence<VectorType>(system, type);
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_associative_container(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_associative_container(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -210,6 +276,10 @@ namespace dispatchkit
|
|||||||
bootstrap_default_constructible<ContainerType>(system, type);
|
bootstrap_default_constructible<ContainerType>(system, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bootstrap a given PairType
|
||||||
|
* http://www.sgi.com/tech/stl/pair.html
|
||||||
|
*/
|
||||||
template<typename PairType>
|
template<typename PairType>
|
||||||
void bootstrap_pair(Dispatch_Engine &system, const std::string &type)
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_pair_associative_container(Dispatch_Engine &system, const std::string &type)
|
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");
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_unique_associative_container(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_unique_associative_container(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -239,6 +317,10 @@ namespace dispatchkit
|
|||||||
register_function(system, &ContainerType::count, "count");
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_sorted_associative_container(Dispatch_Engine &system, const std::string &type)
|
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");
|
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>
|
template<typename ContainerType>
|
||||||
void bootstrap_unique_sorted_associative_container(Dispatch_Engine &system, const std::string &type)
|
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);
|
bootstrap_unique_associative_container<ContainerType>(system, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a MapType container
|
||||||
|
* http://www.sgi.com/tech/stl/Map.html
|
||||||
|
*/
|
||||||
template<typename MapType>
|
template<typename MapType>
|
||||||
void bootstrap_map(Dispatch_Engine &system, const std::string &type)
|
void bootstrap_map(Dispatch_Engine &system, const std::string &type)
|
||||||
{
|
{
|
||||||
@ -266,6 +356,10 @@ namespace dispatchkit
|
|||||||
bootstrap_pair_associative_container<MapType>(system, type);
|
bootstrap_pair_associative_container<MapType>(system, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a String container
|
||||||
|
* http://www.sgi.com/tech/stl/basic_string.html
|
||||||
|
*/
|
||||||
template<typename String>
|
template<typename String>
|
||||||
void bootstrap_string(Dispatch_Engine &system, const std::string &type)
|
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_first_not_of), "find_first_not_of");
|
||||||
register_function(system, find_func(&String::find_last_not_of), "find_last_not_of");
|
register_function(system, find_func(&String::find_last_not_of), "find_last_not_of");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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__
|
#ifndef __boxed_value_hpp__
|
||||||
#define __boxed_value_hpp__
|
#define __boxed_value_hpp__
|
||||||
|
|
||||||
@ -13,16 +19,32 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
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
|
class Boxed_Value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* used for explicitly creating a "void" object
|
||||||
|
*/
|
||||||
struct Void_Type
|
struct Void_Type
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* structure which holds the internal state of a Boxed_Value
|
||||||
|
*/
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* used to provide type-erased access to the internal boost::shared_ptr
|
||||||
|
* reference count information
|
||||||
|
*/
|
||||||
struct Shared_Ptr_Proxy
|
struct Shared_Ptr_Proxy
|
||||||
{
|
{
|
||||||
virtual ~Shared_Ptr_Proxy()
|
virtual ~Shared_Ptr_Proxy()
|
||||||
@ -33,6 +55,9 @@ namespace dispatchkit
|
|||||||
virtual long use_count(boost::any *) = 0;
|
virtual long use_count(boost::any *) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Typed implementation of the Shared_Ptr_Proxy
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Shared_Ptr_Proxy_Impl : Shared_Ptr_Proxy
|
struct Shared_Ptr_Proxy_Impl : Shared_Ptr_Proxy
|
||||||
{
|
{
|
||||||
@ -83,6 +108,12 @@ namespace dispatchkit
|
|||||||
boost::shared_ptr<Shared_Ptr_Proxy> m_ptr_proxy;
|
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
|
struct Object_Cache
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
|
boost::shared_ptr<Data> get(Boxed_Value::Void_Type)
|
||||||
@ -131,7 +162,6 @@ namespace dispatchkit
|
|||||||
|
|
||||||
if (itr != m_ptrs.end())
|
if (itr != m_ptrs.end())
|
||||||
{
|
{
|
||||||
// std::cout << "Reference wrapper ptr found, using it" << std::endl;
|
|
||||||
(*data) = (itr->second);
|
(*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()
|
void cull()
|
||||||
{
|
{
|
||||||
std::map<void *, Data >::iterator itr = m_ptrs.begin();
|
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)
|
if (itr->second.m_ptr_proxy->unique(&itr->second.m_obj) == 1)
|
||||||
{
|
{
|
||||||
std::map<void *, Data >::iterator todel = itr;
|
std::map<void *, Data >::iterator todel = itr;
|
||||||
// std::cout << "Releasing unique ptr " << std::endl;
|
|
||||||
++itr;
|
++itr;
|
||||||
m_ptrs.erase(todel);
|
m_ptrs.erase(todel);
|
||||||
} else {
|
} else {
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::cout << "References held: " << m_ptrs.size() << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::map<void *, Data > m_ptrs;
|
std::map<void *, Data > m_ptrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Basic Boxed_Value constructor
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
explicit Boxed_Value(T t)
|
explicit Boxed_Value(T t)
|
||||||
: m_data(get_object_cache().get(t))
|
: m_data(get_object_cache().get(t))
|
||||||
@ -195,11 +228,17 @@ namespace dispatchkit
|
|||||||
get_object_cache().cull();
|
get_object_cache().cull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy constructor - each copy shares the same data pointer
|
||||||
|
*/
|
||||||
Boxed_Value(const Boxed_Value &t_so)
|
Boxed_Value(const Boxed_Value &t_so)
|
||||||
: m_data(t_so.m_data)
|
: m_data(t_so.m_data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unknown-type constructor
|
||||||
|
*/
|
||||||
Boxed_Value()
|
Boxed_Value()
|
||||||
: m_data(get_object_cache().get())
|
: 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()
|
Object_Cache &get_object_cache()
|
||||||
{
|
{
|
||||||
static Object_Cache oc;
|
static Object_Cache oc;
|
||||||
return 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)
|
Boxed_Value assign(const Boxed_Value &rhs)
|
||||||
{
|
{
|
||||||
(*m_data) = (*rhs.m_data);
|
(*m_data) = (*rhs.m_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shared data assignment, same as copy construction
|
||||||
|
*/
|
||||||
Boxed_Value &operator=(const Boxed_Value &rhs)
|
Boxed_Value &operator=(const Boxed_Value &rhs)
|
||||||
{
|
{
|
||||||
m_data = rhs.m_data;
|
m_data = rhs.m_data;
|
||||||
@ -234,6 +281,9 @@ namespace dispatchkit
|
|||||||
return m_data->m_type_info;
|
return m_data->m_type_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if the object is uninitialized
|
||||||
|
*/
|
||||||
bool is_unknown() const
|
bool is_unknown() const
|
||||||
{
|
{
|
||||||
return m_data->m_type_info.m_is_unknown;
|
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>
|
template<typename Result>
|
||||||
struct Cast_Helper
|
struct Cast_Helper
|
||||||
{
|
{
|
||||||
@ -271,6 +325,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a const & type
|
||||||
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const Result &>
|
struct Cast_Helper<const Result &>
|
||||||
{
|
{
|
||||||
@ -287,6 +344,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a const * type
|
||||||
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<const Result *>
|
struct Cast_Helper<const Result *>
|
||||||
{
|
{
|
||||||
@ -303,6 +363,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a * type
|
||||||
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<Result *>
|
struct Cast_Helper<Result *>
|
||||||
{
|
{
|
||||||
@ -319,6 +382,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a & type
|
||||||
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<Result &>
|
struct Cast_Helper<Result &>
|
||||||
{
|
{
|
||||||
@ -335,6 +401,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a boost::shared_ptr<> type
|
||||||
|
*/
|
||||||
template<typename Result>
|
template<typename Result>
|
||||||
struct Cast_Helper<typename boost::shared_ptr<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<>
|
template<>
|
||||||
struct Cast_Helper<Boxed_Value>
|
struct Cast_Helper<Boxed_Value>
|
||||||
{
|
{
|
||||||
@ -358,6 +430,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for casting to a const Boxed_Value & type
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Cast_Helper<const Boxed_Value &>
|
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
|
class bad_boxed_cast : public std::bad_cast
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -396,6 +474,11 @@ namespace dispatchkit
|
|||||||
std::string m_what;
|
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>
|
template<typename Type>
|
||||||
typename Cast_Helper<Type>::Result_Type boxed_cast(const Boxed_Value &bv)
|
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
|
struct Boxed_POD_Value
|
||||||
{
|
{
|
||||||
Boxed_POD_Value(const Boxed_Value &v)
|
Boxed_POD_Value(const Boxed_Value &v)
|
||||||
@ -456,7 +543,6 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool operator==(const Boxed_POD_Value &r) const
|
bool operator==(const Boxed_POD_Value &r) const
|
||||||
{
|
{
|
||||||
return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i);
|
return ((m_isfloat)?d:i) == ((r.m_isfloat)?r.d:r.i);
|
||||||
@ -533,6 +619,9 @@ namespace dispatchkit
|
|||||||
bool m_isfloat;
|
bool m_isfloat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cast_Helper for converting from Boxed_Value to Boxed_POD_Value
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Cast_Helper<Boxed_POD_Value>
|
struct Cast_Helper<Boxed_POD_Value>
|
||||||
{
|
{
|
||||||
|
@ -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__
|
#ifndef __dispatchkit_hpp__
|
||||||
#define __dispatchkit_hpp__
|
#define __dispatchkit_hpp__
|
||||||
|
|
||||||
@ -19,6 +25,11 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
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
|
class Dispatch_Function : public Proxy_Function
|
||||||
{
|
{
|
||||||
public:
|
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
|
class Dispatch_Engine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -87,18 +102,27 @@ namespace dispatchkit
|
|||||||
m_scopes.push_back(Scope());
|
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)
|
bool register_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &name)
|
||||||
{
|
{
|
||||||
return add_function(f, name);
|
return add_function(f, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a generic, named boost::function() to the system
|
||||||
|
*/
|
||||||
template<typename Function>
|
template<typename Function>
|
||||||
bool register_function(const Function &func, const std::string &name)
|
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);
|
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>
|
template<typename Class>
|
||||||
void set_object(const std::string &name, const Class &obj)
|
void set_object(const std::string &name, const Class &obj)
|
||||||
{
|
{
|
||||||
@ -115,17 +139,26 @@ namespace dispatchkit
|
|||||||
add_object(name, obj);
|
add_object(name, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a named object to the current scope
|
||||||
|
*/
|
||||||
template<typename Class>
|
template<typename Class>
|
||||||
void add_object(const std::string &name, const Class &obj)
|
void add_object(const std::string &name, const Class &obj)
|
||||||
{
|
{
|
||||||
m_scopes.back()[name] = Boxed_Value(obj);
|
m_scopes.back()[name] = Boxed_Value(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new scope to the stack
|
||||||
|
*/
|
||||||
void new_scope()
|
void new_scope()
|
||||||
{
|
{
|
||||||
m_scopes.push_back(Scope());
|
m_scopes.push_back(Scope());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops the current scope from the stack
|
||||||
|
*/
|
||||||
void pop_scope()
|
void pop_scope()
|
||||||
{
|
{
|
||||||
if (m_scopes.size() > 1)
|
if (m_scopes.size() > 1)
|
||||||
@ -136,18 +169,30 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current stack
|
||||||
|
*/
|
||||||
Stack get_stack()
|
Stack get_stack()
|
||||||
{
|
{
|
||||||
return m_scopes;
|
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)
|
Stack set_stack(Stack s)
|
||||||
{
|
{
|
||||||
std::swap(s, m_scopes);
|
std::swap(s, m_scopes);
|
||||||
return s;
|
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
|
Boxed_Value get_object(const std::string &name) const
|
||||||
{
|
{
|
||||||
if (name == "_")
|
if (name == "_")
|
||||||
@ -174,13 +219,18 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new named type
|
||||||
|
*/
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void register_type(const std::string &name)
|
void register_type(const std::string &name)
|
||||||
{
|
{
|
||||||
m_types.insert(std::make_pair(name, Get_Type_Info<Type>::get()));
|
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_Info get_type(const std::string &name) const
|
||||||
{
|
{
|
||||||
Type_Name_Map::const_iterator itr = m_types.find(name);
|
Type_Name_Map::const_iterator itr = m_types.find(name);
|
||||||
@ -193,6 +243,11 @@ namespace dispatchkit
|
|||||||
throw std::range_error("Type Not Known");
|
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
|
std::string get_type_name(const Type_Info &ti) const
|
||||||
{
|
{
|
||||||
for (Type_Name_Map::const_iterator itr = m_types.begin();
|
for (Type_Name_Map::const_iterator itr = m_types.begin();
|
||||||
@ -208,11 +263,37 @@ namespace dispatchkit
|
|||||||
return ti.m_bare_type_info->name();
|
return ti.m_bare_type_info->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all registered types
|
||||||
|
*/
|
||||||
std::vector<std::pair<std::string, Type_Info> > get_types() const
|
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 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> >
|
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
|
get_function_impl(const std::string &t_name, bool include_objects) const
|
||||||
{
|
{
|
||||||
@ -238,18 +319,11 @@ namespace dispatchkit
|
|||||||
return funcs;
|
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
|
* Implementation detail for adding a function. Returns
|
||||||
{
|
* true if the function was added, false if a function with the
|
||||||
return get_function_impl(t_name, true);
|
* same signature and name already exists.
|
||||||
}
|
*/
|
||||||
|
|
||||||
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:
|
|
||||||
bool add_function(const boost::shared_ptr<Proxy_Function> &f, const std::string &t_name)
|
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
|
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;
|
Boxed_Value m_place_holder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump object info to stdout
|
||||||
|
*/
|
||||||
void dump_object(Boxed_Value o, const Dispatch_Engine &e)
|
void dump_object(Boxed_Value o, const Dispatch_Engine &e)
|
||||||
{
|
{
|
||||||
std::cout << e.get_type_name(o.get_type_info()) << std::endl;
|
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)
|
void dump_type(const Type_Info &type, const Dispatch_Engine &e)
|
||||||
{
|
{
|
||||||
std::cout << e.get_type_name(type);
|
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)
|
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();
|
std::vector<Type_Info> params = f.second->get_param_types();
|
||||||
@ -307,12 +390,14 @@ namespace dispatchkit
|
|||||||
{
|
{
|
||||||
std::cout << ", ";
|
std::cout << ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << ") " << std::endl;
|
std::cout << ") " << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump all system info to stdout
|
||||||
|
*/
|
||||||
void dump_system(const Dispatch_Engine &s)
|
void dump_system(const Dispatch_Engine &s)
|
||||||
{
|
{
|
||||||
std::cout << "Registered Types: " << std::endl;
|
std::cout << "Registered Types: " << std::endl;
|
||||||
@ -326,7 +411,6 @@ namespace dispatchkit
|
|||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > funcs = s.get_functions();
|
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;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -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>
|
#include <boost/preprocessor.hpp>
|
||||||
|
|
||||||
#define addparam(z,n,text) params.push_back(Boxed_Value(BOOST_PP_CAT(p, n) ));
|
#define addparam(z,n,text) params.push_back(Boxed_Value(BOOST_PP_CAT(p, n) ));
|
||||||
@ -17,6 +23,10 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
namespace dispatchkit
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Internal helper class for handling the return
|
||||||
|
* value of a build_function_caller
|
||||||
|
*/
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
class Function_Caller_Ret
|
class Function_Caller_Ret
|
||||||
{
|
{
|
||||||
@ -32,6 +42,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization for void return types
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
class Function_Caller_Ret<void>
|
class Function_Caller_Ret<void>
|
||||||
{
|
{
|
||||||
@ -54,6 +67,14 @@ namespace dispatchkit
|
|||||||
|
|
||||||
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>
|
template<typename FunctionType>
|
||||||
boost::function<FunctionType>
|
boost::function<FunctionType>
|
||||||
build_function_caller(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs)
|
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);
|
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>
|
template<typename FunctionType>
|
||||||
boost::function<FunctionType>
|
boost::function<FunctionType>
|
||||||
build_function_caller(boost::shared_ptr<Proxy_Function> func)
|
build_function_caller(boost::shared_ptr<Proxy_Function> func)
|
||||||
@ -71,6 +105,10 @@ namespace dispatchkit
|
|||||||
return build_function_caller<FunctionType>(funcs);
|
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>
|
template<typename FunctionType>
|
||||||
boost::function<FunctionType>
|
boost::function<FunctionType>
|
||||||
build_function_caller(const Boxed_Value &bv)
|
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));
|
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>
|
template<typename FunctionType, typename ScriptEngine>
|
||||||
boost::function<FunctionType> build_functor(ScriptEngine &e, const std::string &script)
|
boost::function<FunctionType> build_functor(ScriptEngine &e, const std::string &script)
|
||||||
{
|
{
|
||||||
@ -92,6 +137,9 @@ namespace dispatchkit
|
|||||||
|
|
||||||
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) >
|
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
|
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) )
|
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);
|
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) >
|
template<typename Ret BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, typename Param) >
|
||||||
boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, 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)
|
build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs)
|
||||||
|
@ -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>
|
#include <boost/preprocessor.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_PP_IS_ITERATING
|
#ifndef BOOST_PP_IS_ITERATING
|
||||||
@ -18,12 +24,22 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
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) >
|
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) )
|
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) ));
|
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) >
|
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()
|
boost::function<boost::shared_ptr<Class> (BOOST_PP_ENUM_PARAMS(n, Param))> build_constructor()
|
||||||
{
|
{
|
||||||
|
@ -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>
|
#include <boost/preprocessor.hpp>
|
||||||
|
|
||||||
#define gettypeinfo(z,n,text) ti.push_back(Get_Type_Info<Param ## n>::get());
|
#define gettypeinfo(z,n,text) ti.push_back(Get_Type_Info<Param ## n>::get());
|
||||||
@ -22,7 +28,9 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
namespace dispatchkit
|
||||||
{
|
{
|
||||||
// handle_return implementations
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return
|
struct Handle_Return
|
||||||
{
|
{
|
||||||
@ -32,6 +40,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
template<typename Ret>
|
template<typename Ret>
|
||||||
struct Handle_Return<Ret &>
|
struct Handle_Return<Ret &>
|
||||||
{
|
{
|
||||||
@ -41,6 +52,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<Boxed_Value>
|
struct Handle_Return<Boxed_Value>
|
||||||
{
|
{
|
||||||
@ -50,6 +64,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<Boxed_Value &>
|
struct Handle_Return<Boxed_Value &>
|
||||||
{
|
{
|
||||||
@ -59,6 +76,9 @@ namespace dispatchkit
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used internally for handling a return value from a Proxy_Function call
|
||||||
|
*/
|
||||||
template<>
|
template<>
|
||||||
struct Handle_Return<void>
|
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
|
struct Param_List_Builder
|
||||||
{
|
{
|
||||||
Param_List_Builder &operator<<(const Boxed_Value &so)
|
Param_List_Builder &operator<<(const Boxed_Value &so)
|
||||||
@ -93,6 +120,10 @@ namespace dispatchkit
|
|||||||
std::vector<Boxed_Value> objects;
|
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
|
struct arity_error : std::range_error
|
||||||
{
|
{
|
||||||
arity_error(int t_got, int t_expected)
|
arity_error(int t_got, int t_expected)
|
||||||
@ -105,7 +136,6 @@ namespace dispatchkit
|
|||||||
int got;
|
int got;
|
||||||
int expected;
|
int expected;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
#define BOOST_PP_ITERATION_LIMITS ( 0, 10 )
|
||||||
@ -114,6 +144,14 @@ namespace dispatchkit
|
|||||||
|
|
||||||
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
|
class Proxy_Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -125,6 +163,9 @@ namespace dispatchkit
|
|||||||
virtual std::string annotation() const = 0;
|
virtual std::string annotation() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception thrown if a function's guard fails to execute
|
||||||
|
*/
|
||||||
class guard_error : public std::runtime_error
|
class guard_error : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
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
|
class Dynamic_Proxy_Function : public Proxy_Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -225,10 +270,20 @@ namespace dispatchkit
|
|||||||
boost::shared_ptr<Proxy_Function> m_guard;
|
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
|
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
|
class Bound_Function : public Proxy_Function
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -291,7 +346,6 @@ namespace dispatchkit
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,12 +359,16 @@ namespace dispatchkit
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<Proxy_Function> m_f;
|
boost::shared_ptr<Proxy_Function> m_f;
|
||||||
std::vector<Boxed_Value> m_args;
|
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>
|
template<typename Func>
|
||||||
class Proxy_Function_Impl : public Proxy_Function
|
class Proxy_Function_Impl : public Proxy_Function
|
||||||
{
|
{
|
||||||
@ -352,11 +410,16 @@ namespace dispatchkit
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Func m_f;
|
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
|
struct dispatch_error : std::runtime_error
|
||||||
{
|
{
|
||||||
dispatch_error() throw()
|
dispatch_error() throw()
|
||||||
@ -367,6 +430,11 @@ namespace dispatchkit
|
|||||||
virtual ~dispatch_error() throw() {}
|
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,
|
Boxed_Value dispatch(const std::vector<std::pair<std::string, boost::shared_ptr<Proxy_Function> > > &funcs,
|
||||||
const std::vector<Boxed_Value> &plist)
|
const std::vector<Boxed_Value> &plist)
|
||||||
{
|
{
|
||||||
@ -385,7 +453,6 @@ namespace dispatchkit
|
|||||||
//try again
|
//try again
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw dispatch_error();
|
throw dispatch_error();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,7 +463,10 @@ namespace dispatchkit
|
|||||||
|
|
||||||
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) >
|
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))> &)
|
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;
|
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)>
|
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,
|
Boxed_Value call_func(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &f,
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
@ -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)>
|
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))> &,
|
bool compare_types(const boost::function<Ret (BOOST_PP_ENUM_PARAMS(n, Param))> &,
|
||||||
const std::vector<Boxed_Value> ¶ms)
|
const std::vector<Boxed_Value> ¶ms)
|
||||||
@ -440,8 +521,6 @@ namespace dispatchkit
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -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>
|
#include <boost/preprocessor.hpp>
|
||||||
|
|
||||||
#ifndef BOOST_PP_IS_ITERATING
|
#ifndef BOOST_PP_IS_ITERATING
|
||||||
@ -10,12 +16,20 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
namespace dispatchkit
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Helper function for register_member function
|
||||||
|
*/
|
||||||
template<typename T, typename Class>
|
template<typename T, typename Class>
|
||||||
T &get_member(T Class::* m, Class *obj)
|
T &get_member(T Class::* m, Class *obj)
|
||||||
{
|
{
|
||||||
return obj->*m;
|
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>
|
template<typename T, typename Class>
|
||||||
void register_member(Dispatch_Engine &s, T Class::* m, const std::string &name)
|
void register_member(Dispatch_Engine &s, T Class::* m, const std::string &name)
|
||||||
{
|
{
|
||||||
@ -33,18 +47,27 @@ namespace dispatchkit
|
|||||||
|
|
||||||
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)>
|
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)
|
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);
|
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)>
|
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)
|
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);
|
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)>
|
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)
|
void register_function(Dispatch_Engine &s, Ret (Class::*f)(BOOST_PP_ENUM_PARAMS(n, Param))const, const std::string &name)
|
||||||
{
|
{
|
||||||
|
@ -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__
|
#ifndef __type_info_hpp__
|
||||||
#define __type_info_hpp__
|
#define __type_info_hpp__
|
||||||
|
|
||||||
@ -12,6 +18,9 @@
|
|||||||
|
|
||||||
namespace dispatchkit
|
namespace dispatchkit
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* compile time deduced information about a type
|
||||||
|
*/
|
||||||
struct Type_Info
|
struct Type_Info
|
||||||
{
|
{
|
||||||
Type_Info(bool t_is_const, bool t_is_reference, bool t_is_pointer, bool t_is_void,
|
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;
|
bool m_is_unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper used to create a Type_Info object
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Get_Type_Info
|
struct Get_Type_Info
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See LICENSE.TXT for details.
|
// 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_
|
#ifndef CHAISCRIPT_ENGINE_HPP_
|
||||||
#define CHAISCRIPT_ENGINE_HPP_
|
#define CHAISCRIPT_ENGINE_HPP_
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See LICENSE.TXT for details.
|
// 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_
|
#ifndef CHAISCRIPT_EVAL_HPP_
|
||||||
#define CHAISCRIPT_EVAL_HPP_
|
#define CHAISCRIPT_EVAL_HPP_
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See LICENSE.TXT for details.
|
// 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_
|
#ifndef CHAISCRIPT_PARSER_HPP_
|
||||||
#define CHAISCRIPT_PARSER_HPP_
|
#define CHAISCRIPT_PARSER_HPP_
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
// This file is distributed under the BSD License.
|
// This file is distributed under the BSD License.
|
||||||
// See LICENSE.TXT for details.
|
// 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_
|
#ifndef CHAISCRIPT_PRELUDE_HPP_
|
||||||
#define CHAISCRIPT_PRELUDE_HPP_
|
#define CHAISCRIPT_PRELUDE_HPP_
|
||||||
|
Loading…
x
Reference in New Issue
Block a user