#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 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>; #endif