#pragma once #include #include namespace detail { template struct rank : rank { }; template<> struct rank<0> { }; struct get_func { template struct wrapper { using type = T; }; template using func_member = wrapper; template static wrapper> test( rank<2> ) { return {}; } template struct func_lambda { using type = typename func_lambda::type; }; template struct func_lambda { using type = R(Ts...); }; template struct func_lambda { using type = R(Ts...); }; template struct func_lambda { using type = R(Ts...); }; template> static wrapper> test( rank<1> ) { return {}; } }; template struct Fn; template struct Fn { using result_type = R; template using get = typename std::tuple_element>::type; }; } template using get_func = typename decltype(detail::get_func::test( detail::rank<2>{} ))::type::type; template using get_result_type = typename detail::Fn>::result_type; template using get_argument = typename detail::Fn>::template get; namespace detail { template class FunctionN; template class FunctionN { public: template class instance { public: using func = R(Ts...); static R call( Ts... args ){ return ( f )( args... ); } }; }; } template using Function = typename detail::FunctionN::template instance; namespace detail { template struct MemberFunction; template struct MemberFunction { using type = R(Object::*)(Ts...); using type_const = R(Object::*)(Ts...) const; }; } namespace detail { template class MemberN; template class MemberN { public: template class instance { public: using func = R(Object &, Ts...); static R call( Object& object, Ts... args ){ return ( object.*f )( args... ); } }; }; } template using MemberFunction = typename detail::MemberFunction::type; template func> using Member = typename detail::MemberN::template instance; namespace detail { template class ConstMemberN; template class ConstMemberN { public: template class instance { public: using func = R(const Object &, Ts...); static R call( const Object& object, Ts... args ){ return ( object.*f )( args... ); } }; }; } template using ConstMemberFunction = typename detail::MemberFunction::type_const; template func> using ConstMember = typename detail::ConstMemberN::template instance; // misc namespace detail { template struct seq { }; template struct gens : gens { }; template struct gens<0, S...> { using type = seq; }; template using seq_new = typename gens::type; template class FunctorNInvoke; template class FunctorNInvoke { std::tuple args; template struct caller; template struct caller> { static inline R call( FunctorNInvoke *self, Functor functor ){ (void) self; return functor( std::get( self->args )... ); } }; public: FunctorNInvoke( Ts... args ) : args( args... ){ } inline R operator()( Functor functor ) { return caller>::call( this, functor ); } }; } template using FunctorInvoke = detail::FunctorNInvoke>;