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