// This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009, Jonathan Turner (jturner@minnow-lang.org) // and Jason Turner (lefticus@gmail.com) // http://www.chaiscript.com #include #define addparam(z,n,text) params.push_back(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__ #include #include #include #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() namespace chaiscript { /** * Build a function caller that knows how to dispatch on a set of functions * example: * boost::function 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 boost::function functor(const std::vector > &funcs) { FunctionType *p; 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(Proxy_Function f) * { * boost::function local_f = * build_function_caller(f); * } * \returns A boost::function object for dispatching * \param[in] func A function to execute. */ template boost::function functor(Proxy_Function func) { std::vector > funcs; funcs.push_back(std::make_pair(std::string(), func)); return functor(funcs); } /** * Helper for automatically unboxing a Boxed_Value that contains a function object * and creating a typesafe C++ function caller from it. */ template boost::function functor(const Boxed_Value &bv) { return functor(boxed_cast(bv)); } } # 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