// 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 #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 dispatchkit { /** * 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 dispatchkit { /** * 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 build_function_caller(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(boost::shared_ptr 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 build_function_caller(boost::shared_ptr func) { std::vector > > funcs; funcs.push_back(std::make_pair(std::string(), func)); return build_function_caller(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 build_function_caller(const Boxed_Value &bv) { return build_function_caller(boxed_cast >(bv)); } /** * Helper for calling script code as if it were native C++ code * example: * boost::function 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 boost::function build_functor(ScriptEngine &e, const std::string &script) { return build_function_caller(e.evaluate_string(script)); } } # endif #else # define n BOOST_PP_ITERATION() namespace dispatchkit { /** * 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