// This file is distributed under the BSD License. // See "license.txt" for details. // Copyright 2009-2012, Jonathan Turner (jonathan@emptycrate.com) // Copyright 2009-2015, Jason Turner (jason@emptycrate.com) // http://www.chaiscript.com #ifndef CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ #define CHAISCRIPT_FUNCTION_CALL_DETAIL_HPP_ #include #include #include #include #include #include "boxed_cast.hpp" #include "boxed_number.hpp" #include "boxed_value.hpp" #include "type_conversions.hpp" #include "proxy_functions.hpp" namespace chaiscript { namespace dispatch { namespace detail { /// Internal helper class for handling the return /// value of a build_function_caller template struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, const std::vector ¶ms, const Type_Conversions &t_conversions) { return boxed_cast(dispatch::dispatch(t_funcs, params, t_conversions)); } }; /** * Specialization for arithmetic return types */ template struct Function_Caller_Ret { static Ret call(const std::vector &t_funcs, const std::vector ¶ms, const Type_Conversions &t_conversions) { return Boxed_Number(dispatch::dispatch(t_funcs, params, t_conversions)).get_as(); } }; /** * Specialization for void return types */ template<> struct Function_Caller_Ret { static void call(const std::vector &t_funcs, const std::vector ¶ms, const Type_Conversions &t_conversions) { dispatch::dispatch(t_funcs, params, t_conversions); } }; /** * used internally for unwrapping a function call's types */ template struct Build_Function_Caller_Helper { Build_Function_Caller_Helper(std::vector t_funcs, const Type_Conversions &t_conversions) : m_funcs(std::move(t_funcs)), m_conversions(t_conversions) { } Ret operator()(Param...param) { return Function_Caller_Ret::value && !std::is_same::value>::call(m_funcs, { (std::is_reference::value&&!(std::is_same::type>::type>::value))?Boxed_Value(std::ref(param)):Boxed_Value(param)... }, m_conversions ); } std::vector m_funcs; Type_Conversions m_conversions; }; template std::function build_function_caller_helper(Ret (Params...), const std::vector &funcs, const Type_Conversions *t_conversions) { if (funcs.size() == 1) { std::shared_ptr> pfi = std::dynamic_pointer_cast > (funcs[0]); if (pfi) { return pfi->internal_function(); } // looks like this either wasn't a Proxy_Function_Impl or the types didn't match // we cannot make any other guesses or assumptions really, so continuing } return std::function(Build_Function_Caller_Helper(funcs, t_conversions?*t_conversions:Type_Conversions())); } } } } #endif