mbed library sources. Supersedes mbed-src.

Fork of mbed by teralytic

Committer:
rodriguise
Date:
Mon Oct 17 18:47:01 2016 +0000
Revision:
148:4802eb17e82b
Parent:
144:ef7eb2e8f9f7
backup

Who changed what in which revision?

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