Image Component Library (ICL)
Function.h
Go to the documentation of this file.
1 /********************************************************************
2 ** Image Component Library (ICL) **
3 ** **
4 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld **
5 ** Neuroinformatics Group **
6 ** Website: www.iclcv.org and **
7 ** http://opensource.cit-ec.de/projects/icl **
8 ** **
9 ** File : ICLUtils/src/ICLUtils/Function.h **
10 ** Module : ICLUtils **
11 ** Authors: Christof Elbrechter **
12 ** **
13 ** **
14 ** GNU LESSER GENERAL PUBLIC LICENSE **
15 ** This file may be used under the terms of the GNU Lesser General **
16 ** Public License version 3.0 as published by the **
17 ** **
18 ** Free Software Foundation and appearing in the file LICENSE.LGPL **
19 ** included in the packaging of this file. Please review the **
20 ** following information to ensure the license requirements will **
21 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt **
22 ** **
23 ** The development of this software was supported by the **
24 ** Excellence Cluster EXC 277 Cognitive Interaction Technology. **
25 ** The Excellence Cluster EXC 277 is a grant of the Deutsche **
26 ** Forschungsgemeinschaft (DFG) in the context of the German **
27 ** Excellence Initiative. **
28 ** **
29 ********************************************************************/
30 
31 #pragma once
32 
33 #include <ICLUtils/SmartPtr.h>
34 #include <functional>
35 #include <ICLUtils/CompatMacros.h>
36 
37 namespace icl{
38  namespace utils{
39  struct NO_ARG;
41  // FunctionImpl classes and specializations /////////////
43 
45 
46  template<class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
47  struct FunctionImpl{
49  virtual R operator()(A a, B b, C c) const = 0;
50  virtual ~FunctionImpl(){}
51  };
52 
54 
55  template<class R, class A, class B>
56  struct FunctionImpl<R, A, B, NO_ARG>{
58  virtual R operator()(A a, B b) const = 0;
59  virtual ~FunctionImpl(){}
60  };
61 
63 
64  template<class R, class A>
65  struct FunctionImpl<R, A, NO_ARG>{
67  virtual R operator()(A a) const = 0;
68  virtual ~FunctionImpl(){}
69  };
70 
72 
73  template<class R>
74  struct FunctionImpl<R, NO_ARG>{
76  virtual R operator()() const = 0;
77  virtual ~FunctionImpl(){}
78  };
79 
81  // Member Function Implementations ///////////////////////
83 
85 
89  template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
90  struct MemberFunctionImpl : public FunctionImpl<R, A, B, C>{
91  Object *obj;
92  R (Object::*method)(A, B, C);
93  virtual R operator()(A a,B b,C c) const { return (obj->*method)(a, b, c); }
94  };
95 
97  template <class Object, class R, class A, class B>
98  struct MemberFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{
99  Object *obj;
100  R (Object::*method)(A, B);
101  virtual R operator()(A a,B b) const { return (obj->*method)(a, b); }
102  };
103 
104  template <class Object, class R, class A>
105  struct MemberFunctionImpl<Object, R, A, NO_ARG, NO_ARG> : public FunctionImpl<R, A>{
106  Object *obj;
107  R (Object::*method)(A);
108  virtual R operator()(A a) const { return (obj->*method)(a); }
109  };
110 
111  template <class Object, class R>
112  struct MemberFunctionImpl<Object, R, NO_ARG, NO_ARG, NO_ARG> : public FunctionImpl<R>{
113  Object *obj;
114  R (Object::*method)();
115  virtual R operator()() const { return (obj->*method)(); }
116  };
119  // CONST Member Function Implementations /////////////////
122 
124 
128  template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
129  struct ConstMemberFunctionImpl : public FunctionImpl<R, A, B, C>{
130  const Object *obj;
131  R (Object::*method)(A, B, C) const;
132  virtual R operator()(A a,B b,C c) const { return (obj->*method)(a, b, c); }
133  };
136  template <class Object, class R, class A, class B>
137  struct ConstMemberFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{
138  const Object *obj;
139  R (Object::*method)(A, B) const;
140  virtual R operator()(A a,B b) const { return (obj->*method)(a, b); }
141  };
142 
143  template <class Object, class R, class A>
144  struct ConstMemberFunctionImpl<Object, R, A, NO_ARG> : public FunctionImpl<R, A>{
145  const Object *obj;
146  R (Object::*method)(A) const;
147  virtual R operator()(A a) const { return (obj->*method)(a); }
148  };
149 
150  template <class Object, class R>
151  struct ConstMemberFunctionImpl<Object, R, NO_ARG> : public FunctionImpl<R>{
152  const Object *obj;
153  R (Object::*method)() const;
154  virtual R operator()() const { return (obj->*method)(); }
155  };
158  // Functor Member Functions //////////////////////////////
161 
163 
167  template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
168  struct FunctorFunctionImpl : public FunctionImpl<R, A, B, C>{
169  Object *obj;
170  virtual R operator()(A a,B b, C c) const { return (*obj)(a,b,c); }
171  };
172 
174  template <class Object, class R, class A, class B>
175  struct FunctorFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{
176  Object *obj;
177  virtual R operator()(A a,B b) const { return (*obj)(a,b); }
178  };
179 
180  template <class Object, class R, class A>
181  struct FunctorFunctionImpl<Object, R, A, NO_ARG> : public FunctionImpl<R, A>{
182  Object *obj;
183  virtual R operator()(A a) const { return (*obj)(a); }
184  };
185  template <class Object, class R>
186  struct FunctorFunctionImpl<Object, R, NO_ARG> : public FunctionImpl<R>{
187  Object *obj;
188  virtual R operator()() const { return (*obj)(); }
189  };
192  // CONST Functor Member Functions ////////////////////////
195 
197 
201  template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
202  struct ConstFunctorFunctionImpl : public FunctionImpl<R, A, B, C>{
203  const Object *obj;
204  virtual R operator()(A a,B b, C c) const { return (*obj)(a,b,c); }
205  };
206 
208  template <class Object, class R, class A, class B>
209  struct ConstFunctorFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{
210  const Object *obj;
211  virtual R operator()(A a,B b) const { return (*obj)(a,b); }
212  };
213 
214  template <class Object, class R, class A>
215  struct ConstFunctorFunctionImpl<Object, R, A, NO_ARG> : public FunctionImpl<R, A>{
216  const Object *obj;
217  virtual R operator()(A a) const { return (*obj)(a); }
218  };
219  template <class Object, class R>
220  struct ConstFunctorFunctionImpl<Object, R, NO_ARG> : public FunctionImpl<R>{
221  const Object *obj;
222  virtual R operator()() const { return (*obj)(); }
223  };
226  // Global Function Wrappers //////////////////////////////
229 
230 
232 
236  template <class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
237  struct GlobalFunctionImpl : public FunctionImpl<R, A, B, C>{
238  R (*global_function)(A, B, C);
239  virtual R operator()(A a,B b,C c) const { return global_function(a, b,c); }
240  };
242  template <class R, class A, class B>
243  struct GlobalFunctionImpl<R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{
244  R (*global_function)(A, B);
245  virtual R operator()(A a,B b) const { return global_function(a, b); }
246  };
247 
248  template <class R, class A>
249  struct GlobalFunctionImpl<R, A, NO_ARG> : public FunctionImpl<R, A>{
250  R (*global_function)(A);
251  virtual R operator()(A a) const { return global_function(a); }
252  };
253  template <class R>
254  struct GlobalFunctionImpl<R, NO_ARG> : public FunctionImpl<R>{
255  R (*global_function)();
256  virtual R operator()() const { return global_function(); }
257  };
260  // The Function class ////////////////////////////////////
263 
265 
283  template<class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG>
284  struct Function {
287 
290 
293 
295 
298  Function(R (*global_function)(A,B,C)):impl(new GlobalFunctionImpl<R,A,B,C>){
299  ((GlobalFunctionImpl<R,A,B,C>*)(impl.get()))->global_function = global_function;
300  }
301 
304 
306 
308  R operator()(A a, B b, C c) const { return (*impl)(a,b,c); }
309 
311  operator bool() const { return impl; }
312 
313  operator Function<R,A,B,C> () const { return (*(const Function<R,A,B,C>*)(this)); }
314  };
315 
317  template<class R, class A, class B>
318  struct Function<R, A, B, NO_ARG> : public std::binary_function<A, B, R>{
319  Function(){}
320  Function(FunctionImpl<R,A,B> *impl):impl(impl){}
321  Function(icl::utils::SmartPtr<FunctionImpl<R,A,B> >impl):impl(impl){}
322  Function(R (*global_function)(A,B)):impl(new GlobalFunctionImpl<R,A,B>){
323  ((GlobalFunctionImpl<R,A,B>*)(impl.get()))->global_function = global_function;
324  }
326  R operator()(A a, B b) const { return (*impl)(a,b); }
327  operator bool() const { return impl; }
328 
329  operator Function<R,A,B> () const { return (*(const Function<R,A,B>*)(this)); }
330  };
331 
332  template<class R, class A>
333  struct Function<R, A, NO_ARG> : public std::unary_function<A, R>{
334  Function(){}
335  Function(FunctionImpl<R,A> *impl):impl(impl){}
336  Function(icl::utils::SmartPtr<FunctionImpl<R,A> >impl):impl(impl){}
337  Function(R (*global_function)(A)):impl(new GlobalFunctionImpl<R,A>){
338  ((GlobalFunctionImpl<R,A>*)(impl.get()))->global_function = global_function;
339  }
341  R operator()(A a) const { return (*impl)(a); }
342  operator bool() const { return impl; }
343 
344  operator Function<R,A> () const { return (*(const Function<R,A>*)(this)); }
345  };
346  template<class R>
347  struct Function<R, NO_ARG>{
348  typedef R result_type;
349  Function(){}
350  Function(FunctionImpl<R> *impl):impl(impl){}
351  Function(icl::utils::SmartPtr<FunctionImpl<R> >impl):impl(impl){}
352  Function(R (*global_function)()):impl(new GlobalFunctionImpl<R>){
353  ((GlobalFunctionImpl<R>*)(impl.get()))->global_function = global_function;
354  }
356  R operator()() const { return (*impl)(); }
357 
358  operator bool() const { return impl; }
359 
360  operator Function<R> () const { return (*(const Function<R>*)(this)); }
361  };
367  // Function creator functions (from member functions /////
370 
372 
375  template<class Object, class R, class A, class B, class C>
376  Function<R, A, B, C> function(Object &obj, R(Object::*method)(A, B, C)){
378  impl->obj = &obj;
379  impl->method = method;
380  return Function<R,A,B,C>(impl);
381  }
382 
384 
387  template<class Object,class R, class A, class B>
388  Function<R, A, B> function(Object &obj, R(Object::*method)(A, B)){
390  impl->obj = &obj;
391  impl->method = method;
392  return Function<R,A,B>(impl);
393  }
394 
396 
399  template<class Object,class R, class A>
400  Function<R, A> function(Object &obj, R(Object::*method)(A)){
402  impl->obj = &obj;
403  impl->method = method;
404  return Function<R,A>(impl);
405  }
406 
408 
412  template<class Object,class R>
413  Function<R> function(Object &obj, R(Object::*method)()){
415  impl->obj = &obj;
416  impl->method = method;
417  return Function<R>(impl);
418  }
419 
421 
424  template<class Object,class R,class A,class B,class C>
425  Function<R, A, B, C> function(const Object &obj, R(Object::*method)(A a, B b, C c) const){
427  impl->obj = &obj;
428  impl->method = method;
429  return Function<R,A,B,C>(impl);
430  }
431 
433 
436  template<class Object,class R,class A,class B>
437  Function<R, A, B> function(const Object &obj, R(Object::*method)(A a, B b) const){
439  impl->obj = &obj;
440  impl->method = method;
441  return Function<R,A,B>(impl);
442  }
444 
447  template<class Object,class R,class A>
448  Function<R, A> function(const Object &obj, R(Object::*method)(A a) const){
450  impl->obj = &obj;
451  impl->method = method;
452  return Function<R,A>(impl);
453  }
455 
459  template<class Object,class R>
460  Function<R> function(const Object &obj, R(Object::*method)() const){
462  impl->obj = &obj;
463  impl->method = method;
464  return Function<R>(impl);
465  }
466 
468 
471  template<class Object,class R, class A, class B, class C>
472  Function<R, A, B, C> function(Object *obj, R(Object::*method)(A, B, C)){ return function<Object, R, A, B, C>(*obj, method); }
473 
475 
478  template<class Object,class R, class A, class B>
479  Function<R, A, B> function(Object *obj, R(Object::*method)(A, B)){ return function<Object, R, A, B>(*obj, method); }
480 
482 
485  template<class Object,class R, class A>
486  Function<R, A> function(Object *obj, R(Object::*method)(A)){ return function<Object, R, A>(*obj, method); }
487 
489 
493  template<class Object,class R>
494  Function<R> function(Object *obj, R(Object::*method)()){ return function<Object, R>(*obj, method); }
495 
497 
500  template<class Object,class R, class A, class B, class C>
501  Function<R, A, B, C> function(const Object *obj, R(Object::*method)(A, B, C) const){ return function<Object, R, A, B, C>(*obj, method); }
502 
504 
507  template<class Object,class R, class A, class B>
508  Function<R, A, B> function(const Object *obj, R(Object::*method)(A, B) const){ return function<Object, R, A, B>(*obj, method); }
509 
511 
514  template<class Object,class R, class A>
515  Function<R, A> function(const Object *obj, R(Object::*method)(A) const){ return function<Object, R, A>(*obj, method); }
516 
518 
522  template<class Object,class R>
523  Function<R> function(const Object *obj, R(Object::*method)() const){ return function<Object, R>(*obj, method); }
524 
525 
527  // Function creator functions (from functors) ////////////
529 
531 
532  template <class R = void, class A = NO_ARG, class B = NO_ARG, class C = NO_ARG> struct SelectFunctor{};
533 
535 
539  template<class Object,class R, class A, class B, class C>
542  impl->obj = &obj;
543  return Function<R,A,B,C>(impl);
544  }
545 
547 
551  template<class Object,class R, class A, class B, class C>
552  Function<R, A, B> function(const Object &obj, SelectFunctor<R, A, B, C>){
554  impl->obj = &obj;
555  return Function<R,A,B,C>(impl);
556  }
557 
559 
560  template<class Object>
561  Function<> function(Object &obj){
562  return function(obj,SelectFunctor<void,NO_ARG,NO_ARG,NO_ARG>());
563  }
564 
566 
567  template<class Object>
568  Function<> function(const Object &obj){
569  return function(obj,SelectFunctor<void,NO_ARG,NO_ARG,NO_ARG>());
570  }
571 
573 
577  template<class Object,class R, class A, class B, class C>
578  Function<R, A, B, C> function(Object *obj, SelectFunctor<R, A, B, C> selector){ return function<Object, R, A, B, C>(*obj, selector); }
579 
581 
585  template<class Object,class R, class A, class B, class C>
586  Function<R, A, B, C> function(const Object *obj, SelectFunctor<R, A, B, C> selector){ return function<Object, R, A, B, C>(*obj, selector); }
587 
588 
590  // Function creator functions (from global functions) ////
592 
594 
597  template<class R, class A, class B, class C>
598  Function<R, A, B, C> function(R(*global_function)(A a, B b, C c)){
599  return Function<R,A,B,C>(global_function);
600  }
601 
603 
606  template<class R, class A, class B>
607  Function<R, A, B> function(R(*global_function)(A a, B b)){
608  return Function<R,A,B>(global_function);
609  }
610 
611 
613 
616  template<class R, class A>
617  Function<R, A> function(R(*global_function)(A a)){
618  return Function<R,A>(global_function);
619  }
620 
622 
625  template<class R>
626  Function<R> function(R(*global_function)()){
627  return Function<R>(global_function);
628  }
629  } // namespace utils
630 }
631 
The General Function Template.
Definition: Function.h:284
const Object * obj
Definition: Function.h:203
FunctionImpl implementation for Functors.
Definition: Function.h:168
virtual R operator()(A a, B b, C c) const
function interface
Definition: Function.h:204
undocument this line if you encounter any issues!
Definition: Any.h:37
virtual R operator()(A a, B b, C c) const
function interface
Definition: Function.h:239
virtual R operator()(A a, B b, C c) const
function interface
Definition: Function.h:170
FunctionImpl implementation for member functions.
Definition: Function.h:90
Function(R(*global_function)(A, B, C))
Constructor from given global function (for implicit conversion)
Definition: Function.h:298
R(Object::* method)(A, B, C)
Definition: Function.h:92
Object * obj
Definition: Function.h:169
Function(FunctionImpl< R, A, B, C > *impl)
Constructor with given Impl.
Definition: Function.h:289
R(* global_function)(A, B, C)
Definition: Function.h:238
R operator()(A a, B b, C c) const
function operator (always const)
Definition: Function.h:308
FunctionImpl implementation for functors of const objects.
Definition: Function.h:202
const Object * obj
Definition: Function.h:130
General Implementation for binary functions.
Definition: Function.h:47
virtual ~FunctionImpl()
Definition: Function.h:59
virtual R operator()(A a, B b, C c) const
function interface
Definition: Function.h:93
icl::utils::SmartPtr< FunctionImpl< R, A, B, C > > impl
Implementation.
Definition: Function.h:303
FunctionImpl implementation for const member functions.
Definition: Function.h:129
Object * obj
Definition: Function.h:91
Function()
Empty constructor (implementation will become null)
Definition: Function.h:286
virtual ~FunctionImpl()
Definition: Function.h:68
Empty utility template that can be used to select a special functor.
Definition: Function.h:532
virtual R operator()(A a, B b, C c) const
function interface
Definition: Function.h:132
FunctionImpl implementation for global functions.
Definition: Function.h:237
virtual R operator()(A a, B b, C c) const =0
function interface
R(Object::* method)(A, B, C) const
Definition: Function.h:131
Function(icl::utils::SmartPtr< FunctionImpl< R, A, B, C > >impl)
Constructor with given SmartPtr<Impl>
Definition: Function.h:292
virtual ~FunctionImpl()
Definition: Function.h:50
virtual ~FunctionImpl()
Definition: Function.h:77
Specialization of the SmartPtrBase class for Pointers.
Definition: SmartPtr.h:75