WORKS
Dependencies: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
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 #include <stddef.h> 00022 #include <stdarg.h> 00023 #include <new> 00024 #include "FunctionPointerBase.h" 00025 #include "FunctionPointerBind.h" 00026 00027 namespace mbed { 00028 /** A class for storing and calling a pointer to a static or member void function without arguments 00029 */ 00030 template <typename R> 00031 class FunctionPointer0 : public FunctionPointerBase<R>{ 00032 public: 00033 typedef R(*static_fp)(void); 00034 typedef struct arg_struct{ 00035 } ArgStruct; 00036 /** Create a FunctionPointer, attaching a static function 00037 * 00038 * @param function The void static function to attach (default is none) 00039 */ 00040 FunctionPointer0(static_fp function = 0): 00041 FunctionPointerBase<R>() 00042 { 00043 attach(function); 00044 } 00045 00046 /** Create a FunctionPointer, attaching a member function 00047 * 00048 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00049 * @param function The address of the void member function to attach 00050 */ 00051 template<typename T> 00052 FunctionPointer0(T *object, R (T::*member)(void)): 00053 FunctionPointerBase<R>() 00054 { 00055 attach(object, member); 00056 } 00057 00058 /** Attach a static function 00059 * 00060 * @param function The void static function to attach (default is none) 00061 */ 00062 void attach(static_fp function) { 00063 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function); 00064 FunctionPointerBase<R>::_membercaller = &FunctionPointer0::staticcaller; 00065 } 00066 00067 /** Attach a member function 00068 * 00069 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00070 * @param function The address of the void member function to attach 00071 */ 00072 template<typename T> 00073 void attach(T *object, R (T::*member)(void)) { 00074 FunctionPointerBase<R>::_object = static_cast<void*>(object); 00075 *reinterpret_cast<R (T::**)(void)>(FunctionPointerBase<R>::_member) = member; 00076 FunctionPointerBase<R>::_membercaller = &FunctionPointer0::membercaller<T>; 00077 } 00078 00079 /** Call the attached static or member function 00080 */ 00081 R call(){ 00082 return FunctionPointerBase<R>::call(NULL); 00083 } 00084 00085 FunctionPointerBind<R> bind() { 00086 FunctionPointerBind<R> fp; 00087 fp.bind(&FunctionPointerBase<R>::_nullops, (ArgStruct *) NULL, this); 00088 return fp; 00089 } 00090 00091 static_fp get_function()const { 00092 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object); 00093 } 00094 00095 R operator ()(void) { 00096 return call(); 00097 } 00098 00099 private: 00100 template<typename T> 00101 static R membercaller(void *object, uintptr_t *member, void *arg) { 00102 (void) arg; 00103 T* o = static_cast<T*>(object); 00104 R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member); 00105 return (o->**m)(); 00106 } 00107 static R staticcaller(void *object, uintptr_t *member, void *arg) { 00108 (void) arg; 00109 (void) member; 00110 static_fp f = reinterpret_cast<static_fp>(object); 00111 return f(); 00112 } 00113 }; 00114 00115 /* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */ 00116 00117 /** A class for storing and calling a pointer to a static or member void function with one argument 00118 */ 00119 template <typename R, typename A1> 00120 class FunctionPointer1 : public FunctionPointerBase<R> { 00121 protected: 00122 typedef struct arg_struct{ 00123 A1 a1; 00124 arg_struct(const A1 *b1) { 00125 a1 = *b1; 00126 } 00127 } ArgStruct; 00128 00129 public: 00130 typedef R(*static_fp)(A1); 00131 /** Create a FunctionPointer, attaching a static function 00132 * 00133 * @param function The void static function to attach (default is none) 00134 */ 00135 FunctionPointer1(static_fp function = 0) { 00136 attach(function); 00137 } 00138 00139 /** Create a FunctionPointer, attaching a member function 00140 * 00141 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00142 * @param function The address of the void member function to attach 00143 */ 00144 template<typename T> 00145 FunctionPointer1(T *object, R (T::*member)(A1)) { 00146 attach(object, member); 00147 } 00148 00149 /** Attach a static function 00150 * 00151 * @param function The void static function to attach (default is none) 00152 */ 00153 void attach(static_fp function) { 00154 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function); 00155 FunctionPointerBase<R>::_membercaller = &FunctionPointer1::staticcaller; 00156 } 00157 00158 /** Attach a member function 00159 * 00160 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00161 * @param function The address of the void member function to attach 00162 */ 00163 template<typename T> 00164 void attach(T *object, R (T::*member)(A1)) 00165 { 00166 FunctionPointerBase<R>::_object = static_cast<void*>(object); 00167 *reinterpret_cast<R (T::**)(A1)>(FunctionPointerBase<R>::_member) = member; 00168 FunctionPointerBase<R>::_membercaller = &FunctionPointer1::membercaller<T>; 00169 } 00170 00171 FunctionPointerBind<R> bind(const A1 &a1) { 00172 FunctionPointerBind<R> fp; 00173 fp.bind(&_fp1_ops, (ArgStruct *) NULL, this, &a1); 00174 return fp; 00175 } 00176 00177 00178 /** Call the attached static or member function 00179 */ 00180 R call(A1 a1) 00181 { 00182 ArgStruct Args(&a1); 00183 return FunctionPointerBase<R>::call(&Args); 00184 } 00185 00186 static_fp get_function()const 00187 { 00188 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object); 00189 } 00190 00191 R operator ()(A1 a) { 00192 return call(a); 00193 } 00194 00195 private: 00196 template<typename T> 00197 static R membercaller(void *object, uintptr_t *member, void *arg) { 00198 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00199 T* o = static_cast<T*>(object); 00200 R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member); 00201 return (o->**m)(Args->a1); 00202 } 00203 static R staticcaller(void *object, uintptr_t *member, void *arg) { 00204 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00205 (void) member; 00206 static_fp f = reinterpret_cast<static_fp>(object); 00207 return f(Args->a1); 00208 } 00209 /* static void constructor(void * dest, va_list args) { 00210 new(dest) ArgStruct(va_arg(args,A1*)); 00211 } 00212 static void copy_constructor(void *dest , void* src) { 00213 ArgStruct *src_args = static_cast<ArgStruct *>(src); 00214 new(dest) ArgStruct(&(src_args->a1)); 00215 } 00216 static void destructor(void *args) { 00217 ArgStruct *argstruct = static_cast<ArgStruct *>(args); 00218 argstruct->~arg_struct(); 00219 } 00220 */ 00221 protected: 00222 static const struct FunctionPointerBase<R>::ArgOps _fp1_ops; 00223 }; 00224 00225 template <typename R, typename A1> 00226 const struct FunctionPointerBase<R>::ArgOps FunctionPointer1<R,A1>::_fp1_ops = { 00227 FunctionPointer1<R,A1>::constructor, 00228 FunctionPointer1<R,A1>::copy_constructor, 00229 FunctionPointer1<R,A1>::destructor 00230 }; 00231 00232 00233 /** A class for storing and calling a pointer to a static or member void function with two arguments 00234 */ 00235 template <typename R, typename A1, typename A2> 00236 class FunctionPointer2 : public FunctionPointerBase<R> { 00237 protected: 00238 typedef struct arg_struct{ 00239 A1 a1; 00240 A2 a2; 00241 arg_struct(const A1 *b1, const A2 *b2) { 00242 a1 = *b1; 00243 a2 = *b2; 00244 } 00245 } ArgStruct; 00246 00247 public: 00248 typedef R(*static_fp)(A1, A2); 00249 /** Create a FunctionPointer, attaching a static function 00250 * 00251 * @param function The void static function to attach (default is none) 00252 */ 00253 FunctionPointer2(static_fp function = 0) { 00254 attach(function); 00255 } 00256 00257 /** Create a FunctionPointer, attaching a member function 00258 * 00259 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00260 * @param function The address of the void member function to attach 00261 */ 00262 template<typename T> 00263 FunctionPointer2(T *object, R (T::*member)(A1, A2)) { 00264 attach(object, member); 00265 } 00266 00267 /** Attach a static function 00268 * 00269 * @param function The void static function to attach (default is none) 00270 */ 00271 void attach(static_fp function) { 00272 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function); 00273 FunctionPointerBase<R>::_membercaller = &FunctionPointer2::staticcaller; 00274 } 00275 00276 /** Attach a member function 00277 * 00278 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00279 * @param function The address of the void member function to attach 00280 */ 00281 template<typename T> 00282 void attach(T *object, R (T::*member)(A1, A2)) 00283 { 00284 FunctionPointerBase<R>::_object = static_cast<void*>(object); 00285 *reinterpret_cast<R (T::**)(A1, A2)>(FunctionPointerBase<R>::_member) = member; 00286 FunctionPointerBase<R>::_membercaller = &FunctionPointer2::membercaller<T>; 00287 } 00288 00289 FunctionPointerBind<R> bind(const A1 &a1, const A2 &a2) { 00290 FunctionPointerBind<R> fp; 00291 fp.bind(&_fp2_ops, (ArgStruct *) NULL, this, &a1, &a2); 00292 return fp; 00293 } 00294 00295 00296 /** Call the attached static or member function 00297 */ 00298 R call(A1 a1, A2 a2) 00299 { 00300 ArgStruct Args(&a1, &a2); 00301 return FunctionPointerBase<R>::call(&Args); 00302 } 00303 00304 static_fp get_function()const 00305 { 00306 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object); 00307 } 00308 00309 R operator ()(A1 a1, A2 a2) { 00310 return call(a1, a2); 00311 } 00312 00313 private: 00314 template<typename T> 00315 static R membercaller(void *object, uintptr_t *member, void *arg) { 00316 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00317 T* o = static_cast<T*>(object); 00318 R (T::**m)(A1, A2) = reinterpret_cast<R (T::**)(A1, A2)>(member); 00319 return (o->**m)(Args->a1, Args->a2); 00320 } 00321 static R staticcaller(void *object, uintptr_t *member, void *arg) { 00322 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00323 (void) member; 00324 static_fp f = reinterpret_cast<static_fp>(object); 00325 return f(Args->a1, Args->a2); 00326 } 00327 /* static void constructor(void * dest, va_list args) { 00328 A1 *a1 = va_arg(args, A1*); 00329 A2 *a2 = va_arg(args, A2*); 00330 new(dest) ArgStruct(a1, a2); 00331 } 00332 static void copy_constructor(void *dest , void* src) { 00333 ArgStruct *src_args = static_cast<ArgStruct *>(src); 00334 new(dest) ArgStruct(&(src_args->a1), &(src_args->a2)); 00335 } 00336 static void destructor(void *args) { 00337 ArgStruct *argstruct = static_cast<ArgStruct *>(args); 00338 argstruct->~arg_struct(); 00339 } 00340 */ 00341 protected: 00342 static const struct FunctionPointerBase<R>::ArgOps _fp2_ops; 00343 }; 00344 00345 template <typename R, typename A1, typename A2> 00346 const struct FunctionPointerBase<R>::ArgOps FunctionPointer2<R,A1,A2>::_fp2_ops = { 00347 FunctionPointer2<R,A1,A2>::constructor, 00348 FunctionPointer2<R,A1,A2>::copy_constructor, 00349 FunctionPointer2<R,A1,A2>::destructor 00350 }; 00351 00352 /** A class for storing and calling a pointer to a static or member void function with three arguments 00353 */ 00354 template <typename R, typename A1, typename A2, typename A3> 00355 class FunctionPointer3 : public FunctionPointerBase<R> { 00356 protected: 00357 typedef struct arg_struct{ 00358 A1 a1; 00359 A2 a2; 00360 A3 a3; 00361 arg_struct(const A1 *b1, const A2 *b2, const A3* b3) { 00362 a1 = *b1; 00363 a2 = *b2; 00364 a3 = *b3; 00365 } 00366 } ArgStruct; 00367 00368 public: 00369 typedef R(*static_fp)(A1, A2, A3); 00370 /** Create a FunctionPointer, attaching a static function 00371 * 00372 * @param function The void static function to attach (default is none) 00373 */ 00374 FunctionPointer3(static_fp function = 0) { 00375 attach(function); 00376 } 00377 00378 /** Create a FunctionPointer, attaching a member function 00379 * 00380 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00381 * @param function The address of the void member function to attach 00382 */ 00383 template<typename T> 00384 FunctionPointer3(T *object, R (T::*member)(A1, A2, A3)) { 00385 attach(object, member); 00386 } 00387 00388 /** Attach a static function 00389 * 00390 * @param function The void static function to attach (default is none) 00391 */ 00392 void attach(static_fp function) { 00393 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function); 00394 FunctionPointerBase<R>::_membercaller = &FunctionPointer3::staticcaller; 00395 } 00396 00397 /** Attach a member function 00398 * 00399 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00400 * @param function The address of the void member function to attach 00401 */ 00402 template<typename T> 00403 void attach(T *object, R (T::*member)(A1, A2, A3)) 00404 { 00405 FunctionPointerBase<R>::_object = static_cast<void*>(object); 00406 *reinterpret_cast<R (T::**)(A1, A2, A3)>(FunctionPointerBase<R>::_member) = member; 00407 FunctionPointerBase<R>::_membercaller = &FunctionPointer3::membercaller<T>; 00408 } 00409 00410 FunctionPointerBind<R> bind(const A1 &a1, const A2 &a2, const A3 &a3) { 00411 FunctionPointerBind<R> fp; 00412 fp.bind(&_fp3_ops, (ArgStruct *) NULL, this, &a1, &a2, &a3); 00413 return fp; 00414 } 00415 00416 00417 /** Call the attached static or member function 00418 */ 00419 R call(A1 a1, A2 a2, A3 a3) 00420 { 00421 ArgStruct Args(&a1, &a2, &a3); 00422 return FunctionPointerBase<R>::call(&Args); 00423 } 00424 00425 static_fp get_function()const 00426 { 00427 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object); 00428 } 00429 00430 R operator ()(A1 a1, A2 a2, A3 a3) { 00431 return call(a1, a2, a3); 00432 } 00433 00434 private: 00435 template<typename T> 00436 static R membercaller(void *object, uintptr_t *member, void *arg) { 00437 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00438 T* o = static_cast<T*>(object); 00439 R (T::**m)(A1, A2, A3) = reinterpret_cast<R (T::**)(A1, A2, A3)>(member); 00440 return (o->**m)(Args->a1, Args->a2, Args->a3); 00441 } 00442 static R staticcaller(void *object, uintptr_t *member, void *arg) { 00443 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00444 (void) member; 00445 static_fp f = reinterpret_cast<static_fp>(object); 00446 return f(Args->a1, Args->a2, Args->a3); 00447 } 00448 /* static void constructor(void * dest, va_list args) { 00449 A1 *a1 = va_arg(args, A1*); 00450 A2 *a2 = va_arg(args, A2*); 00451 A3 *a3 = va_arg(args, A3*); 00452 new(dest) ArgStruct(a1, a2, a3); 00453 } 00454 static void copy_constructor(void *dest , void* src) { 00455 ArgStruct *src_args = static_cast<ArgStruct *>(src); 00456 new(dest) ArgStruct(&(src_args->a1), &(src_args->a2), &(src_args->a3)); 00457 } 00458 static void destructor(void *args) { 00459 ArgStruct *argstruct = static_cast<ArgStruct *>(args); 00460 argstruct->~arg_struct(); 00461 } 00462 */ 00463 protected: 00464 static const struct FunctionPointerBase<R>::ArgOps _fp3_ops; 00465 }; 00466 00467 template <typename R, typename A1, typename A2, typename A3> 00468 const struct FunctionPointerBase<R>::ArgOps FunctionPointer3<R,A1,A2,A3>::_fp3_ops = { 00469 FunctionPointer3<R,A1,A2,A3>::constructor, 00470 FunctionPointer3<R,A1,A2,A3>::copy_constructor, 00471 FunctionPointer3<R,A1,A2,A3>::destructor 00472 }; 00473 00474 /** A class for storing and calling a pointer to a static or member void function with four arguments 00475 */ 00476 template <typename R, typename A1, typename A2, typename A3, typename A4> 00477 class FunctionPointer4 : public FunctionPointerBase<R> { 00478 protected: 00479 typedef struct arg_struct{ 00480 A1 a1; 00481 A2 a2; 00482 A3 a3; 00483 A4 a4; 00484 arg_struct(const A1 *b1, const A2 *b2, const A3* b3, const A4* b4) { 00485 a1 = *b1; 00486 a2 = *b2; 00487 a3 = *b3; 00488 a4 = *b4; 00489 } 00490 } ArgStruct; 00491 00492 public: 00493 typedef R(*static_fp)(A1, A2, A3, A4); 00494 /** Create a FunctionPointer, attaching a static function 00495 * 00496 * @param function The void static function to attach (default is none) 00497 */ 00498 FunctionPointer4(static_fp function = 0) { 00499 attach(function); 00500 } 00501 00502 /** Create a FunctionPointer, attaching a member function 00503 * 00504 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00505 * @param function The address of the void member function to attach 00506 */ 00507 template<typename T> 00508 FunctionPointer4(T *object, R (T::*member)(A1, A2, A3, A4)) { 00509 attach(object, member); 00510 } 00511 00512 /** Attach a static function 00513 * 00514 * @param function The void static function to attach (default is none) 00515 */ 00516 void attach(static_fp function) { 00517 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function); 00518 FunctionPointerBase<R>::_membercaller = &FunctionPointer4::staticcaller; 00519 } 00520 00521 /** Attach a member function 00522 * 00523 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00524 * @param function The address of the void member function to attach 00525 */ 00526 template<typename T> 00527 void attach(T *object, R (T::*member)(A1, A2, A3, A4)) 00528 { 00529 FunctionPointerBase<R>::_object = static_cast<void*>(object); 00530 *reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(FunctionPointerBase<R>::_member) = member; 00531 FunctionPointerBase<R>::_membercaller = &FunctionPointer4::membercaller<T>; 00532 } 00533 00534 FunctionPointerBind<R> bind(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) { 00535 FunctionPointerBind<R> fp; 00536 fp.bind(&_fp4_ops, (ArgStruct *) NULL, this, &a1, &a2, &a3, &a4); 00537 return fp; 00538 } 00539 00540 00541 /** Call the attached static or member function 00542 */ 00543 R call(A1 a1, A2 a2, A3 a3, A4 a4) 00544 { 00545 ArgStruct Args(&a1, &a2, &a3, &a4); 00546 return FunctionPointerBase<R>::call(&Args); 00547 } 00548 00549 static_fp get_function()const 00550 { 00551 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object); 00552 } 00553 00554 R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) { 00555 return call(a1, a2, a3, a4); 00556 } 00557 00558 private: 00559 template<typename T> 00560 static R membercaller(void *object, uintptr_t *member, void *arg) { 00561 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00562 T* o = static_cast<T*>(object); 00563 R (T::**m)(A1, A2, A3, A4) = reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(member); 00564 return (o->**m)(Args->a1, Args->a2, Args->a3, Args->a4); 00565 } 00566 static R staticcaller(void *object, uintptr_t *member, void *arg) { 00567 ArgStruct *Args = static_cast<ArgStruct *>(arg); 00568 (void) member; 00569 static_fp f = reinterpret_cast<static_fp>(object); 00570 return f(Args->a1, Args->a2, Args->a3, Args->a4); 00571 } 00572 /* static void constructor(void * dest, va_list args) { 00573 A1 *a1 = va_arg(args, A1*); 00574 A2 *a2 = va_arg(args, A2*); 00575 A3 *a3 = va_arg(args, A3*); 00576 A4 *a4 = va_arg(args, A4*); 00577 new(dest) ArgStruct(a1, a2, a3, a4); 00578 } 00579 static void copy_constructor(void *dest , void* src) { 00580 ArgStruct *src_args = static_cast<ArgStruct *>(src); 00581 new(dest) ArgStruct(&(src_args->a1), &(src_args->a2), &(src_args->a3), &(src_args->a4)); 00582 } 00583 static void destructor(void *args) { 00584 ArgStruct *argstruct = static_cast<ArgStruct *>(args); 00585 argstruct->~arg_struct(); 00586 } 00587 */ 00588 protected: 00589 static const struct FunctionPointerBase<R>::ArgOps _fp4_ops; 00590 }; 00591 00592 template <typename R, typename A1, typename A2, typename A3, typename A4> 00593 const struct FunctionPointerBase<R>::ArgOps FunctionPointer4<R,A1,A2,A3,A4>::_fp4_ops = { 00594 FunctionPointer4<R,A1,A2,A3,A4>::constructor, 00595 FunctionPointer4<R,A1,A2,A3,A4>::copy_constructor, 00596 FunctionPointer4<R,A1,A2,A3,A4>::destructor 00597 }; 00598 00599 typedef FunctionPointer0<void> FunctionPointer; 00600 //typedef FunctionPointer1<void, int> event_callback_t; 00601 00602 } // namespace mbed 00603 00604 #endif
Generated on Tue Jul 12 2022 12:28:31 by
1.7.2
