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