ok

Dependents:   I2C

Committer:
daniwestside
Date:
Wed Nov 27 11:10:54 2019 +0000
Revision:
0:87794c1656d6
aaa

Who changed what in which revision?

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