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@0:e62fc62bc488, 2011-12-11 (annotated)
- Committer:
- Renegr
- Date:
- Sun Dec 11 22:04:59 2011 +0000
- Revision:
- 0:e62fc62bc488
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Renegr | 0:e62fc62bc488 | 1 | /* FunctionPointers.h |
Renegr | 0:e62fc62bc488 | 2 | * Modified version of Andy Kirkhams FPointer.h |
Renegr | 0:e62fc62bc488 | 3 | * http://mbed.org/users/AjK/libraries/FPointer/ll7nhv |
Renegr | 0:e62fc62bc488 | 4 | * Advantages: |
Renegr | 0:e62fc62bc488 | 5 | * - reduced size of from 12 -> 8 byte by usage of a unnamed union |
Renegr | 0:e62fc62bc488 | 6 | * - speedup function call by removing one error check |
Renegr | 0:e62fc62bc488 | 7 | * - replaced call() function by () operator |
Renegr | 0:e62fc62bc488 | 8 | * - templated: you can define the return and argument types |
Renegr | 0:e62fc62bc488 | 9 | * - implementations for 1 and 2 arguments, easy extendable to more arguments |
Renegr | 0:e62fc62bc488 | 10 | * Disadvantage: |
Renegr | 0:e62fc62bc488 | 11 | * - do NOT call operator() without an attached callback function |
Renegr | 0:e62fc62bc488 | 12 | */ |
Renegr | 0:e62fc62bc488 | 13 | |
Renegr | 0:e62fc62bc488 | 14 | #ifndef FUNCTIONPOINTERS_H |
Renegr | 0:e62fc62bc488 | 15 | #define FUNCTIONPOINTERS_H |
Renegr | 0:e62fc62bc488 | 16 | |
Renegr | 0:e62fc62bc488 | 17 | template<class Tret=void> |
Renegr | 0:e62fc62bc488 | 18 | class FPtrRetT { |
Renegr | 0:e62fc62bc488 | 19 | public: |
Renegr | 0:e62fc62bc488 | 20 | FPtrRetT() : obj_callback( NULL), c_callback( NULL) { |
Renegr | 0:e62fc62bc488 | 21 | } |
Renegr | 0:e62fc62bc488 | 22 | |
Renegr | 0:e62fc62bc488 | 23 | void attach(Tret (*function)()) { |
Renegr | 0:e62fc62bc488 | 24 | c_callback = function; |
Renegr | 0:e62fc62bc488 | 25 | } |
Renegr | 0:e62fc62bc488 | 26 | |
Renegr | 0:e62fc62bc488 | 27 | template<class T> |
Renegr | 0:e62fc62bc488 | 28 | void attach(T& item, Tret (T::*method)()) { |
Renegr | 0:e62fc62bc488 | 29 | obj_callback = reinterpret_cast<FPtrDummy*>(&item); |
Renegr | 0:e62fc62bc488 | 30 | method_callback = reinterpret_cast<Tret (FPtrDummy::*)()>(method); |
Renegr | 0:e62fc62bc488 | 31 | } |
Renegr | 0:e62fc62bc488 | 32 | |
Renegr | 0:e62fc62bc488 | 33 | Tret operator()() const { |
Renegr | 0:e62fc62bc488 | 34 | return obj_callback ? (obj_callback->*method_callback)() : (*c_callback)(); |
Renegr | 0:e62fc62bc488 | 35 | } |
Renegr | 0:e62fc62bc488 | 36 | |
Renegr | 0:e62fc62bc488 | 37 | private: |
Renegr | 0:e62fc62bc488 | 38 | class FPtrDummy; |
Renegr | 0:e62fc62bc488 | 39 | |
Renegr | 0:e62fc62bc488 | 40 | FPtrDummy *obj_callback; |
Renegr | 0:e62fc62bc488 | 41 | union { |
Renegr | 0:e62fc62bc488 | 42 | Tret (*c_callback)(); |
Renegr | 0:e62fc62bc488 | 43 | Tret (FPtrDummy::*method_callback)(); |
Renegr | 0:e62fc62bc488 | 44 | }; |
Renegr | 0:e62fc62bc488 | 45 | }; |
Renegr | 0:e62fc62bc488 | 46 | |
Renegr | 0:e62fc62bc488 | 47 | template<class Tret, class Targ1> |
Renegr | 0:e62fc62bc488 | 48 | class FPtr1ArgT { |
Renegr | 0:e62fc62bc488 | 49 | public: |
Renegr | 0:e62fc62bc488 | 50 | FPtr1ArgT() : obj_callback( NULL), c_callback( NULL) { |
Renegr | 0:e62fc62bc488 | 51 | } |
Renegr | 0:e62fc62bc488 | 52 | |
Renegr | 0:e62fc62bc488 | 53 | void attach(Tret (*function)(Targ1)) { |
Renegr | 0:e62fc62bc488 | 54 | c_callback = function; |
Renegr | 0:e62fc62bc488 | 55 | } |
Renegr | 0:e62fc62bc488 | 56 | |
Renegr | 0:e62fc62bc488 | 57 | template<class T> |
Renegr | 0:e62fc62bc488 | 58 | void attach(T& item, Tret (T::*method)(Targ1)) { |
Renegr | 0:e62fc62bc488 | 59 | obj_callback = reinterpret_cast<FPtrDummy*>(&item); |
Renegr | 0:e62fc62bc488 | 60 | method_callback = reinterpret_cast<Tret (FPtrDummy::*)(Targ1)>(method); |
Renegr | 0:e62fc62bc488 | 61 | } |
Renegr | 0:e62fc62bc488 | 62 | |
Renegr | 0:e62fc62bc488 | 63 | Tret operator()(Targ1 arg1) const { |
Renegr | 0:e62fc62bc488 | 64 | return obj_callback ? (obj_callback->*method_callback)(arg1) : (*c_callback)(arg1); |
Renegr | 0:e62fc62bc488 | 65 | } |
Renegr | 0:e62fc62bc488 | 66 | |
Renegr | 0:e62fc62bc488 | 67 | private: |
Renegr | 0:e62fc62bc488 | 68 | class FPtrDummy; |
Renegr | 0:e62fc62bc488 | 69 | |
Renegr | 0:e62fc62bc488 | 70 | FPtrDummy *obj_callback; |
Renegr | 0:e62fc62bc488 | 71 | union { |
Renegr | 0:e62fc62bc488 | 72 | Tret (*c_callback)(Targ1); |
Renegr | 0:e62fc62bc488 | 73 | Tret (FPtrDummy::*method_callback)(Targ1); |
Renegr | 0:e62fc62bc488 | 74 | }; |
Renegr | 0:e62fc62bc488 | 75 | }; |
Renegr | 0:e62fc62bc488 | 76 | |
Renegr | 0:e62fc62bc488 | 77 | template<class Tret, class Targ1, class Targ2> |
Renegr | 0:e62fc62bc488 | 78 | class FPtr2ArgT { |
Renegr | 0:e62fc62bc488 | 79 | public: |
Renegr | 0:e62fc62bc488 | 80 | FPtr2ArgT() : obj_callback( NULL), c_callback( NULL) { |
Renegr | 0:e62fc62bc488 | 81 | } |
Renegr | 0:e62fc62bc488 | 82 | |
Renegr | 0:e62fc62bc488 | 83 | void attach(Tret (*function)(Targ1,Targ2)) { |
Renegr | 0:e62fc62bc488 | 84 | c_callback = function; |
Renegr | 0:e62fc62bc488 | 85 | } |
Renegr | 0:e62fc62bc488 | 86 | |
Renegr | 0:e62fc62bc488 | 87 | template<class T> |
Renegr | 0:e62fc62bc488 | 88 | void attach(T& item, Tret (T::*method)(Targ1,Targ2)) { |
Renegr | 0:e62fc62bc488 | 89 | obj_callback = reinterpret_cast<FPointerDummy*>(&item); |
Renegr | 0:e62fc62bc488 | 90 | method_callback = reinterpret_cast<Tret (FPtrDummy::*)(Targ1,Targ2)>(method); |
Renegr | 0:e62fc62bc488 | 91 | } |
Renegr | 0:e62fc62bc488 | 92 | |
Renegr | 0:e62fc62bc488 | 93 | Tret operator()(Targ1 arg1, Targ2 arg2) const { |
Renegr | 0:e62fc62bc488 | 94 | return obj_callback ? (obj_callback->*method_callback)(arg1, arg2) : (*c_callback)(arg1, arg2); |
Renegr | 0:e62fc62bc488 | 95 | } |
Renegr | 0:e62fc62bc488 | 96 | |
Renegr | 0:e62fc62bc488 | 97 | private: |
Renegr | 0:e62fc62bc488 | 98 | class FPtrDummy; |
Renegr | 0:e62fc62bc488 | 99 | |
Renegr | 0:e62fc62bc488 | 100 | FPtrDummy *obj_callback; |
Renegr | 0:e62fc62bc488 | 101 | union { |
Renegr | 0:e62fc62bc488 | 102 | Tret (*c_callback)(Targ1,Targ2); |
Renegr | 0:e62fc62bc488 | 103 | Tret (FPtrDummy::*method_callback)(Targ1,Targ2); |
Renegr | 0:e62fc62bc488 | 104 | }; |
Renegr | 0:e62fc62bc488 | 105 | }; |
Renegr | 0:e62fc62bc488 | 106 | |
Renegr | 0:e62fc62bc488 | 107 | #endif |