#include <FXGenericTools.h>
Inheritance diagram for FX::Generic::BoundFunctor< parslist >:
The source for this class is illustrative of the power of the compile-time metaprogramming facilities TnFOX provides - it was surprisingly easy to write, though I'm sure MSVC7.1's good compliance with the ISO C++ spec has made things a world easier. I had expected to be spending a week hacking away at it, not a day!
This class is used throughout TnFOX wherever a callback is required. It permits arbitrary parameters to be passed to the callback in a type-safe fashion and thus is a great improvement over the void *data
method C-style callbacks traditionally use - you no longer need to cast the "user data pointer" to some structure & extract the parameters, nor allocate & maintain a separate user data structure - all this is now taken care of for you by the compiler. Compile-time introspection is used to ensure that parameters are not copy constructed except when being stored within the binding - however, the helper friend functions do require an extra copy construction at the point of creation.
Since at the time of writing (Nov 2003) no C++ compiler implements the export
C++ facility, it greatly eases things if object code does not need to know about the types used by some bound functor. Thus you can take a reference or pointer to BoundFunctor's base class, BoundFunctorV which permits functor invocation but with throwing away of the return (as you can't know its type). This comes at the cost of an extra virtual method indirection at runtime. BoundFunctor varies in size according to what the bound parameters require to be stored, but it's typically small - from twelve bytes onwards - usually the custom code generated by the compiler is more (though with a decent optimising compiler, it's near-perfect - no more than a Functor call).
Note that unlike Functor, BoundFunctor when copied makes a true new copy plus passing a Functor to its constructor does not destroy what's passed to it. Thus you can use one Functor to construct many bound calls to the same thing but with different parameters.
In the future, the ability to bind some of the arguments but leaving the remainder to be filled will be added. It's not difficult - just I haven't had call for it yet.
You'll almost certainly want to use one of the convenience functions FX::Generic::BindFunctor, FX::Generic::BindFunc or FX::Generic::BindObj eg;
int main(int argc, char **argv); FX::Generic::Functor<FX::Generic::TL::create<int, int, char **>::value> mainf(main); FX::Generic::BoundFunctorV &mainfb=FX::Generic::BindFunctor(mainf, 4, { "Niall", "is", "a", "teapot", 0 }); mainf(2, { "Hello", "World", 0 }); // Calls main(2, { "Hello", "World", 0 }) mainfb(); // Calls main(4, { "Niall", "is", "a", "teapot", 0 })
FX::Generic::BoundFunctorV &mainfb=FX::Generic::BindObj(main, 4, { "Niall", "is", "a", "teapot", 0 });
Definition at line 1786 of file FXGenericTools.h.
Public Member Functions | |
template<typename fn> | |
BoundFunctor (fn fnptr, TL::instantiateH< realparslist > &_parvals) | |
template<typename obj, typename fn> | |
BoundFunctor (obj &objinst, fn fnptr, TL::instantiateH< realparslist > &_parvals) | |
BoundFunctor (const Functor< parslist > &_functor) | |
BoundFunctor (const Functor< parslist > &_functor, P1 p1) | |
BoundFunctor (const Functor< parslist > &_functor, P1 p1, P2 p2) | |
BoundFunctor (const Functor< parslist > &_functor, P1 p1, P2 p2, P3 p3) | |
BoundFunctor (const Functor< parslist > &_functor, P1 p1, P2 p2, P3 p3, P4 p4) | |
BoundFunctor (const BoundFunctor &o) | |
BoundFunctor & | operator= (const BoundFunctor &o) |
Functor< parslist > & | functor () |
TL::instantiateH< realparslist > & | parameters () |
R | operator() () |