## Introduction

Functors (function objects) play an important role in the Standard Template Library (STL). I have created several functors and supporting functions to manipulate functors such that new functors which are slightly modified from existing functors can easily be produced without rewriting the existing functors. This is in line with the principle of code reuse.

## Limitations

The following functors use partial specialization of template classes. Thus it cannot be compiled using Visual C++ since it does not support partial specialization. Anyone is welcome to port the code to Visual C++. You just need to change all the functors' name so that they will be unique, e.g. `FunctionToFunctor1Arg`

, `FunctionToFunctor2Arg`

, etc.

## Conversion to functors

To manipulate functors, you must have functors in the first place. However a lot of useful code in legacy libraries are not functors. They are mostly functions. Some may be member functions. Even if there are functors, they may not be STL compliant (i.e. they do not `typedef`

their return type and arguments). It is not always possible to convert these to STL compliant functors as the source code may not be available or it is very tedious to do manually.

To enable ease of converting these functions to STL compliant functors, four functors with partial specialization are created. In addition, an overloaded supporting function is provided to ease the usage of these four functors. The functors are: `FunctionToFunctor`

, `MemberFunctionToFunctor`

, `ConstMemberFunctionToFunctor`

and `FunctorToFunctor`

. The supporting function is `to_functor`

. These functors are capable of converting functions, member functions or functors with up to ten arguments to the corresponding STL compliant functor. The number of arguments supporting is capped at ten because not a lot of functions have more than ten arguments.

### Usage

The usage for `FunctionToFunctor `

is `FunctionToFunctor<Arg1T,Arg2T,....,ArgNT,RetT>`

, where `Arg1T..ArgNT`

(`N`

<=10) is the type for the various arguments of the function and `RetT`

is the return type of the function. `FunctionToFunctor`

's constructor requires the function's name.

The usage for `MemberFunctionToFunctor`

is `MemberFunctionToFunctor`

`<ObjectT,Arg1T,Arg2T,....,ArgN,RetT>`

, where `ObjectT`

is the type for the object containing the member function, `Arg1T..ArgNT`

(`N`

<=10) is the type for the various arguments of the function and `RetT`

is the return type of the function. `MemberFunctionToFunctor`

's constructor requires an instance of the object and the member function's name.

The usage for `ConstMemberFunctionToFunctor`

is `ConstMemberFunctionToFunctor <ObjectT,Arg1T,Arg2T,....,ArgN,RetT>`

, where `ObjectT`

is the type for the object containing the member function, `Arg1T..ArgNT`

(`N`

<=10) is the type for the various arguments of the function and `RetT`

is the return type of the function. `ConstMemberFunctionToFunctor`

's constructor requires an instance of the object and the const member function's name.

The usage for `FunctorToFunctor`

is `FunctorToFunctor <FunctorT,Arg1T,Arg2T,....,ArgNT,RetT>`

, where `FunctorT`

is the type for the functor, `Arg1T..ArgNT`

(`N`

<=10) is the type for the various arguments of the function and `RetT`

is the return type of the function. `FunctorToFunctor`

's constructor requires an instance of the functor.

The usage for `to_functor`

is `to_functor(function_name)`

for a function, `to_functor(Object_instance, Object::function_name)`

for a member function and `to_functor<Arg1T,Arg2T,...., ArgNT,RetT>(functor_instance)`

for a functor.

### Example

int Square(int x) {return x*x;}
FunctionToFunctor<int,int> square(Square);
cout << square(3) << endl;
void Cube(const double& x, double& y) {y = x*x*x;}
FunctionToFunctor<const double&,double&,void> cube(Cube);
double z = 0.0;
cube(2,z);
cout << z << endl;
struct Test
{
bool IsPositive(double x) {return x > 0;}
bool IsEven(int x) const {return !(x%2);}
};
MemberFunctionToFunctor<Test,double,bool> isPos(Test(), Test::IsPositive);
cout << isPos(3.2) << endl;
ConstMemberFunctionToFunctor<Test,int,bool> isEven(Test(), Test::IsEven);
cout << isEven(4) << endl;
struct IsNegative
{
bool operator()(int x) {return x < 0;}
};
FunctorToFunctor<IsNegative,int,bool> isNeg(IsNegative());
cout << isNeg(-2) << endl;
cout << to_functor(Square)(2) << endl;
cout << to_functor(Test(), Test::IsPositive)(2.2) << endl;
cout << to_functor<int,bool>(IsNegative())(4) << endl;

## Alter results from a functor

Sometimes it is useful to be able to manipulate results from a functor. Let's say you want to create a functor which is similar to an existing functor except that its result is always 5 times larger. To accomplish this, `AlterFunctorResult `

was created.

### Usage

The usage for `AlterFunctorResult`

is `AlterFunctorResult<FunctorT,Arg1T,...ArgNT,RetT,BinaryOperationT>`

where `FunctorT`

, `ArgNT`

has the same definition as above and `BinaryOperationT`

is a functor which performs binary operations, taking in two inputs and outputs a single output. Examples are the STL `plus<>`

, `minus<>`

, `multiplies<>`

and `divides<>`

. `AlterFunctorResult`

's constructor requires an instance of the functor to be modified, the input to modify the output of the existing functor and an instance of the binary operation functor.

### Example

struct Cube
{
double operator()(double x) {return x*x;}
};
AlterFunctorResult<Cube,double,double,multiplies<double> >
cubeMultFive(Cube(), 5.0, multiplies<double>()); cout <<
cubeMultFive(3) << endl;

## Set arguments of functors with default values

The last set of functors perform the same operation as the functions `bind1st`

and `bind2nd`

of the STL library. That is, it allows an argument of a functor to have a default value. Thus when calling the functor, that argument can be left out. The limitation of the STL library is that it only supports functors with up to 2 arguments only. This set of functors is meant to complement the STL library by supporting functors with up to 10 arguments. By supporting up to 10 arguments, it also meant that the programmer can choose to bind from the first argument up to the tenth argument and not only the first two arguments.

### Usage

The general format of the set of functors is `BindFunctor???`

where `???`

is 1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th or 10th. All the ten set of functors have the same syntax. For example, to use `BindFunctor3rd`

on a functor with 4 arguments, you will use `BindFunctor3rd<FunctorT,Arg1T,Arg2T,Arg3T,Arg4T,RetT>`

and the constructor requires an instance of the functor and the default value for the 3rd argument.

### Example

struct BoxVolume
{
int operator()(int length, int breadth, int height)
{return length * breadth * height;}
};
BindFunctor2nd<BoxVolume,int,int,int,int> boxvol(BoxVolume(), 3);
cout << boxvol(2,5) << endl;
cout << boxvol(1,3) << endl;

## Summary

The usefulness of these sets of functors depends on the imagination of the programmer. I believe it will be useful for generic programming as it will enable legacy C functions to be converted to functors which can then be manipulated in several ways before feeding into another function. This allows new functions to be created without recoding the existing functions.

Do let me know of any bugs in the code so that I may correct them. It is no joke trying to examine the code for minor coding errors as the codes are rather repetitive and boring to examine properly. I am also keen to learn of any desired improvement to the code.