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.LGPL ** 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 #include <ICLUtils/CompatMacros.h> 00036 00037 namespace icl{ 00038 namespace utils{ 00039 struct NO_ARG; 00041 // FunctionImpl classes and specializations ///////////// 00043 00045 00046 template<class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00047 struct FunctionImpl{ 00049 virtual R operator()(A a, B b, C c) const = 0; 00050 virtual ~FunctionImpl(){} 00051 }; 00052 00054 00055 template<class R, class A, class B> 00056 struct FunctionImpl<R, A, B, NO_ARG>{ 00058 virtual R operator()(A a, B b) const = 0; 00059 virtual ~FunctionImpl(){} 00060 }; 00061 00063 00064 template<class R, class A> 00065 struct FunctionImpl<R, A, NO_ARG>{ 00067 virtual R operator()(A a) const = 0; 00068 virtual ~FunctionImpl(){} 00069 }; 00070 00072 00073 template<class R> 00074 struct FunctionImpl<R, NO_ARG>{ 00076 virtual R operator()() const = 0; 00077 virtual ~FunctionImpl(){} 00078 }; 00079 00081 // Member Function Implementations /////////////////////// 00083 00085 00089 template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00090 struct MemberFunctionImpl : public FunctionImpl<R, A, B, C>{ 00091 Object *obj; 00092 R (Object::*method)(A, B, C); 00093 virtual R operator()(A a,B b,C c) const { return (obj->*method)(a, b, c); } 00094 }; 00095 00097 template <class Object, class R, class A, class B> 00098 struct MemberFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{ 00099 Object *obj; 00100 R (Object::*method)(A, B); 00101 virtual R operator()(A a,B b) const { return (obj->*method)(a, b); } 00102 }; 00103 00104 template <class Object, class R, class A> 00105 struct MemberFunctionImpl<Object, R, A, NO_ARG, NO_ARG> : public FunctionImpl<R, A>{ 00106 Object *obj; 00107 R (Object::*method)(A); 00108 virtual R operator()(A a) const { return (obj->*method)(a); } 00109 }; 00110 00111 template <class Object, class R> 00112 struct MemberFunctionImpl<Object, R, NO_ARG, NO_ARG, NO_ARG> : public FunctionImpl<R>{ 00113 Object *obj; 00114 R (Object::*method)(); 00115 virtual R operator()() const { return (obj->*method)(); } 00116 }; 00119 00120 // CONST Member Function Implementations ///////////////// 00122 00124 00128 template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00129 struct ConstMemberFunctionImpl : public FunctionImpl<R, A, B, C>{ 00130 const Object *obj; 00131 R (Object::*method)(A, B, C) const; 00132 virtual R operator()(A a,B b,C c) const { return (obj->*method)(a, b, c); } 00133 }; 00136 template <class Object, class R, class A, class B> 00137 struct ConstMemberFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{ 00138 const Object *obj; 00139 R (Object::*method)(A, B) const; 00140 virtual R operator()(A a,B b) const { return (obj->*method)(a, b); } 00141 }; 00142 00143 template <class Object, class R, class A> 00144 struct ConstMemberFunctionImpl<Object, R, A, NO_ARG> : public FunctionImpl<R, A>{ 00145 const Object *obj; 00146 R (Object::*method)(A) const; 00147 virtual R operator()(A a) const { return (obj->*method)(a); } 00148 }; 00149 00150 template <class Object, class R> 00151 struct ConstMemberFunctionImpl<Object, R, NO_ARG> : public FunctionImpl<R>{ 00152 const Object *obj; 00153 R (Object::*method)() const; 00154 virtual R operator()() const { return (obj->*method)(); } 00155 }; 00158 00159 // Functor Member Functions ////////////////////////////// 00161 00163 00167 template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00168 struct FunctorFunctionImpl : public FunctionImpl<R, A, B, C>{ 00169 Object *obj; 00170 virtual R operator()(A a,B b, C c) const { return (*obj)(a,b,c); } 00171 }; 00172 00174 template <class Object, class R, class A, class B> 00175 struct FunctorFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{ 00176 Object *obj; 00177 virtual R operator()(A a,B b) const { return (*obj)(a,b); } 00178 }; 00179 00180 template <class Object, class R, class A> 00181 struct FunctorFunctionImpl<Object, R, A, NO_ARG> : public FunctionImpl<R, A>{ 00182 Object *obj; 00183 virtual R operator()(A a) const { return (*obj)(a); } 00184 }; 00185 template <class Object, class R> 00186 struct FunctorFunctionImpl<Object, R, NO_ARG> : public FunctionImpl<R>{ 00187 Object *obj; 00188 virtual R operator()() const { return (*obj)(); } 00189 }; 00192 00193 // CONST Functor Member Functions //////////////////////// 00195 00197 00201 template <class Object, class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00202 struct ConstFunctorFunctionImpl : public FunctionImpl<R, A, B, C>{ 00203 const Object *obj; 00204 virtual R operator()(A a,B b, C c) const { return (*obj)(a,b,c); } 00205 }; 00206 00208 template <class Object, class R, class A, class B> 00209 struct ConstFunctorFunctionImpl<Object, R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{ 00210 const Object *obj; 00211 virtual R operator()(A a,B b) const { return (*obj)(a,b); } 00212 }; 00213 00214 template <class Object, class R, class A> 00215 struct ConstFunctorFunctionImpl<Object, R, A, NO_ARG> : public FunctionImpl<R, A>{ 00216 const Object *obj; 00217 virtual R operator()(A a) const { return (*obj)(a); } 00218 }; 00219 template <class Object, class R> 00220 struct ConstFunctorFunctionImpl<Object, R, NO_ARG> : public FunctionImpl<R>{ 00221 const Object *obj; 00222 virtual R operator()() const { return (*obj)(); } 00223 }; 00226 00227 // Global Function Wrappers ////////////////////////////// 00229 00230 00232 00236 template <class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00237 struct GlobalFunctionImpl : public FunctionImpl<R, A, B, C>{ 00238 R (*global_function)(A, B, C); 00239 virtual R operator()(A a,B b,C c) const { return global_function(a, b,c); } 00240 }; 00242 template <class R, class A, class B> 00243 struct GlobalFunctionImpl<R, A, B, NO_ARG> : public FunctionImpl<R, A, B>{ 00244 R (*global_function)(A, B); 00245 virtual R operator()(A a,B b) const { return global_function(a, b); } 00246 }; 00247 00248 template <class R, class A> 00249 struct GlobalFunctionImpl<R, A, NO_ARG> : public FunctionImpl<R, A>{ 00250 R (*global_function)(A); 00251 virtual R operator()(A a) const { return global_function(a); } 00252 }; 00253 template <class R> 00254 struct GlobalFunctionImpl<R, NO_ARG> : public FunctionImpl<R>{ 00255 R (*global_function)(); 00256 virtual R operator()() const { return global_function(); } 00257 }; 00260 00261 // The Function class //////////////////////////////////// 00263 00265 00283 template<class R=void, class A=NO_ARG, class B=NO_ARG, class C=NO_ARG> 00284 struct Function { 00286 Function(){} 00287 00289 Function(FunctionImpl<R,A,B,C> *impl):impl(impl){} 00290 00292 Function(icl::utils::SmartPtr<FunctionImpl<R,A,B,C> >impl):impl(impl){} 00293 00295 00298 Function(R (*global_function)(A,B,C)):impl(new GlobalFunctionImpl<R,A,B,C>){ 00299 ((GlobalFunctionImpl<R,A,B,C>*)(impl.get()))->global_function = global_function; 00300 } 00301 00303 icl::utils::SmartPtr<FunctionImpl<R,A,B,C> >impl; 00304 00306 00308 R operator()(A a, B b, C c) const { return (*impl)(a,b,c); } 00309 00311 operator bool() const { return impl; } 00312 00313 operator Function<R,A,B,C> () const { return (*(const Function<R,A,B,C>*)(this)); } 00314 }; 00315 00317 template<class R, class A, class B> 00318 struct Function<R, A, B, NO_ARG> : public std::binary_function<A, B, R>{ 00319 Function(){} 00320 Function(FunctionImpl<R,A,B> *impl):impl(impl){} 00321 Function(icl::utils::SmartPtr<FunctionImpl<R,A,B> >impl):impl(impl){} 00322 Function(R (*global_function)(A,B)):impl(new GlobalFunctionImpl<R,A,B>){ 00323 ((GlobalFunctionImpl<R,A,B>*)(impl.get()))->global_function = global_function; 00324 } 00325 icl::utils::SmartPtr<FunctionImpl<R,A,B> >impl; 00326 R operator()(A a, B b) const { return (*impl)(a,b); } 00327 operator bool() const { return impl; } 00328 00329 operator Function<R,A,B> () const { return (*(const Function<R,A,B>*)(this)); } 00330 }; 00331 00332 template<class R, class A> 00333 struct Function<R, A, NO_ARG> : public std::unary_function<A, R>{ 00334 Function(){} 00335 Function(FunctionImpl<R,A> *impl):impl(impl){} 00336 Function(icl::utils::SmartPtr<FunctionImpl<R,A> >impl):impl(impl){} 00337 Function(R (*global_function)(A)):impl(new GlobalFunctionImpl<R,A>){ 00338 ((GlobalFunctionImpl<R,A>*)(impl.get()))->global_function = global_function; 00339 } 00340 icl::utils::SmartPtr<FunctionImpl<R,A> >impl; 00341 R operator()(A a) const { return (*impl)(a); } 00342 operator bool() const { return impl; } 00343 00344 operator Function<R,A> () const { return (*(const Function<R,A>*)(this)); } 00345 }; 00346 template<class R> 00347 struct Function<R, NO_ARG>{ 00348 typedef R result_type; 00349 Function(){} 00350 Function(FunctionImpl<R> *impl):impl(impl){} 00351 Function(icl::utils::SmartPtr<FunctionImpl<R> >impl):impl(impl){} 00352 Function(R (*global_function)()):impl(new GlobalFunctionImpl<R>){ 00353 ((GlobalFunctionImpl<R>*)(impl.get()))->global_function = global_function; 00354 } 00355 icl::utils::SmartPtr<FunctionImpl<R> >impl; 00356 R operator()() const { return (*impl)(); } 00357 00358 operator bool() const { return impl; } 00359 00360 operator Function<R> () const { return (*(const Function<R>*)(this)); } 00361 }; 00367 00368 // Function creator functions (from member functions ///// 00370 00372 00375 template<class Object, class R, class A, class B, class C> 00376 Function<R, A, B, C> function(Object &obj, R(Object::*method)(A, B, C)){ 00377 MemberFunctionImpl<Object,R,A,B,C> *impl = new MemberFunctionImpl<Object,R,A,B,C>; 00378 impl->obj = &obj; 00379 impl->method = method; 00380 return Function<R,A,B,C>(impl); 00381 } 00382 00384 00387 template<class Object,class R, class A, class B> 00388 Function<R, A, B> function(Object &obj, R(Object::*method)(A, B)){ 00389 MemberFunctionImpl<Object,R,A,B> *impl = new MemberFunctionImpl<Object,R,A,B>; 00390 impl->obj = &obj; 00391 impl->method = method; 00392 return Function<R,A,B>(impl); 00393 } 00394 00396 00399 template<class Object,class R, class A> 00400 Function<R, A> function(Object &obj, R(Object::*method)(A)){ 00401 MemberFunctionImpl<Object,R,A> *impl = new MemberFunctionImpl<Object,R,A>; 00402 impl->obj = &obj; 00403 impl->method = method; 00404 return Function<R,A>(impl); 00405 } 00406 00408 00412 template<class Object,class R> 00413 Function<R> function(Object &obj, R(Object::*method)()){ 00414 MemberFunctionImpl<Object,R> *impl = new MemberFunctionImpl<Object,R>; 00415 impl->obj = &obj; 00416 impl->method = method; 00417 return Function<R>(impl); 00418 } 00419 00421 00424 template<class Object,class R,class A,class B,class C> 00425 Function<R, A, B, C> function(const Object &obj, R(Object::*method)(A a, B b, C c) const){ 00426 ConstMemberFunctionImpl<Object,R,A,B,C> *impl = new ConstMemberFunctionImpl<Object,R,A,B,C>; 00427 impl->obj = &obj; 00428 impl->method = method; 00429 return Function<R,A,B,C>(impl); 00430 } 00431 00433 00436 template<class Object,class R,class A,class B> 00437 Function<R, A, B> function(const Object &obj, R(Object::*method)(A a, B b) const){ 00438 ConstMemberFunctionImpl<Object,R,A,B> *impl = new ConstMemberFunctionImpl<Object,R,A,B>; 00439 impl->obj = &obj; 00440 impl->method = method; 00441 return Function<R,A,B>(impl); 00442 } 00444 00447 template<class Object,class R,class A> 00448 Function<R, A> function(const Object &obj, R(Object::*method)(A a) const){ 00449 ConstMemberFunctionImpl<Object,R,A> *impl = new ConstMemberFunctionImpl<Object,R,A>; 00450 impl->obj = &obj; 00451 impl->method = method; 00452 return Function<R,A>(impl); 00453 } 00455 00459 template<class Object,class R> 00460 Function<R> function(const Object &obj, R(Object::*method)() const){ 00461 ConstMemberFunctionImpl<Object,R> *impl = new ConstMemberFunctionImpl<Object,R>; 00462 impl->obj = &obj; 00463 impl->method = method; 00464 return Function<R>(impl); 00465 } 00466 00468 00471 template<class Object,class R, class A, class B, class C> 00472 Function<R, A, B, C> function(Object *obj, R(Object::*method)(A, B, C)){ return function<Object, R, A, B, C>(*obj, method); } 00473 00475 00478 template<class Object,class R, class A, class B> 00479 Function<R, A, B> function(Object *obj, R(Object::*method)(A, B)){ return function<Object, R, A, B>(*obj, method); } 00480 00482 00485 template<class Object,class R, class A> 00486 Function<R, A> function(Object *obj, R(Object::*method)(A)){ return function<Object, R, A>(*obj, method); } 00487 00489 00493 template<class Object,class R> 00494 Function<R> function(Object *obj, R(Object::*method)()){ return function<Object, R>(*obj, method); } 00495 00497 00500 template<class Object,class R, class A, class B, class C> 00501 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); } 00502 00504 00507 template<class Object,class R, class A, class B> 00508 Function<R, A, B> function(const Object *obj, R(Object::*method)(A, B) const){ return function<Object, R, A, B>(*obj, method); } 00509 00511 00514 template<class Object,class R, class A> 00515 Function<R, A> function(const Object *obj, R(Object::*method)(A) const){ return function<Object, R, A>(*obj, method); } 00516 00518 00522 template<class Object,class R> 00523 Function<R> function(const Object *obj, R(Object::*method)() const){ return function<Object, R>(*obj, method); } 00524 00525 00527 // Function creator functions (from functors) //////////// 00529 00531 00532 template <class R = void, class A = NO_ARG, class B = NO_ARG, class C = NO_ARG> struct SelectFunctor{}; 00533 00535 00539 template<class Object,class R, class A, class B, class C> 00540 Function<R, A, B, C> function(Object &obj, SelectFunctor<R, A, B, C>){ 00541 FunctorFunctionImpl<Object,R,A,B,C> *impl = new FunctorFunctionImpl<Object,R,A,B,C>; 00542 impl->obj = &obj; 00543 return Function<R,A,B,C>(impl); 00544 } 00545 00547 00551 template<class Object,class R, class A, class B, class C> 00552 Function<R, A, B> function(const Object &obj, SelectFunctor<R, A, B, C>){ 00553 ConstFunctorFunctionImpl<Object,R,A,B,C> *impl = new ConstFunctorFunctionImpl<Object,R,A,B,C>; 00554 impl->obj = &obj; 00555 return Function<R,A,B,C>(impl); 00556 } 00557 00559 00560 template<class Object> 00561 Function<> function(Object &obj){ 00562 return function(obj,SelectFunctor<void,NO_ARG,NO_ARG,NO_ARG>()); 00563 } 00564 00566 00567 template<class Object> 00568 Function<> function(const Object &obj){ 00569 return function(obj,SelectFunctor<void,NO_ARG,NO_ARG,NO_ARG>()); 00570 } 00571 00573 00577 template<class Object,class R, class A, class B, class C> 00578 Function<R, A, B, C> function(Object *obj, SelectFunctor<R, A, B, C> selector){ return function<Object, R, A, B, C>(*obj, selector); } 00579 00581 00585 template<class Object,class R, class A, class B, class C> 00586 Function<R, A, B, C> function(const Object *obj, SelectFunctor<R, A, B, C> selector){ return function<Object, R, A, B, C>(*obj, selector); } 00587 00588 00590 // Function creator functions (from global functions) //// 00592 00594 00597 template<class R, class A, class B, class C> 00598 Function<R, A, B, C> function(R(*global_function)(A a, B b, C c)){ 00599 return Function<R,A,B,C>(global_function); 00600 } 00601 00603 00606 template<class R, class A, class B> 00607 Function<R, A, B> function(R(*global_function)(A a, B b)){ 00608 return Function<R,A,B>(global_function); 00609 } 00610 00611 00613 00616 template<class R, class A> 00617 Function<R, A> function(R(*global_function)(A a)){ 00618 return Function<R,A>(global_function); 00619 } 00620 00622 00625 template<class R> 00626 Function<R> function(R(*global_function)()){ 00627 return Function<R>(global_function); 00628 } 00629 } // namespace utils 00630 } 00631