FRDM K64F Metronome

Committer:
ram54288
Date:
Sun May 14 18:37:05 2017 +0000
Revision:
0:dbad57390bd1
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:dbad57390bd1 1 /* mbed Microcontroller Library
ram54288 0:dbad57390bd1 2 * Copyright (c) 2006-2015 ARM Limited
ram54288 0:dbad57390bd1 3 *
ram54288 0:dbad57390bd1 4 * Licensed under the Apache License, Version 2.0 (the "License");
ram54288 0:dbad57390bd1 5 * you may not use this file except in compliance with the License.
ram54288 0:dbad57390bd1 6 * You may obtain a copy of the License at
ram54288 0:dbad57390bd1 7 *
ram54288 0:dbad57390bd1 8 * http://www.apache.org/licenses/LICENSE-2.0
ram54288 0:dbad57390bd1 9 *
ram54288 0:dbad57390bd1 10 * Unless required by applicable law or agreed to in writing, software
ram54288 0:dbad57390bd1 11 * distributed under the License is distributed on an "AS IS" BASIS,
ram54288 0:dbad57390bd1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
ram54288 0:dbad57390bd1 13 * See the License for the specific language governing permissions and
ram54288 0:dbad57390bd1 14 * limitations under the License.
ram54288 0:dbad57390bd1 15 */
ram54288 0:dbad57390bd1 16 #ifndef MBED_FUNCTIONPOINTER_H
ram54288 0:dbad57390bd1 17 #define MBED_FUNCTIONPOINTER_H
ram54288 0:dbad57390bd1 18
ram54288 0:dbad57390bd1 19 #include <string.h>
ram54288 0:dbad57390bd1 20 #include <stdint.h>
ram54288 0:dbad57390bd1 21 #include <stddef.h>
ram54288 0:dbad57390bd1 22 #include <stdarg.h>
ram54288 0:dbad57390bd1 23 #include <new>
ram54288 0:dbad57390bd1 24 #include "FunctionPointerBase.h"
ram54288 0:dbad57390bd1 25 #include "FunctionPointerBind.h"
ram54288 0:dbad57390bd1 26
ram54288 0:dbad57390bd1 27 namespace mbed {
ram54288 0:dbad57390bd1 28 /** A class for storing and calling a pointer to a static or member void function without arguments
ram54288 0:dbad57390bd1 29 */
ram54288 0:dbad57390bd1 30 template <typename R>
ram54288 0:dbad57390bd1 31 class FunctionPointer0 : public FunctionPointerBase<R>{
ram54288 0:dbad57390bd1 32 public:
ram54288 0:dbad57390bd1 33 typedef R(*static_fp)(void);
ram54288 0:dbad57390bd1 34 typedef struct arg_struct{
ram54288 0:dbad57390bd1 35 } ArgStruct;
ram54288 0:dbad57390bd1 36 /** Create a FunctionPointer, attaching a static function
ram54288 0:dbad57390bd1 37 *
ram54288 0:dbad57390bd1 38 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 39 */
ram54288 0:dbad57390bd1 40 FunctionPointer0(static_fp function = 0):
ram54288 0:dbad57390bd1 41 FunctionPointerBase<R>()
ram54288 0:dbad57390bd1 42 {
ram54288 0:dbad57390bd1 43 attach(function);
ram54288 0:dbad57390bd1 44 }
ram54288 0:dbad57390bd1 45
ram54288 0:dbad57390bd1 46 /** Create a FunctionPointer, attaching a member function
ram54288 0:dbad57390bd1 47 *
ram54288 0:dbad57390bd1 48 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 49 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 50 */
ram54288 0:dbad57390bd1 51 template<typename T>
ram54288 0:dbad57390bd1 52 FunctionPointer0(T *object, R (T::*member)(void)):
ram54288 0:dbad57390bd1 53 FunctionPointerBase<R>()
ram54288 0:dbad57390bd1 54 {
ram54288 0:dbad57390bd1 55 attach(object, member);
ram54288 0:dbad57390bd1 56 }
ram54288 0:dbad57390bd1 57
ram54288 0:dbad57390bd1 58 /** Attach a static function
ram54288 0:dbad57390bd1 59 *
ram54288 0:dbad57390bd1 60 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 61 */
ram54288 0:dbad57390bd1 62 void attach(static_fp function) {
ram54288 0:dbad57390bd1 63 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function);
ram54288 0:dbad57390bd1 64 FunctionPointerBase<R>::_membercaller = &FunctionPointer0::staticcaller;
ram54288 0:dbad57390bd1 65 }
ram54288 0:dbad57390bd1 66
ram54288 0:dbad57390bd1 67 /** Attach a member function
ram54288 0:dbad57390bd1 68 *
ram54288 0:dbad57390bd1 69 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 70 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 71 */
ram54288 0:dbad57390bd1 72 template<typename T>
ram54288 0:dbad57390bd1 73 void attach(T *object, R (T::*member)(void)) {
ram54288 0:dbad57390bd1 74 FunctionPointerBase<R>::_object = static_cast<void*>(object);
ram54288 0:dbad57390bd1 75 *reinterpret_cast<R (T::**)(void)>(FunctionPointerBase<R>::_member) = member;
ram54288 0:dbad57390bd1 76 FunctionPointerBase<R>::_membercaller = &FunctionPointer0::membercaller<T>;
ram54288 0:dbad57390bd1 77 }
ram54288 0:dbad57390bd1 78
ram54288 0:dbad57390bd1 79 /** Call the attached static or member function
ram54288 0:dbad57390bd1 80 */
ram54288 0:dbad57390bd1 81 R call(){
ram54288 0:dbad57390bd1 82 return FunctionPointerBase<R>::call(NULL);
ram54288 0:dbad57390bd1 83 }
ram54288 0:dbad57390bd1 84
ram54288 0:dbad57390bd1 85 FunctionPointerBind<R> bind() {
ram54288 0:dbad57390bd1 86 FunctionPointerBind<R> fp;
ram54288 0:dbad57390bd1 87 fp.bind(&FunctionPointerBase<R>::_nullops, (ArgStruct *) NULL, this);
ram54288 0:dbad57390bd1 88 return fp;
ram54288 0:dbad57390bd1 89 }
ram54288 0:dbad57390bd1 90
ram54288 0:dbad57390bd1 91 static_fp get_function()const {
ram54288 0:dbad57390bd1 92 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object);
ram54288 0:dbad57390bd1 93 }
ram54288 0:dbad57390bd1 94
ram54288 0:dbad57390bd1 95 R operator ()(void) {
ram54288 0:dbad57390bd1 96 return call();
ram54288 0:dbad57390bd1 97 }
ram54288 0:dbad57390bd1 98
ram54288 0:dbad57390bd1 99 private:
ram54288 0:dbad57390bd1 100 template<typename T>
ram54288 0:dbad57390bd1 101 static R membercaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 102 (void) arg;
ram54288 0:dbad57390bd1 103 T* o = static_cast<T*>(object);
ram54288 0:dbad57390bd1 104 R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
ram54288 0:dbad57390bd1 105 return (o->**m)();
ram54288 0:dbad57390bd1 106 }
ram54288 0:dbad57390bd1 107 static R staticcaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 108 (void) arg;
ram54288 0:dbad57390bd1 109 (void) member;
ram54288 0:dbad57390bd1 110 static_fp f = reinterpret_cast<static_fp>(object);
ram54288 0:dbad57390bd1 111 return f();
ram54288 0:dbad57390bd1 112 }
ram54288 0:dbad57390bd1 113 };
ram54288 0:dbad57390bd1 114
ram54288 0:dbad57390bd1 115 /* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
ram54288 0:dbad57390bd1 116
ram54288 0:dbad57390bd1 117 /** A class for storing and calling a pointer to a static or member void function with one argument
ram54288 0:dbad57390bd1 118 */
ram54288 0:dbad57390bd1 119 template <typename R, typename A1>
ram54288 0:dbad57390bd1 120 class FunctionPointer1 : public FunctionPointerBase<R> {
ram54288 0:dbad57390bd1 121 protected:
ram54288 0:dbad57390bd1 122 typedef struct arg_struct{
ram54288 0:dbad57390bd1 123 A1 a1;
ram54288 0:dbad57390bd1 124 arg_struct(const A1 *b1) {
ram54288 0:dbad57390bd1 125 a1 = *b1;
ram54288 0:dbad57390bd1 126 }
ram54288 0:dbad57390bd1 127 } ArgStruct;
ram54288 0:dbad57390bd1 128
ram54288 0:dbad57390bd1 129 public:
ram54288 0:dbad57390bd1 130 typedef R(*static_fp)(A1);
ram54288 0:dbad57390bd1 131 /** Create a FunctionPointer, attaching a static function
ram54288 0:dbad57390bd1 132 *
ram54288 0:dbad57390bd1 133 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 134 */
ram54288 0:dbad57390bd1 135 FunctionPointer1(static_fp function = 0) {
ram54288 0:dbad57390bd1 136 attach(function);
ram54288 0:dbad57390bd1 137 }
ram54288 0:dbad57390bd1 138
ram54288 0:dbad57390bd1 139 /** Create a FunctionPointer, attaching a member function
ram54288 0:dbad57390bd1 140 *
ram54288 0:dbad57390bd1 141 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 142 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 143 */
ram54288 0:dbad57390bd1 144 template<typename T>
ram54288 0:dbad57390bd1 145 FunctionPointer1(T *object, R (T::*member)(A1)) {
ram54288 0:dbad57390bd1 146 attach(object, member);
ram54288 0:dbad57390bd1 147 }
ram54288 0:dbad57390bd1 148
ram54288 0:dbad57390bd1 149 /** Attach a static function
ram54288 0:dbad57390bd1 150 *
ram54288 0:dbad57390bd1 151 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 152 */
ram54288 0:dbad57390bd1 153 void attach(static_fp function) {
ram54288 0:dbad57390bd1 154 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function);
ram54288 0:dbad57390bd1 155 FunctionPointerBase<R>::_membercaller = &FunctionPointer1::staticcaller;
ram54288 0:dbad57390bd1 156 }
ram54288 0:dbad57390bd1 157
ram54288 0:dbad57390bd1 158 /** Attach a member function
ram54288 0:dbad57390bd1 159 *
ram54288 0:dbad57390bd1 160 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 161 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 162 */
ram54288 0:dbad57390bd1 163 template<typename T>
ram54288 0:dbad57390bd1 164 void attach(T *object, R (T::*member)(A1))
ram54288 0:dbad57390bd1 165 {
ram54288 0:dbad57390bd1 166 FunctionPointerBase<R>::_object = static_cast<void*>(object);
ram54288 0:dbad57390bd1 167 *reinterpret_cast<R (T::**)(A1)>(FunctionPointerBase<R>::_member) = member;
ram54288 0:dbad57390bd1 168 FunctionPointerBase<R>::_membercaller = &FunctionPointer1::membercaller<T>;
ram54288 0:dbad57390bd1 169 }
ram54288 0:dbad57390bd1 170
ram54288 0:dbad57390bd1 171 FunctionPointerBind<R> bind(const A1 &a1) {
ram54288 0:dbad57390bd1 172 FunctionPointerBind<R> fp;
ram54288 0:dbad57390bd1 173 fp.bind(&_fp1_ops, (ArgStruct *) NULL, this, &a1);
ram54288 0:dbad57390bd1 174 return fp;
ram54288 0:dbad57390bd1 175 }
ram54288 0:dbad57390bd1 176
ram54288 0:dbad57390bd1 177
ram54288 0:dbad57390bd1 178 /** Call the attached static or member function
ram54288 0:dbad57390bd1 179 */
ram54288 0:dbad57390bd1 180 R call(A1 a1)
ram54288 0:dbad57390bd1 181 {
ram54288 0:dbad57390bd1 182 ArgStruct Args(&a1);
ram54288 0:dbad57390bd1 183 return FunctionPointerBase<R>::call(&Args);
ram54288 0:dbad57390bd1 184 }
ram54288 0:dbad57390bd1 185
ram54288 0:dbad57390bd1 186 static_fp get_function()const
ram54288 0:dbad57390bd1 187 {
ram54288 0:dbad57390bd1 188 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object);
ram54288 0:dbad57390bd1 189 }
ram54288 0:dbad57390bd1 190
ram54288 0:dbad57390bd1 191 R operator ()(A1 a) {
ram54288 0:dbad57390bd1 192 return call(a);
ram54288 0:dbad57390bd1 193 }
ram54288 0:dbad57390bd1 194
ram54288 0:dbad57390bd1 195 private:
ram54288 0:dbad57390bd1 196 template<typename T>
ram54288 0:dbad57390bd1 197 static R membercaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 198 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 199 T* o = static_cast<T*>(object);
ram54288 0:dbad57390bd1 200 R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
ram54288 0:dbad57390bd1 201 return (o->**m)(Args->a1);
ram54288 0:dbad57390bd1 202 }
ram54288 0:dbad57390bd1 203 static R staticcaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 204 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 205 (void) member;
ram54288 0:dbad57390bd1 206 static_fp f = reinterpret_cast<static_fp>(object);
ram54288 0:dbad57390bd1 207 return f(Args->a1);
ram54288 0:dbad57390bd1 208 }
ram54288 0:dbad57390bd1 209 /* static void constructor(void * dest, va_list args) {
ram54288 0:dbad57390bd1 210 new(dest) ArgStruct(va_arg(args,A1*));
ram54288 0:dbad57390bd1 211 }
ram54288 0:dbad57390bd1 212 static void copy_constructor(void *dest , void* src) {
ram54288 0:dbad57390bd1 213 ArgStruct *src_args = static_cast<ArgStruct *>(src);
ram54288 0:dbad57390bd1 214 new(dest) ArgStruct(&(src_args->a1));
ram54288 0:dbad57390bd1 215 }
ram54288 0:dbad57390bd1 216 static void destructor(void *args) {
ram54288 0:dbad57390bd1 217 ArgStruct *argstruct = static_cast<ArgStruct *>(args);
ram54288 0:dbad57390bd1 218 argstruct->~arg_struct();
ram54288 0:dbad57390bd1 219 }
ram54288 0:dbad57390bd1 220 */
ram54288 0:dbad57390bd1 221 protected:
ram54288 0:dbad57390bd1 222 static const struct FunctionPointerBase<R>::ArgOps _fp1_ops;
ram54288 0:dbad57390bd1 223 };
ram54288 0:dbad57390bd1 224
ram54288 0:dbad57390bd1 225 template <typename R, typename A1>
ram54288 0:dbad57390bd1 226 const struct FunctionPointerBase<R>::ArgOps FunctionPointer1<R,A1>::_fp1_ops = {
ram54288 0:dbad57390bd1 227 FunctionPointer1<R,A1>::constructor,
ram54288 0:dbad57390bd1 228 FunctionPointer1<R,A1>::copy_constructor,
ram54288 0:dbad57390bd1 229 FunctionPointer1<R,A1>::destructor
ram54288 0:dbad57390bd1 230 };
ram54288 0:dbad57390bd1 231
ram54288 0:dbad57390bd1 232
ram54288 0:dbad57390bd1 233 /** A class for storing and calling a pointer to a static or member void function with two arguments
ram54288 0:dbad57390bd1 234 */
ram54288 0:dbad57390bd1 235 template <typename R, typename A1, typename A2>
ram54288 0:dbad57390bd1 236 class FunctionPointer2 : public FunctionPointerBase<R> {
ram54288 0:dbad57390bd1 237 protected:
ram54288 0:dbad57390bd1 238 typedef struct arg_struct{
ram54288 0:dbad57390bd1 239 A1 a1;
ram54288 0:dbad57390bd1 240 A2 a2;
ram54288 0:dbad57390bd1 241 arg_struct(const A1 *b1, const A2 *b2) {
ram54288 0:dbad57390bd1 242 a1 = *b1;
ram54288 0:dbad57390bd1 243 a2 = *b2;
ram54288 0:dbad57390bd1 244 }
ram54288 0:dbad57390bd1 245 } ArgStruct;
ram54288 0:dbad57390bd1 246
ram54288 0:dbad57390bd1 247 public:
ram54288 0:dbad57390bd1 248 typedef R(*static_fp)(A1, A2);
ram54288 0:dbad57390bd1 249 /** Create a FunctionPointer, attaching a static function
ram54288 0:dbad57390bd1 250 *
ram54288 0:dbad57390bd1 251 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 252 */
ram54288 0:dbad57390bd1 253 FunctionPointer2(static_fp function = 0) {
ram54288 0:dbad57390bd1 254 attach(function);
ram54288 0:dbad57390bd1 255 }
ram54288 0:dbad57390bd1 256
ram54288 0:dbad57390bd1 257 /** Create a FunctionPointer, attaching a member function
ram54288 0:dbad57390bd1 258 *
ram54288 0:dbad57390bd1 259 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 260 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 261 */
ram54288 0:dbad57390bd1 262 template<typename T>
ram54288 0:dbad57390bd1 263 FunctionPointer2(T *object, R (T::*member)(A1, A2)) {
ram54288 0:dbad57390bd1 264 attach(object, member);
ram54288 0:dbad57390bd1 265 }
ram54288 0:dbad57390bd1 266
ram54288 0:dbad57390bd1 267 /** Attach a static function
ram54288 0:dbad57390bd1 268 *
ram54288 0:dbad57390bd1 269 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 270 */
ram54288 0:dbad57390bd1 271 void attach(static_fp function) {
ram54288 0:dbad57390bd1 272 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function);
ram54288 0:dbad57390bd1 273 FunctionPointerBase<R>::_membercaller = &FunctionPointer2::staticcaller;
ram54288 0:dbad57390bd1 274 }
ram54288 0:dbad57390bd1 275
ram54288 0:dbad57390bd1 276 /** Attach a member function
ram54288 0:dbad57390bd1 277 *
ram54288 0:dbad57390bd1 278 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 279 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 280 */
ram54288 0:dbad57390bd1 281 template<typename T>
ram54288 0:dbad57390bd1 282 void attach(T *object, R (T::*member)(A1, A2))
ram54288 0:dbad57390bd1 283 {
ram54288 0:dbad57390bd1 284 FunctionPointerBase<R>::_object = static_cast<void*>(object);
ram54288 0:dbad57390bd1 285 *reinterpret_cast<R (T::**)(A1, A2)>(FunctionPointerBase<R>::_member) = member;
ram54288 0:dbad57390bd1 286 FunctionPointerBase<R>::_membercaller = &FunctionPointer2::membercaller<T>;
ram54288 0:dbad57390bd1 287 }
ram54288 0:dbad57390bd1 288
ram54288 0:dbad57390bd1 289 FunctionPointerBind<R> bind(const A1 &a1, const A2 &a2) {
ram54288 0:dbad57390bd1 290 FunctionPointerBind<R> fp;
ram54288 0:dbad57390bd1 291 fp.bind(&_fp2_ops, (ArgStruct *) NULL, this, &a1, &a2);
ram54288 0:dbad57390bd1 292 return fp;
ram54288 0:dbad57390bd1 293 }
ram54288 0:dbad57390bd1 294
ram54288 0:dbad57390bd1 295
ram54288 0:dbad57390bd1 296 /** Call the attached static or member function
ram54288 0:dbad57390bd1 297 */
ram54288 0:dbad57390bd1 298 R call(A1 a1, A2 a2)
ram54288 0:dbad57390bd1 299 {
ram54288 0:dbad57390bd1 300 ArgStruct Args(&a1, &a2);
ram54288 0:dbad57390bd1 301 return FunctionPointerBase<R>::call(&Args);
ram54288 0:dbad57390bd1 302 }
ram54288 0:dbad57390bd1 303
ram54288 0:dbad57390bd1 304 static_fp get_function()const
ram54288 0:dbad57390bd1 305 {
ram54288 0:dbad57390bd1 306 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object);
ram54288 0:dbad57390bd1 307 }
ram54288 0:dbad57390bd1 308
ram54288 0:dbad57390bd1 309 R operator ()(A1 a1, A2 a2) {
ram54288 0:dbad57390bd1 310 return call(a1, a2);
ram54288 0:dbad57390bd1 311 }
ram54288 0:dbad57390bd1 312
ram54288 0:dbad57390bd1 313 private:
ram54288 0:dbad57390bd1 314 template<typename T>
ram54288 0:dbad57390bd1 315 static R membercaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 316 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 317 T* o = static_cast<T*>(object);
ram54288 0:dbad57390bd1 318 R (T::**m)(A1, A2) = reinterpret_cast<R (T::**)(A1, A2)>(member);
ram54288 0:dbad57390bd1 319 return (o->**m)(Args->a1, Args->a2);
ram54288 0:dbad57390bd1 320 }
ram54288 0:dbad57390bd1 321 static R staticcaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 322 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 323 (void) member;
ram54288 0:dbad57390bd1 324 static_fp f = reinterpret_cast<static_fp>(object);
ram54288 0:dbad57390bd1 325 return f(Args->a1, Args->a2);
ram54288 0:dbad57390bd1 326 }
ram54288 0:dbad57390bd1 327 /* static void constructor(void * dest, va_list args) {
ram54288 0:dbad57390bd1 328 A1 *a1 = va_arg(args, A1*);
ram54288 0:dbad57390bd1 329 A2 *a2 = va_arg(args, A2*);
ram54288 0:dbad57390bd1 330 new(dest) ArgStruct(a1, a2);
ram54288 0:dbad57390bd1 331 }
ram54288 0:dbad57390bd1 332 static void copy_constructor(void *dest , void* src) {
ram54288 0:dbad57390bd1 333 ArgStruct *src_args = static_cast<ArgStruct *>(src);
ram54288 0:dbad57390bd1 334 new(dest) ArgStruct(&(src_args->a1), &(src_args->a2));
ram54288 0:dbad57390bd1 335 }
ram54288 0:dbad57390bd1 336 static void destructor(void *args) {
ram54288 0:dbad57390bd1 337 ArgStruct *argstruct = static_cast<ArgStruct *>(args);
ram54288 0:dbad57390bd1 338 argstruct->~arg_struct();
ram54288 0:dbad57390bd1 339 }
ram54288 0:dbad57390bd1 340 */
ram54288 0:dbad57390bd1 341 protected:
ram54288 0:dbad57390bd1 342 static const struct FunctionPointerBase<R>::ArgOps _fp2_ops;
ram54288 0:dbad57390bd1 343 };
ram54288 0:dbad57390bd1 344
ram54288 0:dbad57390bd1 345 template <typename R, typename A1, typename A2>
ram54288 0:dbad57390bd1 346 const struct FunctionPointerBase<R>::ArgOps FunctionPointer2<R,A1,A2>::_fp2_ops = {
ram54288 0:dbad57390bd1 347 FunctionPointer2<R,A1,A2>::constructor,
ram54288 0:dbad57390bd1 348 FunctionPointer2<R,A1,A2>::copy_constructor,
ram54288 0:dbad57390bd1 349 FunctionPointer2<R,A1,A2>::destructor
ram54288 0:dbad57390bd1 350 };
ram54288 0:dbad57390bd1 351
ram54288 0:dbad57390bd1 352 /** A class for storing and calling a pointer to a static or member void function with three arguments
ram54288 0:dbad57390bd1 353 */
ram54288 0:dbad57390bd1 354 template <typename R, typename A1, typename A2, typename A3>
ram54288 0:dbad57390bd1 355 class FunctionPointer3 : public FunctionPointerBase<R> {
ram54288 0:dbad57390bd1 356 protected:
ram54288 0:dbad57390bd1 357 typedef struct arg_struct{
ram54288 0:dbad57390bd1 358 A1 a1;
ram54288 0:dbad57390bd1 359 A2 a2;
ram54288 0:dbad57390bd1 360 A3 a3;
ram54288 0:dbad57390bd1 361 arg_struct(const A1 *b1, const A2 *b2, const A3* b3) {
ram54288 0:dbad57390bd1 362 a1 = *b1;
ram54288 0:dbad57390bd1 363 a2 = *b2;
ram54288 0:dbad57390bd1 364 a3 = *b3;
ram54288 0:dbad57390bd1 365 }
ram54288 0:dbad57390bd1 366 } ArgStruct;
ram54288 0:dbad57390bd1 367
ram54288 0:dbad57390bd1 368 public:
ram54288 0:dbad57390bd1 369 typedef R(*static_fp)(A1, A2, A3);
ram54288 0:dbad57390bd1 370 /** Create a FunctionPointer, attaching a static function
ram54288 0:dbad57390bd1 371 *
ram54288 0:dbad57390bd1 372 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 373 */
ram54288 0:dbad57390bd1 374 FunctionPointer3(static_fp function = 0) {
ram54288 0:dbad57390bd1 375 attach(function);
ram54288 0:dbad57390bd1 376 }
ram54288 0:dbad57390bd1 377
ram54288 0:dbad57390bd1 378 /** Create a FunctionPointer, attaching a member function
ram54288 0:dbad57390bd1 379 *
ram54288 0:dbad57390bd1 380 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 381 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 382 */
ram54288 0:dbad57390bd1 383 template<typename T>
ram54288 0:dbad57390bd1 384 FunctionPointer3(T *object, R (T::*member)(A1, A2, A3)) {
ram54288 0:dbad57390bd1 385 attach(object, member);
ram54288 0:dbad57390bd1 386 }
ram54288 0:dbad57390bd1 387
ram54288 0:dbad57390bd1 388 /** Attach a static function
ram54288 0:dbad57390bd1 389 *
ram54288 0:dbad57390bd1 390 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 391 */
ram54288 0:dbad57390bd1 392 void attach(static_fp function) {
ram54288 0:dbad57390bd1 393 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function);
ram54288 0:dbad57390bd1 394 FunctionPointerBase<R>::_membercaller = &FunctionPointer3::staticcaller;
ram54288 0:dbad57390bd1 395 }
ram54288 0:dbad57390bd1 396
ram54288 0:dbad57390bd1 397 /** Attach a member function
ram54288 0:dbad57390bd1 398 *
ram54288 0:dbad57390bd1 399 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 400 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 401 */
ram54288 0:dbad57390bd1 402 template<typename T>
ram54288 0:dbad57390bd1 403 void attach(T *object, R (T::*member)(A1, A2, A3))
ram54288 0:dbad57390bd1 404 {
ram54288 0:dbad57390bd1 405 FunctionPointerBase<R>::_object = static_cast<void*>(object);
ram54288 0:dbad57390bd1 406 *reinterpret_cast<R (T::**)(A1, A2, A3)>(FunctionPointerBase<R>::_member) = member;
ram54288 0:dbad57390bd1 407 FunctionPointerBase<R>::_membercaller = &FunctionPointer3::membercaller<T>;
ram54288 0:dbad57390bd1 408 }
ram54288 0:dbad57390bd1 409
ram54288 0:dbad57390bd1 410 FunctionPointerBind<R> bind(const A1 &a1, const A2 &a2, const A3 &a3) {
ram54288 0:dbad57390bd1 411 FunctionPointerBind<R> fp;
ram54288 0:dbad57390bd1 412 fp.bind(&_fp3_ops, (ArgStruct *) NULL, this, &a1, &a2, &a3);
ram54288 0:dbad57390bd1 413 return fp;
ram54288 0:dbad57390bd1 414 }
ram54288 0:dbad57390bd1 415
ram54288 0:dbad57390bd1 416
ram54288 0:dbad57390bd1 417 /** Call the attached static or member function
ram54288 0:dbad57390bd1 418 */
ram54288 0:dbad57390bd1 419 R call(A1 a1, A2 a2, A3 a3)
ram54288 0:dbad57390bd1 420 {
ram54288 0:dbad57390bd1 421 ArgStruct Args(&a1, &a2, &a3);
ram54288 0:dbad57390bd1 422 return FunctionPointerBase<R>::call(&Args);
ram54288 0:dbad57390bd1 423 }
ram54288 0:dbad57390bd1 424
ram54288 0:dbad57390bd1 425 static_fp get_function()const
ram54288 0:dbad57390bd1 426 {
ram54288 0:dbad57390bd1 427 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object);
ram54288 0:dbad57390bd1 428 }
ram54288 0:dbad57390bd1 429
ram54288 0:dbad57390bd1 430 R operator ()(A1 a1, A2 a2, A3 a3) {
ram54288 0:dbad57390bd1 431 return call(a1, a2, a3);
ram54288 0:dbad57390bd1 432 }
ram54288 0:dbad57390bd1 433
ram54288 0:dbad57390bd1 434 private:
ram54288 0:dbad57390bd1 435 template<typename T>
ram54288 0:dbad57390bd1 436 static R membercaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 437 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 438 T* o = static_cast<T*>(object);
ram54288 0:dbad57390bd1 439 R (T::**m)(A1, A2, A3) = reinterpret_cast<R (T::**)(A1, A2, A3)>(member);
ram54288 0:dbad57390bd1 440 return (o->**m)(Args->a1, Args->a2, Args->a3);
ram54288 0:dbad57390bd1 441 }
ram54288 0:dbad57390bd1 442 static R staticcaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 443 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 444 (void) member;
ram54288 0:dbad57390bd1 445 static_fp f = reinterpret_cast<static_fp>(object);
ram54288 0:dbad57390bd1 446 return f(Args->a1, Args->a2, Args->a3);
ram54288 0:dbad57390bd1 447 }
ram54288 0:dbad57390bd1 448 /* static void constructor(void * dest, va_list args) {
ram54288 0:dbad57390bd1 449 A1 *a1 = va_arg(args, A1*);
ram54288 0:dbad57390bd1 450 A2 *a2 = va_arg(args, A2*);
ram54288 0:dbad57390bd1 451 A3 *a3 = va_arg(args, A3*);
ram54288 0:dbad57390bd1 452 new(dest) ArgStruct(a1, a2, a3);
ram54288 0:dbad57390bd1 453 }
ram54288 0:dbad57390bd1 454 static void copy_constructor(void *dest , void* src) {
ram54288 0:dbad57390bd1 455 ArgStruct *src_args = static_cast<ArgStruct *>(src);
ram54288 0:dbad57390bd1 456 new(dest) ArgStruct(&(src_args->a1), &(src_args->a2), &(src_args->a3));
ram54288 0:dbad57390bd1 457 }
ram54288 0:dbad57390bd1 458 static void destructor(void *args) {
ram54288 0:dbad57390bd1 459 ArgStruct *argstruct = static_cast<ArgStruct *>(args);
ram54288 0:dbad57390bd1 460 argstruct->~arg_struct();
ram54288 0:dbad57390bd1 461 }
ram54288 0:dbad57390bd1 462 */
ram54288 0:dbad57390bd1 463 protected:
ram54288 0:dbad57390bd1 464 static const struct FunctionPointerBase<R>::ArgOps _fp3_ops;
ram54288 0:dbad57390bd1 465 };
ram54288 0:dbad57390bd1 466
ram54288 0:dbad57390bd1 467 template <typename R, typename A1, typename A2, typename A3>
ram54288 0:dbad57390bd1 468 const struct FunctionPointerBase<R>::ArgOps FunctionPointer3<R,A1,A2,A3>::_fp3_ops = {
ram54288 0:dbad57390bd1 469 FunctionPointer3<R,A1,A2,A3>::constructor,
ram54288 0:dbad57390bd1 470 FunctionPointer3<R,A1,A2,A3>::copy_constructor,
ram54288 0:dbad57390bd1 471 FunctionPointer3<R,A1,A2,A3>::destructor
ram54288 0:dbad57390bd1 472 };
ram54288 0:dbad57390bd1 473
ram54288 0:dbad57390bd1 474 /** A class for storing and calling a pointer to a static or member void function with four arguments
ram54288 0:dbad57390bd1 475 */
ram54288 0:dbad57390bd1 476 template <typename R, typename A1, typename A2, typename A3, typename A4>
ram54288 0:dbad57390bd1 477 class FunctionPointer4 : public FunctionPointerBase<R> {
ram54288 0:dbad57390bd1 478 protected:
ram54288 0:dbad57390bd1 479 typedef struct arg_struct{
ram54288 0:dbad57390bd1 480 A1 a1;
ram54288 0:dbad57390bd1 481 A2 a2;
ram54288 0:dbad57390bd1 482 A3 a3;
ram54288 0:dbad57390bd1 483 A4 a4;
ram54288 0:dbad57390bd1 484 arg_struct(const A1 *b1, const A2 *b2, const A3* b3, const A4* b4) {
ram54288 0:dbad57390bd1 485 a1 = *b1;
ram54288 0:dbad57390bd1 486 a2 = *b2;
ram54288 0:dbad57390bd1 487 a3 = *b3;
ram54288 0:dbad57390bd1 488 a4 = *b4;
ram54288 0:dbad57390bd1 489 }
ram54288 0:dbad57390bd1 490 } ArgStruct;
ram54288 0:dbad57390bd1 491
ram54288 0:dbad57390bd1 492 public:
ram54288 0:dbad57390bd1 493 typedef R(*static_fp)(A1, A2, A3, A4);
ram54288 0:dbad57390bd1 494 /** Create a FunctionPointer, attaching a static function
ram54288 0:dbad57390bd1 495 *
ram54288 0:dbad57390bd1 496 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 497 */
ram54288 0:dbad57390bd1 498 FunctionPointer4(static_fp function = 0) {
ram54288 0:dbad57390bd1 499 attach(function);
ram54288 0:dbad57390bd1 500 }
ram54288 0:dbad57390bd1 501
ram54288 0:dbad57390bd1 502 /** Create a FunctionPointer, attaching a member function
ram54288 0:dbad57390bd1 503 *
ram54288 0:dbad57390bd1 504 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 505 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 506 */
ram54288 0:dbad57390bd1 507 template<typename T>
ram54288 0:dbad57390bd1 508 FunctionPointer4(T *object, R (T::*member)(A1, A2, A3, A4)) {
ram54288 0:dbad57390bd1 509 attach(object, member);
ram54288 0:dbad57390bd1 510 }
ram54288 0:dbad57390bd1 511
ram54288 0:dbad57390bd1 512 /** Attach a static function
ram54288 0:dbad57390bd1 513 *
ram54288 0:dbad57390bd1 514 * @param function The void static function to attach (default is none)
ram54288 0:dbad57390bd1 515 */
ram54288 0:dbad57390bd1 516 void attach(static_fp function) {
ram54288 0:dbad57390bd1 517 FunctionPointerBase<R>::_object = reinterpret_cast<void*>(function);
ram54288 0:dbad57390bd1 518 FunctionPointerBase<R>::_membercaller = &FunctionPointer4::staticcaller;
ram54288 0:dbad57390bd1 519 }
ram54288 0:dbad57390bd1 520
ram54288 0:dbad57390bd1 521 /** Attach a member function
ram54288 0:dbad57390bd1 522 *
ram54288 0:dbad57390bd1 523 * @param object The object pointer to invoke the member function on (i.e. the this pointer)
ram54288 0:dbad57390bd1 524 * @param function The address of the void member function to attach
ram54288 0:dbad57390bd1 525 */
ram54288 0:dbad57390bd1 526 template<typename T>
ram54288 0:dbad57390bd1 527 void attach(T *object, R (T::*member)(A1, A2, A3, A4))
ram54288 0:dbad57390bd1 528 {
ram54288 0:dbad57390bd1 529 FunctionPointerBase<R>::_object = static_cast<void*>(object);
ram54288 0:dbad57390bd1 530 *reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(FunctionPointerBase<R>::_member) = member;
ram54288 0:dbad57390bd1 531 FunctionPointerBase<R>::_membercaller = &FunctionPointer4::membercaller<T>;
ram54288 0:dbad57390bd1 532 }
ram54288 0:dbad57390bd1 533
ram54288 0:dbad57390bd1 534 FunctionPointerBind<R> bind(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4) {
ram54288 0:dbad57390bd1 535 FunctionPointerBind<R> fp;
ram54288 0:dbad57390bd1 536 fp.bind(&_fp4_ops, (ArgStruct *) NULL, this, &a1, &a2, &a3, &a4);
ram54288 0:dbad57390bd1 537 return fp;
ram54288 0:dbad57390bd1 538 }
ram54288 0:dbad57390bd1 539
ram54288 0:dbad57390bd1 540
ram54288 0:dbad57390bd1 541 /** Call the attached static or member function
ram54288 0:dbad57390bd1 542 */
ram54288 0:dbad57390bd1 543 R call(A1 a1, A2 a2, A3 a3, A4 a4)
ram54288 0:dbad57390bd1 544 {
ram54288 0:dbad57390bd1 545 ArgStruct Args(&a1, &a2, &a3, &a4);
ram54288 0:dbad57390bd1 546 return FunctionPointerBase<R>::call(&Args);
ram54288 0:dbad57390bd1 547 }
ram54288 0:dbad57390bd1 548
ram54288 0:dbad57390bd1 549 static_fp get_function()const
ram54288 0:dbad57390bd1 550 {
ram54288 0:dbad57390bd1 551 return reinterpret_cast<static_fp>(FunctionPointerBase<R>::_object);
ram54288 0:dbad57390bd1 552 }
ram54288 0:dbad57390bd1 553
ram54288 0:dbad57390bd1 554 R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) {
ram54288 0:dbad57390bd1 555 return call(a1, a2, a3, a4);
ram54288 0:dbad57390bd1 556 }
ram54288 0:dbad57390bd1 557
ram54288 0:dbad57390bd1 558 private:
ram54288 0:dbad57390bd1 559 template<typename T>
ram54288 0:dbad57390bd1 560 static R membercaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 561 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 562 T* o = static_cast<T*>(object);
ram54288 0:dbad57390bd1 563 R (T::**m)(A1, A2, A3, A4) = reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(member);
ram54288 0:dbad57390bd1 564 return (o->**m)(Args->a1, Args->a2, Args->a3, Args->a4);
ram54288 0:dbad57390bd1 565 }
ram54288 0:dbad57390bd1 566 static R staticcaller(void *object, uintptr_t *member, void *arg) {
ram54288 0:dbad57390bd1 567 ArgStruct *Args = static_cast<ArgStruct *>(arg);
ram54288 0:dbad57390bd1 568 (void) member;
ram54288 0:dbad57390bd1 569 static_fp f = reinterpret_cast<static_fp>(object);
ram54288 0:dbad57390bd1 570 return f(Args->a1, Args->a2, Args->a3, Args->a4);
ram54288 0:dbad57390bd1 571 }
ram54288 0:dbad57390bd1 572 /* static void constructor(void * dest, va_list args) {
ram54288 0:dbad57390bd1 573 A1 *a1 = va_arg(args, A1*);
ram54288 0:dbad57390bd1 574 A2 *a2 = va_arg(args, A2*);
ram54288 0:dbad57390bd1 575 A3 *a3 = va_arg(args, A3*);
ram54288 0:dbad57390bd1 576 A4 *a4 = va_arg(args, A4*);
ram54288 0:dbad57390bd1 577 new(dest) ArgStruct(a1, a2, a3, a4);
ram54288 0:dbad57390bd1 578 }
ram54288 0:dbad57390bd1 579 static void copy_constructor(void *dest , void* src) {
ram54288 0:dbad57390bd1 580 ArgStruct *src_args = static_cast<ArgStruct *>(src);
ram54288 0:dbad57390bd1 581 new(dest) ArgStruct(&(src_args->a1), &(src_args->a2), &(src_args->a3), &(src_args->a4));
ram54288 0:dbad57390bd1 582 }
ram54288 0:dbad57390bd1 583 static void destructor(void *args) {
ram54288 0:dbad57390bd1 584 ArgStruct *argstruct = static_cast<ArgStruct *>(args);
ram54288 0:dbad57390bd1 585 argstruct->~arg_struct();
ram54288 0:dbad57390bd1 586 }
ram54288 0:dbad57390bd1 587 */
ram54288 0:dbad57390bd1 588 protected:
ram54288 0:dbad57390bd1 589 static const struct FunctionPointerBase<R>::ArgOps _fp4_ops;
ram54288 0:dbad57390bd1 590 };
ram54288 0:dbad57390bd1 591
ram54288 0:dbad57390bd1 592 template <typename R, typename A1, typename A2, typename A3, typename A4>
ram54288 0:dbad57390bd1 593 const struct FunctionPointerBase<R>::ArgOps FunctionPointer4<R,A1,A2,A3,A4>::_fp4_ops = {
ram54288 0:dbad57390bd1 594 FunctionPointer4<R,A1,A2,A3,A4>::constructor,
ram54288 0:dbad57390bd1 595 FunctionPointer4<R,A1,A2,A3,A4>::copy_constructor,
ram54288 0:dbad57390bd1 596 FunctionPointer4<R,A1,A2,A3,A4>::destructor
ram54288 0:dbad57390bd1 597 };
ram54288 0:dbad57390bd1 598
ram54288 0:dbad57390bd1 599 typedef FunctionPointer0<void> FunctionPointer;
ram54288 0:dbad57390bd1 600 //typedef FunctionPointer1<void, int> event_callback_t;
ram54288 0:dbad57390bd1 601
ram54288 0:dbad57390bd1 602 } // namespace mbed
ram54288 0:dbad57390bd1 603
ram54288 0:dbad57390bd1 604 #endif