mbed official / mbed Featured

The official mbed C/C++ SDK provides the software platform and libraries to build your applications.

Dependents:   hello SerialTestv11 SerialTestv12 Sierpinski ... more

mbed 2

This is the mbed 2 library. If you'd like to learn about using mbed-os, please see the mbed-os docs.

Committer:
Kojto
Date:
Thu Jul 07 14:34:11 2016 +0100
Revision:
122:f9eeca106725
Child:
123:b0220dba8be7
Release 122 of the mbed library

Changes:
- new targets - Nucleo L432KC, Beetle, Nucleo F446ZE, Nucleo L011K4
- Thread safety addition - mbed API should contain a statement about thread safety
- critical section API addition
- CAS API (core_util_atomic_incr/decr)
- DEVICE_ are generated from targets.json file, device.h deprecated
- Callback replaces FunctionPointer to provide std like interface
- mbed HAL API docs improvements
- toolchain - prexif attributes with MBED_
- add new attributes - packed, weak, forcedinline, align
- target.json - contains targets definitions
- ST - L1XX - Cube update to 1.5
- SPI clock selection fix (clock from APB domain)
- F7 - Cube update v1.4.0
- L0 - baudrate init fix
- L1 - Cube update v1.5
- F3 - baudrate init fix, 3 targets CAN support
- F4 - Cube update v1.12.0, 3 targets CAN support
- L4XX - Cube update v1.5.1
- F0 - update Cube to v1.5.0
- L4 - 2 targets (L476RG/VG) CAN support
- NXP - pwm clock fix for KSDK2 MCU
- LPC2368 - remove ARM toolchain support - due to regression
- KSDK2 - fix SPI , I2C address and repeat start
- Silabs - some fixes backported from mbed 3
- Renesas - RZ_A1H - SystemCoreClockUpdate addition

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto122:f9eeca106725 1/* mbed Microcontroller Library
Kojto122:f9eeca106725 2 * Copyright (c) 2006-2015 ARM Limited
Kojto122:f9eeca106725 3 *
Kojto122:f9eeca106725 4 * Licensed under the Apache License, Version 2.0 (the "License");
Kojto122:f9eeca106725 5 * you may not use this file except in compliance with the License.
Kojto122:f9eeca106725 6 * You may obtain a copy of the License at
Kojto122:f9eeca106725 7 *
Kojto122:f9eeca106725 8 * http://www.apache.org/licenses/LICENSE-2.0
Kojto122:f9eeca106725 9 *
Kojto122:f9eeca106725 10 * Unless required by applicable law or agreed to in writing, software
Kojto122:f9eeca106725 11 * distributed under the License is distributed on an "AS IS" BASIS,
Kojto122:f9eeca106725 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Kojto122:f9eeca106725 13 * See the License for the specific language governing permissions and
Kojto122:f9eeca106725 14 * limitations under the License.
Kojto122:f9eeca106725 15 */
Kojto122:f9eeca106725 16#ifndef MBED_CALLBACK_H
Kojto122:f9eeca106725 17#define MBED_CALLBACK_H
Kojto122:f9eeca106725 18
Kojto122:f9eeca106725 19#include <string.h>
Kojto122:f9eeca106725 20#include <stdint.h>
Kojto122:f9eeca106725 21
Kojto122:f9eeca106725 22namespace mbed {
Kojto122:f9eeca106725 23
Kojto122:f9eeca106725 24
Kojto122:f9eeca106725 25/** Callback class based on template specialization
Kojto122:f9eeca106725 26 *
Kojto122:f9eeca106725 27 * @Note Synchronization level: Not protected
Kojto122:f9eeca106725 28 */
Kojto122:f9eeca106725 29template <typename F>
Kojto122:f9eeca106725 30class Callback;
Kojto122:f9eeca106725 31
Kojto122:f9eeca106725 32/** Templated function class
Kojto122:f9eeca106725 33 */
Kojto122:f9eeca106725 34template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
Kojto122:f9eeca106725 35class Callback<R(A0, A1, A2, A3, A4)> {
Kojto122:f9eeca106725 36public:
Kojto122:f9eeca106725 37 /** Create a Callback with a static function
Kojto122:f9eeca106725 38 * @param func Static function to attach
Kojto122:f9eeca106725 39 */
Kojto122:f9eeca106725 40 Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
Kojto122:f9eeca106725 41 attach(func);
Kojto122:f9eeca106725 42 }
Kojto122:f9eeca106725 43
Kojto122:f9eeca106725 44 /** Create a Callback with a static function and bound pointer
Kojto122:f9eeca106725 45 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 46 * @param func Static function to attach
Kojto122:f9eeca106725 47 */
Kojto122:f9eeca106725 48 template<typename T>
Kojto122:f9eeca106725 49 Callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
Kojto122:f9eeca106725 50 attach(obj, func);
Kojto122:f9eeca106725 51 }
Kojto122:f9eeca106725 52
Kojto122:f9eeca106725 53 /** Create a Callback with a member function
Kojto122:f9eeca106725 54 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 55 * @param func Member function to attach
Kojto122:f9eeca106725 56 */
Kojto122:f9eeca106725 57 template<typename T>
Kojto122:f9eeca106725 58 Callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
Kojto122:f9eeca106725 59 attach(obj, func);
Kojto122:f9eeca106725 60 }
Kojto122:f9eeca106725 61
Kojto122:f9eeca106725 62 /** Create a Callback with another Callback
Kojto122:f9eeca106725 63 * @param func Callback to attach
Kojto122:f9eeca106725 64 */
Kojto122:f9eeca106725 65 Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
Kojto122:f9eeca106725 66 attach(func);
Kojto122:f9eeca106725 67 }
Kojto122:f9eeca106725 68
Kojto122:f9eeca106725 69 /** Attach a static function
Kojto122:f9eeca106725 70 * @param func Static function to attach
Kojto122:f9eeca106725 71 */
Kojto122:f9eeca106725 72 void attach(R (*func)(A0, A1, A2, A3, A4)) {
Kojto122:f9eeca106725 73 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 74 _thunk = func ? &Callback::_staticthunk : 0;
Kojto122:f9eeca106725 75 }
Kojto122:f9eeca106725 76
Kojto122:f9eeca106725 77 /** Attach a static function with a bound pointer
Kojto122:f9eeca106725 78 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 79 * @param func Static function to attach
Kojto122:f9eeca106725 80 */
Kojto122:f9eeca106725 81 template <typename T>
Kojto122:f9eeca106725 82 void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
Kojto122:f9eeca106725 83 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 84 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 85 _thunk = &Callback::_boundthunk<T>;
Kojto122:f9eeca106725 86 }
Kojto122:f9eeca106725 87
Kojto122:f9eeca106725 88 /** Attach a member function
Kojto122:f9eeca106725 89 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 90 * @param func Member function to attach
Kojto122:f9eeca106725 91 */
Kojto122:f9eeca106725 92 template<typename T>
Kojto122:f9eeca106725 93 void attach(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
Kojto122:f9eeca106725 94 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 95 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 96 _thunk = &Callback::_methodthunk<T>;
Kojto122:f9eeca106725 97 }
Kojto122:f9eeca106725 98
Kojto122:f9eeca106725 99 /** Attach a Callback
Kojto122:f9eeca106725 100 * @param func The Callback to attach
Kojto122:f9eeca106725 101 */
Kojto122:f9eeca106725 102 void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
Kojto122:f9eeca106725 103 _obj = func._obj;
Kojto122:f9eeca106725 104 memcpy(&_func, &func._func, sizeof _func);
Kojto122:f9eeca106725 105 _thunk = func._thunk;
Kojto122:f9eeca106725 106 }
Kojto122:f9eeca106725 107
Kojto122:f9eeca106725 108 /** Call the attached function
Kojto122:f9eeca106725 109 */
Kojto122:f9eeca106725 110 R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Kojto122:f9eeca106725 111 if (!_thunk) {
Kojto122:f9eeca106725 112 return (R)0;
Kojto122:f9eeca106725 113 }
Kojto122:f9eeca106725 114 return _thunk(_obj, &_func, a0, a1, a2, a3, a4);
Kojto122:f9eeca106725 115 }
Kojto122:f9eeca106725 116
Kojto122:f9eeca106725 117 /** Call the attached function
Kojto122:f9eeca106725 118 */
Kojto122:f9eeca106725 119 R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Kojto122:f9eeca106725 120 return call(a0, a1, a2, a3, a4);
Kojto122:f9eeca106725 121 }
Kojto122:f9eeca106725 122
Kojto122:f9eeca106725 123 /** Test if function has been attached
Kojto122:f9eeca106725 124 */
Kojto122:f9eeca106725 125 operator bool() const {
Kojto122:f9eeca106725 126 return _thunk;
Kojto122:f9eeca106725 127 }
Kojto122:f9eeca106725 128
Kojto122:f9eeca106725 129 /** Static thunk for passing as C-style function
Kojto122:f9eeca106725 130 * @param func Callback to call passed as void pointer
Kojto122:f9eeca106725 131 */
Kojto122:f9eeca106725 132 static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Kojto122:f9eeca106725 133 return static_cast<Callback<R(A0, A1, A2, A3, A4)>*>(func)
Kojto122:f9eeca106725 134 ->call(a0, a1, a2, a3, a4);
Kojto122:f9eeca106725 135 }
Kojto122:f9eeca106725 136
Kojto122:f9eeca106725 137private:
Kojto122:f9eeca106725 138 // Internal thunks for various function types
Kojto122:f9eeca106725 139 static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Kojto122:f9eeca106725 140 return (*reinterpret_cast<R (**)(A0, A1, A2, A3, A4)>(func))
Kojto122:f9eeca106725 141 (a0, a1, a2, a3, a4);
Kojto122:f9eeca106725 142 }
Kojto122:f9eeca106725 143
Kojto122:f9eeca106725 144 template<typename T>
Kojto122:f9eeca106725 145 static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Kojto122:f9eeca106725 146 return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3, A4)>(func))
Kojto122:f9eeca106725 147 (static_cast<T*>(obj), a0, a1, a2, a3, a4);
Kojto122:f9eeca106725 148 }
Kojto122:f9eeca106725 149
Kojto122:f9eeca106725 150 template<typename T>
Kojto122:f9eeca106725 151 static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Kojto122:f9eeca106725 152 return (static_cast<T*>(obj)->*
Kojto122:f9eeca106725 153 (*reinterpret_cast<R (T::**)(A0, A1, A2, A3, A4)>(func)))
Kojto122:f9eeca106725 154 (a0, a1, a2, a3, a4);
Kojto122:f9eeca106725 155 }
Kojto122:f9eeca106725 156
Kojto122:f9eeca106725 157 // Stored as pointer to function and pointer to optional object
Kojto122:f9eeca106725 158 // Function pointer is stored as union of possible function types
Kojto122:f9eeca106725 159 // to garuntee proper size and alignment
Kojto122:f9eeca106725 160 struct _class;
Kojto122:f9eeca106725 161 union {
Kojto122:f9eeca106725 162 void (*_staticfunc)();
Kojto122:f9eeca106725 163 void (*_boundfunc)(_class *);
Kojto122:f9eeca106725 164 void (_class::*_methodfunc)();
Kojto122:f9eeca106725 165 } _func;
Kojto122:f9eeca106725 166
Kojto122:f9eeca106725 167 void *_obj;
Kojto122:f9eeca106725 168
Kojto122:f9eeca106725 169 // Thunk registered on attach to dispatch calls
Kojto122:f9eeca106725 170 R (*_thunk)(void*, void*, A0, A1, A2, A3, A4);
Kojto122:f9eeca106725 171};
Kojto122:f9eeca106725 172
Kojto122:f9eeca106725 173/** Templated function class
Kojto122:f9eeca106725 174 */
Kojto122:f9eeca106725 175template <typename R, typename A0, typename A1, typename A2, typename A3>
Kojto122:f9eeca106725 176class Callback<R(A0, A1, A2, A3)> {
Kojto122:f9eeca106725 177public:
Kojto122:f9eeca106725 178 /** Create a Callback with a static function
Kojto122:f9eeca106725 179 * @param func Static function to attach
Kojto122:f9eeca106725 180 */
Kojto122:f9eeca106725 181 Callback(R (*func)(A0, A1, A2, A3) = 0) {
Kojto122:f9eeca106725 182 attach(func);
Kojto122:f9eeca106725 183 }
Kojto122:f9eeca106725 184
Kojto122:f9eeca106725 185 /** Create a Callback with a static function and bound pointer
Kojto122:f9eeca106725 186 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 187 * @param func Static function to attach
Kojto122:f9eeca106725 188 */
Kojto122:f9eeca106725 189 template<typename T>
Kojto122:f9eeca106725 190 Callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
Kojto122:f9eeca106725 191 attach(obj, func);
Kojto122:f9eeca106725 192 }
Kojto122:f9eeca106725 193
Kojto122:f9eeca106725 194 /** Create a Callback with a member function
Kojto122:f9eeca106725 195 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 196 * @param func Member function to attach
Kojto122:f9eeca106725 197 */
Kojto122:f9eeca106725 198 template<typename T>
Kojto122:f9eeca106725 199 Callback(T *obj, R (T::*func)(A0, A1, A2, A3)) {
Kojto122:f9eeca106725 200 attach(obj, func);
Kojto122:f9eeca106725 201 }
Kojto122:f9eeca106725 202
Kojto122:f9eeca106725 203 /** Create a Callback with another Callback
Kojto122:f9eeca106725 204 * @param func Callback to attach
Kojto122:f9eeca106725 205 */
Kojto122:f9eeca106725 206 Callback(const Callback<R(A0, A1, A2, A3)> &func) {
Kojto122:f9eeca106725 207 attach(func);
Kojto122:f9eeca106725 208 }
Kojto122:f9eeca106725 209
Kojto122:f9eeca106725 210 /** Attach a static function
Kojto122:f9eeca106725 211 * @param func Static function to attach
Kojto122:f9eeca106725 212 */
Kojto122:f9eeca106725 213 void attach(R (*func)(A0, A1, A2, A3)) {
Kojto122:f9eeca106725 214 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 215 _thunk = func ? &Callback::_staticthunk : 0;
Kojto122:f9eeca106725 216 }
Kojto122:f9eeca106725 217
Kojto122:f9eeca106725 218 /** Attach a static function with a bound pointer
Kojto122:f9eeca106725 219 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 220 * @param func Static function to attach
Kojto122:f9eeca106725 221 */
Kojto122:f9eeca106725 222 template <typename T>
Kojto122:f9eeca106725 223 void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
Kojto122:f9eeca106725 224 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 225 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 226 _thunk = &Callback::_boundthunk<T>;
Kojto122:f9eeca106725 227 }
Kojto122:f9eeca106725 228
Kojto122:f9eeca106725 229 /** Attach a member function
Kojto122:f9eeca106725 230 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 231 * @param func Member function to attach
Kojto122:f9eeca106725 232 */
Kojto122:f9eeca106725 233 template<typename T>
Kojto122:f9eeca106725 234 void attach(T *obj, R (T::*func)(A0, A1, A2, A3)) {
Kojto122:f9eeca106725 235 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 236 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 237 _thunk = &Callback::_methodthunk<T>;
Kojto122:f9eeca106725 238 }
Kojto122:f9eeca106725 239
Kojto122:f9eeca106725 240 /** Attach a Callback
Kojto122:f9eeca106725 241 * @param func The Callback to attach
Kojto122:f9eeca106725 242 */
Kojto122:f9eeca106725 243 void attach(const Callback<R(A0, A1, A2, A3)> &func) {
Kojto122:f9eeca106725 244 _obj = func._obj;
Kojto122:f9eeca106725 245 memcpy(&_func, &func._func, sizeof _func);
Kojto122:f9eeca106725 246 _thunk = func._thunk;
Kojto122:f9eeca106725 247 }
Kojto122:f9eeca106725 248
Kojto122:f9eeca106725 249 /** Call the attached function
Kojto122:f9eeca106725 250 */
Kojto122:f9eeca106725 251 R call(A0 a0, A1 a1, A2 a2, A3 a3) {
Kojto122:f9eeca106725 252 if (!_thunk) {
Kojto122:f9eeca106725 253 return (R)0;
Kojto122:f9eeca106725 254 }
Kojto122:f9eeca106725 255 return _thunk(_obj, &_func, a0, a1, a2, a3);
Kojto122:f9eeca106725 256 }
Kojto122:f9eeca106725 257
Kojto122:f9eeca106725 258 /** Call the attached function
Kojto122:f9eeca106725 259 */
Kojto122:f9eeca106725 260 R operator()(A0 a0, A1 a1, A2 a2, A3 a3) {
Kojto122:f9eeca106725 261 return call(a0, a1, a2, a3);
Kojto122:f9eeca106725 262 }
Kojto122:f9eeca106725 263
Kojto122:f9eeca106725 264 /** Test if function has been attached
Kojto122:f9eeca106725 265 */
Kojto122:f9eeca106725 266 operator bool() const {
Kojto122:f9eeca106725 267 return _thunk;
Kojto122:f9eeca106725 268 }
Kojto122:f9eeca106725 269
Kojto122:f9eeca106725 270 /** Static thunk for passing as C-style function
Kojto122:f9eeca106725 271 * @param func Callback to call passed as void pointer
Kojto122:f9eeca106725 272 */
Kojto122:f9eeca106725 273 static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
Kojto122:f9eeca106725 274 return static_cast<Callback<R(A0, A1, A2, A3)>*>(func)
Kojto122:f9eeca106725 275 ->call(a0, a1, a2, a3);
Kojto122:f9eeca106725 276 }
Kojto122:f9eeca106725 277
Kojto122:f9eeca106725 278private:
Kojto122:f9eeca106725 279 // Internal thunks for various function types
Kojto122:f9eeca106725 280 static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
Kojto122:f9eeca106725 281 return (*reinterpret_cast<R (**)(A0, A1, A2, A3)>(func))
Kojto122:f9eeca106725 282 (a0, a1, a2, a3);
Kojto122:f9eeca106725 283 }
Kojto122:f9eeca106725 284
Kojto122:f9eeca106725 285 template<typename T>
Kojto122:f9eeca106725 286 static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
Kojto122:f9eeca106725 287 return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3)>(func))
Kojto122:f9eeca106725 288 (static_cast<T*>(obj), a0, a1, a2, a3);
Kojto122:f9eeca106725 289 }
Kojto122:f9eeca106725 290
Kojto122:f9eeca106725 291 template<typename T>
Kojto122:f9eeca106725 292 static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
Kojto122:f9eeca106725 293 return (static_cast<T*>(obj)->*
Kojto122:f9eeca106725 294 (*reinterpret_cast<R (T::**)(A0, A1, A2, A3)>(func)))
Kojto122:f9eeca106725 295 (a0, a1, a2, a3);
Kojto122:f9eeca106725 296 }
Kojto122:f9eeca106725 297
Kojto122:f9eeca106725 298 // Stored as pointer to function and pointer to optional object
Kojto122:f9eeca106725 299 // Function pointer is stored as union of possible function types
Kojto122:f9eeca106725 300 // to garuntee proper size and alignment
Kojto122:f9eeca106725 301 struct _class;
Kojto122:f9eeca106725 302 union {
Kojto122:f9eeca106725 303 void (*_staticfunc)();
Kojto122:f9eeca106725 304 void (*_boundfunc)(_class *);
Kojto122:f9eeca106725 305 void (_class::*_methodfunc)();
Kojto122:f9eeca106725 306 } _func;
Kojto122:f9eeca106725 307
Kojto122:f9eeca106725 308 void *_obj;
Kojto122:f9eeca106725 309
Kojto122:f9eeca106725 310 // Thunk registered on attach to dispatch calls
Kojto122:f9eeca106725 311 R (*_thunk)(void*, void*, A0, A1, A2, A3);
Kojto122:f9eeca106725 312};
Kojto122:f9eeca106725 313
Kojto122:f9eeca106725 314/** Templated function class
Kojto122:f9eeca106725 315 */
Kojto122:f9eeca106725 316template <typename R, typename A0, typename A1, typename A2>
Kojto122:f9eeca106725 317class Callback<R(A0, A1, A2)> {
Kojto122:f9eeca106725 318public:
Kojto122:f9eeca106725 319 /** Create a Callback with a static function
Kojto122:f9eeca106725 320 * @param func Static function to attach
Kojto122:f9eeca106725 321 */
Kojto122:f9eeca106725 322 Callback(R (*func)(A0, A1, A2) = 0) {
Kojto122:f9eeca106725 323 attach(func);
Kojto122:f9eeca106725 324 }
Kojto122:f9eeca106725 325
Kojto122:f9eeca106725 326 /** Create a Callback with a static function and bound pointer
Kojto122:f9eeca106725 327 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 328 * @param func Static function to attach
Kojto122:f9eeca106725 329 */
Kojto122:f9eeca106725 330 template<typename T>
Kojto122:f9eeca106725 331 Callback(T *obj, R (*func)(T*, A0, A1, A2)) {
Kojto122:f9eeca106725 332 attach(obj, func);
Kojto122:f9eeca106725 333 }
Kojto122:f9eeca106725 334
Kojto122:f9eeca106725 335 /** Create a Callback with a member function
Kojto122:f9eeca106725 336 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 337 * @param func Member function to attach
Kojto122:f9eeca106725 338 */
Kojto122:f9eeca106725 339 template<typename T>
Kojto122:f9eeca106725 340 Callback(T *obj, R (T::*func)(A0, A1, A2)) {
Kojto122:f9eeca106725 341 attach(obj, func);
Kojto122:f9eeca106725 342 }
Kojto122:f9eeca106725 343
Kojto122:f9eeca106725 344 /** Create a Callback with another Callback
Kojto122:f9eeca106725 345 * @param func Callback to attach
Kojto122:f9eeca106725 346 */
Kojto122:f9eeca106725 347 Callback(const Callback<R(A0, A1, A2)> &func) {
Kojto122:f9eeca106725 348 attach(func);
Kojto122:f9eeca106725 349 }
Kojto122:f9eeca106725 350
Kojto122:f9eeca106725 351 /** Attach a static function
Kojto122:f9eeca106725 352 * @param func Static function to attach
Kojto122:f9eeca106725 353 */
Kojto122:f9eeca106725 354 void attach(R (*func)(A0, A1, A2)) {
Kojto122:f9eeca106725 355 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 356 _thunk = func ? &Callback::_staticthunk : 0;
Kojto122:f9eeca106725 357 }
Kojto122:f9eeca106725 358
Kojto122:f9eeca106725 359 /** Attach a static function with a bound pointer
Kojto122:f9eeca106725 360 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 361 * @param func Static function to attach
Kojto122:f9eeca106725 362 */
Kojto122:f9eeca106725 363 template <typename T>
Kojto122:f9eeca106725 364 void attach(T *obj, R (*func)(T*, A0, A1, A2)) {
Kojto122:f9eeca106725 365 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 366 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 367 _thunk = &Callback::_boundthunk<T>;
Kojto122:f9eeca106725 368 }
Kojto122:f9eeca106725 369
Kojto122:f9eeca106725 370 /** Attach a member function
Kojto122:f9eeca106725 371 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 372 * @param func Member function to attach
Kojto122:f9eeca106725 373 */
Kojto122:f9eeca106725 374 template<typename T>
Kojto122:f9eeca106725 375 void attach(T *obj, R (T::*func)(A0, A1, A2)) {
Kojto122:f9eeca106725 376 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 377 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 378 _thunk = &Callback::_methodthunk<T>;
Kojto122:f9eeca106725 379 }
Kojto122:f9eeca106725 380
Kojto122:f9eeca106725 381 /** Attach a Callback
Kojto122:f9eeca106725 382 * @param func The Callback to attach
Kojto122:f9eeca106725 383 */
Kojto122:f9eeca106725 384 void attach(const Callback<R(A0, A1, A2)> &func) {
Kojto122:f9eeca106725 385 _obj = func._obj;
Kojto122:f9eeca106725 386 memcpy(&_func, &func._func, sizeof _func);
Kojto122:f9eeca106725 387 _thunk = func._thunk;
Kojto122:f9eeca106725 388 }
Kojto122:f9eeca106725 389
Kojto122:f9eeca106725 390 /** Call the attached function
Kojto122:f9eeca106725 391 */
Kojto122:f9eeca106725 392 R call(A0 a0, A1 a1, A2 a2) {
Kojto122:f9eeca106725 393 if (!_thunk) {
Kojto122:f9eeca106725 394 return (R)0;
Kojto122:f9eeca106725 395 }
Kojto122:f9eeca106725 396 return _thunk(_obj, &_func, a0, a1, a2);
Kojto122:f9eeca106725 397 }
Kojto122:f9eeca106725 398
Kojto122:f9eeca106725 399 /** Call the attached function
Kojto122:f9eeca106725 400 */
Kojto122:f9eeca106725 401 R operator()(A0 a0, A1 a1, A2 a2) {
Kojto122:f9eeca106725 402 return call(a0, a1, a2);
Kojto122:f9eeca106725 403 }
Kojto122:f9eeca106725 404
Kojto122:f9eeca106725 405 /** Test if function has been attached
Kojto122:f9eeca106725 406 */
Kojto122:f9eeca106725 407 operator bool() const {
Kojto122:f9eeca106725 408 return _thunk;
Kojto122:f9eeca106725 409 }
Kojto122:f9eeca106725 410
Kojto122:f9eeca106725 411 /** Static thunk for passing as C-style function
Kojto122:f9eeca106725 412 * @param func Callback to call passed as void pointer
Kojto122:f9eeca106725 413 */
Kojto122:f9eeca106725 414 static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
Kojto122:f9eeca106725 415 return static_cast<Callback<R(A0, A1, A2)>*>(func)
Kojto122:f9eeca106725 416 ->call(a0, a1, a2);
Kojto122:f9eeca106725 417 }
Kojto122:f9eeca106725 418
Kojto122:f9eeca106725 419private:
Kojto122:f9eeca106725 420 // Internal thunks for various function types
Kojto122:f9eeca106725 421 static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2) {
Kojto122:f9eeca106725 422 return (*reinterpret_cast<R (**)(A0, A1, A2)>(func))
Kojto122:f9eeca106725 423 (a0, a1, a2);
Kojto122:f9eeca106725 424 }
Kojto122:f9eeca106725 425
Kojto122:f9eeca106725 426 template<typename T>
Kojto122:f9eeca106725 427 static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) {
Kojto122:f9eeca106725 428 return (*reinterpret_cast<R (**)(T*, A0, A1, A2)>(func))
Kojto122:f9eeca106725 429 (static_cast<T*>(obj), a0, a1, a2);
Kojto122:f9eeca106725 430 }
Kojto122:f9eeca106725 431
Kojto122:f9eeca106725 432 template<typename T>
Kojto122:f9eeca106725 433 static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) {
Kojto122:f9eeca106725 434 return (static_cast<T*>(obj)->*
Kojto122:f9eeca106725 435 (*reinterpret_cast<R (T::**)(A0, A1, A2)>(func)))
Kojto122:f9eeca106725 436 (a0, a1, a2);
Kojto122:f9eeca106725 437 }
Kojto122:f9eeca106725 438
Kojto122:f9eeca106725 439 // Stored as pointer to function and pointer to optional object
Kojto122:f9eeca106725 440 // Function pointer is stored as union of possible function types
Kojto122:f9eeca106725 441 // to garuntee proper size and alignment
Kojto122:f9eeca106725 442 struct _class;
Kojto122:f9eeca106725 443 union {
Kojto122:f9eeca106725 444 void (*_staticfunc)();
Kojto122:f9eeca106725 445 void (*_boundfunc)(_class *);
Kojto122:f9eeca106725 446 void (_class::*_methodfunc)();
Kojto122:f9eeca106725 447 } _func;
Kojto122:f9eeca106725 448
Kojto122:f9eeca106725 449 void *_obj;
Kojto122:f9eeca106725 450
Kojto122:f9eeca106725 451 // Thunk registered on attach to dispatch calls
Kojto122:f9eeca106725 452 R (*_thunk)(void*, void*, A0, A1, A2);
Kojto122:f9eeca106725 453};
Kojto122:f9eeca106725 454
Kojto122:f9eeca106725 455/** Templated function class
Kojto122:f9eeca106725 456 */
Kojto122:f9eeca106725 457template <typename R, typename A0, typename A1>
Kojto122:f9eeca106725 458class Callback<R(A0, A1)> {
Kojto122:f9eeca106725 459public:
Kojto122:f9eeca106725 460 /** Create a Callback with a static function
Kojto122:f9eeca106725 461 * @param func Static function to attach
Kojto122:f9eeca106725 462 */
Kojto122:f9eeca106725 463 Callback(R (*func)(A0, A1) = 0) {
Kojto122:f9eeca106725 464 attach(func);
Kojto122:f9eeca106725 465 }
Kojto122:f9eeca106725 466
Kojto122:f9eeca106725 467 /** Create a Callback with a static function and bound pointer
Kojto122:f9eeca106725 468 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 469 * @param func Static function to attach
Kojto122:f9eeca106725 470 */
Kojto122:f9eeca106725 471 template<typename T>
Kojto122:f9eeca106725 472 Callback(T *obj, R (*func)(T*, A0, A1)) {
Kojto122:f9eeca106725 473 attach(obj, func);
Kojto122:f9eeca106725 474 }
Kojto122:f9eeca106725 475
Kojto122:f9eeca106725 476 /** Create a Callback with a member function
Kojto122:f9eeca106725 477 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 478 * @param func Member function to attach
Kojto122:f9eeca106725 479 */
Kojto122:f9eeca106725 480 template<typename T>
Kojto122:f9eeca106725 481 Callback(T *obj, R (T::*func)(A0, A1)) {
Kojto122:f9eeca106725 482 attach(obj, func);
Kojto122:f9eeca106725 483 }
Kojto122:f9eeca106725 484
Kojto122:f9eeca106725 485 /** Create a Callback with another Callback
Kojto122:f9eeca106725 486 * @param func Callback to attach
Kojto122:f9eeca106725 487 */
Kojto122:f9eeca106725 488 Callback(const Callback<R(A0, A1)> &func) {
Kojto122:f9eeca106725 489 attach(func);
Kojto122:f9eeca106725 490 }
Kojto122:f9eeca106725 491
Kojto122:f9eeca106725 492 /** Attach a static function
Kojto122:f9eeca106725 493 * @param func Static function to attach
Kojto122:f9eeca106725 494 */
Kojto122:f9eeca106725 495 void attach(R (*func)(A0, A1)) {
Kojto122:f9eeca106725 496 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 497 _thunk = func ? &Callback::_staticthunk : 0;
Kojto122:f9eeca106725 498 }
Kojto122:f9eeca106725 499
Kojto122:f9eeca106725 500 /** Attach a static function with a bound pointer
Kojto122:f9eeca106725 501 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 502 * @param func Static function to attach
Kojto122:f9eeca106725 503 */
Kojto122:f9eeca106725 504 template <typename T>
Kojto122:f9eeca106725 505 void attach(T *obj, R (*func)(T*, A0, A1)) {
Kojto122:f9eeca106725 506 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 507 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 508 _thunk = &Callback::_boundthunk<T>;
Kojto122:f9eeca106725 509 }
Kojto122:f9eeca106725 510
Kojto122:f9eeca106725 511 /** Attach a member function
Kojto122:f9eeca106725 512 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 513 * @param func Member function to attach
Kojto122:f9eeca106725 514 */
Kojto122:f9eeca106725 515 template<typename T>
Kojto122:f9eeca106725 516 void attach(T *obj, R (T::*func)(A0, A1)) {
Kojto122:f9eeca106725 517 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 518 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 519 _thunk = &Callback::_methodthunk<T>;
Kojto122:f9eeca106725 520 }
Kojto122:f9eeca106725 521
Kojto122:f9eeca106725 522 /** Attach a Callback
Kojto122:f9eeca106725 523 * @param func The Callback to attach
Kojto122:f9eeca106725 524 */
Kojto122:f9eeca106725 525 void attach(const Callback<R(A0, A1)> &func) {
Kojto122:f9eeca106725 526 _obj = func._obj;
Kojto122:f9eeca106725 527 memcpy(&_func, &func._func, sizeof _func);
Kojto122:f9eeca106725 528 _thunk = func._thunk;
Kojto122:f9eeca106725 529 }
Kojto122:f9eeca106725 530
Kojto122:f9eeca106725 531 /** Call the attached function
Kojto122:f9eeca106725 532 */
Kojto122:f9eeca106725 533 R call(A0 a0, A1 a1) {
Kojto122:f9eeca106725 534 if (!_thunk) {
Kojto122:f9eeca106725 535 return (R)0;
Kojto122:f9eeca106725 536 }
Kojto122:f9eeca106725 537 return _thunk(_obj, &_func, a0, a1);
Kojto122:f9eeca106725 538 }
Kojto122:f9eeca106725 539
Kojto122:f9eeca106725 540 /** Call the attached function
Kojto122:f9eeca106725 541 */
Kojto122:f9eeca106725 542 R operator()(A0 a0, A1 a1) {
Kojto122:f9eeca106725 543 return call(a0, a1);
Kojto122:f9eeca106725 544 }
Kojto122:f9eeca106725 545
Kojto122:f9eeca106725 546 /** Test if function has been attached
Kojto122:f9eeca106725 547 */
Kojto122:f9eeca106725 548 operator bool() const {
Kojto122:f9eeca106725 549 return _thunk;
Kojto122:f9eeca106725 550 }
Kojto122:f9eeca106725 551
Kojto122:f9eeca106725 552 /** Static thunk for passing as C-style function
Kojto122:f9eeca106725 553 * @param func Callback to call passed as void pointer
Kojto122:f9eeca106725 554 */
Kojto122:f9eeca106725 555 static R thunk(void *func, A0 a0, A1 a1) {
Kojto122:f9eeca106725 556 return static_cast<Callback<R(A0, A1)>*>(func)
Kojto122:f9eeca106725 557 ->call(a0, a1);
Kojto122:f9eeca106725 558 }
Kojto122:f9eeca106725 559
Kojto122:f9eeca106725 560private:
Kojto122:f9eeca106725 561 // Internal thunks for various function types
Kojto122:f9eeca106725 562 static R _staticthunk(void*, void *func, A0 a0, A1 a1) {
Kojto122:f9eeca106725 563 return (*reinterpret_cast<R (**)(A0, A1)>(func))
Kojto122:f9eeca106725 564 (a0, a1);
Kojto122:f9eeca106725 565 }
Kojto122:f9eeca106725 566
Kojto122:f9eeca106725 567 template<typename T>
Kojto122:f9eeca106725 568 static R _boundthunk(void *obj, void *func, A0 a0, A1 a1) {
Kojto122:f9eeca106725 569 return (*reinterpret_cast<R (**)(T*, A0, A1)>(func))
Kojto122:f9eeca106725 570 (static_cast<T*>(obj), a0, a1);
Kojto122:f9eeca106725 571 }
Kojto122:f9eeca106725 572
Kojto122:f9eeca106725 573 template<typename T>
Kojto122:f9eeca106725 574 static R _methodthunk(void *obj, void *func, A0 a0, A1 a1) {
Kojto122:f9eeca106725 575 return (static_cast<T*>(obj)->*
Kojto122:f9eeca106725 576 (*reinterpret_cast<R (T::**)(A0, A1)>(func)))
Kojto122:f9eeca106725 577 (a0, a1);
Kojto122:f9eeca106725 578 }
Kojto122:f9eeca106725 579
Kojto122:f9eeca106725 580 // Stored as pointer to function and pointer to optional object
Kojto122:f9eeca106725 581 // Function pointer is stored as union of possible function types
Kojto122:f9eeca106725 582 // to garuntee proper size and alignment
Kojto122:f9eeca106725 583 struct _class;
Kojto122:f9eeca106725 584 union {
Kojto122:f9eeca106725 585 void (*_staticfunc)();
Kojto122:f9eeca106725 586 void (*_boundfunc)(_class *);
Kojto122:f9eeca106725 587 void (_class::*_methodfunc)();
Kojto122:f9eeca106725 588 } _func;
Kojto122:f9eeca106725 589
Kojto122:f9eeca106725 590 void *_obj;
Kojto122:f9eeca106725 591
Kojto122:f9eeca106725 592 // Thunk registered on attach to dispatch calls
Kojto122:f9eeca106725 593 R (*_thunk)(void*, void*, A0, A1);
Kojto122:f9eeca106725 594};
Kojto122:f9eeca106725 595
Kojto122:f9eeca106725 596/** Templated function class
Kojto122:f9eeca106725 597 */
Kojto122:f9eeca106725 598template <typename R, typename A0>
Kojto122:f9eeca106725 599class Callback<R(A0)> {
Kojto122:f9eeca106725 600public:
Kojto122:f9eeca106725 601 /** Create a Callback with a static function
Kojto122:f9eeca106725 602 * @param func Static function to attach
Kojto122:f9eeca106725 603 */
Kojto122:f9eeca106725 604 Callback(R (*func)(A0) = 0) {
Kojto122:f9eeca106725 605 attach(func);
Kojto122:f9eeca106725 606 }
Kojto122:f9eeca106725 607
Kojto122:f9eeca106725 608 /** Create a Callback with a static function and bound pointer
Kojto122:f9eeca106725 609 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 610 * @param func Static function to attach
Kojto122:f9eeca106725 611 */
Kojto122:f9eeca106725 612 template<typename T>
Kojto122:f9eeca106725 613 Callback(T *obj, R (*func)(T*, A0)) {
Kojto122:f9eeca106725 614 attach(obj, func);
Kojto122:f9eeca106725 615 }
Kojto122:f9eeca106725 616
Kojto122:f9eeca106725 617 /** Create a Callback with a member function
Kojto122:f9eeca106725 618 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 619 * @param func Member function to attach
Kojto122:f9eeca106725 620 */
Kojto122:f9eeca106725 621 template<typename T>
Kojto122:f9eeca106725 622 Callback(T *obj, R (T::*func)(A0)) {
Kojto122:f9eeca106725 623 attach(obj, func);
Kojto122:f9eeca106725 624 }
Kojto122:f9eeca106725 625
Kojto122:f9eeca106725 626 /** Create a Callback with another Callback
Kojto122:f9eeca106725 627 * @param func Callback to attach
Kojto122:f9eeca106725 628 */
Kojto122:f9eeca106725 629 Callback(const Callback<R(A0)> &func) {
Kojto122:f9eeca106725 630 attach(func);
Kojto122:f9eeca106725 631 }
Kojto122:f9eeca106725 632
Kojto122:f9eeca106725 633 /** Attach a static function
Kojto122:f9eeca106725 634 * @param func Static function to attach
Kojto122:f9eeca106725 635 */
Kojto122:f9eeca106725 636 void attach(R (*func)(A0)) {
Kojto122:f9eeca106725 637 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 638 _thunk = func ? &Callback::_staticthunk : 0;
Kojto122:f9eeca106725 639 }
Kojto122:f9eeca106725 640
Kojto122:f9eeca106725 641 /** Attach a static function with a bound pointer
Kojto122:f9eeca106725 642 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 643 * @param func Static function to attach
Kojto122:f9eeca106725 644 */
Kojto122:f9eeca106725 645 template <typename T>
Kojto122:f9eeca106725 646 void attach(T *obj, R (*func)(T*, A0)) {
Kojto122:f9eeca106725 647 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 648 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 649 _thunk = &Callback::_boundthunk<T>;
Kojto122:f9eeca106725 650 }
Kojto122:f9eeca106725 651
Kojto122:f9eeca106725 652 /** Attach a member function
Kojto122:f9eeca106725 653 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 654 * @param func Member function to attach
Kojto122:f9eeca106725 655 */
Kojto122:f9eeca106725 656 template<typename T>
Kojto122:f9eeca106725 657 void attach(T *obj, R (T::*func)(A0)) {
Kojto122:f9eeca106725 658 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 659 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 660 _thunk = &Callback::_methodthunk<T>;
Kojto122:f9eeca106725 661 }
Kojto122:f9eeca106725 662
Kojto122:f9eeca106725 663 /** Attach a Callback
Kojto122:f9eeca106725 664 * @param func The Callback to attach
Kojto122:f9eeca106725 665 */
Kojto122:f9eeca106725 666 void attach(const Callback<R(A0)> &func) {
Kojto122:f9eeca106725 667 _obj = func._obj;
Kojto122:f9eeca106725 668 memcpy(&_func, &func._func, sizeof _func);
Kojto122:f9eeca106725 669 _thunk = func._thunk;
Kojto122:f9eeca106725 670 }
Kojto122:f9eeca106725 671
Kojto122:f9eeca106725 672 /** Call the attached function
Kojto122:f9eeca106725 673 */
Kojto122:f9eeca106725 674 R call(A0 a0) {
Kojto122:f9eeca106725 675 if (!_thunk) {
Kojto122:f9eeca106725 676 return (R)0;
Kojto122:f9eeca106725 677 }
Kojto122:f9eeca106725 678 return _thunk(_obj, &_func, a0);
Kojto122:f9eeca106725 679 }
Kojto122:f9eeca106725 680
Kojto122:f9eeca106725 681 /** Call the attached function
Kojto122:f9eeca106725 682 */
Kojto122:f9eeca106725 683 R operator()(A0 a0) {
Kojto122:f9eeca106725 684 return call(a0);
Kojto122:f9eeca106725 685 }
Kojto122:f9eeca106725 686
Kojto122:f9eeca106725 687 /** Test if function has been attached
Kojto122:f9eeca106725 688 */
Kojto122:f9eeca106725 689 operator bool() const {
Kojto122:f9eeca106725 690 return _thunk;
Kojto122:f9eeca106725 691 }
Kojto122:f9eeca106725 692
Kojto122:f9eeca106725 693 /** Static thunk for passing as C-style function
Kojto122:f9eeca106725 694 * @param func Callback to call passed as void pointer
Kojto122:f9eeca106725 695 */
Kojto122:f9eeca106725 696 static R thunk(void *func, A0 a0) {
Kojto122:f9eeca106725 697 return static_cast<Callback<R(A0)>*>(func)
Kojto122:f9eeca106725 698 ->call(a0);
Kojto122:f9eeca106725 699 }
Kojto122:f9eeca106725 700
Kojto122:f9eeca106725 701private:
Kojto122:f9eeca106725 702 // Internal thunks for various function types
Kojto122:f9eeca106725 703 static R _staticthunk(void*, void *func, A0 a0) {
Kojto122:f9eeca106725 704 return (*reinterpret_cast<R (**)(A0)>(func))
Kojto122:f9eeca106725 705 (a0);
Kojto122:f9eeca106725 706 }
Kojto122:f9eeca106725 707
Kojto122:f9eeca106725 708 template<typename T>
Kojto122:f9eeca106725 709 static R _boundthunk(void *obj, void *func, A0 a0) {
Kojto122:f9eeca106725 710 return (*reinterpret_cast<R (**)(T*, A0)>(func))
Kojto122:f9eeca106725 711 (static_cast<T*>(obj), a0);
Kojto122:f9eeca106725 712 }
Kojto122:f9eeca106725 713
Kojto122:f9eeca106725 714 template<typename T>
Kojto122:f9eeca106725 715 static R _methodthunk(void *obj, void *func, A0 a0) {
Kojto122:f9eeca106725 716 return (static_cast<T*>(obj)->*
Kojto122:f9eeca106725 717 (*reinterpret_cast<R (T::**)(A0)>(func)))
Kojto122:f9eeca106725 718 (a0);
Kojto122:f9eeca106725 719 }
Kojto122:f9eeca106725 720
Kojto122:f9eeca106725 721 // Stored as pointer to function and pointer to optional object
Kojto122:f9eeca106725 722 // Function pointer is stored as union of possible function types
Kojto122:f9eeca106725 723 // to garuntee proper size and alignment
Kojto122:f9eeca106725 724 struct _class;
Kojto122:f9eeca106725 725 union {
Kojto122:f9eeca106725 726 void (*_staticfunc)();
Kojto122:f9eeca106725 727 void (*_boundfunc)(_class *);
Kojto122:f9eeca106725 728 void (_class::*_methodfunc)();
Kojto122:f9eeca106725 729 } _func;
Kojto122:f9eeca106725 730
Kojto122:f9eeca106725 731 void *_obj;
Kojto122:f9eeca106725 732
Kojto122:f9eeca106725 733 // Thunk registered on attach to dispatch calls
Kojto122:f9eeca106725 734 R (*_thunk)(void*, void*, A0);
Kojto122:f9eeca106725 735};
Kojto122:f9eeca106725 736
Kojto122:f9eeca106725 737/** Templated function class
Kojto122:f9eeca106725 738 */
Kojto122:f9eeca106725 739template <typename R>
Kojto122:f9eeca106725 740class Callback<R()> {
Kojto122:f9eeca106725 741public:
Kojto122:f9eeca106725 742 /** Create a Callback with a static function
Kojto122:f9eeca106725 743 * @param func Static function to attach
Kojto122:f9eeca106725 744 */
Kojto122:f9eeca106725 745 Callback(R (*func)() = 0) {
Kojto122:f9eeca106725 746 attach(func);
Kojto122:f9eeca106725 747 }
Kojto122:f9eeca106725 748
Kojto122:f9eeca106725 749 /** Create a Callback with a static function and bound pointer
Kojto122:f9eeca106725 750 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 751 * @param func Static function to attach
Kojto122:f9eeca106725 752 */
Kojto122:f9eeca106725 753 template<typename T>
Kojto122:f9eeca106725 754 Callback(T *obj, R (*func)(T*)) {
Kojto122:f9eeca106725 755 attach(obj, func);
Kojto122:f9eeca106725 756 }
Kojto122:f9eeca106725 757
Kojto122:f9eeca106725 758 /** Create a Callback with a member function
Kojto122:f9eeca106725 759 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 760 * @param func Member function to attach
Kojto122:f9eeca106725 761 */
Kojto122:f9eeca106725 762 template<typename T>
Kojto122:f9eeca106725 763 Callback(T *obj, R (T::*func)()) {
Kojto122:f9eeca106725 764 attach(obj, func);
Kojto122:f9eeca106725 765 }
Kojto122:f9eeca106725 766
Kojto122:f9eeca106725 767 /** Create a Callback with another Callback
Kojto122:f9eeca106725 768 * @param func Callback to attach
Kojto122:f9eeca106725 769 */
Kojto122:f9eeca106725 770 Callback(const Callback<R()> &func) {
Kojto122:f9eeca106725 771 attach(func);
Kojto122:f9eeca106725 772 }
Kojto122:f9eeca106725 773
Kojto122:f9eeca106725 774 /** Attach a static function
Kojto122:f9eeca106725 775 * @param func Static function to attach
Kojto122:f9eeca106725 776 */
Kojto122:f9eeca106725 777 void attach(R (*func)()) {
Kojto122:f9eeca106725 778 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 779 _thunk = func ? &Callback::_staticthunk : 0;
Kojto122:f9eeca106725 780 }
Kojto122:f9eeca106725 781
Kojto122:f9eeca106725 782 /** Attach a static function with a bound pointer
Kojto122:f9eeca106725 783 * @param obj Pointer to object to bind to function
Kojto122:f9eeca106725 784 * @param func Static function to attach
Kojto122:f9eeca106725 785 */
Kojto122:f9eeca106725 786 template <typename T>
Kojto122:f9eeca106725 787 void attach(T *obj, R (*func)(T*)) {
Kojto122:f9eeca106725 788 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 789 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 790 _thunk = &Callback::_boundthunk<T>;
Kojto122:f9eeca106725 791 }
Kojto122:f9eeca106725 792
Kojto122:f9eeca106725 793 /** Attach a member function
Kojto122:f9eeca106725 794 * @param obj Pointer to object to invoke member function on
Kojto122:f9eeca106725 795 * @param func Member function to attach
Kojto122:f9eeca106725 796 */
Kojto122:f9eeca106725 797 template<typename T>
Kojto122:f9eeca106725 798 void attach(T *obj, R (T::*func)()) {
Kojto122:f9eeca106725 799 _obj = static_cast<void*>(obj);
Kojto122:f9eeca106725 800 memcpy(&_func, &func, sizeof func);
Kojto122:f9eeca106725 801 _thunk = &Callback::_methodthunk<T>;
Kojto122:f9eeca106725 802 }
Kojto122:f9eeca106725 803
Kojto122:f9eeca106725 804 /** Attach a Callback
Kojto122:f9eeca106725 805 * @param func The Callback to attach
Kojto122:f9eeca106725 806 */
Kojto122:f9eeca106725 807 void attach(const Callback<R()> &func) {
Kojto122:f9eeca106725 808 _obj = func._obj;
Kojto122:f9eeca106725 809 memcpy(&_func, &func._func, sizeof _func);
Kojto122:f9eeca106725 810 _thunk = func._thunk;
Kojto122:f9eeca106725 811 }
Kojto122:f9eeca106725 812
Kojto122:f9eeca106725 813 /** Call the attached function
Kojto122:f9eeca106725 814 */
Kojto122:f9eeca106725 815 R call() {
Kojto122:f9eeca106725 816 if (!_thunk) {
Kojto122:f9eeca106725 817 return (R)0;
Kojto122:f9eeca106725 818 }
Kojto122:f9eeca106725 819 return _thunk(_obj, &_func);
Kojto122:f9eeca106725 820 }
Kojto122:f9eeca106725 821
Kojto122:f9eeca106725 822 /** Call the attached function
Kojto122:f9eeca106725 823 */
Kojto122:f9eeca106725 824 R operator()() {
Kojto122:f9eeca106725 825 return call();
Kojto122:f9eeca106725 826 }
Kojto122:f9eeca106725 827
Kojto122:f9eeca106725 828 /** Test if function has been attached
Kojto122:f9eeca106725 829 */
Kojto122:f9eeca106725 830 operator bool() const {
Kojto122:f9eeca106725 831 return _thunk;
Kojto122:f9eeca106725 832 }
Kojto122:f9eeca106725 833
Kojto122:f9eeca106725 834 /** Static thunk for passing as C-style function
Kojto122:f9eeca106725 835 * @param func Callback to call passed as void pointer
Kojto122:f9eeca106725 836 */
Kojto122:f9eeca106725 837 static R thunk(void *func) {
Kojto122:f9eeca106725 838 return static_cast<Callback<R()>*>(func)
Kojto122:f9eeca106725 839 ->call();
Kojto122:f9eeca106725 840 }
Kojto122:f9eeca106725 841
Kojto122:f9eeca106725 842private:
Kojto122:f9eeca106725 843 // Internal thunks for various function types
Kojto122:f9eeca106725 844 static R _staticthunk(void*, void *func) {
Kojto122:f9eeca106725 845 return (*reinterpret_cast<R (**)()>(func))
Kojto122:f9eeca106725 846 ();
Kojto122:f9eeca106725 847 }
Kojto122:f9eeca106725 848
Kojto122:f9eeca106725 849 template<typename T>
Kojto122:f9eeca106725 850 static R _boundthunk(void *obj, void *func) {
Kojto122:f9eeca106725 851 return (*reinterpret_cast<R (**)(T*)>(func))
Kojto122:f9eeca106725 852 (static_cast<T*>(obj));
Kojto122:f9eeca106725 853 }
Kojto122:f9eeca106725 854
Kojto122:f9eeca106725 855 template<typename T>
Kojto122:f9eeca106725 856 static R _methodthunk(void *obj, void *func) {
Kojto122:f9eeca106725 857 return (static_cast<T*>(obj)->*
Kojto122:f9eeca106725 858 (*reinterpret_cast<R (T::**)()>(func)))
Kojto122:f9eeca106725 859 ();
Kojto122:f9eeca106725 860 }
Kojto122:f9eeca106725 861
Kojto122:f9eeca106725 862 // Stored as pointer to function and pointer to optional object
Kojto122:f9eeca106725 863 // Function pointer is stored as union of possible function types
Kojto122:f9eeca106725 864 // to garuntee proper size and alignment
Kojto122:f9eeca106725 865 struct _class;
Kojto122:f9eeca106725 866 union {
Kojto122:f9eeca106725 867 void (*_staticfunc)();
Kojto122:f9eeca106725 868 void (*_boundfunc)(_class *);
Kojto122:f9eeca106725 869 void (_class::*_methodfunc)();
Kojto122:f9eeca106725 870 } _func;
Kojto122:f9eeca106725 871
Kojto122:f9eeca106725 872 void *_obj;
Kojto122:f9eeca106725 873
Kojto122:f9eeca106725 874 // Thunk registered on attach to dispatch calls
Kojto122:f9eeca106725 875 R (*_thunk)(void*, void*);
Kojto122:f9eeca106725 876};
Kojto122:f9eeca106725 877
Kojto122:f9eeca106725 878 typedef Callback<void(int)> event_callback_t;
Kojto122:f9eeca106725 879
Kojto122:f9eeca106725 880
Kojto122:f9eeca106725 881} // namespace mbed
Kojto122:f9eeca106725 882
Kojto122:f9eeca106725 883#endif