1 #if !defined( INCLUDED_FUNCTIONAL_H )
2 #define INCLUDED_FUNCTIONAL_H
10 struct rank : rank<N - 1> {
25 using func_member = wrapper<typename F::func>;
28 static wrapper<func_member<F>> test(rank<2>) { return {}; }
32 using type = typename func_lambda<decltype(&F::operator())>::type;
35 template<class R, class... Ts>
36 struct func_lambda<R(*)(Ts...)> {
37 using type = R(Ts...);
40 template<class Object, class R, class... Ts>
41 struct func_lambda<R(Object::*)(Ts...) const> {
42 using type = R(Ts...);
45 template<class Object, class R, class... Ts>
46 struct func_lambda<R(Object::*)(Ts...)> {
47 using type = R(Ts...);
50 template<class F, class = func_lambda<F>>
51 static wrapper<func_lambda<F>> test(rank<1>) { return {}; }
57 template<class R, class... Ts>
59 using result_type = R;
62 using get = typename std::tuple_element<N, std::tuple<Ts...>>::type;
66 template<class Caller>
67 using get_func = typename decltype(detail::get_func::test<Caller>(detail::rank<2>{}))::type::type;
69 template<class Caller>
70 using get_result_type = typename detail::Fn<get_func<Caller>>::result_type;
72 template<class Caller, int N>
73 using get_argument = typename detail::Fn<get_func<Caller>>::template get<N>;
75 template<class Object, class F>
78 template<class Object, class R, class... Ts>
79 class MemberN<Object, R(Ts...)> {
81 template<R(Object::*f)(Ts...)>
84 using func = R(Object &, Ts...);
86 static R call(Object &object, Ts... args) {
87 return (object.*f)(args...);
92 template<class Object, class F>
95 template<class Object, class R, class... Ts>
96 class ConstMemberN<Object, R(Ts...)> {
98 template<R(Object::*f)(Ts...) const>
101 using func = R(const Object &, Ts...);
103 static R call(const Object &object, Ts... args) {
104 return (object.*f)(args...);
112 template<class R, class... Ts>
113 class FunctionN<R(Ts...)> {
115 template<R(*f)(Ts...)>
118 using func = R(Ts...);
120 static R call(Ts... args) {
126 template<class Caller, class F>
127 class CallerShiftFirst;
129 template<class Caller, class R, class FirstArgument, class... Ts>
130 class CallerShiftFirst<Caller, R(FirstArgument, Ts...)> {
132 using func = R(FirstArgument, Ts...);
134 static R call(FirstArgument, Ts... args) {
135 return Caller::call(args...);
139 template<class Functor, class F>
140 class FunctorNInvoke;
147 template<int N, int... S>
148 struct gens : gens<N - 1, N - 1, S...> {
152 struct gens<0, S...> {
153 using type = seq<S...>;
157 using seq_new = typename gens<N>::type;
160 template<class Functor, class R, class... Ts>
161 class FunctorNInvoke<Functor, R(Ts...)> {
162 std::tuple<Ts...> args;
168 struct caller<detail::seq<I...>> {
169 static inline R call(FunctorNInvoke<Functor, R(Ts...)> *self, Functor functor) {
171 return functor(std::get<I>(self->args)...);
176 FunctorNInvoke(Ts... args) : args(args...) {
179 inline R operator()(Functor functor) {
180 return caller<detail::seq_new<sizeof...(Ts)>>::call(this, functor);
184 template<class Functor>
185 using FunctorInvoke = FunctorNInvoke<Functor, get_func<Functor>>;
187 template<class Object, class R, R(Object::*member)()>
188 using Member = typename MemberN<Object, R()>::template instance<member>;
190 template<class Object, class R, R(Object::*member)() const>
191 using ConstMember = typename ConstMemberN<Object, R()>::template instance<member>;
193 template<class Object, class A1, class R, R(Object::*member)(A1)>
194 using Member1 = typename MemberN<Object, R(A1)>::template instance<member>;
196 template<class Object, class A1, class R, R(Object::*member)(A1) const>
197 using ConstMember1 = typename ConstMemberN<Object, R(A1)>::template instance<member>;
199 template<class Object, class A1, class A2, class R, R(Object::*member)(A1, A2)>
200 using Member2 = typename MemberN<Object, R(A1, A2)>::template instance<member>;
202 template<class Object, class A1, class A2, class R, R(Object::*member)(A1, A2) const>
203 using ConstMember2 = typename ConstMemberN<Object, R(A1, A2)>::template instance<member>;
205 template<class Object, class A1, class A2, class A3, class R, R(Object::*member)(A1, A2, A3)>
206 using Member3 = typename MemberN<Object, R(A1, A2, A3)>::template instance<member>;
208 template<class Object, class A1, class A2, class A3, class R, R(Object::*member)(A1, A2, A3) const>
209 using ConstMember3 = typename ConstMemberN<Object, R(A1, A2, A3)>::template instance<member>;
211 template<class R, R(*func)()>
212 using Function0 = typename FunctionN<R()>::template instance<func>;
214 template<class A1, class R, R(*func)(A1)>
215 using Function1 = typename FunctionN<R(A1)>::template instance<func>;
217 template<class A1, class A2, class R, R(*func)(A1, A2)>
218 using Function2 = typename FunctionN<R(A1, A2)>::template instance<func>;
220 template<class A1, class A2, class A3, class R, R(*func)(A1, A2, A3)>
221 using Function3 = typename FunctionN<R(A1, A2, A3)>::template instance<func>;
223 template<class A1, class A2, class A3, class A4, class R, R(*func)(A1, A2, A3, A4)>
224 using Function4 = typename FunctionN<R(A1, A2, A3, A4)>::template instance<func>;
226 template<class Caller, class FirstArgument = void *>
227 using Caller0To1 = CallerShiftFirst<Caller, get_result_type<Caller>(
231 template<class Caller, class FirstArgument = void *>
232 using Caller1To2 = CallerShiftFirst<Caller, get_result_type<Caller>(
234 get_argument<Caller, 0>
237 template<class Caller, class FirstArgument = void *>
238 using Caller2To3 = CallerShiftFirst<Caller, get_result_type<Caller>(
240 get_argument<Caller, 0>,
241 get_argument<Caller, 1>
244 template<class Caller, class FirstArgument = void *>
245 using Caller3To4 = CallerShiftFirst<Caller, get_result_type<Caller>(
247 get_argument<Caller, 0>,
248 get_argument<Caller, 1>,
249 get_argument<Caller, 2>