Image Component Library (ICL)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Function.h
Go to the documentation of this file.
00001 /********************************************************************
00002 **                Image Component Library (ICL)                    **
00003 **                                                                 **
00004 ** Copyright (C) 2006-2013 CITEC, University of Bielefeld          **
00005 **                         Neuroinformatics Group                  **
00006 ** Website: www.iclcv.org and                                      **
00007 **          http://opensource.cit-ec.de/projects/icl               **
00008 **                                                                 **
00009 ** File   : ICLUtils/src/ICLUtils/Function.h                       **
00010 ** Module : ICLUtils                                               **
00011 ** Authors: Christof Elbrechter                                    **
00012 **                                                                 **
00013 **                                                                 **
00014 ** GNU LESSER GENERAL PUBLIC LICENSE                               **
00015 ** This file may be used under the terms of the GNU Lesser General **
00016 ** Public License version 3.0 as published by the                  **
00017 **                                                                 **
00018 ** Free Software Foundation and appearing in the file LICENSE.GPL  **
00019 ** included in the packaging of this file.  Please review the      **
00020 ** following information to ensure the license requirements will   **
00021 ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt                **
00022 **                                                                 **
00023 ** The development of this software was supported by the           **
00024 ** Excellence Cluster EXC 277 Cognitive Interaction Technology.    **
00025 ** The Excellence Cluster EXC 277 is a grant of the Deutsche       **
00026 ** Forschungsgemeinschaft (DFG) in the context of the German       **
00027 ** Excellence Initiative.                                          **
00028 **                                                                 **
00029 ********************************************************************/
00030 
00031 #pragma once
00032 
00033 #include <ICLUtils/SmartPtr.h>
00034 #include <functional>
00035 
00036 namespace icl{
00037   namespace utils{
00039     // FunctionImpl classes and specializations /////////////
00041   
00043 
00044     template<class R=void, class A=void, class B=void, class C=void>
00045     struct FunctionImpl{
00047       virtual R operator()(A a, B b, C c) const = 0;
00048       virtual ~FunctionImpl(){}
00049     };
00050     
00052 
00053     template<class R, class A, class B>
00054     struct FunctionImpl<R,A,B,void>{
00056       virtual R operator()(A a, B b) const = 0;
00057       virtual ~FunctionImpl(){}
00058     };
00059     
00061 
00062     template<class R, class A>
00063     struct FunctionImpl<R,A,void>{
00065       virtual R operator()(A a) const = 0;
00066       virtual ~FunctionImpl(){}
00067     };
00068   
00070 
00071     template<class R>
00072     struct FunctionImpl<R,void,void>{
00074       virtual R operator()() const= 0;
00075       virtual ~FunctionImpl(){}
00076     };
00077   
00079     // Member Function Implementations ///////////////////////
00081     
00083 
00087     template <class Object, class R=void, class A=void, class B=void, class C=void>
00088     struct MemberFunctionImpl : public FunctionImpl<R,A,B,C>{
00089       Object *obj;
00090       R (Object::*method)(A, B, C);
00091       virtual R operator()(A a,B b,C c) const { return (obj->*method)(a, b, c); }
00092     };
00093     
00095     template <class Object, class R, class A, class B>
00096     struct MemberFunctionImpl<Object,R,A,B,void> : public FunctionImpl<R,A,B>{
00097       Object *obj;
00098       R (Object::*method)(A, B);
00099       virtual R operator()(A a,B b) const { return (obj->*method)(a, b); }
00100     };
00101   
00102     template <class Object, class R, class A>
00103     struct MemberFunctionImpl<Object,R,A,void,void> : public FunctionImpl<R,A>{
00104       Object *obj;
00105       R (Object::*method)(A);
00106       virtual R operator()(A a) const { return (obj->*method)(a); }
00107     };
00108     
00109     template <class Object, class R>
00110     struct MemberFunctionImpl<Object,R,void,void,void> : public FunctionImpl<R>{
00111       Object *obj;
00112       R (Object::*method)();
00113       virtual R operator()() const { return (obj->*method)(); }
00114     };
00117 
00118     // CONST Member Function Implementations /////////////////
00120   
00122 
00126     template <class Object, class R=void, class A=void, class B=void, class C=void>
00127     struct ConstMemberFunctionImpl : public FunctionImpl<R,A,B,C>{
00128       const Object *obj;
00129       R (Object::*method)(A, B, C) const;
00130       virtual R operator()(A a,B b,C c) const { return (obj->*method)(a, b, c); }
00131     };
00134     template <class Object, class R, class A, class B>
00135     struct ConstMemberFunctionImpl<Object,R,A,B,void> : public FunctionImpl<R,A,B>{
00136       const Object *obj;
00137       R (Object::*method)(A, B) const;
00138       virtual R operator()(A a,B b) const { return (obj->*method)(a, b); }
00139     };
00140   
00141     template <class Object, class R, class A>
00142     struct ConstMemberFunctionImpl<Object,R,A,void,void> : public FunctionImpl<R,A>{
00143       const Object *obj;
00144       R (Object::*method)(A) const;
00145       virtual R operator()(A a) const { return (obj->*method)(a); }
00146     };
00147     
00148     template <class Object, class R>
00149     struct ConstMemberFunctionImpl<Object,R,void,void,void> : public FunctionImpl<R>{
00150       const Object *obj;
00151       R (Object::*method)() const;
00152       virtual R operator()() const { return (obj->*method)(); }
00153     };
00156 
00157     // Functor Member Functions //////////////////////////////
00159   
00161 
00165     template <class Object, class R=void, class A=void, class B=void, class C=void>
00166     struct FunctorFunctionImpl : public FunctionImpl<R,A,B,C>{
00167       Object *obj;
00168       virtual R operator()(A a,B b, C c) const { return (*obj)(a,b,c); }
00169     };
00170     
00172     template <class Object, class R, class A, class B>
00173     struct FunctorFunctionImpl<Object,R,A,B,void> : public FunctionImpl<R,A,B>{
00174       Object *obj;
00175       virtual R operator()(A a,B b) const { return (*obj)(a,b); }
00176     };
00177   
00178     template <class Object, class R, class A>
00179     struct FunctorFunctionImpl<Object,R,A,void,void> : public FunctionImpl<R,A>{
00180       Object *obj;
00181       virtual R operator()(A a) const { return (*obj)(a); }
00182     };
00183     template <class Object, class R>
00184     struct FunctorFunctionImpl<Object,R,void,void,void> : public FunctionImpl<R>{
00185       Object *obj;
00186       virtual R operator()() const { return (*obj)(); }
00187     };
00190 
00191     // CONST Functor Member Functions ////////////////////////
00193     
00195 
00199     template <class Object, class R=void, class A=void, class B=void, class C=void>
00200     struct ConstFunctorFunctionImpl : public FunctionImpl<R,A,B,C>{
00201       const Object *obj;
00202       virtual R operator()(A a,B b, C c) const { return (*obj)(a,b,c); }
00203     };
00204     
00206     template <class Object, class R, class A, class B>
00207     struct ConstFunctorFunctionImpl<Object,R,A,B,void> : public FunctionImpl<R,A,B>{
00208       const Object *obj;
00209       virtual R operator()(A a,B b) const { return (*obj)(a,b); }
00210     };
00211   
00212     template <class Object, class R, class A>
00213     struct ConstFunctorFunctionImpl<Object,R,A,void,void> : public FunctionImpl<R,A>{
00214       const Object *obj;
00215       virtual R operator()(A a) const { return (*obj)(a); }
00216     };
00217     template <class Object, class R>
00218     struct ConstFunctorFunctionImpl<Object,R,void,void,void> : public FunctionImpl<R>{
00219       const Object *obj;
00220       virtual R operator()() const { return (*obj)(); }
00221     };
00224 
00225     // Global Function Wrappers //////////////////////////////
00227     
00228    
00230 
00234     template <class R=void, class A=void, class B=void, class C=void>
00235     struct GlobalFunctionImpl : public FunctionImpl<R,A,B,C>{
00236       R (*global_function)(A, B, C);
00237       virtual R operator()(A a,B b,C c) const { return global_function(a, b,c); }
00238     };
00240     template <class R, class A, class B>
00241     struct GlobalFunctionImpl<R,A,B,void> : public FunctionImpl<R,A,B>{
00242       R (*global_function)(A, B);
00243       virtual R operator()(A a,B b) const { return global_function(a, b); }
00244     };
00245   
00246     template <class R, class A>
00247     struct GlobalFunctionImpl<R,A,void,void> : public FunctionImpl<R,A>{
00248       R (*global_function)(A);
00249       virtual R operator()(A a) const { return global_function(a); }
00250     };
00251     template <class R>
00252     struct GlobalFunctionImpl<R,void,void,void> : public FunctionImpl<R>{
00253       R (*global_function)();
00254       virtual R operator()() const { return global_function(); }
00255     };
00258 
00259     // The Function class ////////////////////////////////////
00261     
00263 
00281     template<class R=void, class A=void, class B=void, class C=void> 
00282     struct Function {
00284       Function(){}
00285       
00287       Function(FunctionImpl<R,A,B,C> *impl):impl(impl){}
00288   
00290       Function(icl::utils::SmartPtr<FunctionImpl<R,A,B,C> >impl):impl(impl){}
00291   
00293 
00296       Function(R (*global_function)(A,B,C)):impl(new GlobalFunctionImpl<R,A,B,C>){
00297         ((GlobalFunctionImpl<R,A,B,C>*)(impl.get()))->global_function = global_function;
00298       }
00299       
00301       icl::utils::SmartPtr<FunctionImpl<R,A,B,C> >impl;
00302       
00304 
00306       R operator()(A a, B b, C c) const { return (*impl)(a,b,c); }
00307       
00309       operator bool() const { return impl; }
00310   
00311       operator Function<void,A,B,C> () const { return (*(const Function<void,A,B,C>*)(this)); }
00312     };
00313     
00315     template<class R, class A, class B> struct Function<R,A,B,void> : public std::binary_function<A,B,R>{
00316       Function(){}
00317       Function(FunctionImpl<R,A,B> *impl):impl(impl){}
00318       Function(icl::utils::SmartPtr<FunctionImpl<R,A,B> >impl):impl(impl){}
00319       Function(R (*global_function)(A,B)):impl(new GlobalFunctionImpl<R,A,B>){
00320         ((GlobalFunctionImpl<R,A,B>*)(impl.get()))->global_function = global_function;
00321       }
00322       icl::utils::SmartPtr<FunctionImpl<R,A,B> >impl;
00323       R operator()(A a, B b) const { return (*impl)(a,b); }
00324       operator bool() const { return impl; }
00325       
00326       operator Function<void,A,B> () const { return (*(const Function<void,A,B>*)(this)); }
00327     };
00328   
00329     template<class R, class A> struct Function<R,A,void> : public std::unary_function<A,R>{
00330       Function(){}
00331       Function(FunctionImpl<R,A> *impl):impl(impl){}
00332       Function(icl::utils::SmartPtr<FunctionImpl<R,A> >impl):impl(impl){}
00333       Function(R (*global_function)(A)):impl(new GlobalFunctionImpl<R,A>){
00334         ((GlobalFunctionImpl<R,A>*)(impl.get()))->global_function = global_function;
00335       }
00336       icl::utils::SmartPtr<FunctionImpl<R,A> >impl;
00337       R operator()(A a) const { return (*impl)(a); }
00338       operator bool() const { return impl; }
00339       
00340       operator Function<void,A> () const { return (*(const Function<void,A>*)(this)); }
00341     };
00342     template<class R> struct Function<R,void,void>{
00343       typedef R result_type;
00344       Function(){}
00345       Function(FunctionImpl<R> *impl):impl(impl){}
00346       Function(icl::utils::SmartPtr<FunctionImpl<R> >impl):impl(impl){}
00347       Function(R (*global_function)()):impl(new GlobalFunctionImpl<R>){
00348         ((GlobalFunctionImpl<R>*)(impl.get()))->global_function = global_function;
00349       }
00350       icl::utils::SmartPtr<FunctionImpl<R> >impl;
00351       R operator()() const { return (*impl)(); }
00352   
00353       operator bool() const { return impl; }
00354   
00355       operator Function<void> () const { return (*(const Function<void>*)(this)); }
00356     };
00362 
00363     // Function creator functions (from member functions /////
00365   
00367 
00370     template<class Object,class R, class A, class B, class C>
00371     Function<R,A,B,C> function(Object &obj, R (Object::*method)(A,B,C)){
00372       MemberFunctionImpl<Object,R,A,B,C> *impl = new MemberFunctionImpl<Object,R,A,B,C>;
00373       impl->obj = &obj;
00374       impl->method = method;
00375       return Function<R,A,B,C>(impl);
00376     } 
00377     
00379 
00382     template<class Object,class R, class A, class B>
00383     Function<R,A,B> function(Object &obj, R (Object::*method)(A,B)){
00384       MemberFunctionImpl<Object,R,A,B> *impl = new MemberFunctionImpl<Object,R,A,B>;
00385       impl->obj = &obj;
00386       impl->method = method;
00387       return Function<R,A,B>(impl);
00388     } 
00389     
00391 
00394     template<class Object,class R, class A>
00395     Function<R,A> function(Object &obj, R (Object::*method)(A)){
00396       MemberFunctionImpl<Object,R,A> *impl = new MemberFunctionImpl<Object,R,A>;
00397       impl->obj = &obj;
00398       impl->method = method;
00399       return Function<R,A>(impl);
00400     } 
00401   
00403 
00407     template<class Object,class R>
00408     Function<R> function(Object &obj, R (Object::*method)()){
00409       MemberFunctionImpl<Object,R> *impl = new MemberFunctionImpl<Object,R>;
00410       impl->obj = &obj;
00411       impl->method = method;
00412       return Function<R>(impl);
00413     } 
00414   
00416 
00419     template<class Object,class R,class A,class B,class C>
00420     Function<R,A,B,C> function(const Object &obj, R (Object::*method)(A a, B b, C c) const){
00421       ConstMemberFunctionImpl<Object,R,A,B,C> *impl = new ConstMemberFunctionImpl<Object,R,A,B,C>;
00422       impl->obj = &obj;
00423       impl->method = method;
00424       return Function<R,A,B,C>(impl);
00425     } 
00426     
00428 
00431     template<class Object,class R,class A,class B>
00432     Function<R,A,B> function(const Object &obj, R (Object::*method)(A a, B b) const){
00433       ConstMemberFunctionImpl<Object,R,A,B> *impl = new ConstMemberFunctionImpl<Object,R,A,B>;
00434       impl->obj = &obj;
00435       impl->method = method;
00436       return Function<R,A,B>(impl);
00437     } 
00439 
00442     template<class Object,class R,class A>
00443     Function<R,A> function(const Object &obj, R (Object::*method)(A a) const){
00444       ConstMemberFunctionImpl<Object,R,A> *impl = new ConstMemberFunctionImpl<Object,R,A>;
00445       impl->obj = &obj;
00446       impl->method = method;
00447       return Function<R,A>(impl);
00448     } 
00450 
00454     template<class Object,class R>
00455     Function<R> function(const Object &obj, R (Object::*method)() const){
00456       ConstMemberFunctionImpl<Object,R> *impl = new ConstMemberFunctionImpl<Object,R>;
00457       impl->obj = &obj;
00458       impl->method = method;
00459       return Function<R>(impl);
00460     } 
00461   
00463 
00466     template<class Object,class R, class A, class B, class C>
00467     Function<R,A,B,C> function(Object *obj, R (Object::*method)(A,B,C)){ return function<Object,R,A,B,C>(*obj,method); }
00468   
00470 
00473     template<class Object,class R, class A, class B>
00474     Function<R,A,B> function(Object *obj, R (Object::*method)(A,B)){ return function<Object,R,A,B>(*obj,method); }
00475     
00477 
00480     template<class Object,class R, class A>
00481     Function<R,A> function(Object *obj, R (Object::*method)(A)){ return function<Object,R,A>(*obj,method); }
00482     
00484 
00488     template<class Object,class R>
00489     Function<R> function(Object *obj, R (Object::*method)()){ return function<Object,R>(*obj,method); }
00490   
00492 
00495     template<class Object,class R, class A, class B, class C>
00496     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); }
00497    
00499 
00502     template<class Object,class R, class A, class B>
00503     Function<R,A,B> function(const Object *obj, R (Object::*method)(A,B) const){ return function<Object,R,A,B>(*obj,method); }
00504   
00506 
00509     template<class Object,class R, class A>
00510     Function<R,A> function(const Object *obj, R (Object::*method)(A) const){ return function<Object,R,A>(*obj,method); }
00511     
00513 
00517     template<class Object,class R>
00518     Function<R> function(const Object *obj, R (Object::*method)() const){ return function<Object,R>(*obj,method); }
00519   
00520     
00522     // Function creator functions (from functors) ////////////
00524     
00526 
00527     template <class R=void, class A=void, class B=void, class C=void> struct SelectFunctor{};
00528     
00530 
00534     template<class Object,class R, class A, class B, class C>
00535     Function<R,A,B,C> function(Object &obj,SelectFunctor<R,A,B,C>){
00536       FunctorFunctionImpl<Object,R,A,B,C>  *impl = new FunctorFunctionImpl<Object,R,A,B,C>;
00537       impl->obj = &obj;
00538       return Function<R,A,B,C>(impl);
00539     } 
00540   
00542 
00546     template<class Object,class R, class A, class B, class C>
00547     Function<R,A,B> function(const Object &obj,SelectFunctor<R,A,B,C>){
00548       ConstFunctorFunctionImpl<Object,R,A,B,C>  *impl = new ConstFunctorFunctionImpl<Object,R,A,B,C>;
00549       impl->obj = &obj;
00550       return Function<R,A,B,C>(impl);
00551     } 
00552   
00554 
00555     template<class Object>
00556     Function<> function(Object &obj){
00557       return function(obj,SelectFunctor<void,void,void,void>());
00558     } 
00559   
00561 
00562     template<class Object>
00563     Function<> function(const Object &obj){
00564       return function(obj,SelectFunctor<void,void,void,void>());
00565     } 
00566   
00568 
00572     template<class Object,class R, class A, class B, class C>
00573     Function<R,A,B,C> function(Object *obj,SelectFunctor<R,A,B,C> selector){ return function<Object,R,A,B,C>(*obj,selector); }
00574     
00576 
00580     template<class Object,class R, class A, class B, class C>
00581     Function<R,A,B,C> function(const Object *obj,SelectFunctor<R,A,B,C> selector){ return function<Object,R,A,B,C>(*obj,selector); }
00582     
00583     
00585     // Function creator functions (from global functions) ////
00587   
00589 
00592     template<class R, class A, class B, class C>
00593     Function<R,A,B,C> function(R (*global_function)(A a, B b, C c)){
00594       return Function<R,A,B,C>(global_function);
00595     } 
00596     
00598 
00601     template<class R, class A, class B>
00602     Function<R,A,B> function(R (*global_function)(A a, B b)){
00603       return Function<R,A,B>(global_function);
00604     } 
00605   
00606     
00608 
00611     template<class R, class A>
00612     Function<R,A> function(R (*global_function)(A a)){
00613       return Function<R,A>(global_function);
00614     } 
00615   
00617 
00620     template<class R>
00621     Function<R> function(R (*global_function)()){
00622       return Function<R>(global_function);
00623     } 
00624   
00625   
00627 
00628     template<class R, class A, class B, class C>
00629     Function<R,A,B,C> function(FunctionImpl<R,A,B,C> *impl){
00630       return Function<R,A,B,C>(impl);
00631     }
00632   } // namespace utils
00633 }
00634 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines