Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
functionpointer.h
Go to the documentation of this file.
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 19:01:34 by 1.7.2