diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index 7d93393..6900f14 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -4,13 +4,6 @@ // and Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com -#include - -#define gettypeinfo(z,n,text) ti.push_back(chaiscript::detail::Get_Type_Info::get()); -#define casthelper(z,n,text) BOOST_PP_COMMA_IF(n) chaiscript::boxed_cast< Param ## n >(params[n]) -#define trycast(z,n,text) chaiscript::boxed_cast(params[n]); - -#ifndef BOOST_PP_IS_ITERATING #ifndef CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ #define CHAISCRIPT_PROXY_FUNCTIONS_DETAIL_HPP_ @@ -46,19 +39,6 @@ namespace chaiscript }; } -} - -#define BOOST_PP_ITERATION_LIMITS ( 0, 10 ) -#define BOOST_PP_FILENAME_1 -#include BOOST_PP_ITERATE() - - -# endif -#else -# define n BOOST_PP_ITERATION() - -namespace chaiscript -{ namespace dispatch { namespace detail @@ -67,62 +47,105 @@ 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))) + template + std::vector build_param_type_list(Ret (*)(Params...)) { - std::vector ti; - ti.push_back(chaiscript::detail::Get_Type_Info::get()); - - BOOST_PP_REPEAT(n, gettypeinfo, ~) - - return ti; + return std::vector { chaiscript::detail::Get_Type_Info::get(), + chaiscript::detail::Get_Type_Info::get()... }; } + + // Forward declaration + template + struct Try_Cast; + + // implementation + template + struct Try_Cast + { + static void do_try(const std::vector ¶ms, int generation) + { + boxed_cast(params[generation]); + Try_Cast::do_try(params, generation+1); + } + }; + + // 0th case + template<> + struct Try_Cast<> + { + static void do_try(const std::vector &, int) + { + } + }; + + + + /** + * 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_cast(Ret (*)(Params...), + const std::vector ¶ms) + { + try { + Try_Cast::do_try(params, 0); + } catch (const exception::bad_boxed_cast &) { + return false; + } + + return true; + } + + template + struct Call_Func + { + + template + static Ret do_call(const std::function &f, + const std::vector ¶ms, InnerParams ... innerparams) + { + return Call_Func::do_call(f, params, innerparams..., params[sizeof...(Params) - count]); + } + }; + + template + struct Call_Func + { + template + static Ret do_call(const std::function &f, + const std::vector &, InnerParams ... innerparams) + { + return f(boxed_cast(innerparams)...); + } + }; + /** * 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 - Ret call_func(const std::function &f, + template + Ret call_func(const std::function &f, const std::vector ¶ms) { - if (params.size() != n) + if (params.size() == sizeof...(Params)) { - throw exception::arity_error(static_cast(params.size()), n); - } else { - return 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_cast(Ret (*)(BOOST_PP_ENUM_PARAMS(n, Param)), - const std::vector & BOOST_PP_IF(n, params, )) - { - try { - BOOST_PP_REPEAT(n, trycast, ~); - } catch (const exception::bad_boxed_cast &) { - return false; + return Call_Func::do_call(f, params); } - return true; + throw exception::arity_error(static_cast(params.size()), sizeof...(Params)); } + } } + + } -#undef n - -#endif - - -#ifndef BOOST_PP_IS_ITERATING namespace chaiscript {