1 // rak - Rakshasa's toolbox
2 // Copyright (C) 2005-2007, Jari Sundell
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // In addition, as a special exception, the copyright holders give
19 // permission to link the code of portions of this program with the
20 // OpenSSL library under certain conditions as described in each
21 // individual source file, and distribute linked combinations
22 // including the two.
23 //
24 // You must obey the GNU General Public License in all respects for
25 // all of the code used other than OpenSSL. If you modify file(s)
26 // with this exception, you may extend this exception to your version
27 // of the file(s), but you are not obligated to do so. If you do not
28 // wish to do so, delete this exception statement from your version.
29 // If you delete this exception statement from all source files in the
30 // program, then also delete it here.
31 //
32 // Contact: Jari Sundell <jaris@ifi.uio.no>
33 //
34 // Skomakerveien 33
35 // 3185 Skoppum, NORWAY
36
37 // This file contains functors that wrap function pointers and member
38 // function pointers.
39 //
40 // 'fn' functors are polymorphic and derives from 'rak::function' and
41 // thus is less strict about types, this adds the cost of calling a
42 // virtual function.
43 //
44 // 'fun' functors are non-polymorphic and thus cheaper, but requires
45 // the target object's type in the functor's template arguments.
46 //
47 // This should be replaced with TR1 stuff when it becomes widely
48 // available. At the moment it behaves like std::auto_ptr, so be
49 // careful when copying.
50
51 #ifndef RAK_FUNCTIONAL_FUN_H
52 #define RAK_FUNCTIONAL_FUN_H
53
54 #include <memory>
55 #include <functional>
56 #include lt_tr1_functional
57 #include lt_tr1_memory
58
59 namespace rak {
60
61 template <typename Result>
62 class function_base0 {
63 public:
~function_base0()64 virtual ~function_base0() {}
65
66 virtual Result operator () () = 0;
67 };
68
69 template <typename Result, typename Arg1>
70 class function_base1 : public std::unary_function<Arg1, Result> {
71 public:
~function_base1()72 virtual ~function_base1() {}
73
74 virtual Result operator () (Arg1 arg1) = 0;
75 };
76
77 template <typename Result, typename Arg1, typename Arg2>
78 class function_base2 : public std::binary_function<Arg1, Arg2, Result> {
79 public:
~function_base2()80 virtual ~function_base2() {}
81
82 virtual Result operator () (Arg1 arg1, Arg2 arg2) = 0;
83 };
84
85 template <typename Result, typename Arg1, typename Arg2, typename Arg3>
86 class function_base3 {
87 public:
~function_base3()88 virtual ~function_base3() {}
89
90 virtual Result operator () (Arg1 arg1, Arg2 arg2, Arg3 arg3) = 0;
91 };
92
93 template <typename Result>
94 class function0 {
95 public:
96 typedef Result result_type;
97 typedef function_base0<Result> base_type;
98
is_valid()99 bool is_valid() const { return m_base.get() != NULL; }
100
set(base_type * base)101 void set(base_type* base) { m_base = std::shared_ptr<base_type>(base); }
release()102 base_type* release() { return m_base.release(); }
103
operator()104 Result operator () () { return (*m_base)(); }
105
106 private:
107 std::shared_ptr<base_type> m_base;
108 };
109
110 template <typename Result, typename Arg1>
111 class function1 {
112 public:
113 typedef Result result_type;
114 typedef function_base1<Result, Arg1> base_type;
115
is_valid()116 bool is_valid() const { return m_base.get() != NULL; }
117
set(base_type * base)118 void set(base_type* base) { m_base = std::shared_ptr<base_type>(base); }
release()119 base_type* release() { return m_base.release(); }
120
operator()121 Result operator () (Arg1 arg1) { return (*m_base)(arg1); }
122
123 private:
124 std::shared_ptr<base_type> m_base;
125 };
126
127 template <typename Result, typename Arg1, typename Arg2>
128 class function2 {
129 public:
130 typedef Result result_type;
131 typedef function_base2<Result, Arg1, Arg2> base_type;
132
is_valid()133 bool is_valid() const { return m_base.get() != NULL; }
134
set(base_type * base)135 void set(base_type* base) { m_base = std::shared_ptr<base_type>(base); }
release()136 base_type* release() { return m_base.release(); }
137
operator()138 Result operator () (Arg1 arg1, Arg2 arg2) { return (*m_base)(arg1, arg2); }
139
140 private:
141 std::shared_ptr<base_type> m_base;
142 };
143
144 template <typename Result, typename Arg2>
145 class function2<Result, void, Arg2> {
146 public:
147 typedef Result result_type;
148 typedef function_base1<Result, Arg2> base_type;
149
is_valid()150 bool is_valid() const { return m_base.get() != NULL; }
151
set(base_type * base)152 void set(base_type* base) { m_base = std::shared_ptr<base_type>(base); }
release()153 base_type* release() { return m_base.release(); }
154
operator()155 Result operator () (Arg2 arg2) { return (*m_base)(arg2); }
156
157 template <typename Discard>
operator()158 Result operator () (Discard discard, Arg2 arg2) { return (*m_base)(arg2); }
159
160 private:
161 std::shared_ptr<base_type> m_base;
162 };
163
164 template <typename Result, typename Arg1, typename Arg2, typename Arg3>
165 class function3 {
166 public:
167 typedef Result result_type;
168 typedef function_base3<Result, Arg1, Arg2, Arg3> base_type;
169
is_valid()170 bool is_valid() const { return m_base.get() != NULL; }
171
set(base_type * base)172 void set(base_type* base) { m_base = std::shared_ptr<base_type>(base); }
release()173 base_type* release() { return m_base.release(); }
174
operator()175 Result operator () (Arg1 arg1, Arg2 arg2, Arg3 arg3) { return (*m_base)(arg1, arg2, arg3); }
176
177 private:
178 std::shared_ptr<base_type> m_base;
179 };
180
181 template <typename Result>
182 class ptr_fn0_t : public function_base0<Result> {
183 public:
184 typedef Result (*Func)();
185
ptr_fn0_t(Func func)186 ptr_fn0_t(Func func) : m_func(func) {}
~ptr_fn0_t()187 virtual ~ptr_fn0_t() {}
188
operator()189 virtual Result operator () () { return m_func(); }
190
191 private:
192 Func m_func;
193 };
194
195 template <typename Result, typename Arg1>
196 class ptr_fn1_t : public function_base1<Result, Arg1> {
197 public:
198 typedef Result (*Func)(Arg1);
199
ptr_fn1_t(Func func)200 ptr_fn1_t(Func func) : m_func(func) {}
~ptr_fn1_t()201 virtual ~ptr_fn1_t() {}
202
operator()203 virtual Result operator () (Arg1 arg1) { return m_func(arg1); }
204
205 private:
206 Func m_func;
207 };
208
209 template <typename Result, typename Arg1, typename Arg2>
210 class ptr_fn2_t : public function_base2<Result, Arg1, Arg2> {
211 public:
212 typedef Result (*Func)(Arg1, Arg2);
213
ptr_fn2_t(Func func)214 ptr_fn2_t(Func func) : m_func(func) {}
~ptr_fn2_t()215 virtual ~ptr_fn2_t() {}
216
operator()217 virtual Result operator () (Arg1 arg1, Arg2 arg2) { return m_func(arg1, arg2); }
218
219 private:
220 Func m_func;
221 };
222
223 template <typename Object, typename Result>
224 class mem_fn0_t : public function_base0<Result> {
225 public:
226 typedef Result (Object::*Func)();
227
mem_fn0_t(Object * object,Func func)228 mem_fn0_t(Object* object, Func func) : m_object(object), m_func(func) {}
~mem_fn0_t()229 virtual ~mem_fn0_t() {}
230
operator()231 virtual Result operator () () { return (m_object->*m_func)(); }
232
233 private:
234 Object* m_object;
235 Func m_func;
236 };
237
238 template <typename Object, typename Result, typename Arg1>
239 class mem_fn1_t : public function_base1<Result, Arg1> {
240 public:
241 typedef Result (Object::*Func)(Arg1);
242
mem_fn1_t(Object * object,Func func)243 mem_fn1_t(Object* object, Func func) : m_object(object), m_func(func) {}
~mem_fn1_t()244 virtual ~mem_fn1_t() {}
245
operator()246 virtual Result operator () (Arg1 arg1) { return (m_object->*m_func)(arg1); }
247
248 private:
249 Object* m_object;
250 Func m_func;
251 };
252
253 template <typename Object, typename Result, typename Arg1, typename Arg2, typename Arg3>
254 class mem_fn3_t : public function_base3<Result, Arg1, Arg2, Arg3> {
255 public:
256 typedef Result (Object::*Func)(Arg1, Arg2, Arg3);
257
mem_fn3_t(Object * object,Func func)258 mem_fn3_t(Object* object, Func func) : m_object(object), m_func(func) {}
~mem_fn3_t()259 virtual ~mem_fn3_t() {}
260
operator()261 virtual Result operator () (Arg1 arg1, Arg2 arg2, Arg3 arg3) { return (m_object->*m_func)(arg1, arg2, arg3); }
262
263 private:
264 Object* m_object;
265 Func m_func;
266 };
267
268 template <typename Object, typename Result, typename Arg1, typename Arg2>
269 class mem_fn2_t : public function_base2<Result, Arg1, Arg2> {
270 public:
271 typedef Result (Object::*Func)(Arg1, Arg2);
272
mem_fn2_t(Object * object,Func func)273 mem_fn2_t(Object* object, Func func) : m_object(object), m_func(func) {}
~mem_fn2_t()274 virtual ~mem_fn2_t() {}
275
operator()276 virtual Result operator () (Arg1 arg1, Arg2 arg2) { return (m_object->*m_func)(arg1, arg2); }
277
278 private:
279 Object* m_object;
280 Func m_func;
281 };
282
283 template <typename Object, typename Result>
284 class const_mem_fn0_t : public function_base0<Result> {
285 public:
286 typedef Result (Object::*Func)() const;
287
const_mem_fn0_t(const Object * object,Func func)288 const_mem_fn0_t(const Object* object, Func func) : m_object(object), m_func(func) {}
~const_mem_fn0_t()289 virtual ~const_mem_fn0_t() {}
290
operator()291 virtual Result operator () () { return (m_object->*m_func)(); }
292
293 private:
294 const Object* m_object;
295 Func m_func;
296 };
297
298 template <typename Object, typename Result, typename Arg1>
299 class const_mem_fn1_t : public function_base1<Result, Arg1> {
300 public:
301 typedef Result (Object::*Func)(Arg1) const;
302
const_mem_fn1_t(const Object * object,Func func)303 const_mem_fn1_t(const Object* object, Func func) : m_object(object), m_func(func) {}
~const_mem_fn1_t()304 virtual ~const_mem_fn1_t() {}
305
operator()306 virtual Result operator () (Arg1 arg1) { return (m_object->*m_func)(arg1); }
307
308 private:
309 const Object* m_object;
310 Func m_func;
311 };
312
313 // Unary functor with a bound argument.
314 template <typename Object, typename Result, typename Arg1>
315 class mem_fn0_b1_t : public function_base0<Result> {
316 public:
317 typedef Result (Object::*Func)(Arg1);
318
mem_fn0_b1_t(Object * object,Func func,const Arg1 arg1)319 mem_fn0_b1_t(Object* object, Func func, const Arg1 arg1) : m_object(object), m_func(func), m_arg1(arg1) {}
~mem_fn0_b1_t()320 virtual ~mem_fn0_b1_t() {}
321
operator()322 virtual Result operator () () { return (m_object->*m_func)(m_arg1); }
323
324 private:
325 Object* m_object;
326 Func m_func;
327 const Arg1 m_arg1;
328 };
329
330 template <typename Object, typename Result, typename Arg1, typename Arg2>
331 class mem_fn1_b1_t : public function_base1<Result, Arg2> {
332 public:
333 typedef Result (Object::*Func)(Arg1, Arg2);
334
mem_fn1_b1_t(Object * object,Func func,const Arg1 arg1)335 mem_fn1_b1_t(Object* object, Func func, const Arg1 arg1) : m_object(object), m_func(func), m_arg1(arg1) {}
~mem_fn1_b1_t()336 virtual ~mem_fn1_b1_t() {}
337
operator()338 virtual Result operator () (const Arg2 arg2) { return (m_object->*m_func)(m_arg1, arg2); }
339
340 private:
341 Object* m_object;
342 Func m_func;
343 const Arg1 m_arg1;
344 };
345
346 template <typename Object, typename Result, typename Arg1, typename Arg2>
347 class mem_fn1_b2_t : public function_base1<Result, Arg1> {
348 public:
349 typedef Result (Object::*Func)(Arg1, Arg2);
350
mem_fn1_b2_t(Object * object,Func func,const Arg2 arg2)351 mem_fn1_b2_t(Object* object, Func func, const Arg2 arg2) : m_object(object), m_func(func), m_arg2(arg2) {}
~mem_fn1_b2_t()352 virtual ~mem_fn1_b2_t() {}
353
operator()354 virtual Result operator () (const Arg1 arg1) { return (m_object->*m_func)(arg1, m_arg2); }
355
356 private:
357 Object* m_object;
358 Func m_func;
359 const Arg2 m_arg2;
360 };
361
362 template <typename Result, typename Arg1>
363 class ptr_fn0_b1_t : public function_base0<Result> {
364 public:
365 typedef Result (*Func)(Arg1);
366
ptr_fn0_b1_t(Func func,const Arg1 arg1)367 ptr_fn0_b1_t(Func func, const Arg1 arg1) : m_func(func), m_arg1(arg1) {}
~ptr_fn0_b1_t()368 virtual ~ptr_fn0_b1_t() {}
369
operator()370 virtual Result operator () () { return m_func(m_arg1); }
371
372 private:
373 Func m_func;
374 Arg1 m_arg1;
375 };
376
377 template <typename Result, typename Arg1, typename Arg2>
378 class ptr_fn1_b1_t : public function_base1<Result, Arg2> {
379 public:
380 typedef Result (*Func)(Arg1, Arg2);
381
ptr_fn1_b1_t(Func func,const Arg1 arg1)382 ptr_fn1_b1_t(Func func, const Arg1 arg1) : m_func(func), m_arg1(arg1) {}
~ptr_fn1_b1_t()383 virtual ~ptr_fn1_b1_t() {}
384
operator()385 virtual Result operator () (Arg2 arg2) { return m_func(m_arg1, arg2); }
386
387 private:
388 Func m_func;
389 Arg1 m_arg1;
390 };
391
392 template <typename Result, typename Arg1, typename Arg2, typename Arg3>
393 class ptr_fn2_b1_t : public function_base2<Result, Arg2, Arg3> {
394 public:
395 typedef Result (*Func)(Arg1, Arg2, Arg3);
396
ptr_fn2_b1_t(Func func,const Arg1 arg1)397 ptr_fn2_b1_t(Func func, const Arg1 arg1) : m_func(func), m_arg1(arg1) {}
~ptr_fn2_b1_t()398 virtual ~ptr_fn2_b1_t() {}
399
operator()400 virtual Result operator () (Arg2 arg2, Arg3 arg3) { return m_func(m_arg1, arg2, arg3); }
401
402 private:
403 Func m_func;
404 Arg1 m_arg1;
405 };
406
407 template <typename Ftor>
408 class ftor_fn1_t : public function_base1<typename Ftor::result_type, typename Ftor::argument_type> {
409 public:
410 typedef typename Ftor::result_type result_type;
411 typedef typename Ftor::argument_type argument_type;
412
ftor_fn1_t(Ftor ftor)413 ftor_fn1_t(Ftor ftor) : m_ftor(ftor) {}
~ftor_fn1_t()414 virtual ~ftor_fn1_t() {}
415
operator()416 virtual result_type operator () (argument_type arg1) { return m_ftor(arg1); }
417
418 private:
419 Ftor m_ftor;
420 };
421
422 template <typename Ftor>
423 class ftor_fn2_t : public function_base2<typename Ftor::result_type, typename Ftor::first_argument_type, typename Ftor::second_argument_type> {
424 public:
425 typedef typename Ftor::result_type result_type;
426 typedef typename Ftor::first_argument_type first_argument_type;
427 typedef typename Ftor::second_argument_type second_argument_type;
428
ftor_fn2_t(Ftor ftor)429 ftor_fn2_t(Ftor ftor) : m_ftor(ftor) {}
~ftor_fn2_t()430 virtual ~ftor_fn2_t() {}
431
operator()432 virtual result_type operator () (first_argument_type arg1, second_argument_type arg2) { return m_ftor(arg1, arg2); }
433
434 private:
435 Ftor m_ftor;
436 };
437
438 template <typename Result>
439 class value_fn0_t : public function_base0<Result> {
440 public:
value_fn0_t(const Result & val)441 value_fn0_t(const Result& val) : m_value(val) {}
442
operator()443 virtual Result operator () () { return m_value; }
444
445 private:
446 Result m_value;
447 };
448
449 template <typename Result, typename SrcResult>
450 class convert_fn0_t : public function_base0<Result> {
451 public:
452 typedef function0<SrcResult> src_type;
453
convert_fn0_t(typename src_type::base_type * object)454 convert_fn0_t(typename src_type::base_type* object) { m_object.set(object); }
~convert_fn0_t()455 virtual ~convert_fn0_t() {}
456
operator()457 virtual Result operator () () {
458 return m_object();
459 }
460
461 private:
462 src_type m_object;
463 };
464
465 template <typename Result, typename Arg1, typename SrcResult, typename SrcArg1>
466 class convert_fn1_t : public function_base1<Result, Arg1> {
467 public:
468 typedef function1<SrcResult, SrcArg1> src_type;
469
convert_fn1_t(typename src_type::base_type * object)470 convert_fn1_t(typename src_type::base_type* object) { m_object.set(object); }
~convert_fn1_t()471 virtual ~convert_fn1_t() {}
472
operator()473 virtual Result operator () (Arg1 arg1) {
474 return m_object(arg1);
475 }
476
477 private:
478 src_type m_object;
479 };
480
481 template <typename Result, typename Arg1, typename Arg2, typename SrcResult, typename SrcArg1, typename SrcArg2>
482 class convert_fn2_t : public function_base2<Result, Arg1, Arg2> {
483 public:
484 typedef function2<SrcResult, SrcArg1, SrcArg2> src_type;
485
convert_fn2_t(typename src_type::base_type * object)486 convert_fn2_t(typename src_type::base_type* object) { m_object.set(object); }
~convert_fn2_t()487 virtual ~convert_fn2_t() {}
488
operator()489 virtual Result operator () (Arg1 arg1, Arg2 arg2) {
490 return m_object(arg1, arg2);
491 }
492
493 private:
494 src_type m_object;
495 };
496
497 template <typename Result>
498 inline function_base0<Result>*
ptr_fn(Result (* func)())499 ptr_fn(Result (*func)()) {
500 return new ptr_fn0_t<Result>(func);
501 }
502
503 template <typename Arg1, typename Result>
504 inline function_base1<Result, Arg1>*
ptr_fn(Result (* func)(Arg1))505 ptr_fn(Result (*func)(Arg1)) {
506 return new ptr_fn1_t<Result, Arg1>(func);
507 }
508
509 template <typename Arg1, typename Arg2, typename Result>
510 inline function_base2<Result, Arg1, Arg2>*
ptr_fn(Result (* func)(Arg1,Arg2))511 ptr_fn(Result (*func)(Arg1, Arg2)) {
512 return new ptr_fn2_t<Result, Arg1, Arg2>(func);
513 }
514
515 template <typename Result, typename Object>
516 inline function_base0<Result>*
mem_fn(Object * object,Result (Object::* func)())517 mem_fn(Object* object, Result (Object::*func)()) {
518 return new mem_fn0_t<Object, Result>(object, func);
519 }
520
521 template <typename Arg1, typename Result, typename Object>
522 inline function_base1<Result, Arg1>*
mem_fn(Object * object,Result (Object::* func)(Arg1))523 mem_fn(Object* object, Result (Object::*func)(Arg1)) {
524 return new mem_fn1_t<Object, Result, Arg1>(object, func);
525 }
526
527 template <typename Arg1, typename Arg2, typename Result, typename Object>
528 inline function_base2<Result, Arg1, Arg2>*
mem_fn(Object * object,Result (Object::* func)(Arg1,Arg2))529 mem_fn(Object* object, Result (Object::*func)(Arg1, Arg2)) {
530 return new mem_fn2_t<Object, Result, Arg1, Arg2>(object, func);
531 }
532
533 template <typename Arg1, typename Arg2, typename Arg3, typename Result, typename Object>
534 inline function_base3<Result, Arg1, Arg2, Arg3>*
mem_fn(Object * object,Result (Object::* func)(Arg1,Arg2,Arg3))535 mem_fn(Object* object, Result (Object::*func)(Arg1, Arg2, Arg3)) {
536 return new mem_fn3_t<Object, Result, Arg1, Arg2, Arg3>(object, func);
537 }
538
539 template <typename Result, typename Object>
540 inline function_base0<Result>*
mem_fn(const Object * object,Result (Object::* func)()const)541 mem_fn(const Object* object, Result (Object::*func)() const) {
542 return new const_mem_fn0_t<Object, Result>(object, func);
543 }
544
545 template <typename Arg1, typename Result, typename Object>
546 inline function_base1<Result, Arg1>*
mem_fn(const Object * object,Result (Object::* func)(Arg1)const)547 mem_fn(const Object* object, Result (Object::*func)(Arg1) const) {
548 return new const_mem_fn1_t<Object, Result, Arg1>(object, func);
549 }
550
551 template <typename Arg1, typename Result, typename Object>
552 inline function_base0<Result>*
bind_mem_fn(Object * object,Result (Object::* func)(Arg1),const Arg1 arg1)553 bind_mem_fn(Object* object, Result (Object::*func)(Arg1), const Arg1 arg1) {
554 return new mem_fn0_b1_t<Object, Result, Arg1>(object, func, arg1);
555 }
556
557 template <typename Arg1, typename Arg2, typename Result, typename Object>
558 inline function_base1<Result, Arg2>*
bind_mem_fn(Object * object,Result (Object::* func)(Arg1,Arg2),const Arg1 arg1)559 bind_mem_fn(Object* object, Result (Object::*func)(Arg1, Arg2), const Arg1 arg1) {
560 return new mem_fn1_b1_t<Object, Result, Arg1, Arg2>(object, func, arg1);
561 }
562
563 template <typename Arg1, typename Arg2, typename Result, typename Object>
564 inline function_base1<Result, Arg1>*
bind2_mem_fn(Object * object,Result (Object::* func)(Arg1,Arg2),const Arg2 arg2)565 bind2_mem_fn(Object* object, Result (Object::*func)(Arg1, Arg2), const Arg2 arg2) {
566 return new mem_fn1_b2_t<Object, Result, Arg1, Arg2>(object, func, arg2);
567 }
568
569 template <typename Arg1, typename Result>
570 inline function_base0<Result>*
bind_ptr_fn(Result (* func)(Arg1),const Arg1 arg1)571 bind_ptr_fn(Result (*func)(Arg1), const Arg1 arg1) {
572 return new ptr_fn0_b1_t<Result, Arg1>(func, arg1);
573 }
574
575 template <typename Arg1, typename Arg2, typename Result>
576 inline function_base1<Result, Arg2>*
bind_ptr_fn(Result (* func)(Arg1,Arg2),const Arg1 arg1)577 bind_ptr_fn(Result (*func)(Arg1, Arg2), const Arg1 arg1) {
578 return new ptr_fn1_b1_t<Result, Arg1, Arg2>(func, arg1);
579 }
580
581 template <typename Arg1, typename Arg2, typename Arg3, typename Result>
582 inline function_base2<Result, Arg2, Arg3>*
bind_ptr_fn(Result (* func)(Arg1,Arg2,Arg3),const Arg1 arg1)583 bind_ptr_fn(Result (*func)(Arg1, Arg2, Arg3), const Arg1 arg1) {
584 return new ptr_fn2_b1_t<Result, Arg1, Arg2, Arg3>(func, arg1);
585 }
586
587 template <typename Ftor>
588 inline function_base1<typename Ftor::result_type, typename Ftor::argument_type>*
ftor_fn1(Ftor ftor)589 ftor_fn1(Ftor ftor) {
590 return new ftor_fn1_t<Ftor>(ftor);
591 }
592
593 template <typename Ftor>
594 inline function_base2<typename Ftor::result_type, typename Ftor::first_argument_type, typename Ftor::second_argument_type>*
ftor_fn2(Ftor ftor)595 ftor_fn2(Ftor ftor) {
596 return new ftor_fn2_t<Ftor>(ftor);
597 }
598
599 template <typename Result>
600 inline function_base0<Result>*
value_fn(const Result & val)601 value_fn(const Result& val) {
602 return new value_fn0_t<Result>(val);
603 }
604
605 template <typename A, typename B>
606 struct equal_types_t {
607 typedef A first_type;
608 typedef B second_type;
609
610 const static int result = 0;
611 };
612
613 template <typename A>
614 struct equal_types_t<A, A> {
615 typedef A first_type;
616 typedef A second_type;
617
618 const static int result = 1;
619 };
620
621 template <typename Result, typename SrcResult>
622 inline function_base0<Result>*
623 convert_fn(function_base0<SrcResult>* src) {
624 if (equal_types_t<function_base0<Result>, function_base0<SrcResult> >::result)
625 // The pointer cast never gets done if the types are different,
626 // but needs to be here to pleasant the compiler.
627 return reinterpret_cast<typename equal_types_t<function_base0<Result>, function_base0<SrcResult> >::first_type*>(src);
628 else
629 return new convert_fn0_t<Result, SrcResult>(src);
630 }
631
632 template <typename Result, typename Arg1, typename SrcResult, typename SrcArg1>
633 inline function_base1<Result, Arg1>*
634 convert_fn(function_base1<SrcResult, SrcArg1>* src) {
635 if (equal_types_t<function_base1<Result, Arg1>, function_base1<SrcResult, SrcArg1> >::result)
636 // The pointer cast never gets done if the types are different,
637 // but needs to be here to pleasant the compiler.
638 return reinterpret_cast<typename equal_types_t<function_base1<Result, Arg1>, function_base1<SrcResult, SrcArg1> >::first_type*>(src);
639 else
640 return new convert_fn1_t<Result, Arg1, SrcResult, SrcArg1>(src);
641 }
642
643 template <typename Result, typename Arg1, typename Arg2, typename SrcResult, typename SrcArg1, typename SrcArg2>
644 inline function_base2<Result, Arg1, Arg2>*
645 convert_fn(function_base2<SrcResult, SrcArg1, SrcArg2>* src) {
646 if (equal_types_t<function_base2<Result, Arg1, Arg2>, function_base2<SrcResult, SrcArg1, SrcArg2> >::result)
647 // The pointer cast never gets done if the types are different,
648 // but needs to be here to pleasant the compiler.
649 return reinterpret_cast<typename equal_types_t<function_base2<Result, Arg1, Arg2>, function_base2<SrcResult, SrcArg1, SrcArg2> >::first_type*>(src);
650 else
651 return new convert_fn2_t<Result, Arg1, Arg2, SrcResult, SrcArg1, SrcArg2>(src);
652 }
653
654 }
655
656 #endif
657