|
16 | 16 | #ifndef MBED_FUNCTIONPOINTER_H
|
17 | 17 | #define MBED_FUNCTIONPOINTER_H
|
18 | 18 |
|
| 19 | +#include "Callback.h" |
19 | 20 | #include <string.h>
|
20 | 21 | #include <stdint.h>
|
21 | 22 |
|
22 | 23 | namespace mbed {
|
23 | 24 |
|
24 |
| -/* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */ |
25 | 25 |
|
26 |
| -/** A class for storing and calling a pointer to a static or member function |
27 |
| - */ |
| 26 | +// Declarations for backwards compatibility |
| 27 | +// To be foward compatible, code should adopt the Callback class |
28 | 28 | template <typename R, typename A1>
|
29 |
| -class FunctionPointerArg1{ |
| 29 | +class FunctionPointerArg1 : public Callback<R(A1)> { |
30 | 30 | public:
|
31 |
| - /** Create a FunctionPointer, attaching a static function |
32 |
| - * |
33 |
| - * @param function The static function to attach (default is none) |
34 |
| - */ |
35 |
| - FunctionPointerArg1(R (*function)(A1) = 0) { |
36 |
| - attach(function); |
37 |
| - } |
| 31 | + FunctionPointerArg1(R (*function)(A1) = 0) |
| 32 | + : Callback<R(A1)>(function) {} |
38 | 33 |
|
39 |
| - /** Create a FunctionPointer, attaching a member function |
40 |
| - * |
41 |
| - * @param object The object pointer to invoke the member function on (i.e. the this pointer) |
42 |
| - * @param function The address of the member function to attach |
43 |
| - */ |
44 | 34 | template<typename T>
|
45 |
| - FunctionPointerArg1(T *object, R (T::*member)(A1)) { |
46 |
| - attach(object, member); |
47 |
| - } |
48 |
| - |
49 |
| - /** Attach a static function |
50 |
| - * |
51 |
| - * @param function The static function to attach (default is none) |
52 |
| - */ |
53 |
| - void attach(R (*function)(A1)) { |
54 |
| - _p.function = function; |
55 |
| - _membercaller = 0; |
56 |
| - } |
57 |
| - |
58 |
| - /** Attach a member function |
59 |
| - * |
60 |
| - * @param object The object pointer to invoke the member function on (i.e. the this pointer) |
61 |
| - * @param function The address of the member function to attach |
62 |
| - */ |
63 |
| - template<typename T> |
64 |
| - void attach(T *object, R (T::*member)(A1)) { |
65 |
| - _p.object = static_cast<void*>(object); |
66 |
| - *reinterpret_cast<R (T::**)(A1)>(_member) = member; |
67 |
| - _membercaller = &FunctionPointerArg1::membercaller<T>; |
68 |
| - } |
69 |
| - |
70 |
| - /** Call the attached static or member function |
71 |
| - */ |
72 |
| - R call(A1 a) { |
73 |
| - if (_membercaller == 0 && _p.function) { |
74 |
| - return _p.function(a); |
75 |
| - } else if (_membercaller && _p.object) { |
76 |
| - return _membercaller(_p.object, _member, a); |
77 |
| - } |
78 |
| - return (R)0; |
79 |
| - } |
80 |
| - |
81 |
| - /** Get registered static function |
82 |
| - */ |
83 |
| - R(*get_function(A1))() { |
84 |
| - return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function; |
85 |
| - } |
| 35 | + FunctionPointerArg1(T *object, R (T::*member)(A1)) |
| 36 | + : Callback<R(A1)>(object, member) {} |
86 | 37 |
|
87 |
| -#ifdef MBED_OPERATORS |
88 |
| - R operator ()(A1 a) { |
89 |
| - return call(a); |
| 38 | + R (*get_function())(A1) { |
| 39 | + return *reinterpret_cast<R (**)(A1)>(this); |
90 | 40 | }
|
91 |
| - operator bool(void) const { |
92 |
| - return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL; |
93 |
| - } |
94 |
| -#endif |
95 |
| -private: |
96 |
| - template<typename T> |
97 |
| - static R membercaller(void *object, uintptr_t *member, A1 a) { |
98 |
| - T* o = static_cast<T*>(object); |
99 |
| - R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member); |
100 |
| - return (o->**m)(a); |
101 |
| - } |
102 |
| - |
103 |
| - union { |
104 |
| - R (*function)(A1); // static function pointer |
105 |
| - void *object; // object this pointer |
106 |
| - } _p; |
107 |
| - uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller |
108 |
| - R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object |
109 | 41 | };
|
110 | 42 |
|
111 |
| -/** A class for storing and calling a pointer to a static or member function (R ()(void)) |
112 |
| - */ |
113 | 43 | template <typename R>
|
114 |
| -class FunctionPointerArg1<R, void>{ |
| 44 | +class FunctionPointerArg1<R, void> : public Callback<R()> { |
115 | 45 | public:
|
116 |
| - /** Create a FunctionPointer, attaching a static function |
117 |
| - * |
118 |
| - * @param function The static function to attach (default is none) |
119 |
| - */ |
120 |
| - FunctionPointerArg1(R (*function)(void) = 0) { |
121 |
| - attach(function); |
122 |
| - } |
| 46 | + FunctionPointerArg1(R (*function)() = 0) |
| 47 | + : Callback<R()>(function) {} |
123 | 48 |
|
124 |
| - /** Create a FunctionPointer, attaching a member function |
125 |
| - * |
126 |
| - * @param object The object pointer to invoke the member function on (i.e. the this pointer) |
127 |
| - * @param function The address of the void member function to attach |
128 |
| - */ |
129 | 49 | template<typename T>
|
130 |
| - FunctionPointerArg1(T *object, R (T::*member)(void)) { |
131 |
| - attach(object, member); |
132 |
| - } |
133 |
| - |
134 |
| - /** Attach a static function |
135 |
| - * |
136 |
| - * @param function The void static function to attach (default is none) |
137 |
| - */ |
138 |
| - void attach(R (*function)(void)) { |
139 |
| - _p.function = function; |
140 |
| - _membercaller = 0; |
141 |
| - } |
142 |
| - |
143 |
| - /** Attach a member function |
144 |
| - * |
145 |
| - * @param object The object pointer to invoke the member function on (i.e. the this pointer) |
146 |
| - * @param function The address of the void member function to attach |
147 |
| - */ |
148 |
| - template<typename T> |
149 |
| - void attach(T *object, R (T::*member)(void)) { |
150 |
| - _p.object = static_cast<void*>(object); |
151 |
| - *reinterpret_cast<R (T::**)(void)>(_member) = member; |
152 |
| - _membercaller = &FunctionPointerArg1::membercaller<T>; |
153 |
| - } |
154 |
| - |
155 |
| - /** Call the attached static or member function |
156 |
| - */ |
157 |
| - R call(){ |
158 |
| - if (_membercaller == 0 && _p.function) { |
159 |
| - return _p.function(); |
160 |
| - } else if (_membercaller && _p.object) { |
161 |
| - return _membercaller(_p.object, _member); |
162 |
| - } |
163 |
| - return (R)0; |
164 |
| - } |
| 50 | + FunctionPointerArg1(T *object, R (T::*member)()) |
| 51 | + : Callback<R()>(object, member) {} |
165 | 52 |
|
166 |
| - /** Get registered static function |
167 |
| - */ |
168 |
| - R(*get_function())() { |
169 |
| - return _membercaller ? (R(*)())0 : (R(*)())_p.function; |
| 53 | + R (*get_function())() { |
| 54 | + return *reinterpret_cast<R (**)()>(this); |
170 | 55 | }
|
171 |
| - |
172 |
| -#ifdef MBED_OPERATORS |
173 |
| - R operator ()(void) { |
174 |
| - return call(); |
175 |
| - } |
176 |
| - operator bool(void) const { |
177 |
| - return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL; |
178 |
| - } |
179 |
| -#endif |
180 |
| - |
181 |
| -private: |
182 |
| - template<typename T> |
183 |
| - static R membercaller(void *object, uintptr_t *member) { |
184 |
| - T* o = static_cast<T*>(object); |
185 |
| - R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member); |
186 |
| - return (o->**m)(); |
187 |
| - } |
188 |
| - |
189 |
| - union { |
190 |
| - R (*function)(void); // static function pointer |
191 |
| - void *object; // object this pointer |
192 |
| - } _p; |
193 |
| - uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller |
194 |
| - R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object |
195 | 56 | };
|
196 | 57 |
|
197 | 58 | typedef FunctionPointerArg1<void, void> FunctionPointer;
|
198 | 59 | typedef FunctionPointerArg1<void, int> event_callback_t;
|
199 | 60 |
|
| 61 | + |
200 | 62 | } // namespace mbed
|
201 | 63 |
|
202 | 64 | #endif
|
0 commit comments