#if !defined( INCLUDED_FUNCTIONAL_H ) #define INCLUDED_FUNCTIONAL_H #include namespace detail { template struct Fn; template struct Fn { using result_type = R; template using get = typename std::tuple_element>::type; }; } template using get_result_type = typename detail::Fn::result_type; template using get_argument = typename detail::Fn::template get; 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 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 class FunctionN; template class FunctionN { public: template class instance { public: using func = R(Ts...); static R call(Ts... args) { return (f)(args...); } }; }; 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; template using Member = typename MemberN::template instance; template using ConstMember = typename ConstMemberN::template instance; template using Member1 = typename MemberN::template instance; template using ConstMember1 = typename ConstMemberN::template instance; template using Member2 = typename MemberN::template instance; template using ConstMember2 = typename ConstMemberN::template instance; template using Member3 = typename MemberN::template instance; template using ConstMember3 = typename ConstMemberN::template instance; template using Function0 = typename FunctionN::template instance; template using Function1 = typename FunctionN::template instance; template using Function2 = typename FunctionN::template instance; template using Function3 = typename FunctionN::template instance; template using Function4 = typename FunctionN::template instance; template using Caller0To1 = CallerShiftFirst( FirstArgument )>; template using Caller1To2 = CallerShiftFirst( FirstArgument, get_argument )>; template using Caller2To3 = CallerShiftFirst( FirstArgument, get_argument, get_argument )>; template using Caller3To4 = CallerShiftFirst( FirstArgument, get_argument, get_argument, get_argument )>; #endif