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: MAX44000 PWM_Tone_Library nexpaq_mdk
Fork of LED_Demo by
functionpointer.h
00001 /* 00002 * Copyright (c) 2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * 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, WITHOUT 00012 * 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 FUNCTIONPOINTER_H 00017 #define FUNCTIONPOINTER_H 00018 00019 #include <string.h> 00020 #include <stdint.h> 00021 00022 00023 /** A class for storing and calling a pointer to a static or member void function 00024 */ 00025 template <typename R> 00026 class FP0{ 00027 public: 00028 /** Create a Function Pointer, attaching a static function 00029 * 00030 * \param function The void static function to attach (default is none) 00031 */ 00032 FP0(R (*function)(void) = 0) { 00033 attach(function); 00034 } 00035 00036 /** Create a FP, attaching a member function 00037 * 00038 * \param object The object pointer to invoke the member function on (i.e. the this pointer) 00039 * \param function The address of the void member function to attach 00040 */ 00041 template<typename T> 00042 FP0(T *object, R (T::*member)(void)) { 00043 attach(object, member); 00044 } 00045 00046 /** Attach a static function 00047 * 00048 * \param function The void static function to attach (default is none) 00049 */ 00050 void attach(R (*function)(void)) { 00051 _p.function = function; 00052 _membercaller = 0; 00053 } 00054 00055 /** Attach a member function 00056 * 00057 * \param object The object pointer to invoke the member function on (i.e. the this pointer) 00058 * \param function The address of the void member function to attach 00059 */ 00060 template<typename T> 00061 void attach(T *object, R (T::*member)(void)) { 00062 _p.object = static_cast<void*>(object); 00063 *reinterpret_cast<R (T::**)(void)>(_member) = member; 00064 _membercaller = &FP0::membercaller<T>; 00065 } 00066 00067 /** Call the attached static or member function 00068 */ 00069 R call(){ 00070 if (_membercaller == 0 && _p.function) { 00071 return _p.function(); 00072 } else if (_membercaller && _p.object) { 00073 return _membercaller(_p.object, _member); 00074 } 00075 return (R)0; 00076 } 00077 00078 typedef R (*static_fp)(); 00079 static_fp get_function() const { 00080 return (R(*)())_p.function; 00081 } 00082 00083 R operator ()(void) { 00084 return call(); 00085 } 00086 operator bool(void) { 00087 void *q = &_p.function; 00088 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL); 00089 } 00090 00091 private: 00092 template<typename T> 00093 static void membercaller(void *object, uintptr_t *member) { 00094 T* o = static_cast<T*>(object); 00095 R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member); 00096 (o->**m)(); 00097 } 00098 00099 union { 00100 R (*function)(void); // static function pointer - 0 if none attached 00101 void *object; // object this pointer - 0 if none attached 00102 } _p; 00103 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller 00104 R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object 00105 }; 00106 00107 /* If we had variadic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */ 00108 00109 /** A class for storing and calling a pointer to a static or member void function 00110 */ 00111 template <typename R, typename A1> 00112 class FP1{ 00113 public: 00114 /** Create a FP, attaching a static function 00115 * 00116 * \param function The void static function to attach (default is none) 00117 */ 00118 FP1(R (*function)(A1) = 0) { 00119 attach(function); 00120 } 00121 00122 /** Create a FP, attaching a member function 00123 * 00124 * \param object The object pointer to invoke the member function on (i.e. the this pointer) 00125 * \param function The address of the void member function to attach 00126 */ 00127 template<typename T> 00128 FP1(T *object, R (T::*member)(A1)) { 00129 attach(object, member); 00130 } 00131 00132 /** Attach a static function 00133 * 00134 * \param function The void static function to attach (default is none) 00135 */ 00136 void attach(R (*function)(A1)) { 00137 _p.function = function; 00138 _membercaller = 0; 00139 } 00140 00141 /** Attach a member function 00142 * 00143 * \param object The object pointer to invoke the member function on (i.e. the this pointer) 00144 * \param function The address of the void member function to attach 00145 */ 00146 template<typename T> 00147 void attach(T *object, R (T::*member)(A1)) { 00148 _p.object = static_cast<void*>(object); 00149 *reinterpret_cast<R (T::**)(A1)>(_member) = member; 00150 _membercaller = &FP1::membercaller<T>; 00151 } 00152 00153 /** Call the attached static or member function 00154 */ 00155 R call(A1 a){ 00156 if (_membercaller == 0 && _p.function) { 00157 return _p.function(a); 00158 } else if (_membercaller && _p.object) { 00159 return _membercaller(_p.object, _member, a); 00160 } 00161 return (R)0; 00162 } 00163 00164 typedef R (*static_fp)(); 00165 static_fp get_function() const { 00166 return (R(*)())_p.function; 00167 } 00168 00169 R operator ()(A1 a) { 00170 return call(a); 00171 } 00172 operator bool(void) 00173 { 00174 void *q = &_p.function; 00175 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL); 00176 } 00177 private: 00178 template<typename T> 00179 static void membercaller(void *object, uintptr_t *member, A1 a) { 00180 T* o = static_cast<T*>(object); 00181 R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member); 00182 (o->**m)(a); 00183 } 00184 00185 union { 00186 R (*function)(A1); // static function pointer - 0 if none attached 00187 void *object; // object this pointer - 0 if none attached 00188 } _p; 00189 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller 00190 R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object 00191 }; 00192 00193 00194 00195 typedef FP0<void> FP; 00196 00197 #endif
Generated on Tue Jul 12 2022 12:28:31 by
