#pragma once #include namespace dukglue { namespace detail { ////////////////////////////////////////////////////////////////////////////////////////////// // Credit to LuaState for this code: // https://github.com/AdUki/LuaState/blob/master/include/Traits.h template struct index_tuple {}; template struct make_indexes_impl; template struct make_indexes_impl, T, Types...> { typedef typename make_indexes_impl, Types...>::type type; }; template struct make_indexes_impl > { typedef index_tuple type; }; template struct make_indexes : make_indexes_impl<0, index_tuple<>, Types...> {}; ////////////////////////////////////////////////////////////////////////////////////////////// template struct indexes {}; template struct indexes_builder : indexes_builder {}; template struct indexes_builder<0, Is...> { typedef indexes index; }; ////////////////////////////////////////////////////////////////////////////////////////////// // This mess is used to use function arugments stored in an std::tuple to an // std::function, function pointer, or method. // std::function template Ret apply_helper(std::function pf, index_tuple< Indexes... >, std::tuple&& tup) { return pf(std::forward(std::get(tup))...); } template Ret apply(std::function pf, const std::tuple& tup) { return apply_helper(pf, typename make_indexes::type(), std::tuple(tup)); } // function pointer template Ret apply_fp_helper(Ret(*pf)(Args...), index_tuple< Indexes... >, std::tuple&& tup) { return pf(std::forward(std::get(tup))...); } template Ret apply_fp(Ret(*pf)(Args...), const std::tuple& tup) { return apply_fp_helper(pf, typename make_indexes::type(), std::tuple(tup)); } // method pointer template Ret apply_method_helper(Ret(Cls::*pf)(Args...), index_tuple< Indexes... >, Cls* obj, std::tuple&& tup) { return (*obj.*pf)(std::forward(std::get(tup))...); } template Ret apply_method(Ret(Cls::*pf)(Args...), Cls* obj, const std::tuple& tup) { return apply_method_helper(pf, typename make_indexes::type(), obj, std::tuple(tup)); } // const method pointer template Ret apply_method_helper(Ret(Cls::*pf)(Args...) const, index_tuple< Indexes... >, Cls* obj, std::tuple&& tup) { return (*obj.*pf)(std::forward(std::get(tup))...); } template Ret apply_method(Ret(Cls::*pf)(Args...) const, Cls* obj, const std::tuple& tup) { return apply_method_helper(pf, typename make_indexes::type(), obj, std::tuple(tup)); } // constructor template Cls* apply_constructor_helper(index_tuple< Indexes... >, std::tuple&& tup) { return new Cls(std::forward(std::get(tup))...); } template Cls* apply_constructor(const std::tuple& tup) { return apply_constructor_helper(typename make_indexes::type(), std::tuple(tup)); } ////////////////////////////////////////////////////////////////////////////////////////////// } }