#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