// Invocation of pointers which supply the parameter type. Full invocation // with paramters is posesible in this fashion with out knowing the class // that the functor refers to. void testGlobalReturnParams() { ArGlobalRetFunctor<bool> functor(retFunction); ArGlobalRetFunctor1<char*, int> functor1(retFunction, 1); ArGlobalRetFunctor2<double, bool, std::string> functor2(retFunction, false, "default arg"); ArRetFunctor<bool> *fBoolPtr; ArRetFunctor1<char*, int> *fCharPtr; ArRetFunctor2<double, bool, std::string> *fDoublePtr; bool bret; char *cret; double dret; printf("\n****** Testing global pointer invocation with return\n"); fBoolPtr=&functor; puts("> bool retFunction() should return true..."); bret=fBoolPtr->invokeR(); printf("Returned: %d\n", bret); fCharPtr=&functor1; puts("> char* retFunction(7) should return \"Hello\"..."); cret=fCharPtr->invokeR(7); printf("Returned: %s\n", cret); fDoublePtr=&functor2; puts("> double retFunction(false, \"argument 3\") should return 4.62..."); dret=fDoublePtr->invokeR(false, "argument 3"); printf("Returned: %e\n", dret); }
void testReturnParams() { TestClass test; ArRetFunctorC<bool, TestClass> functor(test, &TestClass::retFunction); ArRetFunctor1C<char*, TestClass, int> functor1(test, &TestClass::retFunction, 1); ArRetFunctor2C<double, TestClass, bool, std::string> functor2(test, &TestClass::retFunction, false, "default arg"); ArRetFunctor<bool> *fBoolPtr; ArRetFunctor1<char*, int> *fCharPtr; ArRetFunctor2<double, bool, std::string> *fDoublePtr; bool bret; char *cret; double dret; printf("\n****** Testing pointer invocation with return\n"); fBoolPtr=&functor; puts("> TestClass::retFunction() should return true"); bret=fBoolPtr->invokeR(); printf("Returned: %d\n", bret); fCharPtr=&functor1; puts("> TestClass::retFunction(7) should return \"Hello\""); cret=fCharPtr->invokeR(7); printf("Returned: %s\n", cret); fDoublePtr=&functor2; puts("> TestClass::retFunction(false, \"argument 3\") should return 4.62..."); dret=fDoublePtr->invokeR(false, "argument 3"); printf("Returned: %e\n", dret); }
// Direct invocation of the functors with return values and supplying // parameters. It is not posesible to have the operator() for functors with // return values. This is due to limitations of C++ and different C++ // compilers where you can not overload return values in all cases. void testReturnDirect() { TestClass test; ArRetFunctorC<bool, TestClass> functor(test, &TestClass::retFunction); ArRetFunctor1C<char*, TestClass, int> functor1(test, &TestClass::retFunction, 1); ArRetFunctor2C<double, TestClass, bool, std::string> functor2(test, &TestClass::retFunction, false, "default arg"); bool bret; char *cret; double dret; //bret=test.retFunction(); //cret=test.retFunction(4); //dret=test.retFunction(true, "foof"); printf("\n****** Testing direct invocation with return\n"); puts("> TestClass::retFunction() should return true..."); bret=functor.invokeR(); printf("Returned: %d\n", bret); puts("> TestClass::retFunction(5) should return \"Hello\"..."); cret=functor1.invokeR(5); printf("Returned: %s\n", cret); puts("> TestClass::retFunction(true, \"argument 1\") should return 4.62..."); dret=functor2.invokeR(true, "argument 1"); printf("Returned: %e\n", dret); }
// Direct invocation of the global functors with supplying parameters. void testGlobalDirect() { ArGlobalFunctor functor(&function); ArGlobalFunctor1<int> functor1(&function, 1); ArGlobalFunctor2<bool, std::string> functor2(&function, false, "default arg"); printf("\n****** Testing global direct invocation\n"); puts("> Should see function()..."); functor.invoke(); puts("> Should see function(5)..."); functor1.invoke(5); puts("> Should see function(true, \"argument 1\")..."); functor2.invoke(true, "argument 1"); }
// Invocation of a base ArFunctor pointer to a global functor. Because the // pointer is of type ArFunctor, the parameters can not be supplied. The // default parameters, which are supplied when the functor is constructed, // are used. void testGlobalBase() { ArFunctor *fptr; ArGlobalFunctor functor(function); ArGlobalFunctor1<int> functor1(function, 1); ArGlobalFunctor2<bool, std::string> functor2(function, false, "default arg"); printf("\n****** Testing global base invocation\n"); fptr=&functor; puts("> Should see function()..."); fptr->invoke(); fptr=&functor1; puts("> Should see function(1)..."); fptr->invoke(); fptr=&functor2; puts("> Should see function(false, \"default arg\")..."); fptr->invoke(); }
// Direct invocation of the functors with supplying parameters. void testDirect() { TestClass test; ArFunctorC<TestClass> functor(test, &TestClass::function); ArFunctor1C<TestClass, int> functor1(test, &TestClass::function, 1); ArFunctor2C<TestClass, bool, std::string> functor2(test, &TestClass::function, false, "default arg"); printf("\n****** Testing direct invocation using ArFunctor::invoke(...)\n"); puts("> Should see TestClass::function()..."); functor.invoke(); puts("> Should see TestClass::function(1)..."); functor1.invoke(); puts("> Should see TestClass::function(5)..."); functor1.invoke(5); puts("> Should see TestClass::function(true, \"argument 1\")..."); functor2.invoke(true, "argument 1"); }
// Direct invocation of the global functors with supplying parameters. void testGlobalReturnDirect() { ArGlobalRetFunctor<bool> functor(&retFunction); ArGlobalRetFunctor1<char*, int> functor1(&retFunction, 1); ArGlobalRetFunctor2<double, bool, std::string> functor2(&retFunction, false, "default arg"); bool bret; char *cret; double dret; printf("\n****** Testing global direct invocation with return\n"); puts("> bool retFunction() should return true..."); bret=functor.invokeR(); printf("Returned: %d\n", bret); puts("> char* retFunction(5) should return \"Hello\"..."); cret=functor1.invokeR(5); printf("Returned: %s\n", cret); puts("> double retFunction(true, \"argument 1\") should return 4.62..."); dret=functor2.invokeR(true, "argument 1"); printf("Returned: %e\n", dret); }
// Invocation of pointers which supply the parameter type. Full invocation // with paramters is posesible in this fashion with out knowing the class // that the functor refers to. void testGlobalParams() { ArGlobalFunctor functor(function); ArGlobalFunctor1<int> functor1(function, 1); ArGlobalFunctor2<bool, std::string> functor2(function, false, "default arg"); ArFunctor *fptr; ArFunctor1<int> *fptr1; ArFunctor2<bool, std::string> *fptr2; printf("\n****** Testing global pointer invocation\n"); fptr=&functor; puts("> Should see function()..."); fptr->invoke(); fptr1=&functor1; puts("> Should see function(2)..."); fptr1->invoke(2); fptr2=&functor2; puts("> Should see function(true, \"argument 2\")..."); fptr2->invoke(true, "argument 2"); }
// Invocation of a base ArFunctor pointer to a functor. Because the pointer // is of type ArFunctor, the parameters can not be supplied. The default // parameters, which are supplied when the functor is constructed, are used. void testBase() { TestClass test; ArFunctor *fptr; ArFunctorC<TestClass> functor(test, &TestClass::function); ArFunctor1C<TestClass, int> functor1(test, &TestClass::function, 1); ArFunctor2C<TestClass, bool, std::string> functor2(test, &TestClass::function, false, "default arg"); printf("\n****** Testing base invocation\n"); fptr=&functor; puts("> Should see TestClass::function()..."); fptr->invoke(); fptr=&functor1; puts("> Should see TestClass::function(1)..."); fptr->invoke(); fptr=&functor2; puts("> Should see TestClass::function(false, \"default arg\")..."); fptr->invoke(); }
int main() { CallbackClass cb; // For functors with no arguments: std::list<ArFunctor*> functors; ArFunctorC<CallbackClass> functor1(cb, &CallbackClass::callback1); functors.push_back(&functor1); functors.push_back(&functor1); functors.push_back(&functor1); std::for_each(functors.begin(), functors.end(), std::mem_fun(&ArFunctor::invoke)); // For functors with arguments, give mem_fun template parameters. std::list<ArFunctor1<int>*> functorsWithArg; ArFunctor1C<CallbackClass, int> functor2(cb, &CallbackClass::callback2); std::mem_fun1_t<void, ArFunctor1<int>, int> f(&ArFunctor1<int>::invoke); functorsWithArg.push_back(&functor2); functorsWithArg.push_back(&functor2); functorsWithArg.push_back(&functor2); std::for_each(functorsWithArg.begin(), functorsWithArg.end(), std::bind2nd(f, 42)); // You can use other STL algorithms if your functor returns something. // count_if will invoke each functor, and return the number of functor // invocations that returned true (in this case, 3, since they will // always return true) std::list<ArRetFunctor1<bool, const char*>*> functorsWithRet; ArRetFunctor1C<bool, CallbackClass, const char *> functor3(cb, &CallbackClass::callback3); std::mem_fun1_t<bool, ArRetFunctor1<bool, const char*>, const char*> rf(&ArRetFunctor1<bool, const char*>::invokeR); functorsWithRet.push_back(&functor3); functorsWithRet.push_back(&functor3); functorsWithRet.push_back(&functor3); int c = std::count_if(functorsWithRet.begin(), functorsWithRet.end(), std::bind2nd(rf, "testing")); std::cout << "Count=" << c << std::endl; return(0); }
// Invocation of pointers which supply the parameter type. Full invocation // with paramters is posesible in this fashion with out knowing the class // that the functor refers to. void testParams() { TestClass test; ArFunctorC<TestClass> functor(test, &TestClass::function); ArFunctor1C<TestClass, int> functor1(test, &TestClass::function); ArFunctor2C<TestClass, bool, std::string> functor2(test, &TestClass::function); ArFunctor *fptr; ArFunctor1<int> *fptr1; ArFunctor2<bool, std::string> *fptr2; printf("\n****** Testing pointer invocation\n"); fptr=&functor; puts("> Should see TestClass::function()..."); fptr->invoke(); fptr1=&functor1; puts("> Should see TestClass::function(2)..."); fptr1->invoke(2); fptr2=&functor2; puts("> Should see TestClass::function(true, \"argument 2\")..."); fptr2->invoke(true, "argument 2"); }
int main() { CallbackContainer cb; DriverClass driver; ArFunctorC<CallbackContainer> functor1(cb, &CallbackContainer::callback1); ArFunctor1C<CallbackContainer, int> functor2(cb, &CallbackContainer::callback2); ArRetFunctor1C<bool, CallbackContainer, const char *> functor3(cb, &CallbackContainer::callback3); driver.setCallback1(&functor1); driver.setCallback2(&functor2); driver.setCallback3(&functor3); driver.invokeFunctors(); /* You can make functors that target global functions too. */ ArGlobalFunctor globalFunctor(&globalCallback); printf("Invoking globalFunctor... "); globalFunctor.invoke(); /* You can also include the values of arguments in an ArFunctor object, if you * want to use the same value in every invocation of the functor. */ ArFunctor1C<CallbackContainer, int> functor4(cb, &CallbackContainer::callback2, 42); printf("Invoking functor with constant argument... "); functor4.invoke(); /* Functors can be downcast to parent interface classes, as long as their invocation * does not require arguments. */ ArFunctor* baseFunctor = &functor4; printf("Invoking downcast functor... "); baseFunctor->invoke(); return(0); }