ca1d86307f549d388913fbbd7bc358a132b0cfa5
[xonotic/netradiant.git] / libs / generic / functional.h
1
2 #if !defined(INCLUDED_FUNCTIONAL_H)
3 #define INCLUDED_FUNCTIONAL_H
4
5 template<typename Object, typename R, R (Object::*member)()>
6 class Member
7 {
8 public:
9   typedef Object& first_argument_type;
10   typedef R result_type;
11   static result_type call(first_argument_type object)
12   {
13     return (object.*member)();
14   }
15 };
16
17 template<typename Object, typename R, R (Object::*member)() const>
18 class ConstMember
19 {
20 public:
21   typedef const Object& first_argument_type;
22   typedef R result_type;
23   static result_type call(first_argument_type object)
24   {
25     return (object.*member)();
26   }
27 };
28
29 template<typename Object, typename A1, typename R, R (Object::*member)(A1)>
30 class Member1
31 {
32 public:
33   typedef Object& first_argument_type;
34   typedef A1 second_argument_type;
35   typedef R result_type;
36   static result_type call(first_argument_type object, second_argument_type a1)
37   {
38     return (object.*member)(a1);
39   }
40 };
41
42 template<typename Object, typename A1, typename R, R (Object::*member)(A1) const>
43 class ConstMember1
44 {
45 public:
46   typedef const Object& first_argument_type;
47   typedef A1 second_argument_type;
48   typedef R result_type;
49   static result_type call(first_argument_type object, second_argument_type a1)
50   {
51     return (object.*member)(a1);
52   }
53 };
54
55 template<typename Object, typename A2, typename A3, typename R, R (Object::*member)(A2, A3)>
56 class Member2
57 {
58 public:
59   typedef Object& first_argument_type;
60   typedef A2 second_argument_type;
61   typedef A3 third_argument_type;
62   typedef R result_type;
63   static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3)
64   {
65     return (object.*member)(a2, a3);
66   }
67 };
68
69 template<typename Object, typename A2, typename A3, typename R, R (Object::*member)(A2, A3) const>
70 class ConstMember2
71 {
72 public:
73   typedef const Object& first_argument_type;
74   typedef A2 second_argument_type;
75   typedef A3 third_argument_type;
76   typedef R result_type;
77   static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3)
78   {
79     return (object.*member)(a2, a3);
80   }
81 };
82
83 template<typename Object, typename A2, typename A3, typename A4, typename R, R (Object::*member)(A2, A3, A4)>
84 class Member3
85 {
86 public:
87   typedef Object& first_argument_type;
88   typedef A2 second_argument_type;
89   typedef A3 third_argument_type;
90   typedef A4 fourth_argument_type;
91   typedef R result_type;
92   static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
93   {
94     return (object.*member)(a2, a3, a4);
95   }
96 };
97
98 template<typename Object, typename A2, typename A3, typename A4, typename R, R (Object::*member)(A2, A3, A4) const>
99 class ConstMember3
100 {
101 public:
102   typedef const Object& first_argument_type;
103   typedef A2 second_argument_type;
104   typedef A3 third_argument_type;
105   typedef A4 fourth_argument_type;
106   typedef R result_type;
107   static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
108   {
109     return (object.*member)(a2, a3, a4);
110   }
111 };
112
113 template<typename R, R (*func)()> 
114 class Function0
115 {
116 public:
117   typedef R result_type;
118   static result_type call()
119   {
120     return (func)();
121   }
122 };
123
124 template<typename A1, typename R, R (*func)(A1)> 
125 class Function1
126 {
127 public:
128   typedef A1 first_argument_type;
129   typedef R result_type;
130   static result_type call(first_argument_type a1)
131   {
132     return (func)(a1);
133   }
134 };
135
136 template<typename A1, typename A2, typename R, R (*func)(A1, A2)> 
137 class Function2
138 {
139 public:
140   typedef A1 first_argument_type;
141   typedef A2 second_argument_type;
142   typedef R result_type;
143   static result_type call(first_argument_type a1, second_argument_type a2)
144   {
145     return (func)(a1, a2);
146   }
147 };
148
149 template<typename A1, typename A2, typename A3, typename R, R (*func)(A1, A2, A3)> 
150 class Function3
151 {
152 public:
153   typedef A1 first_argument_type;
154   typedef A2 second_argument_type;
155   typedef A3 third_argument_type;
156   typedef R result_type;
157   static result_type call(first_argument_type a1, second_argument_type a2, third_argument_type a3)
158   {
159     return (func)(a1, a2, a3);
160   }
161 };
162
163 template<typename A1, typename A2, typename A3, typename A4, typename R, R (*func)(A1, A2, A3, A4)> 
164 class Function4
165 {
166 public:
167   typedef A1 first_argument_type;
168   typedef A2 second_argument_type;
169   typedef A3 third_argument_type;
170   typedef A4 fourth_argument_type;
171   typedef R result_type;
172   static result_type call(first_argument_type a1, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
173   {
174     return (func)(a1, a2, a3, a4);
175   }
176 };
177
178 template<typename Caller, typename FirstArgument = void*> 
179 class Caller0To1
180 {
181 public:
182   typedef FirstArgument first_argument_type;
183   typedef typename Caller::result_type result_type;
184   static result_type call(first_argument_type)
185   {
186     return Caller::call();
187   }
188 };
189
190 template<typename Caller, typename FirstArgument = void*> 
191 class Caller1To2
192 {
193 public:
194   typedef FirstArgument first_argument_type;
195   typedef typename Caller::first_argument_type second_argument_type;
196   typedef typename Caller::result_type result_type;
197   static result_type call(first_argument_type, second_argument_type a2)
198   {
199     return Caller::call(a2);
200   }
201 };
202
203 template<typename Caller, typename FirstArgument = void*> 
204 class Caller2To3
205 {
206 public:
207   typedef FirstArgument first_argument_type;
208   typedef typename Caller::first_argument_type second_argument_type;
209   typedef typename Caller::second_argument_type third_argument_type;
210   typedef typename Caller::result_type result_type;
211   static result_type call(first_argument_type, second_argument_type a2, third_argument_type a3)
212   {
213     return Caller::call(a2, a3);
214   }
215 };
216
217 template<typename Caller, typename FirstArgument = void*> 
218 class Caller3To4
219 {
220 public:
221   typedef FirstArgument first_argument_type;
222   typedef typename Caller::first_argument_type second_argument_type;
223   typedef typename Caller::second_argument_type third_argument_type;
224   typedef typename Caller::third_argument_type fourth_argument_type;
225   typedef typename Caller::result_type result_type;
226   static result_type call(first_argument_type, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
227   {
228     return Caller::call(a2, a3, a4);
229   }
230 };
231
232 template<typename Functor>
233 class FunctorInvoke
234 {
235 public:
236   typedef typename Functor::result_type result_type;
237   inline result_type operator()(Functor functor)
238   {
239     return functor();
240   }
241 };
242
243 template<typename Functor>
244 class Functor1Invoke
245 {
246   typename Functor::first_argument_type a1;
247 public:
248   typedef typename Functor::first_argument_type first_argument_type;
249   typedef typename Functor::result_type result_type;
250   Functor1Invoke(first_argument_type a1) : a1(a1)
251   {
252   }
253   inline result_type operator()(Functor functor)
254   {
255     return functor(a1);
256   }
257 };
258
259 template<typename Functor>
260 class Functor2Invoke
261 {
262   typename Functor::first_argument_type a1;
263   typename Functor::second_argument_type a2;
264 public:
265   typedef typename Functor::first_argument_type first_argument_type;
266   typedef typename Functor::second_argument_type second_argument_type;
267   typedef typename Functor::result_type result_type;
268   Functor2Invoke(first_argument_type a1, second_argument_type a2)
269     : a1(a1), a2(a2)
270   {
271   }
272   inline result_type operator()(Functor functor)
273   {
274     return functor(a1, a2);
275   }
276 };
277
278 template<typename Functor>
279 class Functor3Invoke
280 {
281   typename Functor::first_argument_type a1;
282   typename Functor::second_argument_type a2;
283   typename Functor::third_argument_type a3;
284 public:
285   typedef typename Functor::first_argument_type first_argument_type;
286   typedef typename Functor::second_argument_type second_argument_type;
287   typedef typename Functor::third_argument_type third_argument_type;
288   typedef typename Functor::result_type result_type;
289   Functor3Invoke(first_argument_type a1, second_argument_type a2, third_argument_type a3)
290     : a1(a1), a2(a2), a3(a3)
291   {
292   }
293   inline result_type operator()(Functor functor)
294   {
295     return functor(a1, a2, a3);
296   }
297 };
298
299 template<typename Type, typename Other, typename True, typename False>
300 class TypeEqual
301 {
302   template<typename Matched>
303   class Match
304   {
305   public:
306     typedef False type;
307   };
308   template<>
309   class Match<Other>
310   {
311   public:
312     typedef True type;
313   };
314 public:
315   typedef typename Match<Type>::type type;
316 };
317
318
319 #endif