#pragma once #include #include namespace ss { //////////////// // function traits //////////////// template struct decayed_arg_n { static_assert(N - 1 != sizeof...(Ts), "index out of range"); using type = typename decayed_arg_n::type; }; template struct decayed_arg_n<0, T, Ts...> { using type = std::decay_t; }; template struct function_traits; template struct function_traits> { using arg_type = Arg; }; template struct function_traits { using arg0 = typename decayed_arg_n<0, Ts...>::type; }; template struct function_traits : function_traits {}; template struct function_traits : function_traits {}; template struct function_traits : function_traits {}; template struct function_traits : function_traits {}; template struct function_traits : function_traits {}; template struct member_wrapper; template struct member_wrapper { using arg_type = typename function_traits::arg0; }; //////////////// // has method //////////////// #define INIT_HAS_METHOD(method) \ template \ class has_m_##method { \ template \ static std::true_type test(decltype(&C::method)); \ \ template \ static std::false_type test(...); \ \ public: \ constexpr static bool value = decltype(test(0))::value; \ }; \ \ template \ constexpr bool has_m_##method##_t = has_m_##method::value; } /* namespace ss */