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