From 70262292733ac29e38e1041d141c72b882123f1a Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Mon, 1 Jun 2015 09:43:29 -0600 Subject: [PATCH] Apply Index expansion technique to simplify code Thanks @sean-parent I saw the technique in your future implementation --- .../dispatchkit/proxy_functions_detail.hpp | 94 ++++++++----------- 1 file changed, 37 insertions(+), 57 deletions(-) diff --git a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp index b90c8d63..a77376f4 100644 --- a/include/chaiscript/dispatchkit/proxy_functions_detail.hpp +++ b/include/chaiscript/dispatchkit/proxy_functions_detail.hpp @@ -53,6 +53,23 @@ namespace chaiscript { namespace detail { + template + struct Indexes + { + }; + + template + struct Make_Indexes + { + typedef typename Make_Indexes::indexes indexes; + }; + + template + struct Make_Indexes<0, I...> + { + typedef Indexes indexes; + }; + /** * Used by Proxy_Function_Impl to return a list of all param types * it contains. @@ -65,77 +82,39 @@ namespace chaiscript } - // Forward declaration - template - struct Try_Cast; - - template - struct Try_Cast - { - static void do_try(const std::vector ¶ms, size_t generation, const Type_Conversions &t_conversions) - { - boxed_cast(params[generation], &t_conversions); - Try_Cast::do_try(params, generation+1, t_conversions); - } - }; - - // 0th case - template<> - struct Try_Cast<> - { - static void do_try(const std::vector &, size_t, const Type_Conversions &) - { - } - }; - - /** * Used by Proxy_Function_Impl to determine if it is equivalent to another * Proxy_Function_Impl object. This function is primarily used to prevent * registration of two functions with the exact same signatures */ - template - bool compare_types_cast(Ret (*)(Params...), + template + bool compare_types_cast(Indexes, Ret (*)(Params...), const std::vector ¶ms, const Type_Conversions &t_conversions) - { + { try { - Try_Cast::do_try(params, 0, t_conversions); + std::initializer_list{(boxed_cast(params[I], &t_conversions), nullptr)...}; + return true; } 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, const Type_Conversions &t_conversions, InnerParams &&... innerparams) - { - return Call_Func::do_call(f, params, t_conversions, std::forward(innerparams)..., params[sizeof...(Params) - count]); - } - }; - template - struct Call_Func + bool compare_types_cast(Ret (*f)(Params...), + const std::vector ¶ms, const Type_Conversions &t_conversions) { -#ifdef CHAISCRIPT_MSVC -#pragma warning(push) -#pragma warning(disable : 4100) /// Disable unreferenced formal parameter warning, which only shows up in MSVC I don't think there's any way around it \todo evaluate this -#endif - template - static Ret do_call(const std::function &f, - const std::vector &, const Type_Conversions &t_conversions, InnerParams &&... innerparams) - { - return f(boxed_cast(std::forward(innerparams), &t_conversions)...); - } -#ifdef CHAISCRIPT_MSVC -#pragma warning(pop) -#endif - }; + typedef typename Make_Indexes::indexes indexes; + return compare_types_cast(indexes(), f, params, t_conversions); + } + + template + Ret call_func(Indexes, const std::function &f, + const std::vector ¶ms, const Type_Conversions &t_conversions) + { + return f(boxed_cast(params[I], &t_conversions)...); + } + /** * Used by Proxy_Function_Impl to perform typesafe execution of a function. @@ -149,7 +128,8 @@ namespace chaiscript { if (params.size() == sizeof...(Params)) { - return Call_Func::do_call(f, params, t_conversions); + typedef typename Make_Indexes::indexes indexes; + return call_func(indexes(), f, params, t_conversions); } throw exception::arity_error(static_cast(params.size()), sizeof...(Params));