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 /*****************************************************************************
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_ */


ecl_utilities
Author(s): Daniel Stonier
autogenerated on Sun Oct 5 2014 23:35:35