function_objects.hpp
Go to the documentation of this file.
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 
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 ** Function Object Wrappers
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 //              ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
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 //              ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
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 //              ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
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 //              ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
01149         }
01150         virtual ~UnaryFunctionReference() {}; 
01157         void operator()(T t) { function_object(t); }
01158 
01159 private:
01160         FunctionObject &function_object;
01161 };
01162 
01163 /*****************************************************************************
01164 ** Nullary Function Generators
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         // The I here is a bit of a trick...if you use A in the constructor above instead of I
01341         // then it gets confused trying to deduce A as often the function arg and the input value
01342         // are different types (e.g. const int& as opposed to int). So fix A in the template
01343         // direction first, then pass it a type I which can be converted on the fly where needed.
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         // This one differs from the previous due to the const reference - this allows things like
01368         // temporaries to pass through unscathed to a function with an argument like const int&.
01369         return BoundUnaryMemberFunction<C,A,R>( function, c, a );
01370 }
01371 
01372 }; // namespace ecl
01373 
01374 #endif /* ECL_UTILITIES_FUNCTION_OBJECTS_HPP_ */


ecl_utilities
Author(s): Daniel Stonier
autogenerated on Mon Jul 3 2017 02:21:39