added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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