00001
00008
00009
00010
00011
00012 #ifndef ECL_UTILITIES_FUNCTION_OBJECTS_HPP_
00013 #define ECL_UTILITIES_FUNCTION_OBJECTS_HPP_
00014
00015
00016
00017
00018
00019 #include <ecl/concepts/nullary_function.hpp>
00020 #include "../utilities/references.hpp"
00021
00022
00023
00024
00025
00026 namespace ecl {
00027
00028
00029
00030
00031
00032
00033
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
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
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
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
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
00358
00359
00360
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
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
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
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
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
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
01087 }
01088 virtual ~UnaryFunctionReference() {};
01095 void operator()(T t) { function_object(t); }
01096
01097 private:
01098 FunctionObject &function_object;
01099 };
01100
01101
01102
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
01279
01280
01281
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
01306
01307 return BoundUnaryMemberFunction<C,A,R>( function, c, a );
01308 }
01309
01310 };
01311
01312 #endif