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.
Fork of mbed-client 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[4]; // 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[4]; // 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 18:06:59 by
 1.7.2 
    