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.
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 /*! \file functionpointer.h 00023 * \brief A class for storing and calling a pointer to a static or member void function. 00024 */ 00025 00026 template <typename R> 00027 class FP0{ 00028 public: 00029 /** Create a function pointer, attaching a static function. 00030 * 00031 * \param function The void static function to attach (default is none). 00032 */ 00033 FP0(R (*function)(void) = 0) { 00034 memset(_member,0,sizeof(_member)); 00035 attach(function); 00036 } 00037 00038 /** Create a function pointer, attaching a member function. 00039 * 00040 * \param object The object pointer to invoke the member function on (the "this" pointer). 00041 * \param function The address of the void member function to attach. 00042 */ 00043 template<typename T> 00044 FP0(T *object, R (T::*member)(void)) { 00045 attach(object, member); 00046 } 00047 00048 /** Attach a static function. 00049 * 00050 * \param function The void static function to attach (default is none). 00051 */ 00052 void attach(R (*function)(void)) { 00053 _p.function = function; 00054 _membercaller = 0; 00055 } 00056 00057 /** Attach a member function. 00058 * 00059 * \param object The object pointer to invoke the member function on (the "this" pointer). 00060 * \param function The address of the void member function to attach. 00061 */ 00062 template<typename T> 00063 void attach(T *object, R (T::*member)(void)) { 00064 _p.object = static_cast<void*>(object); 00065 *reinterpret_cast<R (T::**)(void)>(_member) = member; 00066 _membercaller = &FP0::membercaller<T>; 00067 } 00068 00069 /** Call the attached static or member function. 00070 */ 00071 R call(){ 00072 if (_membercaller == 0 && _p.function) { 00073 return _p.function(); 00074 } else if (_membercaller && _p.object) { 00075 return _membercaller(_p.object, _member); 00076 } 00077 return (R)0; 00078 } 00079 00080 typedef R (*static_fp)(); 00081 static_fp get_function() const { 00082 return (R(*)())_p.function; 00083 } 00084 00085 R operator ()(void) { 00086 return call(); 00087 } 00088 operator bool(void) { 00089 void *q = &_p.function; 00090 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL); 00091 } 00092 00093 private: 00094 template<typename T> 00095 static void membercaller(void *object, uintptr_t *member) { 00096 T* o = static_cast<T*>(object); 00097 R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member); 00098 (o->**m)(); 00099 } 00100 00101 union { 00102 R (*function)(void); // static function pointer - 0 if none attached 00103 void *object; // object this pointer - 0 if none attached 00104 } _p; 00105 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller 00106 R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object 00107 }; 00108 00109 /* If we had variadic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */ 00110 00111 /** A class for storing and calling a pointer to a static or member void function 00112 */ 00113 template <typename R, typename A1> 00114 class FP1{ 00115 public: 00116 /** Create a function pointer, attaching a static function. 00117 * 00118 * \param function The void static function to attach (default is none). 00119 */ 00120 FP1(R (*function)(A1) = 0) { 00121 memset(_member,0,sizeof(_member)); 00122 attach(function); 00123 } 00124 00125 /** Create a function pointeer, attaching a member function. 00126 * 00127 * \param object The object pointer to invoke the member function on (the "this" pointer). 00128 * \param function The address of the void member function to attach. 00129 */ 00130 template<typename T> 00131 FP1(T *object, R (T::*member)(A1)) { 00132 attach(object, member); 00133 } 00134 00135 /** Attach a static function. 00136 * 00137 * \param function The void static function to attach (default is none). 00138 */ 00139 void attach(R (*function)(A1)) { 00140 _p.function = function; 00141 _membercaller = 0; 00142 } 00143 00144 /** Attach a member function. 00145 * 00146 * \param object The object pointer to invoke the member function on (the "this" pointer). 00147 * \param function The address of the void member function to attach. 00148 */ 00149 template<typename T> 00150 void attach(T *object, R (T::*member)(A1)) { 00151 _p.object = static_cast<void*>(object); 00152 *reinterpret_cast<R (T::**)(A1)>(_member) = member; 00153 _membercaller = &FP1::membercaller<T>; 00154 } 00155 00156 /** Call the attached static or member function. 00157 */ 00158 R call(A1 a){ 00159 if (_membercaller == 0 && _p.function) { 00160 return _p.function(a); 00161 } else if (_membercaller && _p.object) { 00162 return _membercaller(_p.object, _member, a); 00163 } 00164 return (R)0; 00165 } 00166 00167 typedef R (*static_fp)(); 00168 static_fp get_function() const { 00169 return (R(*)())_p.function; 00170 } 00171 00172 R operator ()(A1 a) { 00173 return call(a); 00174 } 00175 operator bool(void) 00176 { 00177 void *q = &_p.function; 00178 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL); 00179 } 00180 private: 00181 template<typename T> 00182 static void membercaller(void *object, uintptr_t *member, A1 a) { 00183 T* o = static_cast<T*>(object); 00184 R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member); 00185 (o->**m)(a); 00186 } 00187 00188 union { 00189 R (*function)(A1); // static function pointer - 0 if none attached 00190 void *object; // object this pointer - 0 if none attached 00191 } _p; 00192 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller 00193 R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object 00194 }; 00195 00196 /** A class for storing and calling a pointer to a static or member void function. 00197 */ 00198 template <typename R, typename A1, typename A2> 00199 class FP2{ 00200 public: 00201 /** Create a function pointer, attaching a static function. 00202 * 00203 * \param function The void static function to attach (default is none). 00204 */ 00205 FP2(R (*function)(A1, A2) = 0) { 00206 memset(_member,0,sizeof(_member)); 00207 attach(function); 00208 } 00209 00210 /** Create a function pointer, attaching a member function. 00211 * 00212 * \param object The object pointer to invoke the member function on (the "this" pointer). 00213 * \param function The address of the void member function to attach. 00214 */ 00215 template<typename T> 00216 FP2(T *object, R (T::*member)(A1, A2)) { 00217 attach(object, member); 00218 } 00219 00220 /** Attach a static function. 00221 * 00222 * \param function The void static function to attach (default is none). 00223 */ 00224 void attach(R (*function)(A1, A2)) { 00225 _p.function = function; 00226 _membercaller = 0; 00227 } 00228 00229 /** Attach a member function 00230 * 00231 * \param object The object pointer to invoke the member function on (the "this" pointer). 00232 * \param function The address of the void member function to attach. 00233 */ 00234 template<typename T> 00235 void attach(T *object, R (T::*member)(A1, A2)) { 00236 _p.object = static_cast<void*>(object); 00237 *reinterpret_cast<R (T::**)(A1, A2)>(_member) = member; 00238 _membercaller = &FP2::membercaller<T>; 00239 } 00240 00241 /** Call the attached static or member function. 00242 */ 00243 R call(A1 a1, A2 a2){ 00244 if (_membercaller == 0 && _p.function) { 00245 return _p.function(a1, a2); 00246 } else if (_membercaller && _p.object) { 00247 return _membercaller(_p.object, _member, a1, a2); 00248 } 00249 return (R)0; 00250 } 00251 00252 typedef R (*static_fp)(); 00253 static_fp get_function() const { 00254 return (R(*)())_p.function; 00255 } 00256 00257 R operator ()(A1 a1, A2 a2) { 00258 return call(a1, a2); 00259 } 00260 operator bool(void) 00261 { 00262 void *q = &_p.function; 00263 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL); 00264 } 00265 private: 00266 template<typename T> 00267 static void membercaller(void *object, uintptr_t *member, A1 a1, A2 a2) { 00268 T* o = static_cast<T*>(object); 00269 R (T::**m)(A1, A2) = reinterpret_cast<R (T::**)(A1, A2)>(member); 00270 (o->**m)(a1, a2); 00271 } 00272 00273 union { 00274 R (*function)(A1, A2); // static function pointer - 0 if none attached 00275 void *object; // object this pointer - 0 if none attached 00276 } _p; 00277 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller 00278 R (*_membercaller)(void*, uintptr_t*, A1, A2); // registered membercaller function to convert back and call _m.member on _object 00279 }; 00280 00281 /** A class for storing and calling a pointer to a static or member void function. 00282 */ 00283 template <typename R, typename A1, typename A2, typename A3> 00284 class FP3{ 00285 public: 00286 /** Create a function pointer, attaching a static function. 00287 * 00288 * \param function The void static function to attach (default is none). 00289 */ 00290 FP3(R (*function)(A1, A2, A3) = 0) { 00291 memset(_member,0,sizeof(_member)); 00292 attach(function); 00293 } 00294 00295 /** Create a function pointer, attaching a member function. 00296 * 00297 * \param object The object pointer to invoke the member function on (the "this" pointer). 00298 * \param function The address of the void member function to attach. 00299 */ 00300 template<typename T> 00301 FP3(T *object, R (T::*member)(A1, A2, A3)) { 00302 attach(object, member); 00303 } 00304 00305 /** Attach a static function. 00306 * 00307 * \param function The void static function to attach (default is none). 00308 */ 00309 void attach(R (*function)(A1, A2, A3)) { 00310 _p.function = function; 00311 _membercaller = 0; 00312 } 00313 00314 /** Attach a member function. 00315 * 00316 * \param object The object pointer to invoke the member function on (the "this" pointer). 00317 * \param function The address of the void member function to attach. 00318 */ 00319 template<typename T> 00320 void attach(T *object, R (T::*member)(A1, A2, A3)) { 00321 _p.object = static_cast<void*>(object); 00322 *reinterpret_cast<R (T::**)(A1, A2, A3)>(_member) = member; 00323 _membercaller = &FP3::membercaller<T>; 00324 } 00325 00326 /** Call the attached static or member function. 00327 */ 00328 R call(A1 a1, A2 a2, A3 a3){ 00329 if (_membercaller == 0 && _p.function) { 00330 return _p.function(a1, a2, a3); 00331 } else if (_membercaller && _p.object) { 00332 return _membercaller(_p.object, _member, a1, a2, a3); 00333 } 00334 return (R)0; 00335 } 00336 00337 typedef R (*static_fp)(); 00338 static_fp get_function() const { 00339 return (R(*)())_p.function; 00340 } 00341 00342 R operator ()(A1 a1, A2 a2, A3 a3) { 00343 return call(a1, a2, a3); 00344 } 00345 operator bool(void) 00346 { 00347 void *q = &_p.function; 00348 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL); 00349 } 00350 private: 00351 template<typename T> 00352 static void membercaller(void *object, uintptr_t *member, A1 a1, A2 a2, A3 a3) { 00353 T* o = static_cast<T*>(object); 00354 R (T::**m)(A1, A2, A3) = reinterpret_cast<R (T::**)(A1, A2, A3)>(member); 00355 (o->**m)(a1, a2, a3); 00356 } 00357 00358 union { 00359 R (*function)(A1, A2, A3); // static function pointer - 0 if none attached 00360 void *object; // object this pointer - 0 if none attached 00361 } _p; 00362 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller 00363 R (*_membercaller)(void*, uintptr_t*, A1, A2, A3); // registered membercaller function to convert back and call _m.member on _object 00364 }; 00365 00366 typedef FP0<void> FP; 00367 00368 #endif
Generated on Tue Jul 12 2022 21:20:26 by
1.7.2