$search
00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_UTILITIES_FUNCTION_OBJECTS_HPP_ 00013 #define ECL_UTILITIES_FUNCTION_OBJECTS_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include <ecl/concepts/nullary_function.hpp> 00020 #include "../utilities/references.hpp" 00021 00022 /***************************************************************************** 00023 ** Namespaces 00024 *****************************************************************************/ 00025 00026 namespace ecl { 00027 00028 /***************************************************************************** 00029 ** Using 00030 *****************************************************************************/ 00031 00032 /***************************************************************************** 00033 ** Interface [NullaryFunction] 00034 *****************************************************************************/ 00045 template <typename R = void> 00046 class NullaryFunction { 00047 public: 00048 typedef R result_type; 00049 virtual result_type operator()() = 0; 00050 virtual ~NullaryFunction() {}; 00051 }; 00052 00053 /***************************************************************************** 00054 ** Interface [UnaryFunction] 00055 *****************************************************************************/ 00056 00068 template <typename A, typename R = void> 00069 class UnaryFunction { 00070 public: 00071 typedef R result_type; 00072 typedef A argument_type; 00077 virtual result_type operator()(argument_type arg) = 0; 00078 virtual ~UnaryFunction() {}; 00079 }; 00080 00081 /***************************************************************************** 00082 ** Interface [BinaryFunction] 00083 *****************************************************************************/ 00096 template <typename A1, typename A2, typename R = void> 00097 class BinaryFunction { 00098 public: 00099 typedef R result_type; 00100 typedef A1 first_argument_type; 00101 typedef A2 second_argument_type; 00109 virtual result_type operator()(first_argument_type arg1, second_argument_type arg2) = 0; 00110 virtual ~BinaryFunction() {}; 00111 }; 00112 00113 /***************************************************************************** 00114 ** Interface [FreeFunctions] 00115 *****************************************************************************/ 00125 template <typename R = void> 00126 class NullaryFreeFunction : public NullaryFunction<R> 00127 { 00128 public: 00136 NullaryFreeFunction( R (*function)() ) : free_function(function) {} 00137 virtual ~NullaryFreeFunction() {}; 00146 R operator()() { return free_function(); } 00147 00148 private: 00149 R (*free_function)(); 00150 }; 00151 00159 template <> 00160 class NullaryFreeFunction<void> : public NullaryFunction<void> 00161 { 00162 public: 00170 NullaryFreeFunction( void (*function)() ) : free_function(function) {} 00171 00172 virtual ~NullaryFreeFunction() {}; 00181 void operator()() { free_function(); } 00182 00183 private: 00184 void (*free_function)(); 00185 }; 00186 00199 template <typename A, typename R = void> 00200 class UnaryFreeFunction : public UnaryFunction<A,R> 00201 { 00202 public: 00211 UnaryFreeFunction( R (*function)(A) ) : free_function(function) {} 00212 00213 virtual ~UnaryFreeFunction() {}; 00222 R operator()(A a) { return free_function(a); } 00223 00224 private: 00225 R (*free_function)(A); 00226 }; 00227 00237 template <typename A> 00238 class UnaryFreeFunction<A,void> : public UnaryFunction<A,void> 00239 { 00240 public: 00249 UnaryFreeFunction( void (*function)(A) ) : free_function(function) {} 00250 00251 virtual ~UnaryFreeFunction() {}; 00259 void operator()(A a) { free_function(a); } 00260 00261 private: 00262 void (*free_function)(A); 00263 }; 00264 00265 /***************************************************************************** 00266 ** Interface [BoundFreeFunctions] 00267 *****************************************************************************/ 00291 template <typename A, typename R = void> 00292 class BoundUnaryFreeFunction : public NullaryFunction<R> 00293 { 00294 public: 00303 BoundUnaryFreeFunction( R (*function)(A), A a ) : free_function(function), argument(a) {} 00304 virtual ~BoundUnaryFreeFunction() {}; 00312 R operator()() { return free_function(argument); } 00313 00314 private: 00315 R (*free_function)(A); 00316 A argument; 00317 }; 00318 00328 template <typename A> 00329 class BoundUnaryFreeFunction<A,void> : public NullaryFunction<void> 00330 { 00331 public: 00340 BoundUnaryFreeFunction( void (*function)(A), A a ) : free_function(function), argument(a) {} 00341 virtual ~BoundUnaryFreeFunction() {}; 00349 void operator()() { free_function(argument); } 00350 00351 private: 00352 void (*free_function)(A); 00353 A argument; 00354 }; 00355 00356 /***************************************************************************** 00357 * Interface [MemberFunctions] 00358 ***************************************************************************** 00359 * Could make copies+refs here, just like mem_fun and mem_fun_ref but I can't 00360 * see the need for copy style setups. 00361 ****************************************************************************/ 00362 00390 template <typename C, typename R = void> 00391 class NullaryMemberFunction : public UnaryFunction<C&,R> { 00392 public: 00401 NullaryMemberFunction( R (C::*function)()) : member_function(function) {} 00402 virtual ~NullaryMemberFunction() {}; 00414 R operator()(C &class_object) { 00415 return (class_object.*member_function)(); 00416 } 00417 private: 00418 R (C::*member_function)(); 00419 }; 00420 00431 template <typename C> 00432 class NullaryMemberFunction<C,void> : public UnaryFunction<C&,void> { 00433 public: 00442 NullaryMemberFunction( void (C::*function)()) : member_function(function) {} 00443 virtual ~NullaryMemberFunction() {}; 00453 void operator()(C &class_object) { 00454 (class_object.*member_function)(); 00455 } 00456 private: 00457 void (C::*member_function)(); 00458 }; 00459 00486 template <typename C, typename A, typename R = void> 00487 class UnaryMemberFunction : public BinaryFunction<C&,A,R> { 00488 public: 00497 UnaryMemberFunction( R (C::*function)(A)) : member_function(function) {} 00498 virtual ~UnaryMemberFunction() {}; 00509 R operator()(C &class_object, A a) { 00510 return (class_object.*member_function)(a); 00511 } 00512 private: 00513 R (C::*member_function)(A); 00514 }; 00515 00526 template <typename C, typename A> 00527 class UnaryMemberFunction<C,A,void> : public BinaryFunction<C&,A,void> { 00528 public: 00537 UnaryMemberFunction( void (C::*function)(A)) : member_function(function) {} 00538 virtual ~UnaryMemberFunction() {}; 00549 void operator()(C &class_object, A a) { 00550 (class_object.*member_function)(a); 00551 } 00552 private: 00553 void (C::*member_function)(A); 00554 }; 00555 00556 /***************************************************************************** 00557 ** Interface [BoundMemberFunctions] 00558 *****************************************************************************/ 00559 00585 template <typename C, typename R = void> 00586 class BoundNullaryMemberFunction : public NullaryFunction<R> { 00587 public: 00596 BoundNullaryMemberFunction( R (C::*function)(), C &class_object) : 00597 member_class(class_object), 00598 member_function(function) 00599 {} 00600 virtual ~BoundNullaryMemberFunction() {}; 00609 R operator()() { return (member_class.*member_function)(); } 00610 00611 private: 00612 C &member_class; 00613 R (C::*member_function)(); 00614 }; 00615 00627 template <typename C> 00628 class BoundNullaryMemberFunction<C,void> : public NullaryFunction<void> { 00629 public: 00638 BoundNullaryMemberFunction( void (C::*function)(), C &class_object) : 00639 member_class(class_object), 00640 member_function(function) 00641 {} 00642 00643 virtual ~BoundNullaryMemberFunction() {}; 00649 void operator()() { (member_class.*member_function)(); } 00650 00651 private: 00652 C &member_class; 00653 void (C::*member_function)(); 00654 }; 00655 00684 template <typename C, typename A, typename R = void> 00685 class PartiallyBoundUnaryMemberFunction : public UnaryFunction<A,R> { 00686 public: 00695 PartiallyBoundUnaryMemberFunction( R (C::*function)(A), C &class_object) : 00696 member_class(class_object), 00697 member_function(function) 00698 {} 00699 virtual ~PartiallyBoundUnaryMemberFunction() {}; 00708 R operator()(A a) { 00709 return (member_class.*member_function)(a); 00710 } 00711 private: 00712 C &member_class; 00713 void (C::*member_function)(A); 00714 }; 00743 template <typename C, typename A, typename R = void> 00744 class BoundUnaryMemberFunction : public NullaryFunction<R> { 00745 public: 00755 BoundUnaryMemberFunction( R (C::*function)(A), C &class_object, A a) : 00756 member_class(class_object), 00757 member_function(function), 00758 argument(a) 00759 {} 00760 virtual ~BoundUnaryMemberFunction() {}; 00768 R operator()() { 00769 return (member_class.*member_function)(argument); 00770 } 00771 private: 00772 C &member_class; 00773 void (C::*member_function)(A); 00774 A argument; 00775 }; 00776 /***************************************************************************** 00777 ** Function Object Wrappers 00778 *****************************************************************************/ 00792 template <typename FunctionObject, typename Result = void> 00793 class NullaryFunctionCopy : public NullaryFunction<Result> 00794 { 00795 public: 00804 NullaryFunctionCopy(const FunctionObject &f_o ) : function_object(f_o) { 00805 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>); 00806 } 00807 virtual ~NullaryFunctionCopy() {}; 00816 Result operator()() { return function_object(); } 00817 00818 private: 00819 FunctionObject function_object; 00820 }; 00821 00831 template <typename FunctionObject> 00832 class NullaryFunctionCopy<FunctionObject,void> : public NullaryFunction<void> 00833 { 00834 public: 00843 explicit NullaryFunctionCopy( const FunctionObject &f_o ) : function_object(f_o) { 00844 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>); 00845 } 00846 virtual ~NullaryFunctionCopy() {}; 00853 void operator()() { function_object(); } 00854 00855 private: 00856 FunctionObject function_object; 00857 }; 00858 00872 template <typename FunctionObject, typename Result = void> 00873 class NullaryFunctionReference : public NullaryFunction<Result> 00874 { 00875 public: 00883 explicit NullaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) { 00884 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>); 00885 } 00886 virtual ~NullaryFunctionReference() {}; 00895 Result operator()() { return function_object(); } 00896 00897 private: 00898 FunctionObject &function_object; 00899 }; 00900 00912 template <typename FunctionObject> 00913 class NullaryFunctionReference< FunctionObject, void > : public NullaryFunction<void> 00914 { 00915 public: 00923 explicit NullaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) { 00924 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>); 00925 } 00926 virtual ~NullaryFunctionReference() {}; 00933 void operator()() { function_object(); } 00934 00935 private: 00936 FunctionObject &function_object; 00937 }; 00938 00953 template <typename FunctionObject, typename T, typename Result = void> 00954 class UnaryFunctionCopy : public UnaryFunction<T, Result> 00955 { 00956 public: 00965 UnaryFunctionCopy(const FunctionObject &f_o ) : function_object(f_o) { 00966 // ecl_compile_time_concept_check(UnaryFunction<FunctionObject>); 00967 } 00968 virtual ~UnaryFunctionCopy() {}; 00977 Result operator()(T t) { return function_object(t); } 00978 00979 private: 00980 FunctionObject function_object; 00981 }; 00982 00992 template <typename FunctionObject, typename T> 00993 class UnaryFunctionCopy<FunctionObject,T,void> : public UnaryFunction<T, void> 00994 { 00995 public: 01004 explicit UnaryFunctionCopy( const FunctionObject &f_o ) : function_object(f_o) { 01005 // ecl_compile_time_concept_check(UnaryFunction<FunctionObject>); 01006 } 01007 virtual ~UnaryFunctionCopy() {}; 01014 void operator()(T t) { function_object(t); } 01015 01016 private: 01017 FunctionObject function_object; 01018 }; 01019 01033 template <typename FunctionObject, typename T, typename Result = void> 01034 class UnaryFunctionReference : public UnaryFunction<T, Result> 01035 { 01036 public: 01044 explicit UnaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) { 01045 // ecl_compile_time_concept_check(UnaryFunction<FunctionObject>); 01046 } 01047 01048 virtual ~UnaryFunctionReference() {}; 01056 Result operator()(T t) { return function_object(t); } 01057 01058 private: 01059 FunctionObject &function_object; 01060 }; 01061 01073 template <typename ReferenceWrapper, typename T> 01074 class UnaryFunctionReference< ReferenceWrapper, T, void > : public UnaryFunction<T,void> 01075 { 01076 public: 01077 typedef typename ReferenceWrapper::type FunctionObject; 01085 explicit UnaryFunctionReference( const ReferenceWrapper &wrapper ) : function_object(wrapper.reference()) { 01086 // ecl_compile_time_concept_check(UnaryFunction<FunctionObject>); 01087 } 01088 virtual ~UnaryFunctionReference() {}; 01095 void operator()(T t) { function_object(t); } 01096 01097 private: 01098 FunctionObject &function_object; 01099 }; 01100 01101 /***************************************************************************** 01102 ** Nullary Function Generators 01103 *****************************************************************************/ 01104 01117 template <typename R> 01118 NullaryFreeFunction<R> generateFunctionObject( R (*function)() ) { 01119 return NullaryFreeFunction<R>( function ); 01120 } 01121 01135 template <typename A, typename R> 01136 UnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A) ) { 01137 return UnaryFreeFunction<A,R>( function ); 01138 } 01139 01155 template <typename A, typename R, typename I> 01156 BoundUnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A), I& a ) { 01157 return BoundUnaryFreeFunction<A,R>( function, a ); 01158 } 01159 01176 template <typename A, typename R, typename I> 01177 BoundUnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A), const I& a ) { 01178 return BoundUnaryFreeFunction<A,R>( function, a ); 01179 } 01180 01194 template <typename C, typename R> 01195 NullaryMemberFunction<C,R> generateFunctionObject( R (C::*function)() ) { 01196 return NullaryMemberFunction<C,R>( function ); 01197 } 01198 01213 template <typename C, typename R> 01214 BoundNullaryMemberFunction<C,R> generateFunctionObject( R (C::*function)(), C &c ) { 01215 return BoundNullaryMemberFunction<C,R>( function, c ); 01216 } 01217 01232 template <typename C, typename A, typename R> 01233 UnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A) ) { 01234 return UnaryMemberFunction<C,A,R>( function ); 01235 } 01236 01254 template <typename C, typename A, typename R> 01255 PartiallyBoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c) { 01256 return PartiallyBoundUnaryMemberFunction<C,A,R>( function, c); 01257 } 01258 01276 template <typename C, typename A, typename R, typename I> 01277 BoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c, I& a ) { 01278 // The I here is a bit of a trick...if you use A in the constructor above instead of I 01279 // then it gets confused trying to deduce A as often the function arg and the input value 01280 // are different types (e.g. const int& as opposed to int). So fix A in the template 01281 // direction first, then pass it a type I which can be converted on the fly where needed. 01282 return BoundUnaryMemberFunction<C,A,R>( function, c, a ); 01283 } 01284 01303 template <typename C, typename A, typename R, typename I> 01304 BoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c, const I& a ) { 01305 // This one differs from the previous due to the const reference - this allows things like 01306 // temporaries to pass through unscathed to a function with an argument like const int&. 01307 return BoundUnaryMemberFunction<C,A,R>( function, c, a ); 01308 } 01309 01310 }; // namespace ecl 01311 01312 #endif /* ECL_UTILITIES_FUNCTION_OBJECTS_HPP_ */