#if !defined( INCLUDED_FUNCTIONAL_H ) #define INCLUDED_FUNCTIONAL_H #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 struct MemberFunction; template struct MemberFunction { using type = R(Object::*)(Ts...); using type_const = R(Object::*)(Ts...) const; }; } template using MemberFunction = typename detail::MemberFunction::type; template using ConstMemberFunction = typename detail::MemberFunction::type_const; 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 func> using Member = typename MemberN::template instance; 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 func> using ConstMember = typename ConstMemberN::template instance; 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 FunctionN::template instance; template class CallerShiftFirst; template class CallerShiftFirst { public: using func = R(FirstArgument, Ts...); static R call(FirstArgument, Ts... args) { return Caller::call(args...); } }; template class FunctorNInvoke; 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 { 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 = FunctorNInvoke>; #endif