diff --git a/include/chaiscript/dispatchkit/boxed_value.hpp b/include/chaiscript/dispatchkit/boxed_value.hpp index 5f70a13..07d011b 100644 --- a/include/chaiscript/dispatchkit/boxed_value.hpp +++ b/include/chaiscript/dispatchkit/boxed_value.hpp @@ -119,7 +119,7 @@ namespace chaiscript boost::shared_ptr get(Boxed_Value::Void_Type) { return boost::shared_ptr (new Data( - Get_Type_Info::get(), + detail::Get_Type_Info::get(), boost::any(), false) ); @@ -135,7 +135,7 @@ namespace chaiscript boost::shared_ptr get(const boost::shared_ptr &obj) { boost::shared_ptr data(new Data( - Get_Type_Info::get(), + detail::Get_Type_Info::get(), boost::any(obj), false, boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) @@ -164,7 +164,7 @@ namespace chaiscript boost::shared_ptr get(boost::reference_wrapper obj) { boost::shared_ptr data(new Data( - Get_Type_Info::get(), + detail::Get_Type_Info::get(), boost::any(obj), true) ); @@ -192,7 +192,7 @@ namespace chaiscript boost::shared_ptr get(const T& t) { boost::shared_ptr data(new Data( - Get_Type_Info::get(), + detail::Get_Type_Info::get(), boost::any(boost::shared_ptr(new T(t))), false, boost::shared_ptr(new Data::Shared_Ptr_Proxy_Impl())) @@ -331,175 +331,178 @@ namespace chaiscript }; - // Cast_Helper helper classes + namespace detail + { + // Cast_Helper helper classes - /** - * Generic Cast_Helper, for casting to any type - */ - template - struct Cast_Helper - { - typedef typename boost::reference_wrapper::type > Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Generic Cast_Helper, for casting to any type + */ + template + struct Cast_Helper { - if (ob.is_ref()) + typedef typename boost::reference_wrapper::type > Result_Type; + + static Result_Type cast(const Boxed_Value &ob) { - if (!ob.get_type_info().m_is_const) + if (ob.is_ref()) { - return boost::cref((boost::any_cast >(ob.get())).get()); + if (!ob.get_type_info().m_is_const) + { + return boost::cref((boost::any_cast >(ob.get())).get()); + } else { + return boost::any_cast >(ob.get()); + } } else { - return boost::any_cast >(ob.get()); + return boost::cref(*(boost::any_cast >(ob.get()))); } - } else { - return boost::cref(*(boost::any_cast >(ob.get()))); } - } - }; + }; - /** - * Cast_Helper for casting to a const & type - */ - template - struct Cast_Helper - { - typedef typename boost::reference_wrapper::type > Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Cast_Helper for casting to a const & type + */ + template + struct Cast_Helper { - if (ob.is_ref()) + typedef typename boost::reference_wrapper::type > Result_Type; + + static Result_Type cast(const Boxed_Value &ob) { - if (!ob.get_type_info().m_is_const) + if (ob.is_ref()) { - return boost::cref((boost::any_cast >(ob.get())).get()); + if (!ob.get_type_info().m_is_const) + { + return boost::cref((boost::any_cast >(ob.get())).get()); + } else { + return boost::any_cast >(ob.get()); + } } else { - return boost::any_cast >(ob.get()); + return boost::cref(*(boost::any_cast >(ob.get()))); } - } else { - return boost::cref(*(boost::any_cast >(ob.get()))); } - } - }; + }; - /** - * Cast_Helper for casting to a const * type - */ - template - struct Cast_Helper - { - typedef const Result * Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Cast_Helper for casting to a const * type + */ + template + struct Cast_Helper { - if (ob.is_ref()) + typedef const Result * Result_Type; + + static Result_Type cast(const Boxed_Value &ob) { - if (!ob.get_type_info().m_is_const) + if (ob.is_ref()) + { + if (!ob.get_type_info().m_is_const) + { + return (boost::any_cast >(ob.get())).get_pointer(); + } else { + return (boost::any_cast >(ob.get())).get_pointer(); + } + } else { + return (boost::any_cast >(ob.get())).get(); + } + } + }; + + /** + * Cast_Helper for casting to a * type + */ + template + struct Cast_Helper + { + typedef Result * Result_Type; + + static Result_Type cast(const Boxed_Value &ob) + { + if (ob.is_ref()) { return (boost::any_cast >(ob.get())).get_pointer(); } else { - return (boost::any_cast >(ob.get())).get_pointer(); + return (boost::any_cast >(ob.get())).get(); } - } else { - return (boost::any_cast >(ob.get())).get(); } - } - }; + }; - /** - * Cast_Helper for casting to a * type - */ - template - struct Cast_Helper - { - typedef Result * Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Cast_Helper for casting to a & type + */ + template + struct Cast_Helper { - if (ob.is_ref()) + typedef typename boost::reference_wrapper Result_Type; + + static Result_Type cast(const Boxed_Value &ob) { - return (boost::any_cast >(ob.get())).get_pointer(); - } else { - return (boost::any_cast >(ob.get())).get(); + if (ob.is_ref()) + { + return boost::any_cast >(ob.get()); + } else { + return boost::ref(*(boost::any_cast >(ob.get()))); + } } - } - }; + }; - /** - * Cast_Helper for casting to a & type - */ - template - struct Cast_Helper - { - typedef typename boost::reference_wrapper Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Cast_Helper for casting to a boost::shared_ptr<> type + */ + template + struct Cast_Helper > { - if (ob.is_ref()) + typedef typename boost::shared_ptr Result_Type; + + static Result_Type cast(const Boxed_Value &ob) { - return boost::any_cast >(ob.get()); - } else { - return boost::ref(*(boost::any_cast >(ob.get()))); + return boost::any_cast >(ob.get()); } - } - }; + }; - /** - * Cast_Helper for casting to a boost::shared_ptr<> type - */ - template - struct Cast_Helper > - { - typedef typename boost::shared_ptr Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Cast_Helper for casting to a boost::shared_ptr<> type + */ + template + struct Cast_Helper &> { - return boost::any_cast >(ob.get()); - } - }; + typedef typename boost::shared_ptr Result_Type; - /** - * Cast_Helper for casting to a boost::shared_ptr<> type - */ - template - struct Cast_Helper &> - { - typedef typename boost::shared_ptr Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + static Result_Type cast(const Boxed_Value &ob) + { + return boost::any_cast >(ob.get()); + } + }; + + + + /** + * Cast_Helper for casting to a Boxed_Value type + */ + template<> + struct Cast_Helper { - return boost::any_cast >(ob.get()); - } - }; + typedef const Boxed_Value & Result_Type; + static Result_Type cast(const Boxed_Value &ob) + { + return ob; + } + }; - - /** - * Cast_Helper for casting to a Boxed_Value type - */ - template<> - struct Cast_Helper - { - typedef const Boxed_Value & Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + /** + * Cast_Helper for casting to a const Boxed_Value & type + */ + template<> + struct Cast_Helper { - return ob; - } - }; + typedef const Boxed_Value & Result_Type; - /** - * Cast_Helper for casting to a const Boxed_Value & type - */ - template<> - struct Cast_Helper - { - typedef const Boxed_Value & Result_Type; - - static Result_Type cast(const Boxed_Value &ob) - { - return ob; - } - }; + static Result_Type cast(const Boxed_Value &ob) + { + return ob; + } + }; + } /** * class that is thrown in the event of a bad_boxed_cast. That is, @@ -537,10 +540,10 @@ namespace chaiscript * int &i = boxed_cast(boxedvalue); */ template - typename Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) + typename detail::Cast_Helper::Result_Type boxed_cast(const Boxed_Value &bv) { try { - return Cast_Helper::cast(bv); + return detail::Cast_Helper::cast(bv); } catch (const boost::bad_any_cast &) { throw bad_boxed_cast(bv.get_type_info(), typeid(Type)); } @@ -676,19 +679,22 @@ namespace chaiscript bool m_isfloat; }; - /** - * Cast_Helper for converting from Boxed_Value to Boxed_POD_Value - */ - template<> - struct Cast_Helper - { - typedef Boxed_POD_Value Result_Type; - - static Result_Type cast(const Boxed_Value &ob) + namespace detail + { + /** + * Cast_Helper for converting from Boxed_Value to Boxed_POD_Value + */ + template<> + struct Cast_Helper { - return Boxed_POD_Value(ob); - } - }; + typedef Boxed_POD_Value Result_Type; + + static Result_Type cast(const Boxed_Value &ob) + { + return Boxed_POD_Value(ob); + } + }; + } template Boxed_Value var(T t) @@ -697,7 +703,7 @@ namespace chaiscript } /** - * Return true if the two Boxed_Value's share the same internal type + * Return true if the two Boxed_Values share the same internal type */ static bool type_match(Boxed_Value l, Boxed_Value r) { diff --git a/include/chaiscript/dispatchkit/function_call.hpp b/include/chaiscript/dispatchkit/function_call.hpp index 048d7b7..5f6eccd 100644 --- a/include/chaiscript/dispatchkit/function_call.hpp +++ b/include/chaiscript/dispatchkit/function_call.hpp @@ -4,13 +4,6 @@ // and Jason Turner (lefticus@gmail.com) // http://www.chaiscript.com -#include - -#define addparam(z,n,text) params.push_back(boost::is_reference::value?Boxed_Value(boost::ref(BOOST_PP_CAT(p, n))):Boxed_Value(BOOST_PP_CAT(p, n) )); -#define curry(z,n,text) BOOST_PP_CAT(_, BOOST_PP_INC(n)) - - -#ifndef BOOST_PP_IS_ITERATING #ifndef __function_call_hpp__ #define __function_call_hpp__ @@ -20,50 +13,7 @@ #include #include #include "proxy_functions.hpp" - -namespace chaiscript -{ - /** - * Internal helper class for handling the return - * value of a build_function_caller - */ - template - class Function_Caller_Ret - { - public: - Function_Caller_Ret() - { - } - - Ret call(const std::vector > &t_funcs, - const std::vector ¶ms) - { - return boxed_cast(dispatch(t_funcs, params)); - } - }; - - /** - * Specialization for void return types - */ - template<> - class Function_Caller_Ret - { - public: - Function_Caller_Ret() - { - } - - void call(const std::vector > &t_funcs, - const std::vector ¶ms) - { - dispatch(t_funcs, params); - } - }; -} - -#define BOOST_PP_ITERATION_LIMITS ( 0, 9 ) -#define BOOST_PP_FILENAME_1 -#include BOOST_PP_ITERATE() +#include "function_call_detail.hpp" namespace chaiscript { @@ -118,39 +68,5 @@ namespace chaiscript } -# endif -#else -# define n BOOST_PP_ITERATION() - -namespace chaiscript -{ - /** - * used internally for unwrapping a function call's types - */ - template - Ret function_caller(const std::vector > &funcs - BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) - { - std::vector params; - - BOOST_PP_REPEAT(n, addparam, ~) - - return Function_Caller_Ret().call(funcs, params); - } - - /** - * used internally for unwrapping a function call's types - */ - template - boost::function - build_function_caller_helper(Ret (BOOST_PP_ENUM_PARAMS(n, Param)), const std::vector > &funcs) - { - return boost::bind(&function_caller, funcs - BOOST_PP_ENUM_TRAILING(n, curry, ~)); - } - - -} - #endif diff --git a/include/chaiscript/dispatchkit/proxy_constructors.hpp b/include/chaiscript/dispatchkit/proxy_constructors.hpp index e01a4d8..d2697f7 100644 --- a/include/chaiscript/dispatchkit/proxy_constructors.hpp +++ b/include/chaiscript/dispatchkit/proxy_constructors.hpp @@ -26,7 +26,7 @@ namespace chaiscript Proxy_Function constructor() { T *f = 0; - return (build_constructor_(f)); + return (detail::build_constructor_(f)); } } @@ -35,28 +35,31 @@ namespace chaiscript namespace chaiscript { - /** - * A constructor function, used for creating a new object - * of a given type with a given set of params - */ - template - boost::shared_ptr constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) - { - return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); - } + namespace detail + { + /** + * A constructor function, used for creating a new object + * of a given type with a given set of params + */ + template + boost::shared_ptr constructor_( BOOST_PP_ENUM_BINARY_PARAMS(n, Param, p) ) + { + return boost::shared_ptr(new Class( BOOST_PP_ENUM_PARAMS(n, p) )); + } - /** - * Helper function for build a constructor function - * example: - * dispatchengine.register_function(build_constructor, "MyClass"); - * \todo See if it is possible to make this not be a variadic function - */ - template - Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param))) - { - typedef boost::shared_ptr (sig)(BOOST_PP_ENUM_PARAMS(n, Param)); - return Proxy_Function(new Proxy_Function_Impl(boost::function(&(constructor_)))); - } + /** + * Helper function for build a constructor function + * example: + * dispatchengine.register_function(build_constructor, "MyClass"); + * \todo See if it is possible to make this not be a variadic function + */ + template + Proxy_Function build_constructor_(Class (*)(BOOST_PP_ENUM_PARAMS(n, Param))) + { + typedef boost::shared_ptr (sig)(BOOST_PP_ENUM_PARAMS(n, Param)); + return Proxy_Function(new Proxy_Function_Impl(boost::function(&(constructor_)))); + } + } } #endif diff --git a/include/chaiscript/dispatchkit/proxy_functions.hpp b/include/chaiscript/dispatchkit/proxy_functions.hpp index 36c85c8..b291b06 100644 --- a/include/chaiscript/dispatchkit/proxy_functions.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions.hpp @@ -4,109 +4,22 @@ // and Jason Turner (lefticus@gmail.com) // http://www.chaiscript.com -#include -#define gettypeinfo(z,n,text) ti.push_back(Get_Type_Info::get()); -#define casthelper(z,n,text) ,chaiscript::boxed_cast< Param ## n >(params[n]) -#define comparetype(z,n,text) && ((Get_Type_Info::get() == params[n].get_type_info())) -#define trycast(z,n,text) chaiscript::boxed_cast(params[n]); - - -#ifndef BOOST_PP_IS_ITERATING #ifndef __proxy_functions_hpp__ #define __proxy_functions_hpp__ + #include "boxed_value.hpp" #include "type_info.hpp" #include #include -#include -#include #include #include +#include "proxy_functions_detail.hpp" namespace chaiscript { - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template - struct Handle_Return - { - Boxed_Value operator()(const boost::function &f) - { - return Boxed_Value(f()); - } - }; - - template - struct Handle_Return &> - { - Boxed_Value operator()(const boost::function & ()> &f) - { - return Boxed_Value(f()); - } - }; - - template - struct Handle_Return &> - { - Boxed_Value operator()(const boost::function & ()> &f) - { - return Boxed_Value(f()); - } - }; - - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template - struct Handle_Return - { - Boxed_Value operator()(const boost::function &f) - { - return Boxed_Value(boost::ref(f())); - } - }; - - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - Boxed_Value operator()(const boost::function &f) - { - return f(); - } - }; - - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - Boxed_Value operator()(const boost::function &f) - { - return f(); - } - }; - - /** - * Used internally for handling a return value from a Proxy_Function call - */ - template<> - struct Handle_Return - { - Boxed_Value operator()(const boost::function &f) - { - f(); - return Boxed_Value(Boxed_Value::Void_Type()); - } - }; - /** * Helper for building a list of parameters for calling a Proxy_Function * it does automatic conversion to Boxed_Value types via operator<< @@ -138,30 +51,6 @@ namespace chaiscript std::vector 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) - : std::range_error("Function dispatch arity mismatch"), - got(t_got), expected(t_expected) - { - } - - virtual ~arity_error() throw() {} - int got; - int expected; - }; -} - -#define BOOST_PP_ITERATION_LIMITS ( 0, 10 ) -#define BOOST_PP_FILENAME_1 -#include BOOST_PP_ITERATE() - -namespace chaiscript -{ /** * Pure virtual base class for all Proxy_Function implementations * Proxy_Functions are a type erasure of type safe C++ @@ -321,16 +210,16 @@ namespace chaiscript { std::vector types; - types.push_back(Get_Type_Info::get()); + types.push_back(detail::Get_Type_Info::get()); if (arity >= 0) { for (int i = 0; i < arity; ++i) { - types.push_back(Get_Type_Info::get()); + types.push_back(detail::Get_Type_Info::get()); } } else { - types.push_back(Get_Type_Info >::get()); + types.push_back(detail::Get_Type_Info >::get()); } return types; @@ -395,7 +284,7 @@ namespace chaiscript while (true) { while (barg != m_args.end() - && !(barg->get_type_info() == Get_Type_Info::get())) + && !(barg->get_type_info() == detail::Get_Type_Info::get())) { args.push_back(*barg); ++barg; @@ -408,7 +297,7 @@ namespace chaiscript } if (barg != m_args.end() - && barg->get_type_info() == Get_Type_Info::get()) + && barg->get_type_info() == detail::Get_Type_Info::get()) { ++barg; } @@ -546,70 +435,5 @@ namespace chaiscript } } -# endif -#else -# define n BOOST_PP_ITERATION() - -namespace chaiscript -{ - /** - * Used by Proxy_Function_Impl to return a list of all param types - * it contains. - */ - template - std::vector build_param_type_list(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param))) - { - std::vector ti; - ti.push_back(Get_Type_Info::get()); - - BOOST_PP_REPEAT(n, gettypeinfo, ~) - - 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 - Boxed_Value call_func(const boost::function &f, - const std::vector ¶ms) - { - if (params.size() != n) - { - throw arity_error(params.size(), n); - } else { - return Handle_Return()(boost::bind(f BOOST_PP_REPEAT(n, casthelper, ~))); - } - } - - /** - * 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 - bool compare_types(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), - const std::vector ¶ms) - { - if (params.size() != n) - { - return false; - } else { - bool val = true BOOST_PP_REPEAT(n, comparetype, ~); - if (val) return true; - - try { - BOOST_PP_REPEAT(n, trycast, ~); - } catch (const bad_boxed_cast &) { - return false; - } - - return true; - } - } -} #endif diff --git a/include/chaiscript/dispatchkit/register_function.hpp b/include/chaiscript/dispatchkit/register_function.hpp index 425d242..c628eea 100644 --- a/include/chaiscript/dispatchkit/register_function.hpp +++ b/include/chaiscript/dispatchkit/register_function.hpp @@ -22,15 +22,17 @@ namespace chaiscript return Proxy_Function(new Proxy_Function_Impl(f)); } - - /** - * Helper function for register_member function - */ - template - T &get_member(T Class::* m, Class *obj) - { - return (obj->*m); - } + namespace detail + { + /** + * Helper function for register_member function + */ + template + T &get_member(T Class::* m, Class *obj) + { + return (obj->*m); + } + } /** * Automatically create a get_member helper function for an object @@ -40,7 +42,7 @@ namespace chaiscript template Proxy_Function fun(T Class::* m) { - return fun(boost::function(boost::bind(&get_member, m, _1))); + return fun(boost::function(boost::bind(&detail::get_member, m, _1))); } } diff --git a/include/chaiscript/dispatchkit/type_info.hpp b/include/chaiscript/dispatchkit/type_info.hpp index 5b91e6b..4aa7b59 100644 --- a/include/chaiscript/dispatchkit/type_info.hpp +++ b/include/chaiscript/dispatchkit/type_info.hpp @@ -77,57 +77,59 @@ namespace chaiscript bool m_is_unknown; }; - /** - * Helper used to create a Type_Info object - */ - template - struct Get_Type_Info - { - static Type_Info get() + namespace detail + { + /** + * Helper used to create a Type_Info object + */ + template + struct Get_Type_Info { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - &typeid(T), - &typeid(typename boost::remove_const::type>::type>::type)); - } - }; + static Type_Info get() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(T), + &typeid(typename boost::remove_const::type>::type>::type)); + } + }; - template - struct Get_Type_Info > - { - static Type_Info get() + template + struct Get_Type_Info > { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - &typeid(boost::shared_ptr ), - &typeid(typename boost::remove_const::type>::type>::type)); - } - }; + static Type_Info get() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(boost::shared_ptr ), + &typeid(typename boost::remove_const::type>::type>::type)); + } + }; - template - struct Get_Type_Info > - { - static Type_Info get() + template + struct Get_Type_Info > { - return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, - boost::is_void::value, - &typeid(boost::reference_wrapper ), - &typeid(typename boost::remove_const::type>::type>::type)); - } - }; - + static Type_Info get() + { + return Type_Info(boost::is_const::value, boost::is_reference::value, boost::is_pointer::value, + boost::is_void::value, + &typeid(boost::reference_wrapper ), + &typeid(typename boost::remove_const::type>::type>::type)); + } + }; + } template Type_Info user_type(T) { - return Get_Type_Info::get(); + return detail::Get_Type_Info::get(); } template Type_Info user_type() { - return Get_Type_Info::get(); + return detail::Get_Type_Info::get(); }