A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:a7a43371b306 1 /*
ram54288 0:a7a43371b306 2 * Copyright (c) 2015 ARM Limited. All rights reserved.
ram54288 0:a7a43371b306 3 * SPDX-License-Identifier: Apache-2.0
ram54288 0:a7a43371b306 4 * Licensed under the Apache License, Version 2.0 (the License); you may
ram54288 0:a7a43371b306 5 * not use this file except in compliance with the License.
ram54288 0:a7a43371b306 6 * You may obtain a copy of the License at
ram54288 0:a7a43371b306 7 *
ram54288 0:a7a43371b306 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:a7a43371b306 9 *
ram54288 0:a7a43371b306 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:a7a43371b306 11 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
ram54288 0:a7a43371b306 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:a7a43371b306 13 * See the License for the specific language governing permissions and
ram54288 0:a7a43371b306 14 * limitations under the License.
ram54288 0:a7a43371b306 15 */
ram54288 0:a7a43371b306 16 #ifndef FUNCTIONPOINTER_H
ram54288 0:a7a43371b306 17 #define FUNCTIONPOINTER_H
ram54288 0:a7a43371b306 18
ram54288 0:a7a43371b306 19 #include <string.h>
ram54288 0:a7a43371b306 20 #include <stdint.h>
ram54288 0:a7a43371b306 21
ram54288 0:a7a43371b306 22 /*! \file functionpointer.h
ram54288 0:a7a43371b306 23 * \brief A class for storing and calling a pointer to a static or member void function.
ram54288 0:a7a43371b306 24 */
ram54288 0:a7a43371b306 25
ram54288 0:a7a43371b306 26 template <typename R>
ram54288 0:a7a43371b306 27 class FP0{
ram54288 0:a7a43371b306 28 public:
ram54288 0:a7a43371b306 29 /** Create a function pointer, attaching a static function.
ram54288 0:a7a43371b306 30 *
ram54288 0:a7a43371b306 31 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 32 */
ram54288 0:a7a43371b306 33 FP0(R (*function)(void) = 0) {
ram54288 0:a7a43371b306 34 memset(_member,0,sizeof(_member));
ram54288 0:a7a43371b306 35 attach(function);
ram54288 0:a7a43371b306 36 }
ram54288 0:a7a43371b306 37
ram54288 0:a7a43371b306 38 /** Create a function pointer, attaching a member function.
ram54288 0:a7a43371b306 39 *
ram54288 0:a7a43371b306 40 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 41 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 42 */
ram54288 0:a7a43371b306 43 template<typename T>
ram54288 0:a7a43371b306 44 FP0(T *object, R (T::*member)(void)) {
ram54288 0:a7a43371b306 45 attach(object, member);
ram54288 0:a7a43371b306 46 }
ram54288 0:a7a43371b306 47
ram54288 0:a7a43371b306 48 /** Attach a static function.
ram54288 0:a7a43371b306 49 *
ram54288 0:a7a43371b306 50 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 51 */
ram54288 0:a7a43371b306 52 void attach(R (*function)(void)) {
ram54288 0:a7a43371b306 53 _p.function = function;
ram54288 0:a7a43371b306 54 _membercaller = 0;
ram54288 0:a7a43371b306 55 }
ram54288 0:a7a43371b306 56
ram54288 0:a7a43371b306 57 /** Attach a member function.
ram54288 0:a7a43371b306 58 *
ram54288 0:a7a43371b306 59 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 60 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 61 */
ram54288 0:a7a43371b306 62 template<typename T>
ram54288 0:a7a43371b306 63 void attach(T *object, R (T::*member)(void)) {
ram54288 0:a7a43371b306 64 _p.object = static_cast<void*>(object);
ram54288 0:a7a43371b306 65 *reinterpret_cast<R (T::**)(void)>(_member) = member;
ram54288 0:a7a43371b306 66 _membercaller = &FP0::membercaller<T>;
ram54288 0:a7a43371b306 67 }
ram54288 0:a7a43371b306 68
ram54288 0:a7a43371b306 69 /** Call the attached static or member function.
ram54288 0:a7a43371b306 70 */
ram54288 0:a7a43371b306 71 R call(){
ram54288 0:a7a43371b306 72 if (_membercaller == 0 && _p.function) {
ram54288 0:a7a43371b306 73 return _p.function();
ram54288 0:a7a43371b306 74 } else if (_membercaller && _p.object) {
ram54288 0:a7a43371b306 75 return _membercaller(_p.object, _member);
ram54288 0:a7a43371b306 76 }
ram54288 0:a7a43371b306 77 return (R)0;
ram54288 0:a7a43371b306 78 }
ram54288 0:a7a43371b306 79
ram54288 0:a7a43371b306 80 typedef R (*static_fp)();
ram54288 0:a7a43371b306 81 static_fp get_function() const {
ram54288 0:a7a43371b306 82 return (R(*)())_p.function;
ram54288 0:a7a43371b306 83 }
ram54288 0:a7a43371b306 84
ram54288 0:a7a43371b306 85 R operator ()(void) {
ram54288 0:a7a43371b306 86 return call();
ram54288 0:a7a43371b306 87 }
ram54288 0:a7a43371b306 88 operator bool(void) {
ram54288 0:a7a43371b306 89 void *q = &_p.function;
ram54288 0:a7a43371b306 90 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL);
ram54288 0:a7a43371b306 91 }
ram54288 0:a7a43371b306 92
ram54288 0:a7a43371b306 93 private:
ram54288 0:a7a43371b306 94 template<typename T>
ram54288 0:a7a43371b306 95 static void membercaller(void *object, uintptr_t *member) {
ram54288 0:a7a43371b306 96 T* o = static_cast<T*>(object);
ram54288 0:a7a43371b306 97 R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
ram54288 0:a7a43371b306 98 (o->**m)();
ram54288 0:a7a43371b306 99 }
ram54288 0:a7a43371b306 100
ram54288 0:a7a43371b306 101 union {
ram54288 0:a7a43371b306 102 R (*function)(void); // static function pointer - 0 if none attached
ram54288 0:a7a43371b306 103 void *object; // object this pointer - 0 if none attached
ram54288 0:a7a43371b306 104 } _p;
ram54288 0:a7a43371b306 105 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller
ram54288 0:a7a43371b306 106 R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object
ram54288 0:a7a43371b306 107 };
ram54288 0:a7a43371b306 108
ram54288 0:a7a43371b306 109 /* If we had variadic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
ram54288 0:a7a43371b306 110
ram54288 0:a7a43371b306 111 /** A class for storing and calling a pointer to a static or member void function
ram54288 0:a7a43371b306 112 */
ram54288 0:a7a43371b306 113 template <typename R, typename A1>
ram54288 0:a7a43371b306 114 class FP1{
ram54288 0:a7a43371b306 115 public:
ram54288 0:a7a43371b306 116 /** Create a function pointer, attaching a static function.
ram54288 0:a7a43371b306 117 *
ram54288 0:a7a43371b306 118 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 119 */
ram54288 0:a7a43371b306 120 FP1(R (*function)(A1) = 0) {
ram54288 0:a7a43371b306 121 memset(_member,0,sizeof(_member));
ram54288 0:a7a43371b306 122 attach(function);
ram54288 0:a7a43371b306 123 }
ram54288 0:a7a43371b306 124
ram54288 0:a7a43371b306 125 /** Create a function pointeer, attaching a member function.
ram54288 0:a7a43371b306 126 *
ram54288 0:a7a43371b306 127 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 128 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 129 */
ram54288 0:a7a43371b306 130 template<typename T>
ram54288 0:a7a43371b306 131 FP1(T *object, R (T::*member)(A1)) {
ram54288 0:a7a43371b306 132 attach(object, member);
ram54288 0:a7a43371b306 133 }
ram54288 0:a7a43371b306 134
ram54288 0:a7a43371b306 135 /** Attach a static function.
ram54288 0:a7a43371b306 136 *
ram54288 0:a7a43371b306 137 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 138 */
ram54288 0:a7a43371b306 139 void attach(R (*function)(A1)) {
ram54288 0:a7a43371b306 140 _p.function = function;
ram54288 0:a7a43371b306 141 _membercaller = 0;
ram54288 0:a7a43371b306 142 }
ram54288 0:a7a43371b306 143
ram54288 0:a7a43371b306 144 /** Attach a member function.
ram54288 0:a7a43371b306 145 *
ram54288 0:a7a43371b306 146 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 147 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 148 */
ram54288 0:a7a43371b306 149 template<typename T>
ram54288 0:a7a43371b306 150 void attach(T *object, R (T::*member)(A1)) {
ram54288 0:a7a43371b306 151 _p.object = static_cast<void*>(object);
ram54288 0:a7a43371b306 152 *reinterpret_cast<R (T::**)(A1)>(_member) = member;
ram54288 0:a7a43371b306 153 _membercaller = &FP1::membercaller<T>;
ram54288 0:a7a43371b306 154 }
ram54288 0:a7a43371b306 155
ram54288 0:a7a43371b306 156 /** Call the attached static or member function.
ram54288 0:a7a43371b306 157 */
ram54288 0:a7a43371b306 158 R call(A1 a){
ram54288 0:a7a43371b306 159 if (_membercaller == 0 && _p.function) {
ram54288 0:a7a43371b306 160 return _p.function(a);
ram54288 0:a7a43371b306 161 } else if (_membercaller && _p.object) {
ram54288 0:a7a43371b306 162 return _membercaller(_p.object, _member, a);
ram54288 0:a7a43371b306 163 }
ram54288 0:a7a43371b306 164 return (R)0;
ram54288 0:a7a43371b306 165 }
ram54288 0:a7a43371b306 166
ram54288 0:a7a43371b306 167 typedef R (*static_fp)();
ram54288 0:a7a43371b306 168 static_fp get_function() const {
ram54288 0:a7a43371b306 169 return (R(*)())_p.function;
ram54288 0:a7a43371b306 170 }
ram54288 0:a7a43371b306 171
ram54288 0:a7a43371b306 172 R operator ()(A1 a) {
ram54288 0:a7a43371b306 173 return call(a);
ram54288 0:a7a43371b306 174 }
ram54288 0:a7a43371b306 175 operator bool(void)
ram54288 0:a7a43371b306 176 {
ram54288 0:a7a43371b306 177 void *q = &_p.function;
ram54288 0:a7a43371b306 178 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL);
ram54288 0:a7a43371b306 179 }
ram54288 0:a7a43371b306 180 private:
ram54288 0:a7a43371b306 181 template<typename T>
ram54288 0:a7a43371b306 182 static void membercaller(void *object, uintptr_t *member, A1 a) {
ram54288 0:a7a43371b306 183 T* o = static_cast<T*>(object);
ram54288 0:a7a43371b306 184 R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
ram54288 0:a7a43371b306 185 (o->**m)(a);
ram54288 0:a7a43371b306 186 }
ram54288 0:a7a43371b306 187
ram54288 0:a7a43371b306 188 union {
ram54288 0:a7a43371b306 189 R (*function)(A1); // static function pointer - 0 if none attached
ram54288 0:a7a43371b306 190 void *object; // object this pointer - 0 if none attached
ram54288 0:a7a43371b306 191 } _p;
ram54288 0:a7a43371b306 192 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller
ram54288 0:a7a43371b306 193 R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object
ram54288 0:a7a43371b306 194 };
ram54288 0:a7a43371b306 195
ram54288 0:a7a43371b306 196 /** A class for storing and calling a pointer to a static or member void function.
ram54288 0:a7a43371b306 197 */
ram54288 0:a7a43371b306 198 template <typename R, typename A1, typename A2>
ram54288 0:a7a43371b306 199 class FP2{
ram54288 0:a7a43371b306 200 public:
ram54288 0:a7a43371b306 201 /** Create a function pointer, attaching a static function.
ram54288 0:a7a43371b306 202 *
ram54288 0:a7a43371b306 203 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 204 */
ram54288 0:a7a43371b306 205 FP2(R (*function)(A1, A2) = 0) {
ram54288 0:a7a43371b306 206 memset(_member,0,sizeof(_member));
ram54288 0:a7a43371b306 207 attach(function);
ram54288 0:a7a43371b306 208 }
ram54288 0:a7a43371b306 209
ram54288 0:a7a43371b306 210 /** Create a function pointer, attaching a member function.
ram54288 0:a7a43371b306 211 *
ram54288 0:a7a43371b306 212 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 213 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 214 */
ram54288 0:a7a43371b306 215 template<typename T>
ram54288 0:a7a43371b306 216 FP2(T *object, R (T::*member)(A1, A2)) {
ram54288 0:a7a43371b306 217 attach(object, member);
ram54288 0:a7a43371b306 218 }
ram54288 0:a7a43371b306 219
ram54288 0:a7a43371b306 220 /** Attach a static function.
ram54288 0:a7a43371b306 221 *
ram54288 0:a7a43371b306 222 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 223 */
ram54288 0:a7a43371b306 224 void attach(R (*function)(A1, A2)) {
ram54288 0:a7a43371b306 225 _p.function = function;
ram54288 0:a7a43371b306 226 _membercaller = 0;
ram54288 0:a7a43371b306 227 }
ram54288 0:a7a43371b306 228
ram54288 0:a7a43371b306 229 /** Attach a member function
ram54288 0:a7a43371b306 230 *
ram54288 0:a7a43371b306 231 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 232 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 233 */
ram54288 0:a7a43371b306 234 template<typename T>
ram54288 0:a7a43371b306 235 void attach(T *object, R (T::*member)(A1, A2)) {
ram54288 0:a7a43371b306 236 _p.object = static_cast<void*>(object);
ram54288 0:a7a43371b306 237 *reinterpret_cast<R (T::**)(A1, A2)>(_member) = member;
ram54288 0:a7a43371b306 238 _membercaller = &FP2::membercaller<T>;
ram54288 0:a7a43371b306 239 }
ram54288 0:a7a43371b306 240
ram54288 0:a7a43371b306 241 /** Call the attached static or member function.
ram54288 0:a7a43371b306 242 */
ram54288 0:a7a43371b306 243 R call(A1 a1, A2 a2){
ram54288 0:a7a43371b306 244 if (_membercaller == 0 && _p.function) {
ram54288 0:a7a43371b306 245 return _p.function(a1, a2);
ram54288 0:a7a43371b306 246 } else if (_membercaller && _p.object) {
ram54288 0:a7a43371b306 247 return _membercaller(_p.object, _member, a1, a2);
ram54288 0:a7a43371b306 248 }
ram54288 0:a7a43371b306 249 return (R)0;
ram54288 0:a7a43371b306 250 }
ram54288 0:a7a43371b306 251
ram54288 0:a7a43371b306 252 typedef R (*static_fp)();
ram54288 0:a7a43371b306 253 static_fp get_function() const {
ram54288 0:a7a43371b306 254 return (R(*)())_p.function;
ram54288 0:a7a43371b306 255 }
ram54288 0:a7a43371b306 256
ram54288 0:a7a43371b306 257 R operator ()(A1 a1, A2 a2) {
ram54288 0:a7a43371b306 258 return call(a1, a2);
ram54288 0:a7a43371b306 259 }
ram54288 0:a7a43371b306 260 operator bool(void)
ram54288 0:a7a43371b306 261 {
ram54288 0:a7a43371b306 262 void *q = &_p.function;
ram54288 0:a7a43371b306 263 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL);
ram54288 0:a7a43371b306 264 }
ram54288 0:a7a43371b306 265 private:
ram54288 0:a7a43371b306 266 template<typename T>
ram54288 0:a7a43371b306 267 static void membercaller(void *object, uintptr_t *member, A1 a1, A2 a2) {
ram54288 0:a7a43371b306 268 T* o = static_cast<T*>(object);
ram54288 0:a7a43371b306 269 R (T::**m)(A1, A2) = reinterpret_cast<R (T::**)(A1, A2)>(member);
ram54288 0:a7a43371b306 270 (o->**m)(a1, a2);
ram54288 0:a7a43371b306 271 }
ram54288 0:a7a43371b306 272
ram54288 0:a7a43371b306 273 union {
ram54288 0:a7a43371b306 274 R (*function)(A1, A2); // static function pointer - 0 if none attached
ram54288 0:a7a43371b306 275 void *object; // object this pointer - 0 if none attached
ram54288 0:a7a43371b306 276 } _p;
ram54288 0:a7a43371b306 277 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller
ram54288 0:a7a43371b306 278 R (*_membercaller)(void*, uintptr_t*, A1, A2); // registered membercaller function to convert back and call _m.member on _object
ram54288 0:a7a43371b306 279 };
ram54288 0:a7a43371b306 280
ram54288 0:a7a43371b306 281 /** A class for storing and calling a pointer to a static or member void function.
ram54288 0:a7a43371b306 282 */
ram54288 0:a7a43371b306 283 template <typename R, typename A1, typename A2, typename A3>
ram54288 0:a7a43371b306 284 class FP3{
ram54288 0:a7a43371b306 285 public:
ram54288 0:a7a43371b306 286 /** Create a function pointer, attaching a static function.
ram54288 0:a7a43371b306 287 *
ram54288 0:a7a43371b306 288 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 289 */
ram54288 0:a7a43371b306 290 FP3(R (*function)(A1, A2, A3) = 0) {
ram54288 0:a7a43371b306 291 memset(_member,0,sizeof(_member));
ram54288 0:a7a43371b306 292 attach(function);
ram54288 0:a7a43371b306 293 }
ram54288 0:a7a43371b306 294
ram54288 0:a7a43371b306 295 /** Create a function pointer, attaching a member function.
ram54288 0:a7a43371b306 296 *
ram54288 0:a7a43371b306 297 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 298 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 299 */
ram54288 0:a7a43371b306 300 template<typename T>
ram54288 0:a7a43371b306 301 FP3(T *object, R (T::*member)(A1, A2, A3)) {
ram54288 0:a7a43371b306 302 attach(object, member);
ram54288 0:a7a43371b306 303 }
ram54288 0:a7a43371b306 304
ram54288 0:a7a43371b306 305 /** Attach a static function.
ram54288 0:a7a43371b306 306 *
ram54288 0:a7a43371b306 307 * \param function The void static function to attach (default is none).
ram54288 0:a7a43371b306 308 */
ram54288 0:a7a43371b306 309 void attach(R (*function)(A1, A2, A3)) {
ram54288 0:a7a43371b306 310 _p.function = function;
ram54288 0:a7a43371b306 311 _membercaller = 0;
ram54288 0:a7a43371b306 312 }
ram54288 0:a7a43371b306 313
ram54288 0:a7a43371b306 314 /** Attach a member function.
ram54288 0:a7a43371b306 315 *
ram54288 0:a7a43371b306 316 * \param object The object pointer to invoke the member function on (the "this" pointer).
ram54288 0:a7a43371b306 317 * \param function The address of the void member function to attach.
ram54288 0:a7a43371b306 318 */
ram54288 0:a7a43371b306 319 template<typename T>
ram54288 0:a7a43371b306 320 void attach(T *object, R (T::*member)(A1, A2, A3)) {
ram54288 0:a7a43371b306 321 _p.object = static_cast<void*>(object);
ram54288 0:a7a43371b306 322 *reinterpret_cast<R (T::**)(A1, A2, A3)>(_member) = member;
ram54288 0:a7a43371b306 323 _membercaller = &FP3::membercaller<T>;
ram54288 0:a7a43371b306 324 }
ram54288 0:a7a43371b306 325
ram54288 0:a7a43371b306 326 /** Call the attached static or member function.
ram54288 0:a7a43371b306 327 */
ram54288 0:a7a43371b306 328 R call(A1 a1, A2 a2, A3 a3){
ram54288 0:a7a43371b306 329 if (_membercaller == 0 && _p.function) {
ram54288 0:a7a43371b306 330 return _p.function(a1, a2, a3);
ram54288 0:a7a43371b306 331 } else if (_membercaller && _p.object) {
ram54288 0:a7a43371b306 332 return _membercaller(_p.object, _member, a1, a2, a3);
ram54288 0:a7a43371b306 333 }
ram54288 0:a7a43371b306 334 return (R)0;
ram54288 0:a7a43371b306 335 }
ram54288 0:a7a43371b306 336
ram54288 0:a7a43371b306 337 typedef R (*static_fp)();
ram54288 0:a7a43371b306 338 static_fp get_function() const {
ram54288 0:a7a43371b306 339 return (R(*)())_p.function;
ram54288 0:a7a43371b306 340 }
ram54288 0:a7a43371b306 341
ram54288 0:a7a43371b306 342 R operator ()(A1 a1, A2 a2, A3 a3) {
ram54288 0:a7a43371b306 343 return call(a1, a2, a3);
ram54288 0:a7a43371b306 344 }
ram54288 0:a7a43371b306 345 operator bool(void)
ram54288 0:a7a43371b306 346 {
ram54288 0:a7a43371b306 347 void *q = &_p.function;
ram54288 0:a7a43371b306 348 return (_membercaller != NULL) && _p.object != NULL && (*static_cast<void **>(q) != NULL);
ram54288 0:a7a43371b306 349 }
ram54288 0:a7a43371b306 350 private:
ram54288 0:a7a43371b306 351 template<typename T>
ram54288 0:a7a43371b306 352 static void membercaller(void *object, uintptr_t *member, A1 a1, A2 a2, A3 a3) {
ram54288 0:a7a43371b306 353 T* o = static_cast<T*>(object);
ram54288 0:a7a43371b306 354 R (T::**m)(A1, A2, A3) = reinterpret_cast<R (T::**)(A1, A2, A3)>(member);
ram54288 0:a7a43371b306 355 (o->**m)(a1, a2, a3);
ram54288 0:a7a43371b306 356 }
ram54288 0:a7a43371b306 357
ram54288 0:a7a43371b306 358 union {
ram54288 0:a7a43371b306 359 R (*function)(A1, A2, A3); // static function pointer - 0 if none attached
ram54288 0:a7a43371b306 360 void *object; // object this pointer - 0 if none attached
ram54288 0:a7a43371b306 361 } _p;
ram54288 0:a7a43371b306 362 uintptr_t _member[2]; // aligned raw member function pointer storage - converted back by registered _membercaller
ram54288 0:a7a43371b306 363 R (*_membercaller)(void*, uintptr_t*, A1, A2, A3); // registered membercaller function to convert back and call _m.member on _object
ram54288 0:a7a43371b306 364 };
ram54288 0:a7a43371b306 365
ram54288 0:a7a43371b306 366 typedef FP0<void> FP;
ram54288 0:a7a43371b306 367
ram54288 0:a7a43371b306 368 #endif