Program Listing for File function_objects.hpp
↰ Return to documentation for file (/tmp/ws/src/ecl_core/ecl_utilities/include/ecl/utilities/function_objects.hpp
)
/*****************************************************************************
** Ifdefs
*****************************************************************************/
#ifndef ECL_UTILITIES_FUNCTION_OBJECTS_HPP_
#define ECL_UTILITIES_FUNCTION_OBJECTS_HPP_
/*****************************************************************************
** Includes
*****************************************************************************/
#include <ecl/concepts/nullary_function.hpp>
#include "../utilities/references.hpp"
/*****************************************************************************
** Namespaces
*****************************************************************************/
namespace ecl {
/*****************************************************************************
** Using
*****************************************************************************/
/*****************************************************************************
** Interface [NullaryFunction]
*****************************************************************************/
template <typename R = void>
class NullaryFunction {
public:
typedef R result_type;
virtual result_type operator()() = 0;
virtual ~NullaryFunction() {};
};
/*****************************************************************************
** Interface [UnaryFunction]
*****************************************************************************/
template <typename A, typename R = void>
class UnaryFunction {
public:
typedef R result_type;
typedef A argument_type;
virtual result_type operator()(argument_type arg) = 0;
virtual ~UnaryFunction() {};
};
/*****************************************************************************
** Interface [BinaryFunction]
*****************************************************************************/
template <typename A1, typename A2, typename R = void>
class BinaryFunction {
public:
typedef R result_type;
typedef A1 first_argument_type;
typedef A2 second_argument_type;
virtual result_type operator()(first_argument_type arg1, second_argument_type arg2) = 0;
virtual ~BinaryFunction() {};
};
/*****************************************************************************
** Interface [FreeFunctions]
*****************************************************************************/
template <typename R = void>
class NullaryFreeFunction : public NullaryFunction<R>
{
public:
NullaryFreeFunction( R (*function)() ) : free_function(function) {}
virtual ~NullaryFreeFunction() {};
R operator()() { return free_function(); }
private:
R (*free_function)();
};
template <>
class NullaryFreeFunction<void> : public NullaryFunction<void>
{
public:
NullaryFreeFunction( void (*function)() ) : free_function(function) {}
virtual ~NullaryFreeFunction() {};
void operator()() { free_function(); }
private:
void (*free_function)();
};
template <typename A, typename R = void>
class UnaryFreeFunction : public UnaryFunction<A,R>
{
public:
UnaryFreeFunction( R (*function)(A) ) : free_function(function) {}
virtual ~UnaryFreeFunction() {};
R operator()(A a) { return free_function(a); }
private:
R (*free_function)(A);
};
template <typename A>
class UnaryFreeFunction<A,void> : public UnaryFunction<A,void>
{
public:
UnaryFreeFunction( void (*function)(A) ) : free_function(function) {}
virtual ~UnaryFreeFunction() {};
void operator()(A a) { free_function(a); }
private:
void (*free_function)(A);
};
/*****************************************************************************
** Interface [BoundFreeFunctions]
*****************************************************************************/
template <typename A, typename R = void>
class BoundUnaryFreeFunction : public NullaryFunction<R>
{
public:
BoundUnaryFreeFunction( R (*function)(A), A a ) : free_function(function), argument(a) {}
virtual ~BoundUnaryFreeFunction() {};
R operator()() { return free_function(argument); }
private:
R (*free_function)(A);
A argument;
};
template <typename A>
class BoundUnaryFreeFunction<A,void> : public NullaryFunction<void>
{
public:
BoundUnaryFreeFunction( void (*function)(A), A a ) : free_function(function), argument(a) {}
virtual ~BoundUnaryFreeFunction() {};
void operator()() { free_function(argument); }
private:
void (*free_function)(A);
A argument;
};
/*****************************************************************************
* Interface [MemberFunctions]
*****************************************************************************
* Could make copies+refs here, just like mem_fun and mem_fun_ref but I can't
* see the need for copy style setups.
****************************************************************************/
template <typename C, typename R = void>
class NullaryMemberFunction : public UnaryFunction<C&,R> {
public:
NullaryMemberFunction( R (C::*function)()) : member_function(function) {}
virtual ~NullaryMemberFunction() {};
R operator()(C &class_object) {
return (class_object.*member_function)();
}
private:
R (C::*member_function)();
};
template <typename C>
class NullaryMemberFunction<C,void> : public UnaryFunction<C&,void> {
public:
NullaryMemberFunction( void (C::*function)()) : member_function(function) {}
virtual ~NullaryMemberFunction() {};
void operator()(C &class_object) {
(class_object.*member_function)();
}
private:
void (C::*member_function)();
};
template <typename C, typename A, typename R = void>
class UnaryMemberFunction : public BinaryFunction<C&,A,R> {
public:
UnaryMemberFunction( R (C::*function)(A)) : member_function(function) {}
virtual ~UnaryMemberFunction() {};
R operator()(C &class_object, A a) {
return (class_object.*member_function)(a);
}
private:
R (C::*member_function)(A);
};
template <typename C, typename A>
class UnaryMemberFunction<C,A,void> : public BinaryFunction<C&,A,void> {
public:
UnaryMemberFunction( void (C::*function)(A)) : member_function(function) {}
virtual ~UnaryMemberFunction() {};
void operator()(C &class_object, A a) {
(class_object.*member_function)(a);
}
private:
void (C::*member_function)(A);
};
/*****************************************************************************
** Interface [BoundMemberFunctions]
*****************************************************************************/
template <typename C, typename R = void>
class BoundNullaryMemberFunction : public NullaryFunction<R> {
public:
BoundNullaryMemberFunction( R (C::*function)(), C &class_object) :
member_class(class_object),
member_function(function)
{}
virtual ~BoundNullaryMemberFunction() {};
R operator()() { return (member_class.*member_function)(); }
private:
C &member_class;
R (C::*member_function)();
};
template <typename C>
class BoundNullaryMemberFunction<C,void> : public NullaryFunction<void> {
public:
BoundNullaryMemberFunction( void (C::*function)(), C &class_object) :
member_class(class_object),
member_function(function)
{}
virtual ~BoundNullaryMemberFunction() {};
void operator()() { (member_class.*member_function)(); }
private:
C &member_class;
void (C::*member_function)();
};
template <typename C, typename A, typename R = void>
class PartiallyBoundUnaryMemberFunction : public UnaryFunction<A,R> {
public:
PartiallyBoundUnaryMemberFunction( R (C::*function)(A), C &class_object) :
member_class(class_object),
member_function(function)
{}
virtual ~PartiallyBoundUnaryMemberFunction() {};
R operator()(A a) {
return (member_class.*member_function)(a);
}
private:
C &member_class;
void (C::*member_function)(A);
};
template <typename C, typename A, typename R = void>
class BoundUnaryMemberFunction : public NullaryFunction<R> {
public:
BoundUnaryMemberFunction( R (C::*function)(A), C &class_object, A a) :
member_class(class_object),
member_function(function),
argument(a)
{}
virtual ~BoundUnaryMemberFunction() {};
R operator()() {
return (member_class.*member_function)(argument);
}
private:
C &member_class;
void (C::*member_function)(A);
A argument;
};
template <typename C, typename A, typename B, typename R = void>
class PartiallyBoundBinaryMemberFunction : public BinaryFunction<A,B,R> {
public:
PartiallyBoundBinaryMemberFunction( R (C::*function)(A, B), C &class_object) :
member_class(class_object),
member_function(function)
{}
virtual ~PartiallyBoundBinaryMemberFunction() {};
R operator()(A a, B b) {
return (member_class.*member_function)(a, b);
}
private:
C &member_class;
void (C::*member_function)(A, B);
};
/*****************************************************************************
** Function Object Wrappers
*****************************************************************************/
template <typename FunctionObject, typename Result = void>
class NullaryFunctionCopy : public NullaryFunction<Result>
{
public:
NullaryFunctionCopy(const FunctionObject &f_o ) : function_object(f_o) {
ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
}
virtual ~NullaryFunctionCopy() {};
Result operator()() { return function_object(); }
private:
FunctionObject function_object;
};
template <typename FunctionObject>
class NullaryFunctionCopy<FunctionObject,void> : public NullaryFunction<void>
{
public:
explicit NullaryFunctionCopy( const FunctionObject &f_o ) : function_object(f_o) {
ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
}
virtual ~NullaryFunctionCopy() {};
void operator()() { function_object(); }
private:
FunctionObject function_object;
};
template <typename FunctionObject, typename Result = void>
class NullaryFunctionReference : public NullaryFunction<Result>
{
public:
explicit NullaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) {
ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
}
virtual ~NullaryFunctionReference() {};
Result operator()() { return function_object(); }
private:
FunctionObject &function_object;
};
template <typename FunctionObject>
class NullaryFunctionReference< FunctionObject, void > : public NullaryFunction<void>
{
public:
explicit NullaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) {
ecl_compile_time_concept_check(NullaryFunction<FunctionObject>);
}
virtual ~NullaryFunctionReference() {};
void operator()() { function_object(); }
private:
FunctionObject &function_object;
};
template <typename FunctionObject, typename T, typename Result = void>
class UnaryFunctionCopy : public UnaryFunction<T, Result>
{
public:
UnaryFunctionCopy(const FunctionObject &f_o ) : function_object(f_o) {
// ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
}
virtual ~UnaryFunctionCopy() {};
Result operator()(T t) { return function_object(t); }
private:
FunctionObject function_object;
};
template <typename FunctionObject, typename T>
class UnaryFunctionCopy<FunctionObject,T,void> : public UnaryFunction<T, void>
{
public:
explicit UnaryFunctionCopy( const FunctionObject &f_o ) : function_object(f_o) {
// ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
}
virtual ~UnaryFunctionCopy() {};
void operator()(T t) { function_object(t); }
private:
FunctionObject function_object;
};
template <typename FunctionObject, typename T, typename Result = void>
class UnaryFunctionReference : public UnaryFunction<T, Result>
{
public:
explicit UnaryFunctionReference( const ReferenceWrapper<FunctionObject> &wrapper ) : function_object(wrapper.reference()) {
// ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
}
virtual ~UnaryFunctionReference() {};
Result operator()(T t) { return function_object(t); }
private:
FunctionObject &function_object;
};
template <typename ReferenceWrapper, typename T>
class UnaryFunctionReference< ReferenceWrapper, T, void > : public UnaryFunction<T,void>
{
public:
typedef typename ReferenceWrapper::type FunctionObject;
explicit UnaryFunctionReference( const ReferenceWrapper &wrapper ) : function_object(wrapper.reference()) {
// ecl_compile_time_concept_check(UnaryFunction<FunctionObject>);
}
virtual ~UnaryFunctionReference() {};
void operator()(T t) { function_object(t); }
private:
FunctionObject &function_object;
};
/*****************************************************************************
** Nullary Function Generators
*****************************************************************************/
template <typename R>
NullaryFreeFunction<R> generateFunctionObject( R (*function)() ) {
return NullaryFreeFunction<R>( function );
}
template <typename A, typename R>
UnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A) ) {
return UnaryFreeFunction<A,R>( function );
}
template <typename A, typename R, typename I>
BoundUnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A), I& a ) {
return BoundUnaryFreeFunction<A,R>( function, a );
}
template <typename A, typename R, typename I>
BoundUnaryFreeFunction<A,R> generateFunctionObject( R (*function)(A), const I& a ) {
return BoundUnaryFreeFunction<A,R>( function, a );
}
template <typename C, typename R>
NullaryMemberFunction<C,R> generateFunctionObject( R (C::*function)() ) {
return NullaryMemberFunction<C,R>( function );
}
template <typename C, typename R>
BoundNullaryMemberFunction<C,R> generateFunctionObject( R (C::*function)(), C &c ) {
return BoundNullaryMemberFunction<C,R>( function, c );
}
template <typename C, typename A, typename R>
UnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A) ) {
return UnaryMemberFunction<C,A,R>( function );
}
template <typename C, typename A, typename R>
PartiallyBoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c) {
return PartiallyBoundUnaryMemberFunction<C,A,R>( function, c);
}
template <typename C, typename A, typename R, typename I>
BoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c, I& a ) {
// The I here is a bit of a trick...if you use A in the constructor above instead of I
// then it gets confused trying to deduce A as often the function arg and the input value
// are different types (e.g. const int& as opposed to int). So fix A in the template
// direction first, then pass it a type I which can be converted on the fly where needed.
return BoundUnaryMemberFunction<C,A,R>( function, c, a );
}
template <typename C, typename A, typename R, typename I>
BoundUnaryMemberFunction<C,A,R> generateFunctionObject( R (C::*function)(A), C& c, const I& a ) {
// This one differs from the previous due to the const reference - this allows things like
// temporaries to pass through unscathed to a function with an argument like const int&.
return BoundUnaryMemberFunction<C,A,R>( function, c, a );
}
} // namespace ecl
#endif /* ECL_UTILITIES_FUNCTION_OBJECTS_HPP_ */