Modified version of Andy Kirkhams FPointer.h http://mbed.org/users/AjK/libraries/FPointer/ll7nhv Advantages: - reduced size of from 12 -> 8 byte by usage of a unnamed union - speedup function call by removing one error check - replaced call() function by () operator - templated: you can define the return and argument types - implementations provided for 1 and 2 arguments, easy extendable to more arguments
FunctionPointers.h
- Committer:
- Renegr
- Date:
- 2011-12-11
- Revision:
- 0:e62fc62bc488
File content as of revision 0:e62fc62bc488:
/* FunctionPointers.h * Modified version of Andy Kirkhams FPointer.h * http://mbed.org/users/AjK/libraries/FPointer/ll7nhv * Advantages: * - reduced size of from 12 -> 8 byte by usage of a unnamed union * - speedup function call by removing one error check * - replaced call() function by () operator * - templated: you can define the return and argument types * - implementations for 1 and 2 arguments, easy extendable to more arguments * Disadvantage: * - do NOT call operator() without an attached callback function */ #ifndef FUNCTIONPOINTERS_H #define FUNCTIONPOINTERS_H template<class Tret=void> class FPtrRetT { public: FPtrRetT() : obj_callback( NULL), c_callback( NULL) { } void attach(Tret (*function)()) { c_callback = function; } template<class T> void attach(T& item, Tret (T::*method)()) { obj_callback = reinterpret_cast<FPtrDummy*>(&item); method_callback = reinterpret_cast<Tret (FPtrDummy::*)()>(method); } Tret operator()() const { return obj_callback ? (obj_callback->*method_callback)() : (*c_callback)(); } private: class FPtrDummy; FPtrDummy *obj_callback; union { Tret (*c_callback)(); Tret (FPtrDummy::*method_callback)(); }; }; template<class Tret, class Targ1> class FPtr1ArgT { public: FPtr1ArgT() : obj_callback( NULL), c_callback( NULL) { } void attach(Tret (*function)(Targ1)) { c_callback = function; } template<class T> void attach(T& item, Tret (T::*method)(Targ1)) { obj_callback = reinterpret_cast<FPtrDummy*>(&item); method_callback = reinterpret_cast<Tret (FPtrDummy::*)(Targ1)>(method); } Tret operator()(Targ1 arg1) const { return obj_callback ? (obj_callback->*method_callback)(arg1) : (*c_callback)(arg1); } private: class FPtrDummy; FPtrDummy *obj_callback; union { Tret (*c_callback)(Targ1); Tret (FPtrDummy::*method_callback)(Targ1); }; }; template<class Tret, class Targ1, class Targ2> class FPtr2ArgT { public: FPtr2ArgT() : obj_callback( NULL), c_callback( NULL) { } void attach(Tret (*function)(Targ1,Targ2)) { c_callback = function; } template<class T> void attach(T& item, Tret (T::*method)(Targ1,Targ2)) { obj_callback = reinterpret_cast<FPointerDummy*>(&item); method_callback = reinterpret_cast<Tret (FPtrDummy::*)(Targ1,Targ2)>(method); } Tret operator()(Targ1 arg1, Targ2 arg2) const { return obj_callback ? (obj_callback->*method_callback)(arg1, arg2) : (*c_callback)(arg1, arg2); } private: class FPtrDummy; FPtrDummy *obj_callback; union { Tret (*c_callback)(Targ1,Targ2); Tret (FPtrDummy::*method_callback)(Targ1,Targ2); }; }; #endif