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

Dependencies:   mbed

Committer:
Renegr
Date:
Sun Dec 11 22:04:59 2011 +0000
Revision:
0:e62fc62bc488

        

Who changed what in which revision?

UserRevisionLine numberNew 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