// 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 gettypeinfo(z,n,text) ti.push_back(detail::Get_Type_Info::get()); #define casthelper(z,n,text) ,chaiscript::boxed_cast< Param ## n >(params[n]) #define comparetype(z,n,text) && ((detail::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_detail_hpp__ #define __proxy_functions_detail_hpp__ #include "boxed_value.hpp" #include "type_info.hpp" #include "handle_return.hpp" #include #include #include #include #include #include namespace chaiscript { /** * 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() # 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(detail::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::call(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