Christopher Haster / mbed-hal

Dependencies:   target-freescale

Fork of mbed-hal by Morpheus

Committer:
Christopher Haster
Date:
Fri Apr 01 01:16:52 2016 -0500
Revision:
15:1ce23ed6859a
Parent:
14:4af7fef9cf08
Child:
17:fe43695d093a
Removed unused variable warnings

Who changed what in which revision?

UserRevisionLine numberNew contents of line
screamer 0:9c59db1fbc9e 1 /* mbed Microcontroller Library
screamer 0:9c59db1fbc9e 2 * Copyright (c) 2006-2015 ARM Limited
screamer 0:9c59db1fbc9e 3 *
screamer 0:9c59db1fbc9e 4 * Licensed under the Apache License, Version 2.0 (the "License");
screamer 0:9c59db1fbc9e 5 * you may not use this file except in compliance with the License.
screamer 0:9c59db1fbc9e 6 * You may obtain a copy of the License at
screamer 0:9c59db1fbc9e 7 *
screamer 0:9c59db1fbc9e 8 * http://www.apache.org/licenses/LICENSE-2.0
screamer 0:9c59db1fbc9e 9 *
screamer 0:9c59db1fbc9e 10 * Unless required by applicable law or agreed to in writing, software
screamer 0:9c59db1fbc9e 11 * distributed under the License is distributed on an "AS IS" BASIS,
screamer 0:9c59db1fbc9e 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
screamer 0:9c59db1fbc9e 13 * See the License for the specific language governing permissions and
screamer 0:9c59db1fbc9e 14 * limitations under the License.
screamer 0:9c59db1fbc9e 15 */
Christopher Haster 7:4fdb3a44f646 16 #ifndef MBED_FUNCTIONPOINTER_H
Christopher Haster 7:4fdb3a44f646 17 #define MBED_FUNCTIONPOINTER_H
screamer 0:9c59db1fbc9e 18
Christopher Haster 11:f08e03081748 19 #include <string.h>
Christopher Haster 11:f08e03081748 20 #include <stdint.h>
screamer 0:9c59db1fbc9e 21
screamer 0:9c59db1fbc9e 22 namespace mbed {
screamer 0:9c59db1fbc9e 23
Christopher Haster 14:4af7fef9cf08 24 // Reusable FuncPtr class based on template specialization
Christopher Haster 11:f08e03081748 25 template <typename F>
Christopher Haster 14:4af7fef9cf08 26 class FuncPtr;
Christopher Haster 11:f08e03081748 27
Christopher Haster 11:f08e03081748 28 /** A class for storing and calling a pointer to a static or member function
Christopher Haster 11:f08e03081748 29 */
Christopher Haster 11:f08e03081748 30 template <typename R, typename A1, typename A2, typename A3, typename A4>
Christopher Haster 14:4af7fef9cf08 31 class FuncPtr<R(A1, A2, A3, A4)> {
Christopher Haster 11:f08e03081748 32 public:
Christopher Haster 14:4af7fef9cf08 33 /** Create a FuncPtr, attaching a static function
Christopher Haster 11:f08e03081748 34 *
Christopher Haster 11:f08e03081748 35 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 36 */
Christopher Haster 14:4af7fef9cf08 37 FuncPtr(R (*function)(A1, A2, A3, A4) = 0) {
Christopher Haster 11:f08e03081748 38 attach(function);
Christopher Haster 11:f08e03081748 39 }
Christopher Haster 11:f08e03081748 40
Christopher Haster 14:4af7fef9cf08 41 /** Create a FuncPtr, attaching a static function with bound pointer
Christopher Haster 11:f08e03081748 42 *
Christopher Haster 11:f08e03081748 43 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 44 * @param function The static function to attach
Christopher Haster 11:f08e03081748 45 */
Christopher Haster 11:f08e03081748 46 template<typename T>
Christopher Haster 14:4af7fef9cf08 47 FuncPtr(T *object, R (*function)(T*, A1, A2, A3, A4)) {
Christopher Haster 11:f08e03081748 48 attach(object, function);
Christopher Haster 11:f08e03081748 49 }
Christopher Haster 11:f08e03081748 50
Christopher Haster 14:4af7fef9cf08 51 /** Create a FuncPtr, attaching a member function
Christopher Haster 11:f08e03081748 52 *
Christopher Haster 11:f08e03081748 53 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 54 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 55 */
Christopher Haster 11:f08e03081748 56 template<typename T>
Christopher Haster 14:4af7fef9cf08 57 FuncPtr(T *object, R (T::*member)(A1, A2, A3, A4)) {
Christopher Haster 11:f08e03081748 58 attach(object, member);
Christopher Haster 11:f08e03081748 59 }
Christopher Haster 11:f08e03081748 60
Christopher Haster 14:4af7fef9cf08 61 /** Create a FuncPtr from another FuncPtr
Christopher Haster 11:f08e03081748 62 *
Christopher Haster 11:f08e03081748 63 * @param func The func to attach
Christopher Haster 11:f08e03081748 64 */
Christopher Haster 14:4af7fef9cf08 65 FuncPtr(const FuncPtr<R(A1, A2, A3, A4)> &func) {
Christopher Haster 11:f08e03081748 66 attach(func);
Christopher Haster 11:f08e03081748 67 }
Christopher Haster 11:f08e03081748 68
Christopher Haster 11:f08e03081748 69 /** Attach a static function
Christopher Haster 11:f08e03081748 70 *
Christopher Haster 11:f08e03081748 71 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 72 */
Christopher Haster 11:f08e03081748 73 void attach(R (*function)(A1, A2, A3, A4)) {
Christopher Haster 11:f08e03081748 74 _object = 0;
Christopher Haster 11:f08e03081748 75 *reinterpret_cast<R (**)(A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 76 _thunk = &FuncPtr::staticthunk;
Christopher Haster 11:f08e03081748 77 }
Christopher Haster 11:f08e03081748 78
Christopher Haster 11:f08e03081748 79 /** Attach a static function with bound pointer
Christopher Haster 11:f08e03081748 80 *
Christopher Haster 11:f08e03081748 81 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 82 * @param function The static function to attach
Christopher Haster 11:f08e03081748 83 */
Christopher Haster 11:f08e03081748 84 template <typename T>
Christopher Haster 15:1ce23ed6859a 85 void attach(T *object, R (*function)(T*, A1, A2, A3, A4)) {
Christopher Haster 11:f08e03081748 86 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 87 *reinterpret_cast<R (**)(T*, A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 88 _thunk = &FuncPtr::boundthunk<T>;
Christopher Haster 11:f08e03081748 89 }
Christopher Haster 11:f08e03081748 90
Christopher Haster 11:f08e03081748 91 /** Attach a member function
Christopher Haster 11:f08e03081748 92 *
Christopher Haster 11:f08e03081748 93 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 94 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 95 */
Christopher Haster 11:f08e03081748 96 template<typename T>
Christopher Haster 11:f08e03081748 97 void attach(T *object, R (T::*method)(A1, A2, A3, A4)) {
Christopher Haster 11:f08e03081748 98 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 99 *reinterpret_cast<R (T::**)(A1)>(_function) = method;
Christopher Haster 14:4af7fef9cf08 100 _thunk = &FuncPtr::methodthunk<T>;
Christopher Haster 11:f08e03081748 101 }
Christopher Haster 11:f08e03081748 102
Christopher Haster 14:4af7fef9cf08 103 /** Attach a FuncPtr
Christopher Haster 11:f08e03081748 104 *
Christopher Haster 11:f08e03081748 105 * @param func The func to attach
Christopher Haster 11:f08e03081748 106 */
Christopher Haster 14:4af7fef9cf08 107 void attach(const FuncPtr<R(A1, A2, A3, A4)> &func) {
Christopher Haster 11:f08e03081748 108 _object = func._object;
Christopher Haster 11:f08e03081748 109 memcpy(_function, func._function, sizeof _function);
Christopher Haster 11:f08e03081748 110 _thunk = func._thunk;
Christopher Haster 11:f08e03081748 111 }
Christopher Haster 11:f08e03081748 112
Christopher Haster 11:f08e03081748 113 /** Call the attached static or member function
Christopher Haster 11:f08e03081748 114 */
Christopher Haster 11:f08e03081748 115 R call(A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 11:f08e03081748 116 return _thunk(_object, _function, a1, a2, a3, a4);
Christopher Haster 11:f08e03081748 117 }
Christopher Haster 11:f08e03081748 118
Christopher Haster 11:f08e03081748 119 /** Get registered static function
Christopher Haster 11:f08e03081748 120 */
Christopher Haster 11:f08e03081748 121 R (*get_function(A1, A2, A3, A4))() {
Christopher Haster 11:f08e03081748 122 return reinterpret_cast<R (*)(A1, A2, A3, A4)>(_object ? 0 : _function);
Christopher Haster 11:f08e03081748 123 }
Christopher Haster 11:f08e03081748 124
Christopher Haster 11:f08e03081748 125 #ifdef MBED_OPERATORS
Christopher Haster 11:f08e03081748 126 R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 11:f08e03081748 127 return call(a1, a2, a3, a4);
Christopher Haster 11:f08e03081748 128 }
Christopher Haster 11:f08e03081748 129 operator bool(void) const {
Christopher Haster 11:f08e03081748 130 return static_cast<bool>(_function);
Christopher Haster 11:f08e03081748 131 }
Christopher Haster 11:f08e03081748 132 #endif
Christopher Haster 11:f08e03081748 133 private:
Christopher Haster 11:f08e03081748 134 // Static thunks for various function types
Christopher Haster 15:1ce23ed6859a 135 static R staticthunk(void*, void *func, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 11:f08e03081748 136 R (*f)(A1, A2, A3, A4) = *reinterpret_cast<R (**)(A1, A2, A3, A4)>(func);
Christopher Haster 11:f08e03081748 137 return f(a1, a2, a3, a4);
Christopher Haster 11:f08e03081748 138 }
Christopher Haster 11:f08e03081748 139
Christopher Haster 11:f08e03081748 140 template<typename T>
Christopher Haster 11:f08e03081748 141 static R boundthunk(void *object, void *func, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 11:f08e03081748 142 T *o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 143 R (*f)(T*, A1) = *reinterpret_cast<R (**)(T*, A1)>(func);
Christopher Haster 11:f08e03081748 144 return f(o, a1);
Christopher Haster 11:f08e03081748 145 }
Christopher Haster 11:f08e03081748 146
Christopher Haster 11:f08e03081748 147 template<typename T>
Christopher Haster 11:f08e03081748 148 static R methodthunk(void *object, void *member, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 11:f08e03081748 149 T* o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 150 R (T::*m)(A1, A2, A3, A4) = *reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(member);
Christopher Haster 11:f08e03081748 151 return (o->*m)(a1, a2, a3, a4);
Christopher Haster 11:f08e03081748 152 }
Christopher Haster 11:f08e03081748 153
Christopher Haster 11:f08e03081748 154 // Forward declaration of an unknown class
Christopher Haster 11:f08e03081748 155 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
Christopher Haster 11:f08e03081748 156 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
Christopher Haster 11:f08e03081748 157 // and biggest alignment possible for member function.
Christopher Haster 11:f08e03081748 158 // This type can be used inside unions, it will help to provide the storage
Christopher Haster 11:f08e03081748 159 // with the proper size and alignment guarantees
Christopher Haster 11:f08e03081748 160 class UnknownClass;
Christopher Haster 11:f08e03081748 161
Christopher Haster 11:f08e03081748 162 // object this pointer
Christopher Haster 11:f08e03081748 163 void *_object;
Christopher Haster 11:f08e03081748 164
Christopher Haster 11:f08e03081748 165 // aligned raw member function pointer storage - converted back by registered thunk
Christopher Haster 11:f08e03081748 166 char _function[sizeof(void (UnknownClass::*)())];
Christopher Haster 11:f08e03081748 167
Christopher Haster 11:f08e03081748 168 // registered function to convert back and call _m.member on _object
Christopher Haster 11:f08e03081748 169 R (*_thunk)(void*, void*, A1, A2, A3, A4);
Christopher Haster 11:f08e03081748 170 };
Christopher Haster 11:f08e03081748 171
Christopher Haster 11:f08e03081748 172 /** A class for storing and calling a pointer to a static or member function
Christopher Haster 11:f08e03081748 173 */
Christopher Haster 11:f08e03081748 174 template <typename R, typename A1, typename A2, typename A3>
Christopher Haster 14:4af7fef9cf08 175 class FuncPtr<R(A1, A2, A3)> {
Christopher Haster 11:f08e03081748 176 public:
Christopher Haster 14:4af7fef9cf08 177 /** Create a FuncPtr, attaching a static function
Christopher Haster 11:f08e03081748 178 *
Christopher Haster 11:f08e03081748 179 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 180 */
Christopher Haster 14:4af7fef9cf08 181 FuncPtr(R (*function)(A1, A2, A3) = 0) {
Christopher Haster 11:f08e03081748 182 attach(function);
Christopher Haster 11:f08e03081748 183 }
Christopher Haster 11:f08e03081748 184
Christopher Haster 14:4af7fef9cf08 185 /** Create a FuncPtr, attaching a static function with bound pointer
Christopher Haster 11:f08e03081748 186 *
Christopher Haster 11:f08e03081748 187 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 188 * @param function The static function to attach
Christopher Haster 11:f08e03081748 189 */
Christopher Haster 11:f08e03081748 190 template<typename T>
Christopher Haster 14:4af7fef9cf08 191 FuncPtr(T *object, R (*function)(T*, A1, A2, A3)) {
Christopher Haster 11:f08e03081748 192 attach(object, function);
Christopher Haster 11:f08e03081748 193 }
Christopher Haster 11:f08e03081748 194
Christopher Haster 14:4af7fef9cf08 195 /** Create a FuncPtr, attaching a member function
Christopher Haster 11:f08e03081748 196 *
Christopher Haster 11:f08e03081748 197 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 198 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 199 */
Christopher Haster 11:f08e03081748 200 template<typename T>
Christopher Haster 14:4af7fef9cf08 201 FuncPtr(T *object, R (T::*member)(A1, A2, A3)) {
Christopher Haster 11:f08e03081748 202 attach(object, member);
Christopher Haster 11:f08e03081748 203 }
Christopher Haster 11:f08e03081748 204
Christopher Haster 14:4af7fef9cf08 205 /** Create a FuncPtr from another FuncPtr
Christopher Haster 11:f08e03081748 206 *
Christopher Haster 11:f08e03081748 207 * @param func The func to attach
Christopher Haster 11:f08e03081748 208 */
Christopher Haster 14:4af7fef9cf08 209 FuncPtr(const FuncPtr<R(A1, A2, A3)> &func) {
Christopher Haster 11:f08e03081748 210 attach(func);
Christopher Haster 11:f08e03081748 211 }
Christopher Haster 11:f08e03081748 212
Christopher Haster 11:f08e03081748 213 /** Attach a static function
Christopher Haster 11:f08e03081748 214 *
Christopher Haster 11:f08e03081748 215 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 216 */
Christopher Haster 11:f08e03081748 217 void attach(R (*function)(A1, A2, A3)) {
Christopher Haster 11:f08e03081748 218 _object = 0;
Christopher Haster 11:f08e03081748 219 *reinterpret_cast<R (**)(A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 220 _thunk = &FuncPtr::staticthunk;
Christopher Haster 11:f08e03081748 221 }
Christopher Haster 11:f08e03081748 222
Christopher Haster 11:f08e03081748 223 /** Attach a static function with bound pointer
Christopher Haster 11:f08e03081748 224 *
Christopher Haster 11:f08e03081748 225 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 226 * @param function The static function to attach
Christopher Haster 11:f08e03081748 227 */
Christopher Haster 11:f08e03081748 228 template <typename T>
Christopher Haster 15:1ce23ed6859a 229 void attach(T *object, R (*function)(T*, A1, A2, A3)) {
Christopher Haster 11:f08e03081748 230 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 231 *reinterpret_cast<R (**)(T*, A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 232 _thunk = &FuncPtr::boundthunk<T>;
Christopher Haster 11:f08e03081748 233 }
Christopher Haster 11:f08e03081748 234
Christopher Haster 11:f08e03081748 235 /** Attach a member function
Christopher Haster 11:f08e03081748 236 *
Christopher Haster 11:f08e03081748 237 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 238 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 239 */
Christopher Haster 11:f08e03081748 240 template<typename T>
Christopher Haster 11:f08e03081748 241 void attach(T *object, R (T::*method)(A1, A2, A3)) {
Christopher Haster 11:f08e03081748 242 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 243 *reinterpret_cast<R (T::**)(A1)>(_function) = method;
Christopher Haster 14:4af7fef9cf08 244 _thunk = &FuncPtr::methodthunk<T>;
Christopher Haster 11:f08e03081748 245 }
Christopher Haster 11:f08e03081748 246
Christopher Haster 14:4af7fef9cf08 247 /** Attach a FuncPtr
Christopher Haster 11:f08e03081748 248 *
Christopher Haster 11:f08e03081748 249 * @param func The func to attach
Christopher Haster 11:f08e03081748 250 */
Christopher Haster 14:4af7fef9cf08 251 void attach(const FuncPtr<R(A1, A2, A3)> &func) {
Christopher Haster 11:f08e03081748 252 _object = func._object;
Christopher Haster 11:f08e03081748 253 memcpy(_function, func._function, sizeof _function);
Christopher Haster 11:f08e03081748 254 _thunk = func._thunk;
Christopher Haster 11:f08e03081748 255 }
Christopher Haster 11:f08e03081748 256
Christopher Haster 11:f08e03081748 257 /** Call the attached static or member function
Christopher Haster 11:f08e03081748 258 */
Christopher Haster 11:f08e03081748 259 R call(A1 a1, A2 a2, A3 a3) {
Christopher Haster 11:f08e03081748 260 return _thunk(_object, _function, a1, a2, a3);
Christopher Haster 11:f08e03081748 261 }
Christopher Haster 11:f08e03081748 262
Christopher Haster 11:f08e03081748 263 /** Get registered static function
Christopher Haster 11:f08e03081748 264 */
Christopher Haster 11:f08e03081748 265 R (*get_function(A1, A2, A3))() {
Christopher Haster 11:f08e03081748 266 return reinterpret_cast<R (*)(A1, A2, A3)>(_object ? 0 : _function);
Christopher Haster 11:f08e03081748 267 }
Christopher Haster 11:f08e03081748 268
Christopher Haster 11:f08e03081748 269 #ifdef MBED_OPERATORS
Christopher Haster 11:f08e03081748 270 R operator ()(A1 a1, A2 a2, A3 a3) {
Christopher Haster 11:f08e03081748 271 return call(a1, a2, a3);
Christopher Haster 11:f08e03081748 272 }
Christopher Haster 11:f08e03081748 273 operator bool(void) const {
Christopher Haster 11:f08e03081748 274 return static_cast<bool>(_function);
Christopher Haster 11:f08e03081748 275 }
Christopher Haster 11:f08e03081748 276 #endif
Christopher Haster 11:f08e03081748 277 private:
Christopher Haster 11:f08e03081748 278 // Static thunks for various function types
Christopher Haster 15:1ce23ed6859a 279 static R staticthunk(void*, void *func, A1 a1, A2 a2, A3 a3) {
Christopher Haster 11:f08e03081748 280 R (*f)(A1, A2, A3) = *reinterpret_cast<R (**)(A1, A2, A3)>(func);
Christopher Haster 11:f08e03081748 281 return f(a1, a2, a3);
Christopher Haster 11:f08e03081748 282 }
Christopher Haster 11:f08e03081748 283
Christopher Haster 11:f08e03081748 284 template<typename T>
Christopher Haster 11:f08e03081748 285 static R boundthunk(void *object, void *func, A1 a1, A2 a2, A3 a3) {
Christopher Haster 11:f08e03081748 286 T *o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 287 R (*f)(T*, A1) = *reinterpret_cast<R (**)(T*, A1)>(func);
Christopher Haster 11:f08e03081748 288 return f(o, a1);
Christopher Haster 11:f08e03081748 289 }
Christopher Haster 11:f08e03081748 290
Christopher Haster 11:f08e03081748 291 template<typename T>
Christopher Haster 11:f08e03081748 292 static R methodthunk(void *object, void *member, A1 a1, A2 a2, A3 a3) {
Christopher Haster 11:f08e03081748 293 T* o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 294 R (T::*m)(A1, A2, A3) = *reinterpret_cast<R (T::**)(A1, A2, A3)>(member);
Christopher Haster 11:f08e03081748 295 return (o->*m)(a1, a2, a3);
Christopher Haster 11:f08e03081748 296 }
Christopher Haster 11:f08e03081748 297
Christopher Haster 11:f08e03081748 298 // Forward declaration of an unknown class
Christopher Haster 11:f08e03081748 299 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
Christopher Haster 11:f08e03081748 300 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
Christopher Haster 11:f08e03081748 301 // and biggest alignment possible for member function.
Christopher Haster 11:f08e03081748 302 // This type can be used inside unions, it will help to provide the storage
Christopher Haster 11:f08e03081748 303 // with the proper size and alignment guarantees
Christopher Haster 11:f08e03081748 304 class UnknownClass;
Christopher Haster 11:f08e03081748 305
Christopher Haster 11:f08e03081748 306 // object this pointer
Christopher Haster 11:f08e03081748 307 void *_object;
Christopher Haster 11:f08e03081748 308
Christopher Haster 11:f08e03081748 309 // aligned raw member function pointer storage - converted back by registered thunk
Christopher Haster 11:f08e03081748 310 char _function[sizeof(void (UnknownClass::*)())];
Christopher Haster 11:f08e03081748 311
Christopher Haster 11:f08e03081748 312 // registered function to convert back and call _m.member on _object
Christopher Haster 11:f08e03081748 313 R (*_thunk)(void*, void*, A1, A2, A3);
Christopher Haster 11:f08e03081748 314 };
Christopher Haster 11:f08e03081748 315
Christopher Haster 11:f08e03081748 316 /** A class for storing and calling a pointer to a static or member function
Christopher Haster 11:f08e03081748 317 */
Christopher Haster 11:f08e03081748 318 template <typename R, typename A1, typename A2>
Christopher Haster 14:4af7fef9cf08 319 class FuncPtr<R(A1, A2)> {
Christopher Haster 11:f08e03081748 320 public:
Christopher Haster 14:4af7fef9cf08 321 /** Create a FuncPtr, attaching a static function
Christopher Haster 11:f08e03081748 322 *
Christopher Haster 11:f08e03081748 323 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 324 */
Christopher Haster 14:4af7fef9cf08 325 FuncPtr(R (*function)(A1, A2) = 0) {
Christopher Haster 11:f08e03081748 326 attach(function);
Christopher Haster 11:f08e03081748 327 }
Christopher Haster 11:f08e03081748 328
Christopher Haster 14:4af7fef9cf08 329 /** Create a FuncPtr, attaching a static function with bound pointer
Christopher Haster 11:f08e03081748 330 *
Christopher Haster 11:f08e03081748 331 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 332 * @param function The static function to attach
Christopher Haster 11:f08e03081748 333 */
Christopher Haster 11:f08e03081748 334 template<typename T>
Christopher Haster 14:4af7fef9cf08 335 FuncPtr(T *object, R (*function)(T*, A1, A2)) {
Christopher Haster 11:f08e03081748 336 attach(object, function);
Christopher Haster 11:f08e03081748 337 }
Christopher Haster 11:f08e03081748 338
Christopher Haster 14:4af7fef9cf08 339 /** Create a FuncPtr, attaching a member function
Christopher Haster 11:f08e03081748 340 *
Christopher Haster 11:f08e03081748 341 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 342 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 343 */
Christopher Haster 11:f08e03081748 344 template<typename T>
Christopher Haster 14:4af7fef9cf08 345 FuncPtr(T *object, R (T::*member)(A1, A2)) {
Christopher Haster 11:f08e03081748 346 attach(object, member);
Christopher Haster 11:f08e03081748 347 }
Christopher Haster 11:f08e03081748 348
Christopher Haster 14:4af7fef9cf08 349 /** Create a FuncPtr from another FuncPtr
Christopher Haster 11:f08e03081748 350 *
Christopher Haster 11:f08e03081748 351 * @param func The func to attach
Christopher Haster 11:f08e03081748 352 */
Christopher Haster 14:4af7fef9cf08 353 FuncPtr(const FuncPtr<R(A1, A2)> &func) {
Christopher Haster 11:f08e03081748 354 attach(func);
Christopher Haster 11:f08e03081748 355 }
Christopher Haster 11:f08e03081748 356
Christopher Haster 11:f08e03081748 357 /** Attach a static function
Christopher Haster 11:f08e03081748 358 *
Christopher Haster 11:f08e03081748 359 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 360 */
Christopher Haster 11:f08e03081748 361 void attach(R (*function)(A1, A2)) {
Christopher Haster 11:f08e03081748 362 _object = 0;
Christopher Haster 11:f08e03081748 363 *reinterpret_cast<R (**)(A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 364 _thunk = &FuncPtr::staticthunk;
Christopher Haster 11:f08e03081748 365 }
Christopher Haster 11:f08e03081748 366
Christopher Haster 11:f08e03081748 367 /** Attach a static function with bound pointer
Christopher Haster 11:f08e03081748 368 *
Christopher Haster 11:f08e03081748 369 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 370 * @param function The static function to attach
Christopher Haster 11:f08e03081748 371 */
Christopher Haster 11:f08e03081748 372 template <typename T>
Christopher Haster 15:1ce23ed6859a 373 void attach(T *object, R (*function)(T*, A1, A2)) {
Christopher Haster 11:f08e03081748 374 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 375 *reinterpret_cast<R (**)(T*, A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 376 _thunk = &FuncPtr::boundthunk<T>;
Christopher Haster 11:f08e03081748 377 }
Christopher Haster 11:f08e03081748 378
Christopher Haster 11:f08e03081748 379 /** Attach a member function
Christopher Haster 11:f08e03081748 380 *
Christopher Haster 11:f08e03081748 381 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 382 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 383 */
Christopher Haster 11:f08e03081748 384 template<typename T>
Christopher Haster 11:f08e03081748 385 void attach(T *object, R (T::*method)(A1, A2)) {
Christopher Haster 11:f08e03081748 386 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 387 *reinterpret_cast<R (T::**)(A1)>(_function) = method;
Christopher Haster 14:4af7fef9cf08 388 _thunk = &FuncPtr::methodthunk<T>;
Christopher Haster 11:f08e03081748 389 }
Christopher Haster 11:f08e03081748 390
Christopher Haster 14:4af7fef9cf08 391 /** Attach a FuncPtr
Christopher Haster 11:f08e03081748 392 *
Christopher Haster 11:f08e03081748 393 * @param func The func to attach
Christopher Haster 11:f08e03081748 394 */
Christopher Haster 14:4af7fef9cf08 395 void attach(const FuncPtr<R(A1, A2)> &func) {
Christopher Haster 11:f08e03081748 396 _object = func._object;
Christopher Haster 11:f08e03081748 397 memcpy(_function, func._function, sizeof _function);
Christopher Haster 11:f08e03081748 398 _thunk = func._thunk;
Christopher Haster 11:f08e03081748 399 }
Christopher Haster 11:f08e03081748 400
Christopher Haster 11:f08e03081748 401 /** Call the attached static or member function
Christopher Haster 11:f08e03081748 402 */
Christopher Haster 11:f08e03081748 403 R call(A1 a1, A2 a2) {
Christopher Haster 11:f08e03081748 404 return _thunk(_object, _function, a1, a2);
Christopher Haster 11:f08e03081748 405 }
Christopher Haster 11:f08e03081748 406
Christopher Haster 11:f08e03081748 407 /** Get registered static function
Christopher Haster 11:f08e03081748 408 */
Christopher Haster 11:f08e03081748 409 R (*get_function(A1, A2))() {
Christopher Haster 11:f08e03081748 410 return reinterpret_cast<R (*)(A1, A2)>(_object ? 0 : _function);
Christopher Haster 11:f08e03081748 411 }
Christopher Haster 11:f08e03081748 412
Christopher Haster 11:f08e03081748 413 #ifdef MBED_OPERATORS
Christopher Haster 11:f08e03081748 414 R operator ()(A1 a1, A2 a2) {
Christopher Haster 11:f08e03081748 415 return call(a1, a2);
Christopher Haster 11:f08e03081748 416 }
Christopher Haster 11:f08e03081748 417 operator bool(void) const {
Christopher Haster 11:f08e03081748 418 return static_cast<bool>(_function);
Christopher Haster 11:f08e03081748 419 }
Christopher Haster 11:f08e03081748 420 #endif
Christopher Haster 11:f08e03081748 421 private:
Christopher Haster 11:f08e03081748 422 // Static thunks for various function types
Christopher Haster 15:1ce23ed6859a 423 static R staticthunk(void*, void *func, A1 a1, A2 a2) {
Christopher Haster 11:f08e03081748 424 R (*f)(A1, A2) = *reinterpret_cast<R (**)(A1, A2)>(func);
Christopher Haster 11:f08e03081748 425 return f(a1, a2);
Christopher Haster 11:f08e03081748 426 }
Christopher Haster 11:f08e03081748 427
Christopher Haster 11:f08e03081748 428 template<typename T>
Christopher Haster 11:f08e03081748 429 static R boundthunk(void *object, void *func, A1 a1, A2 a2) {
Christopher Haster 11:f08e03081748 430 T *o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 431 R (*f)(T*, A1) = *reinterpret_cast<R (**)(T*, A1)>(func);
Christopher Haster 11:f08e03081748 432 return f(o, a1);
Christopher Haster 11:f08e03081748 433 }
Christopher Haster 11:f08e03081748 434
Christopher Haster 11:f08e03081748 435 template<typename T>
Christopher Haster 11:f08e03081748 436 static R methodthunk(void *object, void *member, A1 a1, A2 a2) {
Christopher Haster 11:f08e03081748 437 T* o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 438 R (T::*m)(A1, A2) = *reinterpret_cast<R (T::**)(A1, A2)>(member);
Christopher Haster 11:f08e03081748 439 return (o->*m)(a1, a2);
Christopher Haster 11:f08e03081748 440 }
Christopher Haster 11:f08e03081748 441
Christopher Haster 11:f08e03081748 442 // Forward declaration of an unknown class
Christopher Haster 11:f08e03081748 443 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
Christopher Haster 11:f08e03081748 444 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
Christopher Haster 11:f08e03081748 445 // and biggest alignment possible for member function.
Christopher Haster 11:f08e03081748 446 // This type can be used inside unions, it will help to provide the storage
Christopher Haster 11:f08e03081748 447 // with the proper size and alignment guarantees
Christopher Haster 11:f08e03081748 448 class UnknownClass;
Christopher Haster 11:f08e03081748 449
Christopher Haster 11:f08e03081748 450 // object this pointer
Christopher Haster 11:f08e03081748 451 void *_object;
Christopher Haster 11:f08e03081748 452
Christopher Haster 11:f08e03081748 453 // aligned raw member function pointer storage - converted back by registered thunk
Christopher Haster 11:f08e03081748 454 char _function[sizeof(void (UnknownClass::*)())];
Christopher Haster 11:f08e03081748 455
Christopher Haster 11:f08e03081748 456 // registered function to convert back and call _m.member on _object
Christopher Haster 11:f08e03081748 457 R (*_thunk)(void*, void*, A1, A2);
Christopher Haster 11:f08e03081748 458 };
Christopher Haster 11:f08e03081748 459
Christopher Haster 11:f08e03081748 460 /** A class for storing and calling a pointer to a static or member function
Christopher Haster 11:f08e03081748 461 */
Christopher Haster 11:f08e03081748 462 template <typename R, typename A1>
Christopher Haster 14:4af7fef9cf08 463 class FuncPtr<R(A1)> {
Christopher Haster 11:f08e03081748 464 public:
Christopher Haster 14:4af7fef9cf08 465 /** Create a FuncPtr, attaching a static function
Christopher Haster 11:f08e03081748 466 *
Christopher Haster 11:f08e03081748 467 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 468 */
Christopher Haster 14:4af7fef9cf08 469 FuncPtr(R (*function)(A1) = 0) {
Christopher Haster 11:f08e03081748 470 attach(function);
Christopher Haster 11:f08e03081748 471 }
Christopher Haster 11:f08e03081748 472
Christopher Haster 14:4af7fef9cf08 473 /** Create a FuncPtr, attaching a static function with bound pointer
Christopher Haster 11:f08e03081748 474 *
Christopher Haster 11:f08e03081748 475 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 476 * @param function The static function to attach
Christopher Haster 11:f08e03081748 477 */
Christopher Haster 11:f08e03081748 478 template<typename T>
Christopher Haster 14:4af7fef9cf08 479 FuncPtr(T *object, R (*function)(T*, A1)) {
Christopher Haster 11:f08e03081748 480 attach(object, function);
Christopher Haster 11:f08e03081748 481 }
Christopher Haster 11:f08e03081748 482
Christopher Haster 14:4af7fef9cf08 483 /** Create a FuncPtr, attaching a member function
Christopher Haster 11:f08e03081748 484 *
Christopher Haster 11:f08e03081748 485 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 486 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 487 */
Christopher Haster 11:f08e03081748 488 template<typename T>
Christopher Haster 14:4af7fef9cf08 489 FuncPtr(T *object, R (T::*member)(A1)) {
Christopher Haster 11:f08e03081748 490 attach(object, member);
Christopher Haster 11:f08e03081748 491 }
Christopher Haster 11:f08e03081748 492
Christopher Haster 14:4af7fef9cf08 493 /** Create a FuncPtr from another FuncPtr
Christopher Haster 11:f08e03081748 494 *
Christopher Haster 11:f08e03081748 495 * @param func The func to attach
Christopher Haster 11:f08e03081748 496 */
Christopher Haster 14:4af7fef9cf08 497 FuncPtr(const FuncPtr<R(A1)> &func) {
Christopher Haster 11:f08e03081748 498 attach(func);
Christopher Haster 11:f08e03081748 499 }
Christopher Haster 11:f08e03081748 500
Christopher Haster 11:f08e03081748 501 /** Attach a static function
Christopher Haster 11:f08e03081748 502 *
Christopher Haster 11:f08e03081748 503 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 504 */
Christopher Haster 11:f08e03081748 505 void attach(R (*function)(A1)) {
Christopher Haster 11:f08e03081748 506 _object = 0;
Christopher Haster 11:f08e03081748 507 *reinterpret_cast<R (**)(A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 508 _thunk = &FuncPtr::staticthunk;
Christopher Haster 11:f08e03081748 509 }
Christopher Haster 11:f08e03081748 510
Christopher Haster 11:f08e03081748 511 /** Attach a static function with bound pointer
Christopher Haster 11:f08e03081748 512 *
Christopher Haster 11:f08e03081748 513 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 514 * @param function The static function to attach
Christopher Haster 11:f08e03081748 515 */
Christopher Haster 11:f08e03081748 516 template <typename T>
Christopher Haster 15:1ce23ed6859a 517 void attach(T *object, R (*function)(T*, A1)) {
Christopher Haster 11:f08e03081748 518 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 519 *reinterpret_cast<R (**)(T*, A1)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 520 _thunk = &FuncPtr::boundthunk<T>;
Christopher Haster 11:f08e03081748 521 }
Christopher Haster 11:f08e03081748 522
Christopher Haster 11:f08e03081748 523 /** Attach a member function
Christopher Haster 11:f08e03081748 524 *
Christopher Haster 11:f08e03081748 525 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 526 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 527 */
Christopher Haster 11:f08e03081748 528 template<typename T>
Christopher Haster 11:f08e03081748 529 void attach(T *object, R (T::*method)(A1)) {
Christopher Haster 11:f08e03081748 530 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 531 *reinterpret_cast<R (T::**)(A1)>(_function) = method;
Christopher Haster 14:4af7fef9cf08 532 _thunk = &FuncPtr::methodthunk<T>;
Christopher Haster 11:f08e03081748 533 }
Christopher Haster 11:f08e03081748 534
Christopher Haster 14:4af7fef9cf08 535 /** Attach a FuncPtr
Christopher Haster 11:f08e03081748 536 *
Christopher Haster 11:f08e03081748 537 * @param func The func to attach
Christopher Haster 11:f08e03081748 538 */
Christopher Haster 14:4af7fef9cf08 539 void attach(const FuncPtr<R(A1)> &func) {
Christopher Haster 11:f08e03081748 540 _object = func._object;
Christopher Haster 11:f08e03081748 541 memcpy(_function, func._function, sizeof _function);
Christopher Haster 11:f08e03081748 542 _thunk = func._thunk;
Christopher Haster 11:f08e03081748 543 }
Christopher Haster 11:f08e03081748 544
Christopher Haster 11:f08e03081748 545 /** Call the attached static or member function
Christopher Haster 11:f08e03081748 546 */
Christopher Haster 11:f08e03081748 547 R call(A1 a1) {
Christopher Haster 11:f08e03081748 548 return _thunk(_object, _function, a1);
Christopher Haster 11:f08e03081748 549 }
Christopher Haster 11:f08e03081748 550
Christopher Haster 11:f08e03081748 551 /** Get registered static function
Christopher Haster 11:f08e03081748 552 */
Christopher Haster 11:f08e03081748 553 R (*get_function(A1))() {
Christopher Haster 11:f08e03081748 554 return reinterpret_cast<R (*)(A1)>(_object ? 0 : _function);
Christopher Haster 11:f08e03081748 555 }
Christopher Haster 11:f08e03081748 556
Christopher Haster 11:f08e03081748 557 #ifdef MBED_OPERATORS
Christopher Haster 11:f08e03081748 558 R operator ()(A1 a1) {
Christopher Haster 11:f08e03081748 559 return call(a1);
Christopher Haster 11:f08e03081748 560 }
Christopher Haster 11:f08e03081748 561 operator bool(void) const {
Christopher Haster 11:f08e03081748 562 return static_cast<bool>(_function);
Christopher Haster 11:f08e03081748 563 }
Christopher Haster 11:f08e03081748 564 #endif
Christopher Haster 11:f08e03081748 565 private:
Christopher Haster 11:f08e03081748 566 // Static thunks for various function types
Christopher Haster 15:1ce23ed6859a 567 static R staticthunk(void*, void *func, A1 a1) {
Christopher Haster 11:f08e03081748 568 R (*f)(A1) = *reinterpret_cast<R (**)(A1)>(func);
Christopher Haster 11:f08e03081748 569 return f(a1);
Christopher Haster 11:f08e03081748 570 }
Christopher Haster 11:f08e03081748 571
Christopher Haster 11:f08e03081748 572 template<typename T>
Christopher Haster 11:f08e03081748 573 static R boundthunk(void *object, void *func, A1 a1) {
Christopher Haster 11:f08e03081748 574 T *o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 575 R (*f)(T*, A1) = *reinterpret_cast<R (**)(T*, A1)>(func);
Christopher Haster 11:f08e03081748 576 return f(o, a1);
Christopher Haster 11:f08e03081748 577 }
Christopher Haster 11:f08e03081748 578
Christopher Haster 11:f08e03081748 579 template<typename T>
Christopher Haster 11:f08e03081748 580 static R methodthunk(void *object, void *member, A1 a1) {
Christopher Haster 11:f08e03081748 581 T* o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 582 R (T::*m)(A1) = *reinterpret_cast<R (T::**)(A1)>(member);
Christopher Haster 11:f08e03081748 583 return (o->*m)(a1);
Christopher Haster 11:f08e03081748 584 }
Christopher Haster 11:f08e03081748 585
Christopher Haster 11:f08e03081748 586 // Forward declaration of an unknown class
Christopher Haster 11:f08e03081748 587 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
Christopher Haster 11:f08e03081748 588 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
Christopher Haster 11:f08e03081748 589 // and biggest alignment possible for member function.
Christopher Haster 11:f08e03081748 590 // This type can be used inside unions, it will help to provide the storage
Christopher Haster 11:f08e03081748 591 // with the proper size and alignment guarantees
Christopher Haster 11:f08e03081748 592 class UnknownClass;
Christopher Haster 11:f08e03081748 593
Christopher Haster 11:f08e03081748 594 // object this pointer
Christopher Haster 11:f08e03081748 595 void *_object;
Christopher Haster 11:f08e03081748 596
Christopher Haster 11:f08e03081748 597 // aligned raw member function pointer storage - converted back by registered thunk
Christopher Haster 11:f08e03081748 598 char _function[sizeof(void (UnknownClass::*)())];
Christopher Haster 11:f08e03081748 599
Christopher Haster 11:f08e03081748 600 // registered function to convert back and call _m.member on _object
Christopher Haster 11:f08e03081748 601 R (*_thunk)(void*, void*, A1);
Christopher Haster 11:f08e03081748 602 };
Christopher Haster 11:f08e03081748 603
Christopher Haster 11:f08e03081748 604 /** A class for storing and calling a pointer to a static or member function
Christopher Haster 11:f08e03081748 605 */
Christopher Haster 11:f08e03081748 606 template <typename R>
Christopher Haster 14:4af7fef9cf08 607 class FuncPtr<R()> {
Christopher Haster 11:f08e03081748 608 public:
Christopher Haster 14:4af7fef9cf08 609 /** Create a FuncPtr, attaching a static function
Christopher Haster 11:f08e03081748 610 *
Christopher Haster 11:f08e03081748 611 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 612 */
Christopher Haster 14:4af7fef9cf08 613 FuncPtr(R (*function)() = 0) {
Christopher Haster 11:f08e03081748 614 attach(function);
Christopher Haster 11:f08e03081748 615 }
Christopher Haster 11:f08e03081748 616
Christopher Haster 14:4af7fef9cf08 617 /** Create a FuncPtr, attaching a static function with bound pointer
Christopher Haster 11:f08e03081748 618 *
Christopher Haster 11:f08e03081748 619 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 620 * @param function The static function to attach
Christopher Haster 11:f08e03081748 621 */
Christopher Haster 11:f08e03081748 622 template<typename T>
Christopher Haster 14:4af7fef9cf08 623 FuncPtr(T *object, R (*function)(T*)) {
Christopher Haster 11:f08e03081748 624 attach(object, function);
Christopher Haster 11:f08e03081748 625 }
Christopher Haster 11:f08e03081748 626
Christopher Haster 14:4af7fef9cf08 627 /** Create a FuncPtr, attaching a member function
Christopher Haster 11:f08e03081748 628 *
Christopher Haster 11:f08e03081748 629 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 630 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 631 */
Christopher Haster 11:f08e03081748 632 template<typename T>
Christopher Haster 14:4af7fef9cf08 633 FuncPtr(T *object, R (T::*member)()) {
Christopher Haster 11:f08e03081748 634 attach(object, member);
Christopher Haster 11:f08e03081748 635 }
Christopher Haster 11:f08e03081748 636
Christopher Haster 14:4af7fef9cf08 637 /** Create a FuncPtr from another FuncPtr
Christopher Haster 11:f08e03081748 638 *
Christopher Haster 11:f08e03081748 639 * @param func The func to attach
Christopher Haster 11:f08e03081748 640 */
Christopher Haster 14:4af7fef9cf08 641 FuncPtr(const FuncPtr<R()> &func) {
Christopher Haster 11:f08e03081748 642 attach(func);
Christopher Haster 11:f08e03081748 643 }
Christopher Haster 11:f08e03081748 644
Christopher Haster 11:f08e03081748 645 /** Attach a static function
Christopher Haster 11:f08e03081748 646 *
Christopher Haster 11:f08e03081748 647 * @param function The static function to attach (default is none)
Christopher Haster 11:f08e03081748 648 */
Christopher Haster 11:f08e03081748 649 void attach(R (*function)()) {
Christopher Haster 11:f08e03081748 650 _object = 0;
Christopher Haster 11:f08e03081748 651 *reinterpret_cast<R (**)()>(_function) = function;
Christopher Haster 14:4af7fef9cf08 652 _thunk = &FuncPtr::staticthunk;
Christopher Haster 11:f08e03081748 653 }
Christopher Haster 11:f08e03081748 654
Christopher Haster 11:f08e03081748 655 /** Attach a static function with bound pointer
Christopher Haster 11:f08e03081748 656 *
Christopher Haster 11:f08e03081748 657 * @param object Pointer to object to bind to function
Christopher Haster 11:f08e03081748 658 * @param function The static function to attach
Christopher Haster 11:f08e03081748 659 */
Christopher Haster 11:f08e03081748 660 template <typename T>
Christopher Haster 15:1ce23ed6859a 661 void attach(T *object, R (*function)(T*)) {
Christopher Haster 11:f08e03081748 662 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 663 *reinterpret_cast<R (**)(T*)>(_function) = function;
Christopher Haster 14:4af7fef9cf08 664 _thunk = &FuncPtr::boundthunk<T>;
Christopher Haster 11:f08e03081748 665 }
Christopher Haster 11:f08e03081748 666
Christopher Haster 11:f08e03081748 667 /** Attach a member function
Christopher Haster 11:f08e03081748 668 *
Christopher Haster 11:f08e03081748 669 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
Christopher Haster 11:f08e03081748 670 * @param function The address of the member function to attach
Christopher Haster 11:f08e03081748 671 */
Christopher Haster 11:f08e03081748 672 template<typename T>
Christopher Haster 11:f08e03081748 673 void attach(T *object, R (T::*method)()) {
Christopher Haster 11:f08e03081748 674 _object = static_cast<void*>(object);
Christopher Haster 11:f08e03081748 675 *reinterpret_cast<R (T::**)()>(_function) = method;
Christopher Haster 14:4af7fef9cf08 676 _thunk = &FuncPtr::methodthunk<T>;
Christopher Haster 11:f08e03081748 677 }
Christopher Haster 11:f08e03081748 678
Christopher Haster 14:4af7fef9cf08 679 /** Attach a FuncPtr
Christopher Haster 11:f08e03081748 680 *
Christopher Haster 11:f08e03081748 681 * @param func The func to attach
Christopher Haster 11:f08e03081748 682 */
Christopher Haster 14:4af7fef9cf08 683 void attach(const FuncPtr<R()> &func) {
Christopher Haster 11:f08e03081748 684 _object = func._object;
Christopher Haster 11:f08e03081748 685 memcpy(_function, func._function, sizeof _function);
Christopher Haster 11:f08e03081748 686 _thunk = func._thunk;
Christopher Haster 11:f08e03081748 687 }
Christopher Haster 11:f08e03081748 688
Christopher Haster 11:f08e03081748 689 /** Call the attached static or member function
Christopher Haster 11:f08e03081748 690 */
Christopher Haster 11:f08e03081748 691 R call() {
Christopher Haster 11:f08e03081748 692 return _thunk(_object, _function);
Christopher Haster 11:f08e03081748 693 }
Christopher Haster 11:f08e03081748 694
Christopher Haster 11:f08e03081748 695 /** Get registered static function
Christopher Haster 11:f08e03081748 696 */
Christopher Haster 11:f08e03081748 697 R (*get_function())() {
Christopher Haster 11:f08e03081748 698 return reinterpret_cast<R (*)()>(_object ? 0 : _function);
Christopher Haster 11:f08e03081748 699 }
Christopher Haster 11:f08e03081748 700
Christopher Haster 11:f08e03081748 701 #ifdef MBED_OPERATORS
Christopher Haster 11:f08e03081748 702 R operator ()() {
Christopher Haster 11:f08e03081748 703 return call();
Christopher Haster 11:f08e03081748 704 }
Christopher Haster 11:f08e03081748 705 operator bool(void) const {
Christopher Haster 11:f08e03081748 706 return static_cast<bool>(_function);
Christopher Haster 11:f08e03081748 707 }
Christopher Haster 11:f08e03081748 708 #endif
Christopher Haster 11:f08e03081748 709 private:
Christopher Haster 11:f08e03081748 710 // Static thunks for various function types
Christopher Haster 15:1ce23ed6859a 711 static R staticthunk(void*, void *func) {
Christopher Haster 11:f08e03081748 712 R (*f)() = *reinterpret_cast<R (**)()>(func);
Christopher Haster 11:f08e03081748 713 return f();
Christopher Haster 11:f08e03081748 714 }
Christopher Haster 11:f08e03081748 715
Christopher Haster 11:f08e03081748 716 template<typename T>
Christopher Haster 11:f08e03081748 717 static R boundthunk(void *object, void *func) {
Christopher Haster 11:f08e03081748 718 T *o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 719 R (*f)(T*) = *reinterpret_cast<R (**)(T*)>(func);
Christopher Haster 11:f08e03081748 720 return f(o);
Christopher Haster 11:f08e03081748 721 }
Christopher Haster 11:f08e03081748 722
Christopher Haster 11:f08e03081748 723 template<typename T>
Christopher Haster 11:f08e03081748 724 static R methodthunk(void *object, void *member) {
Christopher Haster 11:f08e03081748 725 T* o = static_cast<T*>(object);
Christopher Haster 11:f08e03081748 726 R (T::*m)() = *reinterpret_cast<R (T::**)()>(member);
Christopher Haster 11:f08e03081748 727 return (o->*m)();
Christopher Haster 11:f08e03081748 728 }
Christopher Haster 11:f08e03081748 729
Christopher Haster 11:f08e03081748 730 // Forward declaration of an unknown class
Christopher Haster 11:f08e03081748 731 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
Christopher Haster 11:f08e03081748 732 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
Christopher Haster 11:f08e03081748 733 // and biggest alignment possible for member function.
Christopher Haster 11:f08e03081748 734 // This type can be used inside unions, it will help to provide the storage
Christopher Haster 11:f08e03081748 735 // with the proper size and alignment guarantees
Christopher Haster 11:f08e03081748 736 class UnknownClass;
Christopher Haster 11:f08e03081748 737
Christopher Haster 11:f08e03081748 738 // object this pointer
Christopher Haster 11:f08e03081748 739 void *_object;
Christopher Haster 11:f08e03081748 740
Christopher Haster 11:f08e03081748 741 // aligned raw member function pointer storage - converted back by registered thunk
Christopher Haster 11:f08e03081748 742 union {
Christopher Haster 11:f08e03081748 743 char _function[sizeof(void (UnknownClass::*)())];
Christopher Haster 11:f08e03081748 744 void (UnknownClass::*_unknownMethod)();
Christopher Haster 11:f08e03081748 745 };
Christopher Haster 11:f08e03081748 746
Christopher Haster 11:f08e03081748 747 // registered function to convert back and call _m.member on _object
Christopher Haster 11:f08e03081748 748 R (*_thunk)(void*, void*);
Christopher Haster 11:f08e03081748 749 };
Christopher Haster 11:f08e03081748 750
Christopher Haster 6:c2a3aa792960 751 // Overloads for backwards compatibility
Christopher Haster 6:c2a3aa792960 752 template <typename R, typename A1>
Christopher Haster 14:4af7fef9cf08 753 class FunctionPointerArg1 : public FuncPtr<R(A1)> {};
Christopher Haster 6:c2a3aa792960 754
Christopher Haster 6:c2a3aa792960 755 template <typename R>
Christopher Haster 14:4af7fef9cf08 756 class FunctionPointerArg1<R, void> : public FuncPtr<R()> {};
Christopher Haster 6:c2a3aa792960 757
Christopher Haster 14:4af7fef9cf08 758 typedef FuncPtr<void()> FunctionPointer;
Christopher Haster 14:4af7fef9cf08 759 typedef FuncPtr<void(int)> event_callback_t;
screamer 0:9c59db1fbc9e 760
screamer 0:9c59db1fbc9e 761 } // namespace mbed
screamer 0:9c59db1fbc9e 762
screamer 0:9c59db1fbc9e 763 #endif