Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: target-freescale
FunctionPointer.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef MBED_FUNCTIONPOINTER_H 00017 #define MBED_FUNCTIONPOINTER_H 00018 00019 #include <string.h> 00020 #include <stdint.h> 00021 00022 namespace mbed { 00023 00024 // Reusable FuncPtr class based on template specialization 00025 template <typename F> 00026 class FuncPtr; 00027 00028 /** A class for storing and calling a pointer to a static or member function 00029 */ 00030 template <typename R, typename A1, typename A2, typename A3, typename A4> 00031 class FuncPtr<R(A1, A2, A3, A4)> { 00032 public: 00033 /** Create a FuncPtr, attaching a static function 00034 * 00035 * @param function The static function to attach (default is none) 00036 */ 00037 FuncPtr(R (*function)(A1, A2, A3, A4) = 0) { 00038 attach(function); 00039 } 00040 00041 /** Create a FuncPtr, attaching a static function with bound pointer 00042 * 00043 * @param object Pointer to object to bind to function 00044 * @param function The static function to attach 00045 */ 00046 template<typename T> 00047 FuncPtr(T *object, R (*function)(T*, A1, A2, A3, A4)) { 00048 attach(object, function); 00049 } 00050 00051 /** Create a FuncPtr, attaching a member function 00052 * 00053 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00054 * @param function The address of the member function to attach 00055 */ 00056 template<typename T> 00057 FuncPtr(T *object, R (T::*member)(A1, A2, A3, A4)) { 00058 attach(object, member); 00059 } 00060 00061 /** Create a FuncPtr, attaching a function object 00062 * 00063 * @param object Pointer to a function object to attach 00064 */ 00065 template<typename T> 00066 FuncPtr(T *object) { 00067 attach(object, &T::operator()); 00068 } 00069 00070 /** Create a FuncPtr from another FuncPtr 00071 * 00072 * @param func The func to attach 00073 */ 00074 FuncPtr(const FuncPtr<R(A1, A2, A3, A4)> &func) { 00075 attach(func); 00076 } 00077 00078 /** Attach a static function 00079 * 00080 * @param function The static function to attach (default is none) 00081 */ 00082 void attach(R (*function)(A1, A2, A3, A4)) { 00083 _object = 0; 00084 memcpy(&_function, &function, sizeof function); 00085 _thunk = &FuncPtr::staticthunk; 00086 } 00087 00088 /** Attach a static function with bound pointer 00089 * 00090 * @param object Pointer to object to bind to function 00091 * @param function The static function to attach 00092 */ 00093 template <typename T> 00094 void attach(T *object, R (*function)(T*, A1, A2, A3, A4)) { 00095 _object = static_cast<void*>(object); 00096 memcpy(&_function, &function, sizeof function); 00097 _thunk = &FuncPtr::boundthunk<T>; 00098 } 00099 00100 /** Attach a member function 00101 * 00102 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00103 * @param function The address of the member function to attach 00104 */ 00105 template<typename T> 00106 void attach(T *object, R (T::*method)(A1, A2, A3, A4)) { 00107 _object = static_cast<void*>(object); 00108 memcpy(&_function, &method, sizeof method); 00109 _thunk = &FuncPtr::methodthunk<T>; 00110 } 00111 00112 /** Attach a function object 00113 * 00114 * @param object Pointer to a function object to attach 00115 */ 00116 template<typename T> 00117 void attach(T *object) { 00118 attach(object, &T::operator()); 00119 } 00120 00121 /** Attach a FuncPtr 00122 * 00123 * @param func The func to attach 00124 */ 00125 void attach(const FuncPtr<R(A1, A2, A3, A4)> &func) { 00126 _object = func._object; 00127 memcpy(&_function, &func._function, sizeof _function); 00128 _thunk = func._thunk; 00129 } 00130 00131 /** Call the attached static or member function 00132 */ 00133 R call(A1 a1, A2 a2, A3 a3, A4 a4) { 00134 return _thunk(_object, _function, a1, a2, a3, a4); 00135 } 00136 00137 /** Get registered static function 00138 */ 00139 R (*get_function(A1, A2, A3, A4))() { 00140 return reinterpret_cast<R (*)(A1, A2, A3, A4)>(_object ? 0 : _function); 00141 } 00142 00143 #ifdef MBED_OPERATORS 00144 R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) { 00145 return call(a1, a2, a3, a4); 00146 } 00147 operator bool(void) const { 00148 return static_cast<bool>(_function); 00149 } 00150 #endif 00151 private: 00152 // Static thunks for various function types 00153 static R staticthunk(void*, void *func, A1 a1, A2 a2, A3 a3, A4 a4) { 00154 R (*f)(A1, A2, A3, A4) = *reinterpret_cast<R (**)(A1, A2, A3, A4)>(func); 00155 return f(a1, a2, a3, a4); 00156 } 00157 00158 template<typename T> 00159 static R boundthunk(void *object, void *func, A1 a1, A2 a2, A3 a3, A4 a4) { 00160 T *o = static_cast<T*>(object); 00161 R (*f)(T*, A1, A2, A3, A4) = *reinterpret_cast<R (**)(T*, A1, A2, A3, A4)>(func); 00162 return f(o, a1); 00163 } 00164 00165 template<typename T> 00166 static R methodthunk(void *object, void *member, A1 a1, A2 a2, A3 a3, A4 a4) { 00167 T* o = static_cast<T*>(object); 00168 R (T::*m)(A1, A2, A3, A4) = *reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(member); 00169 return (o->*m)(a1, a2, a3, a4); 00170 } 00171 00172 // Forward declaration of an unknown class 00173 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard). 00174 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size 00175 // and biggest alignment possible for member function. 00176 // This type can be used inside unions, it will help to provide the storage 00177 // with the proper size and alignment guarantees 00178 class UnknownClass; 00179 00180 // object this pointer 00181 void *_object; 00182 00183 // aligned raw member function pointer storage - converted back by registered thunk 00184 char _function[sizeof(void (UnknownClass::*)())]; 00185 00186 // registered function to convert back and call _m.member on _object 00187 R (*_thunk)(void*, void*, A1, A2, A3, A4); 00188 }; 00189 00190 /** A class for storing and calling a pointer to a static or member function 00191 */ 00192 template <typename R, typename A1, typename A2, typename A3> 00193 class FuncPtr<R(A1, A2, A3)> { 00194 public: 00195 /** Create a FuncPtr, attaching a static function 00196 * 00197 * @param function The static function to attach (default is none) 00198 */ 00199 FuncPtr(R (*function)(A1, A2, A3) = 0) { 00200 attach(function); 00201 } 00202 00203 /** Create a FuncPtr, attaching a static function with bound pointer 00204 * 00205 * @param object Pointer to object to bind to function 00206 * @param function The static function to attach 00207 */ 00208 template<typename T> 00209 FuncPtr(T *object, R (*function)(T*, A1, A2, A3)) { 00210 attach(object, function); 00211 } 00212 00213 /** Create a FuncPtr, attaching a member function 00214 * 00215 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00216 * @param function The address of the member function to attach 00217 */ 00218 template<typename T> 00219 FuncPtr(T *object, R (T::*member)(A1, A2, A3)) { 00220 attach(object, member); 00221 } 00222 00223 /** Create a FuncPtr, attaching a function object 00224 * 00225 * @param object Pointer to a function object to attach 00226 */ 00227 template<typename T> 00228 FuncPtr(T *object) { 00229 attach(object, &T::operator()); 00230 } 00231 00232 /** Create a FuncPtr from another FuncPtr 00233 * 00234 * @param func The func to attach 00235 */ 00236 FuncPtr(const FuncPtr<R(A1, A2, A3)> &func) { 00237 attach(func); 00238 } 00239 00240 /** Attach a static function 00241 * 00242 * @param function The static function to attach (default is none) 00243 */ 00244 void attach(R (*function)(A1, A2, A3)) { 00245 _object = 0; 00246 memcpy(&_function, &function, sizeof function); 00247 _thunk = &FuncPtr::staticthunk; 00248 } 00249 00250 /** Attach a static function with bound pointer 00251 * 00252 * @param object Pointer to object to bind to function 00253 * @param function The static function to attach 00254 */ 00255 template <typename T> 00256 void attach(T *object, R (*function)(T*, A1, A2, A3)) { 00257 _object = static_cast<void*>(object); 00258 memcpy(&_function, &function, sizeof function); 00259 _thunk = &FuncPtr::boundthunk<T>; 00260 } 00261 00262 /** Attach a member function 00263 * 00264 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00265 * @param function The address of the member function to attach 00266 */ 00267 template<typename T> 00268 void attach(T *object, R (T::*method)(A1, A2, A3)) { 00269 _object = static_cast<void*>(object); 00270 memcpy(&_function, &method, sizeof method); 00271 _thunk = &FuncPtr::methodthunk<T>; 00272 } 00273 00274 /** Attach a function object 00275 * 00276 * @param object Pointer to a function object to attach 00277 */ 00278 template<typename T> 00279 void attach(T *object) { 00280 attach(object, &T::operator()); 00281 } 00282 00283 /** Attach a FuncPtr 00284 * 00285 * @param func The func to attach 00286 */ 00287 void attach(const FuncPtr<R(A1, A2, A3)> &func) { 00288 _object = func._object; 00289 memcpy(&_function, &func._function, sizeof _function); 00290 _thunk = func._thunk; 00291 } 00292 00293 /** Call the attached static or member function 00294 */ 00295 R call(A1 a1, A2 a2, A3 a3) { 00296 return _thunk(_object, _function, a1, a2, a3); 00297 } 00298 00299 /** Get registered static function 00300 */ 00301 R (*get_function(A1, A2, A3))() { 00302 return reinterpret_cast<R (*)(A1, A2, A3)>(_object ? 0 : _function); 00303 } 00304 00305 #ifdef MBED_OPERATORS 00306 R operator ()(A1 a1, A2 a2, A3 a3) { 00307 return call(a1, a2, a3); 00308 } 00309 operator bool(void) const { 00310 return static_cast<bool>(_function); 00311 } 00312 #endif 00313 private: 00314 // Static thunks for various function types 00315 static R staticthunk(void*, void *func, A1 a1, A2 a2, A3 a3) { 00316 R (*f)(A1, A2, A3) = *reinterpret_cast<R (**)(A1, A2, A3)>(func); 00317 return f(a1, a2, a3); 00318 } 00319 00320 template<typename T> 00321 static R boundthunk(void *object, void *func, A1 a1, A2 a2, A3 a3) { 00322 T *o = static_cast<T*>(object); 00323 R (*f)(T*, A1, A2, A3) = *reinterpret_cast<R (**)(T*, A1, A2, A3)>(func); 00324 return f(o, a1); 00325 } 00326 00327 template<typename T> 00328 static R methodthunk(void *object, void *member, A1 a1, A2 a2, A3 a3) { 00329 T* o = static_cast<T*>(object); 00330 R (T::*m)(A1, A2, A3) = *reinterpret_cast<R (T::**)(A1, A2, A3)>(member); 00331 return (o->*m)(a1, a2, a3); 00332 } 00333 00334 // Forward declaration of an unknown class 00335 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard). 00336 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size 00337 // and biggest alignment possible for member function. 00338 // This type can be used inside unions, it will help to provide the storage 00339 // with the proper size and alignment guarantees 00340 class UnknownClass; 00341 00342 // object this pointer 00343 void *_object; 00344 00345 // aligned raw member function pointer storage - converted back by registered thunk 00346 char _function[sizeof(void (UnknownClass::*)())]; 00347 00348 // registered function to convert back and call _m.member on _object 00349 R (*_thunk)(void*, void*, A1, A2, A3); 00350 }; 00351 00352 /** A class for storing and calling a pointer to a static or member function 00353 */ 00354 template <typename R, typename A1, typename A2> 00355 class FuncPtr<R(A1, A2)> { 00356 public: 00357 /** Create a FuncPtr, attaching a static function 00358 * 00359 * @param function The static function to attach (default is none) 00360 */ 00361 FuncPtr(R (*function)(A1, A2) = 0) { 00362 attach(function); 00363 } 00364 00365 /** Create a FuncPtr, attaching a static function with bound pointer 00366 * 00367 * @param object Pointer to object to bind to function 00368 * @param function The static function to attach 00369 */ 00370 template<typename T> 00371 FuncPtr(T *object, R (*function)(T*, A1, A2)) { 00372 attach(object, function); 00373 } 00374 00375 /** Create a FuncPtr, attaching a member function 00376 * 00377 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00378 * @param function The address of the member function to attach 00379 */ 00380 template<typename T> 00381 FuncPtr(T *object, R (T::*member)(A1, A2)) { 00382 attach(object, member); 00383 } 00384 00385 /** Create a FuncPtr, attaching a function object 00386 * 00387 * @param object Pointer to a function object to attach 00388 */ 00389 template<typename T> 00390 FuncPtr(T *object) { 00391 attach(object, &T::operator()); 00392 } 00393 00394 /** Create a FuncPtr from another FuncPtr 00395 * 00396 * @param func The func to attach 00397 */ 00398 FuncPtr(const FuncPtr<R(A1, A2)> &func) { 00399 attach(func); 00400 } 00401 00402 /** Attach a static function 00403 * 00404 * @param function The static function to attach (default is none) 00405 */ 00406 void attach(R (*function)(A1, A2)) { 00407 _object = 0; 00408 memcpy(&_function, &function, sizeof function); 00409 _thunk = &FuncPtr::staticthunk; 00410 } 00411 00412 /** Attach a static function with bound pointer 00413 * 00414 * @param object Pointer to object to bind to function 00415 * @param function The static function to attach 00416 */ 00417 template <typename T> 00418 void attach(T *object, R (*function)(T*, A1, A2)) { 00419 _object = static_cast<void*>(object); 00420 memcpy(&_function, &function, sizeof function); 00421 _thunk = &FuncPtr::boundthunk<T>; 00422 } 00423 00424 /** Attach a member function 00425 * 00426 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00427 * @param function The address of the member function to attach 00428 */ 00429 template<typename T> 00430 void attach(T *object, R (T::*method)(A1, A2)) { 00431 _object = static_cast<void*>(object); 00432 memcpy(&_function, &method, sizeof method); 00433 _thunk = &FuncPtr::methodthunk<T>; 00434 } 00435 00436 /** Attach a function object 00437 * 00438 * @param object Pointer to a function object to attach 00439 */ 00440 template<typename T> 00441 void attach(T *object) { 00442 attach(object, &T::operator()); 00443 } 00444 00445 /** Attach a FuncPtr 00446 * 00447 * @param func The func to attach 00448 */ 00449 void attach(const FuncPtr<R(A1, A2)> &func) { 00450 _object = func._object; 00451 memcpy(&_function, &func._function, sizeof _function); 00452 _thunk = func._thunk; 00453 } 00454 00455 /** Call the attached static or member function 00456 */ 00457 R call(A1 a1, A2 a2) { 00458 return _thunk(_object, _function, a1, a2); 00459 } 00460 00461 /** Get registered static function 00462 */ 00463 R (*get_function(A1, A2))() { 00464 return reinterpret_cast<R (*)(A1, A2)>(_object ? 0 : _function); 00465 } 00466 00467 #ifdef MBED_OPERATORS 00468 R operator ()(A1 a1, A2 a2) { 00469 return call(a1, a2); 00470 } 00471 operator bool(void) const { 00472 return static_cast<bool>(_function); 00473 } 00474 #endif 00475 private: 00476 // Static thunks for various function types 00477 static R staticthunk(void*, void *func, A1 a1, A2 a2) { 00478 R (*f)(A1, A2) = *reinterpret_cast<R (**)(A1, A2)>(func); 00479 return f(a1, a2); 00480 } 00481 00482 template<typename T> 00483 static R boundthunk(void *object, void *func, A1 a1, A2 a2) { 00484 T *o = static_cast<T*>(object); 00485 R (*f)(T*, A1, A2) = *reinterpret_cast<R (**)(T*, A1, A2)>(func); 00486 return f(o, a1); 00487 } 00488 00489 template<typename T> 00490 static R methodthunk(void *object, void *member, A1 a1, A2 a2) { 00491 T* o = static_cast<T*>(object); 00492 R (T::*m)(A1, A2) = *reinterpret_cast<R (T::**)(A1, A2)>(member); 00493 return (o->*m)(a1, a2); 00494 } 00495 00496 // Forward declaration of an unknown class 00497 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard). 00498 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size 00499 // and biggest alignment possible for member function. 00500 // This type can be used inside unions, it will help to provide the storage 00501 // with the proper size and alignment guarantees 00502 class UnknownClass; 00503 00504 // object this pointer 00505 void *_object; 00506 00507 // aligned raw member function pointer storage - converted back by registered thunk 00508 char _function[sizeof(void (UnknownClass::*)())]; 00509 00510 // registered function to convert back and call _m.member on _object 00511 R (*_thunk)(void*, void*, A1, A2); 00512 }; 00513 00514 /** A class for storing and calling a pointer to a static or member function 00515 */ 00516 template <typename R, typename A1> 00517 class FuncPtr<R(A1)> { 00518 public: 00519 /** Create a FuncPtr, attaching a static function 00520 * 00521 * @param function The static function to attach (default is none) 00522 */ 00523 FuncPtr(R (*function)(A1) = 0) { 00524 attach(function); 00525 } 00526 00527 /** Create a FuncPtr, attaching a static function with bound pointer 00528 * 00529 * @param object Pointer to object to bind to function 00530 * @param function The static function to attach 00531 */ 00532 template<typename T> 00533 FuncPtr(T *object, R (*function)(T*, A1)) { 00534 attach(object, function); 00535 } 00536 00537 /** Create a FuncPtr, attaching a member function 00538 * 00539 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00540 * @param function The address of the member function to attach 00541 */ 00542 template<typename T> 00543 FuncPtr(T *object, R (T::*member)(A1)) { 00544 attach(object, member); 00545 } 00546 00547 /** Create a FuncPtr, attaching a function object 00548 * 00549 * @param object Pointer to a function object to attach 00550 */ 00551 template<typename T> 00552 FuncPtr(T *object) { 00553 attach(object, &T::operator()); 00554 } 00555 00556 /** Create a FuncPtr from another FuncPtr 00557 * 00558 * @param func The func to attach 00559 */ 00560 FuncPtr(const FuncPtr<R(A1)> &func) { 00561 attach(func); 00562 } 00563 00564 /** Attach a static function 00565 * 00566 * @param function The static function to attach (default is none) 00567 */ 00568 void attach(R (*function)(A1)) { 00569 _object = 0; 00570 memcpy(&_function, &function, sizeof function); 00571 _thunk = &FuncPtr::staticthunk; 00572 } 00573 00574 /** Attach a static function with bound pointer 00575 * 00576 * @param object Pointer to object to bind to function 00577 * @param function The static function to attach 00578 */ 00579 template <typename T> 00580 void attach(T *object, R (*function)(T*, A1)) { 00581 _object = static_cast<void*>(object); 00582 memcpy(&_function, &function, sizeof function); 00583 _thunk = &FuncPtr::boundthunk<T>; 00584 } 00585 00586 /** Attach a member function 00587 * 00588 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00589 * @param function The address of the member function to attach 00590 */ 00591 template<typename T> 00592 void attach(T *object, R (T::*method)(A1)) { 00593 _object = static_cast<void*>(object); 00594 memcpy(&_function, &method, sizeof method); 00595 _thunk = &FuncPtr::methodthunk<T>; 00596 } 00597 00598 /** Attach a function object 00599 * 00600 * @param object Pointer to a function object to attach 00601 */ 00602 template<typename T> 00603 void attach(T *object) { 00604 attach(object, &T::operator()); 00605 } 00606 00607 /** Attach a FuncPtr 00608 * 00609 * @param func The func to attach 00610 */ 00611 void attach(const FuncPtr<R(A1)> &func) { 00612 _object = func._object; 00613 memcpy(&_function, &func._function, sizeof _function); 00614 _thunk = func._thunk; 00615 } 00616 00617 /** Call the attached static or member function 00618 */ 00619 R call(A1 a1) { 00620 return _thunk(_object, _function, a1); 00621 } 00622 00623 /** Get registered static function 00624 */ 00625 R (*get_function(A1))() { 00626 return reinterpret_cast<R (*)(A1)>(_object ? 0 : _function); 00627 } 00628 00629 #ifdef MBED_OPERATORS 00630 R operator ()(A1 a1) { 00631 return call(a1); 00632 } 00633 operator bool(void) const { 00634 return static_cast<bool>(_function); 00635 } 00636 #endif 00637 private: 00638 // Static thunks for various function types 00639 static R staticthunk(void*, void *func, A1 a1) { 00640 R (*f)(A1) = *reinterpret_cast<R (**)(A1)>(func); 00641 return f(a1); 00642 } 00643 00644 template<typename T> 00645 static R boundthunk(void *object, void *func, A1 a1) { 00646 T *o = static_cast<T*>(object); 00647 R (*f)(T*, A1) = *reinterpret_cast<R (**)(T*, A1)>(func); 00648 return f(o, a1); 00649 } 00650 00651 template<typename T> 00652 static R methodthunk(void *object, void *member, A1 a1) { 00653 T* o = static_cast<T*>(object); 00654 R (T::*m)(A1) = *reinterpret_cast<R (T::**)(A1)>(member); 00655 return (o->*m)(a1); 00656 } 00657 00658 // Forward declaration of an unknown class 00659 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard). 00660 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size 00661 // and biggest alignment possible for member function. 00662 // This type can be used inside unions, it will help to provide the storage 00663 // with the proper size and alignment guarantees 00664 class UnknownClass; 00665 00666 // object this pointer 00667 void *_object; 00668 00669 // aligned raw member function pointer storage - converted back by registered thunk 00670 char _function[sizeof(void (UnknownClass::*)())]; 00671 00672 // registered function to convert back and call _m.member on _object 00673 R (*_thunk)(void*, void*, A1); 00674 }; 00675 00676 /** A class for storing and calling a pointer to a static or member function 00677 */ 00678 template <typename R> 00679 class FuncPtr<R()> { 00680 public: 00681 /** Create a FuncPtr, attaching a static function 00682 * 00683 * @param function The static function to attach (default is none) 00684 */ 00685 FuncPtr(R (*function)() = 0) { 00686 attach(function); 00687 } 00688 00689 /** Create a FuncPtr, attaching a static function with bound pointer 00690 * 00691 * @param object Pointer to object to bind to function 00692 * @param function The static function to attach 00693 */ 00694 template<typename T> 00695 FuncPtr(T *object, R (*function)(T*)) { 00696 attach(object, function); 00697 } 00698 00699 /** Create a FuncPtr, attaching a member function 00700 * 00701 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00702 * @param function The address of the member function to attach 00703 */ 00704 template<typename T> 00705 FuncPtr(T *object, R (T::*member)()) { 00706 attach(object, member); 00707 } 00708 00709 /** Create a FuncPtr, attaching a function object 00710 * 00711 * @param object Pointer to a function object to attach 00712 */ 00713 template<typename T> 00714 FuncPtr(T *object) { 00715 attach(object, &T::operator()); 00716 } 00717 00718 /** Create a FuncPtr from another FuncPtr 00719 * 00720 * @param func The func to attach 00721 */ 00722 FuncPtr(const FuncPtr<R()> &func) { 00723 attach(func); 00724 } 00725 00726 /** Attach a static function 00727 * 00728 * @param function The static function to attach (default is none) 00729 */ 00730 void attach(R (*function)()) { 00731 _object = 0; 00732 memcpy(&_function, &function, sizeof function); 00733 _thunk = &FuncPtr::staticthunk; 00734 } 00735 00736 /** Attach a static function with bound pointer 00737 * 00738 * @param object Pointer to object to bind to function 00739 * @param function The static function to attach 00740 */ 00741 template <typename T> 00742 void attach(T *object, R (*function)(T*)) { 00743 _object = static_cast<void*>(object); 00744 memcpy(&_function, &function, sizeof function); 00745 _thunk = &FuncPtr::boundthunk<T>; 00746 } 00747 00748 /** Attach a member function 00749 * 00750 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00751 * @param function The address of the member function to attach 00752 */ 00753 template<typename T> 00754 void attach(T *object, R (T::*method)()) { 00755 _object = static_cast<void*>(object); 00756 memcpy(&_function, &method, sizeof method); 00757 _thunk = &FuncPtr::methodthunk<T>; 00758 } 00759 00760 /** Attach a function object 00761 * 00762 * @param object Pointer to a function object to attach 00763 */ 00764 template<typename T> 00765 void attach(T *object) { 00766 attach(object, &T::operator()); 00767 } 00768 00769 /** Attach a FuncPtr 00770 * 00771 * @param func The func to attach 00772 */ 00773 void attach(const FuncPtr<R()> &func) { 00774 _object = func._object; 00775 memcpy(&_function, &func._function, sizeof _function); 00776 _thunk = func._thunk; 00777 } 00778 00779 /** Call the attached static or member function 00780 */ 00781 R call() { 00782 return _thunk(_object, _function); 00783 } 00784 00785 /** Get registered static function 00786 */ 00787 R (*get_function())() { 00788 return reinterpret_cast<R (*)()>(_object ? 0 : _function); 00789 } 00790 00791 #ifdef MBED_OPERATORS 00792 R operator ()() { 00793 return call(); 00794 } 00795 operator bool(void) const { 00796 return static_cast<bool>(_function); 00797 } 00798 #endif 00799 private: 00800 // Static thunks for various function types 00801 static R staticthunk(void*, void *func) { 00802 R (*f)() = *reinterpret_cast<R (**)()>(func); 00803 return f(); 00804 } 00805 00806 template<typename T> 00807 static R boundthunk(void *object, void *func) { 00808 T *o = static_cast<T*>(object); 00809 R (*f)(T*) = *reinterpret_cast<R (**)(T*)>(func); 00810 return f(o); 00811 } 00812 00813 template<typename T> 00814 static R methodthunk(void *object, void *member) { 00815 T* o = static_cast<T*>(object); 00816 R (T::*m)() = *reinterpret_cast<R (T::**)()>(member); 00817 return (o->*m)(); 00818 } 00819 00820 // Forward declaration of an unknown class 00821 // this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard). 00822 // As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size 00823 // and biggest alignment possible for member function. 00824 // This type can be used inside unions, it will help to provide the storage 00825 // with the proper size and alignment guarantees 00826 class UnknownClass; 00827 00828 // object this pointer 00829 void *_object; 00830 00831 // aligned raw member function pointer storage - converted back by registered thunk 00832 union { 00833 char _function[sizeof(void (UnknownClass::*)())]; 00834 void (UnknownClass::*_unknownMethod)(); 00835 }; 00836 00837 // registered function to convert back and call _m.member on _object 00838 R (*_thunk)(void*, void*); 00839 }; 00840 00841 // Overloads for backwards compatibility 00842 template <typename R, typename A1> 00843 class FunctionPointerArg1 : public FuncPtr<R(A1)> {}; 00844 00845 template <typename R> 00846 class FunctionPointerArg1<R, void> : public FuncPtr<R()> {}; 00847 00848 typedef FuncPtr<void()> FunctionPointer; 00849 typedef FuncPtr<void(int)> event_callback_t; 00850 00851 } // namespace mbed 00852 00853 #endif
Generated on Sat Aug 6 2022 08:19:56 by
1.7.2