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
00806 template <typename C, typename A, typename B, typename R = void>
00807 class PartiallyBoundBinaryMemberFunction : public BinaryFunction<A,B,R> {
00808 public:
00817 PartiallyBoundBinaryMemberFunction( R (C::*function)(A, B), C &class_object) :
00818 member_class(class_object),
00819 member_function(function)
00820 {}
00821 virtual ~PartiallyBoundBinaryMemberFunction() {};
00831 R operator()(A a, B b) {
00832 return (member_class.*member_function)(a, b);
00833 }
00834 private:
00835 C &member_class;
00836 void (C::*member_function)(A, B);
00837 };
00838
00839
00840
00854 template <typename FunctionObject, typename Result = void>
00855 class NullaryFunctionCopy : public NullaryFunction<Result>
00856 {
00857 public:
00866 NullaryFunctionCopy(const FunctionObject &f_o ) : function_object(f_o) {
00867 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
00868 }
00869 virtual ~NullaryFunctionCopy() {};
00878 Result operator()() { return function_object(); }
00879
00880 private:
00881 FunctionObject function_object;
00882 };
00883
00893 template <typename FunctionObject>
00894 class NullaryFunctionCopy<FunctionObject,void> : public NullaryFunction<void>
00895 {
00896 public:
00905 explicit NullaryFunctionCopy( const FunctionObject &f_o ) : function_object(f_o) {
00906 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
00907 }
00908 virtual ~NullaryFunctionCopy() {};
00915 void operator()() { function_object(); }
00916
00917 private:
00918 FunctionObject function_object;
00919 };
00920
00934 template <typename FunctionObject, typename Result = void>
00935 class NullaryFunctionReference : public NullaryFunction<Result>
00936 {
00937 public:
00945 explicit NullaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) {
00946 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
00947 }
00948 virtual ~NullaryFunctionReference() {};
00957 Result operator()() { return function_object(); }
00958
00959 private:
00960 FunctionObject &function_object;
00961 };
00962
00974 template <typename FunctionObject>
00975 class NullaryFunctionReference< FunctionObject, void > : public NullaryFunction<void>
00976 {
00977 public:
00985 explicit NullaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) {
00986 ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
00987 }
00988 virtual ~NullaryFunctionReference() {};
00995 void operator()() { function_object(); }
00996
00997 private:
00998 FunctionObject &function_object;
00999 };
01000
01015 template <typename FunctionObject, typename T, typename Result = void>
01016 class UnaryFunctionCopy : public UnaryFunction<T, Result>
01017 {
01018 public:
01027 UnaryFunctionCopy(const FunctionObject &f_o ) : function_object(f_o) {
01028
01029 }
01030 virtual ~UnaryFunctionCopy() {};
01039 Result operator()(T t) { return function_object(t); }
01040
01041 private:
01042 FunctionObject function_object;
01043 };
01044
01054 template <typename FunctionObject, typename T>
01055 class UnaryFunctionCopy<FunctionObject,T,void> : public UnaryFunction<T, void>
01056 {
01057 public:
01066 explicit UnaryFunctionCopy( const FunctionObject &f_o ) : function_object(f_o) {
01067
01068 }
01069 virtual ~UnaryFunctionCopy() {};
01076 void operator()(T t) { function_object(t); }
01077
01078 private:
01079 FunctionObject function_object;
01080 };
01081
01095 template <typename FunctionObject, typename T, typename Result = void>
01096 class UnaryFunctionReference : public UnaryFunction<T, Result>
01097 {
01098 public:
01106 explicit UnaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) {
01107
01108 }
01109
01110 virtual ~UnaryFunctionReference() {};
01118 Result operator()(T t) { return function_object(t); }
01119
01120 private:
01121 FunctionObject &function_object;
01122 };
01123
01135 template <typename ReferenceWrapper, typename T>
01136 class UnaryFunctionReference< ReferenceWrapper, T, void > : public UnaryFunction<T,void>
01137 {
01138 public:
01139 typedef typename ReferenceWrapper::type FunctionObject;
01147 explicit UnaryFunctionReference( const ReferenceWrapper &wrapper ) : function_object(wrapper.reference()) {
01148
01149 }
01150 virtual ~UnaryFunctionReference() {};
01157 void operator()(T t) { function_object(t); }
01158
01159 private:
01160 FunctionObject &function_object;
01161 };
01162
01163
01164
01165
01166
01179 template <typename R>
01180 NullaryFreeFunction<R> generateFunctionObject( R (*function)() ) {
01181 return NullaryFreeFunction<R>( function );
01182 }
01183
01197 template <typename A, typename R>
01198 UnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A) ) {
01199 return UnaryFreeFunction<A,R>( function );
01200 }
01201
01217 template <typename A, typename R, typename I>
01218 BoundUnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A), I& a ) {
01219 return BoundUnaryFreeFunction<A,R>( function, a );
01220 }
01221
01238 template <typename A, typename R, typename I>
01239 BoundUnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A), const I& a ) {
01240 return BoundUnaryFreeFunction<A,R>( function, a );
01241 }
01242
01256 template <typename C, typename R>
01257 NullaryMemberFunction<C,R> generateFunctionObject( R (C::*function)() ) {
01258 return NullaryMemberFunction<C,R>( function );
01259 }
01260
01275 template <typename C, typename R>
01276 BoundNullaryMemberFunction<C,R> generateFunctionObject( R (C::*function)(), C &c ) {
01277 return BoundNullaryMemberFunction<C,R>( function, c );
01278 }
01279
01294 template <typename C, typename A, typename R>
01295 UnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A) ) {
01296 return UnaryMemberFunction<C,A,R>( function );
01297 }
01298
01316 template <typename C, typename A, typename R>
01317 PartiallyBoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c) {
01318 return PartiallyBoundUnaryMemberFunction<C,A,R>( function, c);
01319 }
01320
01338 template <typename C, typename A, typename R, typename I>
01339 BoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c, I& a ) {
01340
01341
01342
01343
01344 return BoundUnaryMemberFunction<C,A,R>( function, c, a );
01345 }
01346
01365 template <typename C, typename A, typename R, typename I>
01366 BoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c, const I& a ) {
01367
01368
01369 return BoundUnaryMemberFunction<C,A,R>( function, c, a );
01370 }
01371
01372 };
01373
01374 #endif