Image Component Library (ICL)
|
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