forked

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Callback.h Source File

Callback.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #ifndef MBED_CALLBACK_H
00017 #define MBED_CALLBACK_H
00018 
00019 #include <string.h>
00020 #include <stdint.h>
00021 #include <new>
00022 #include "platform/mbed_assert.h"
00023 #include "platform/mbed_toolchain.h"
00024 
00025 namespace mbed {
00026 /** \addtogroup platform */
00027 
00028 
00029 /** Callback class based on template specialization
00030  *
00031  * @note Synchronization level: Not protected
00032  * @ingroup platform
00033  */
00034 template <typename F>
00035 class Callback;
00036 
00037 // Internal sfinae declarations
00038 //
00039 // These are used to eliminate overloads based on type attributes
00040 // 1. Does a function object have a call operator
00041 // 2. Does a function object fit in the available storage
00042 //
00043 // These eliminations are handled cleanly by the compiler and avoid
00044 // massive and misleading error messages when confronted with an
00045 // invalid type (or worse, runtime failures)
00046 namespace detail {
00047     struct nil {};
00048 
00049     template <bool B, typename R = nil>
00050     struct enable_if { typedef R type; };
00051 
00052     template <typename R>
00053     struct enable_if<false, R> {};
00054 
00055     template <typename M, M>
00056     struct is_type {
00057         static const bool value = true;
00058     };
00059 }
00060 
00061 #define MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)                            \
00062     typename detail::enable_if<                                             \
00063             detail::is_type<M, &F::operator()>::value &&                    \
00064             sizeof(F) <= sizeof(uintptr_t)                                  \
00065         >::type = detail::nil()
00066 
00067 /** Callback class based on template specialization
00068  *
00069  * @note Synchronization level: Not protected
00070  * @ingroup platform
00071  */
00072 template <typename R>
00073 class Callback<R()> {
00074 public:
00075     /** Create a Callback with a static function
00076      *  @param func     Static function to attach
00077      */
00078     Callback(R (*func)() = 0) {
00079         if (!func) {
00080             _ops = 0;
00081         } else {
00082             generate(func);
00083         }
00084     }
00085 
00086     /** Attach a Callback
00087      *  @param func     The Callback to attach
00088      */
00089     Callback(const Callback<R()> &func) {
00090         if (func._ops) {
00091             func._ops->move(this, &func);
00092         }
00093         _ops = func._ops;
00094     }
00095 
00096     /** Create a Callback with a member function
00097      *  @param obj      Pointer to object to invoke member function on
00098      *  @param method   Member function to attach
00099      */
00100     template<typename T, typename U>
00101     Callback(U *obj, R (T::*method)()) {
00102         generate(method_context<T, R (T::*)()>(obj, method));
00103     }
00104 
00105     /** Create a Callback with a member function
00106      *  @param obj      Pointer to object to invoke member function on
00107      *  @param method   Member function to attach
00108      */
00109     template<typename T, typename U>
00110     Callback(const U *obj, R (T::*method)() const) {
00111         generate(method_context<const T, R (T::*)() const>(obj, method));
00112     }
00113 
00114     /** Create a Callback with a member function
00115      *  @param obj      Pointer to object to invoke member function on
00116      *  @param method   Member function to attach
00117      */
00118     template<typename T, typename U>
00119     Callback(volatile U *obj, R (T::*method)() volatile) {
00120         generate(method_context<volatile T, R (T::*)() volatile>(obj, method));
00121     }
00122 
00123     /** Create a Callback with a member function
00124      *  @param obj      Pointer to object to invoke member function on
00125      *  @param method   Member function to attach
00126      */
00127     template<typename T, typename U>
00128     Callback(const volatile U *obj, R (T::*method)() const volatile) {
00129         generate(method_context<const volatile T, R (T::*)() const volatile>(obj, method));
00130     }
00131 
00132     /** Create a Callback with a static function and bound pointer
00133      *  @param func     Static function to attach
00134      *  @param arg      Pointer argument to function 
00135      */
00136     template<typename T, typename U>
00137     Callback(R (*func)(T*), U *arg) {
00138         generate(function_context<R (*)(T*), T>(func, arg));
00139     }
00140 
00141     /** Create a Callback with a static function and bound pointer
00142      *  @param func     Static function to attach
00143      *  @param arg      Pointer argument to function 
00144      */
00145     template<typename T, typename U>
00146     Callback(R (*func)(const T*), const U *arg) {
00147         generate(function_context<R (*)(const T*), const T>(func, arg));
00148     }
00149 
00150     /** Create a Callback with a static function and bound pointer
00151      *  @param func     Static function to attach
00152      *  @param arg      Pointer argument to function 
00153      */
00154     template<typename T, typename U>
00155     Callback(R (*func)(volatile T*), volatile U *arg) {
00156         generate(function_context<R (*)(volatile T*), volatile T>(func, arg));
00157     }
00158 
00159     /** Create a Callback with a static function and bound pointer
00160      *  @param func     Static function to attach
00161      *  @param arg      Pointer argument to function 
00162      */
00163     template<typename T, typename U>
00164     Callback(R (*func)(const volatile T*), const volatile U *arg) {
00165         generate(function_context<R (*)(const volatile T*), const volatile T>(func, arg));
00166     }
00167 
00168     /** Create a Callback with a function object
00169      *  @param f Function object to attach
00170      *  @note The function object is limited to a single word of storage
00171      */
00172     template <typename F>
00173     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
00174         generate(f);
00175     }
00176 
00177     /** Create a Callback with a function object
00178      *  @param f Function object to attach
00179      *  @note The function object is limited to a single word of storage
00180      */
00181     template <typename F>
00182     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
00183         generate(f);
00184     }
00185 
00186     /** Create a Callback with a function object
00187      *  @param f Function object to attach
00188      *  @note The function object is limited to a single word of storage
00189      */
00190     template <typename F>
00191     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
00192         generate(f);
00193     }
00194 
00195     /** Create a Callback with a function object
00196      *  @param f Function object to attach
00197      *  @note The function object is limited to a single word of storage
00198      */
00199     template <typename F>
00200     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
00201         generate(f);
00202     }
00203 
00204     /** Create a Callback with a static function and bound pointer
00205      *  @param obj  Pointer to object to bind to function
00206      *  @param func Static function to attach
00207      *  @deprecated
00208      *      Arguments to callback have been reordered to Callback(func, arg)
00209      */
00210     template<typename T, typename U>
00211     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00212         "Arguments to callback have been reordered to Callback(func, arg)")
00213     Callback(U *obj, R (*func)(T*)) {
00214         new (this) Callback(func, obj);
00215     }
00216 
00217     /** Create a Callback with a static function and bound pointer
00218      *  @param obj  Pointer to object to bind to function
00219      *  @param func Static function to attach
00220      *  @deprecated
00221      *      Arguments to callback have been reordered to Callback(func, arg)
00222      */
00223     template<typename T, typename U>
00224     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00225         "Arguments to callback have been reordered to Callback(func, arg)")
00226     Callback(const U *obj, R (*func)(const T*)) {
00227         new (this) Callback(func, obj);
00228     }
00229 
00230     /** Create a Callback with a static function and bound pointer
00231      *  @param obj  Pointer to object to bind to function
00232      *  @param func Static function to attach
00233      *  @deprecated
00234      *      Arguments to callback have been reordered to Callback(func, arg)
00235      */
00236     template<typename T, typename U>
00237     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00238         "Arguments to callback have been reordered to Callback(func, arg)")
00239     Callback(volatile U *obj, R (*func)(volatile T*)) {
00240         new (this) Callback(func, obj);
00241     }
00242 
00243     /** Create a Callback with a static function and bound pointer
00244      *  @param obj  Pointer to object to bind to function
00245      *  @param func Static function to attach
00246      *  @deprecated
00247      *      Arguments to callback have been reordered to Callback(func, arg)
00248      */
00249     template<typename T, typename U>
00250     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00251         "Arguments to callback have been reordered to Callback(func, arg)")
00252     Callback(const volatile U *obj, R (*func)(const volatile T*)) {
00253         new (this) Callback(func, obj);
00254     }
00255 
00256     /** Destroy a callback
00257      */
00258     ~Callback() {
00259         if (_ops) {
00260             _ops->dtor(this);
00261         }
00262     }
00263 
00264     /** Attach a static function
00265      *  @param func     Static function to attach
00266      *  @deprecated
00267      *      Replaced by simple assignment 'Callback cb = func'
00268      */
00269     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00270         "Replaced by simple assignment 'Callback cb = func")
00271     void attach(R (*func)()) {
00272         this->~Callback();
00273         new (this) Callback(func);
00274     }
00275 
00276     /** Attach a Callback
00277      *  @param func     The Callback to attach
00278      *  @deprecated
00279      *      Replaced by simple assignment 'Callback cb = func'
00280      */
00281     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00282         "Replaced by simple assignment 'Callback cb = func")
00283     void attach(const Callback<R()> &func) {
00284         this->~Callback();
00285         new (this) Callback(func);
00286     }
00287 
00288     /** Attach a member function
00289      *  @param obj      Pointer to object to invoke member function on
00290      *  @param method   Member function to attach
00291      *  @deprecated
00292      *      Replaced by simple assignment 'Callback cb = func'
00293      */
00294     template<typename T, typename U>
00295     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00296         "Replaced by simple assignment 'Callback cb = func")
00297     void attach(U *obj, R (T::*method)()) {
00298         this->~Callback();
00299         new (this) Callback(obj, method);
00300     }
00301 
00302     /** Attach a member function
00303      *  @param obj      Pointer to object to invoke member function on
00304      *  @param method   Member function to attach
00305      *  @deprecated
00306      *      Replaced by simple assignment 'Callback cb = func'
00307      */
00308     template<typename T, typename U>
00309     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00310         "Replaced by simple assignment 'Callback cb = func")
00311     void attach(const U *obj, R (T::*method)() const) {
00312         this->~Callback();
00313         new (this) Callback(obj, method);
00314     }
00315 
00316     /** Attach a member function
00317      *  @param obj      Pointer to object to invoke member function on
00318      *  @param method   Member function to attach
00319      *  @deprecated
00320      *      Replaced by simple assignment 'Callback cb = func'
00321      */
00322     template<typename T, typename U>
00323     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00324         "Replaced by simple assignment 'Callback cb = func")
00325     void attach(volatile U *obj, R (T::*method)() volatile) {
00326         this->~Callback();
00327         new (this) Callback(obj, method);
00328     }
00329 
00330     /** Attach a member function
00331      *  @param obj      Pointer to object to invoke member function on
00332      *  @param method   Member function to attach
00333      *  @deprecated
00334      *      Replaced by simple assignment 'Callback cb = func'
00335      */
00336     template<typename T, typename U>
00337     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00338         "Replaced by simple assignment 'Callback cb = func")
00339     void attach(const volatile U *obj, R (T::*method)() const volatile) {
00340         this->~Callback();
00341         new (this) Callback(obj, method);
00342     }
00343 
00344     /** Attach a static function with a bound pointer
00345      *  @param func     Static function to attach
00346      *  @param arg      Pointer argument to function
00347      *  @deprecated
00348      *      Replaced by simple assignment 'Callback cb = func'
00349      */
00350     template <typename T, typename U>
00351     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00352         "Replaced by simple assignment 'Callback cb = func")
00353     void attach(R (*func)(T*), U *arg) {
00354         this->~Callback();
00355         new (this) Callback(func, arg);
00356     }
00357 
00358     /** Attach a static function with a bound pointer
00359      *  @param func     Static function to attach
00360      *  @param arg      Pointer argument to function
00361      *  @deprecated
00362      *      Replaced by simple assignment 'Callback cb = func'
00363      */
00364     template <typename T, typename U>
00365     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00366         "Replaced by simple assignment 'Callback cb = func")
00367     void attach(R (*func)(const T*), const U *arg) {
00368         this->~Callback();
00369         new (this) Callback(func, arg);
00370     }
00371 
00372     /** Attach a static function with a bound pointer
00373      *  @param func     Static function to attach
00374      *  @param arg      Pointer argument to function
00375      *  @deprecated
00376      *      Replaced by simple assignment 'Callback cb = func'
00377      */
00378     template <typename T, typename U>
00379     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00380         "Replaced by simple assignment 'Callback cb = func")
00381     void attach(R (*func)(volatile T*), volatile U *arg) {
00382         this->~Callback();
00383         new (this) Callback(func, arg);
00384     }
00385 
00386     /** Attach a static function with a bound pointer
00387      *  @param func     Static function to attach
00388      *  @param arg      Pointer argument to function
00389      *  @deprecated
00390      *      Replaced by simple assignment 'Callback cb = func'
00391      */
00392     template <typename T, typename U>
00393     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00394         "Replaced by simple assignment 'Callback cb = func")
00395     void attach(R (*func)(const volatile T*), const volatile U *arg) {
00396         this->~Callback();
00397         new (this) Callback(func, arg);
00398     }
00399 
00400     /** Attach a function object
00401      *  @param f     Function object to attach
00402      *  @note The function object is limited to a single word of storage
00403      *  @deprecated
00404      *      Replaced by simple assignment 'Callback cb = func'
00405      */
00406     template <typename F>
00407     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00408         "Replaced by simple assignment 'Callback cb = func")
00409     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
00410         this->~Callback();
00411         new (this) Callback(f);
00412     }
00413 
00414     /** Attach a function object
00415      *  @param f     Function object to attach
00416      *  @note The function object is limited to a single word of storage
00417      *  @deprecated
00418      *      Replaced by simple assignment 'Callback cb = func'
00419      */
00420     template <typename F>
00421     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00422         "Replaced by simple assignment 'Callback cb = func")
00423     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
00424         this->~Callback();
00425         new (this) Callback(f);
00426     }
00427 
00428     /** Attach a function object
00429      *  @param f Function object to attach
00430      *  @note The function object is limited to a single word of storage
00431      *  @deprecated
00432      *      Replaced by simple assignment 'Callback cb = func'
00433      */
00434     template <typename F>
00435     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00436         "Replaced by simple assignment 'Callback cb = func")
00437     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
00438         this->~Callback();
00439         new (this) Callback(f);
00440     }
00441 
00442     /** Attach a function object
00443      *  @param f Function object to attach
00444      *  @note The function object is limited to a single word of storage
00445      *  @deprecated
00446      *      Replaced by simple assignment 'Callback cb = func'
00447      */
00448     template <typename F>
00449     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00450         "Replaced by simple assignment 'Callback cb = func")
00451     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
00452         this->~Callback();
00453         new (this) Callback(f);
00454     }
00455 
00456     /** Attach a static function with a bound pointer
00457      *  @param obj  Pointer to object to bind to function
00458      *  @param func Static function to attach
00459      *  @deprecated
00460      *      Arguments to callback have been reordered to attach(func, arg)
00461      */
00462     template <typename T, typename U>
00463     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00464         "Arguments to callback have been reordered to attach(func, arg)")
00465     void attach(U *obj, R (*func)(T*)) {
00466         this->~Callback();
00467         new (this) Callback(func, obj);
00468     }
00469 
00470     /** Attach a static function with a bound pointer
00471      *  @param obj  Pointer to object to bind to function
00472      *  @param func Static function to attach
00473      *  @deprecated
00474      *      Arguments to callback have been reordered to attach(func, arg)
00475      */
00476     template <typename T, typename U>
00477     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00478         "Arguments to callback have been reordered to attach(func, arg)")
00479     void attach(const U *obj, R (*func)(const T*)) {
00480         this->~Callback();
00481         new (this) Callback(func, obj);
00482     }
00483 
00484     /** Attach a static function with a bound pointer
00485      *  @param obj  Pointer to object to bind to function
00486      *  @param func Static function to attach
00487      *  @deprecated
00488      *      Arguments to callback have been reordered to attach(func, arg)
00489      */
00490     template <typename T, typename U>
00491     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00492         "Arguments to callback have been reordered to attach(func, arg)")
00493     void attach(volatile U *obj, R (*func)(volatile T*)) {
00494         this->~Callback();
00495         new (this) Callback(func, obj);
00496     }
00497 
00498     /** Attach a static function with a bound pointer
00499      *  @param obj  Pointer to object to bind to function
00500      *  @param func Static function to attach
00501      *  @deprecated
00502      *      Arguments to callback have been reordered to attach(func, arg)
00503      */
00504     template <typename T, typename U>
00505     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00506         "Arguments to callback have been reordered to attach(func, arg)")
00507     void attach(const volatile U *obj, R (*func)(const volatile T*)) {
00508         this->~Callback();
00509         new (this) Callback(func, obj);
00510     }
00511 
00512     /** Assign a callback
00513      */
00514     Callback &operator=(const Callback &that) {
00515         if (this != &that) {
00516             this->~Callback();
00517             new (this) Callback(that);
00518         }
00519 
00520         return *this;
00521     }
00522 
00523     /** Call the attached function
00524      */
00525     R call() const {
00526         MBED_ASSERT(_ops);
00527         return _ops->call(this);
00528     }
00529 
00530     /** Call the attached function
00531      */
00532     R operator()() const {
00533         return call();
00534     }
00535 
00536     /** Test if function has been attached
00537      */
00538     operator bool() const {
00539         return _ops;
00540     }
00541 
00542     /** Test for equality
00543      */
00544     friend bool operator==(const Callback &l, const Callback &r) {
00545         return memcmp(&l, &r, sizeof(Callback)) == 0;
00546     }
00547 
00548     /** Test for inequality
00549      */
00550     friend bool operator!=(const Callback &l, const Callback &r) {
00551         return !(l == r);
00552     }
00553 
00554     /** Static thunk for passing as C-style function
00555      *  @param func Callback to call passed as void pointer
00556      *  @return the value as determined by func which is of 
00557      *      type and determined by the signiture of func
00558      */
00559     static R thunk(void *func) {
00560         return static_cast<Callback*>(func)->call();
00561     }
00562 
00563 private:
00564     // Stored as pointer to function and pointer to optional object
00565     // Function pointer is stored as union of possible function types
00566     // to garuntee proper size and alignment
00567     struct _class;
00568     union {
00569         void (*_staticfunc)();
00570         void (*_boundfunc)(_class*);
00571         void (_class::*_methodfunc)();
00572     } _func;
00573     void *_obj;
00574 
00575     // Dynamically dispatched operations
00576     const struct ops {
00577         R (*call)(const void*);
00578         void (*move)(void*, const void*);
00579         void (*dtor)(void*);
00580     } *_ops;
00581 
00582     // Generate operations for function object
00583     template <typename F>
00584     void generate(const F &f) {
00585         static const ops ops = {
00586             &Callback::function_call<F>,
00587             &Callback::function_move<F>,
00588             &Callback::function_dtor<F>,
00589         };
00590 
00591         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
00592                 "Type F must not exceed the size of the Callback class");
00593         new (this) F(f);
00594         _ops = &ops;
00595     }
00596 
00597     // Function attributes
00598     template <typename F>
00599     static R function_call(const void *p) {
00600         return (*(F*)p)();
00601     }
00602 
00603     template <typename F>
00604     static void function_move(void *d, const void *p) {
00605         new (d) F(*(F*)p);
00606     }
00607 
00608     template <typename F>
00609     static void function_dtor(void *p) {
00610         ((F*)p)->~F();
00611     }
00612 
00613     // Wrappers for functions with context
00614     template <typename O, typename M>
00615     struct method_context {
00616         M method;
00617         O *obj;
00618 
00619         method_context(O *obj, M method)
00620             : method(method), obj(obj) {}
00621 
00622         R operator()() const {
00623             return (obj->*method)();
00624         }
00625     };
00626 
00627     template <typename F, typename A>
00628     struct function_context {
00629         F func;
00630         A *arg;
00631 
00632         function_context(F func, A *arg)
00633             : func(func), arg(arg) {}
00634 
00635         R operator()() const {
00636             return func(arg);
00637         }
00638     };
00639 };
00640 
00641 /** Callback class based on template specialization
00642  *
00643  * @note Synchronization level: Not protected
00644  * @ingroup platform
00645  */
00646 template <typename R, typename A0>
00647 class Callback<R(A0)> {
00648 public:
00649     /** Create a Callback with a static function
00650      *  @param func     Static function to attach
00651      */
00652     Callback(R (*func)(A0) = 0) {
00653         if (!func) {
00654             _ops = 0;
00655         } else {
00656             generate(func);
00657         }
00658     }
00659 
00660     /** Attach a Callback
00661      *  @param func     The Callback to attach
00662      */
00663     Callback(const Callback<R(A0)> &func) {
00664         if (func._ops) {
00665             func._ops->move(this, &func);
00666         }
00667         _ops = func._ops;
00668     }
00669 
00670     /** Create a Callback with a member function
00671      *  @param obj      Pointer to object to invoke member function on
00672      *  @param method   Member function to attach
00673      */
00674     template<typename T, typename U>
00675     Callback(U *obj, R (T::*method)(A0)) {
00676         generate(method_context<T, R (T::*)(A0)>(obj, method));
00677     }
00678 
00679     /** Create a Callback with a member function
00680      *  @param obj      Pointer to object to invoke member function on
00681      *  @param method   Member function to attach
00682      */
00683     template<typename T, typename U>
00684     Callback(const U *obj, R (T::*method)(A0) const) {
00685         generate(method_context<const T, R (T::*)(A0) const>(obj, method));
00686     }
00687 
00688     /** Create a Callback with a member function
00689      *  @param obj      Pointer to object to invoke member function on
00690      *  @param method   Member function to attach
00691      */
00692     template<typename T, typename U>
00693     Callback(volatile U *obj, R (T::*method)(A0) volatile) {
00694         generate(method_context<volatile T, R (T::*)(A0) volatile>(obj, method));
00695     }
00696 
00697     /** Create a Callback with a member function
00698      *  @param obj      Pointer to object to invoke member function on
00699      *  @param method   Member function to attach
00700      */
00701     template<typename T, typename U>
00702     Callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
00703         generate(method_context<const volatile T, R (T::*)(A0) const volatile>(obj, method));
00704     }
00705 
00706     /** Create a Callback with a static function and bound pointer
00707      *  @param func     Static function to attach
00708      *  @param arg      Pointer argument to function 
00709      */
00710     template<typename T, typename U>
00711     Callback(R (*func)(T*, A0), U *arg) {
00712         generate(function_context<R (*)(T*, A0), T>(func, arg));
00713     }
00714 
00715     /** Create a Callback with a static function and bound pointer
00716      *  @param func     Static function to attach
00717      *  @param arg      Pointer argument to function 
00718      */
00719     template<typename T, typename U>
00720     Callback(R (*func)(const T*, A0), const U *arg) {
00721         generate(function_context<R (*)(const T*, A0), const T>(func, arg));
00722     }
00723 
00724     /** Create a Callback with a static function and bound pointer
00725      *  @param func     Static function to attach
00726      *  @param arg      Pointer argument to function 
00727      */
00728     template<typename T, typename U>
00729     Callback(R (*func)(volatile T*, A0), volatile U *arg) {
00730         generate(function_context<R (*)(volatile T*, A0), volatile T>(func, arg));
00731     }
00732 
00733     /** Create a Callback with a static function and bound pointer
00734      *  @param func     Static function to attach
00735      *  @param arg      Pointer argument to function 
00736      */
00737     template<typename T, typename U>
00738     Callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
00739         generate(function_context<R (*)(const volatile T*, A0), const volatile T>(func, arg));
00740     }
00741 
00742     /** Create a Callback with a function object
00743      *  @param f Function object to attach
00744      *  @note The function object is limited to a single word of storage
00745      */
00746     template <typename F>
00747     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
00748         generate(f);
00749     }
00750 
00751     /** Create a Callback with a function object
00752      *  @param f Function object to attach
00753      *  @note The function object is limited to a single word of storage
00754      */
00755     template <typename F>
00756     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
00757         generate(f);
00758     }
00759 
00760     /** Create a Callback with a function object
00761      *  @param f Function object to attach
00762      *  @note The function object is limited to a single word of storage
00763      */
00764     template <typename F>
00765     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
00766         generate(f);
00767     }
00768 
00769     /** Create a Callback with a function object
00770      *  @param f Function object to attach
00771      *  @note The function object is limited to a single word of storage
00772      */
00773     template <typename F>
00774     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
00775         generate(f);
00776     }
00777 
00778     /** Create a Callback with a static function and bound pointer
00779      *  @param obj  Pointer to object to bind to function
00780      *  @param func Static function to attach
00781      *  @deprecated
00782      *      Arguments to callback have been reordered to Callback(func, arg)
00783      */
00784     template<typename T, typename U>
00785     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00786         "Arguments to callback have been reordered to Callback(func, arg)")
00787     Callback(U *obj, R (*func)(T*, A0)) {
00788         new (this) Callback(func, obj);
00789     }
00790 
00791     /** Create a Callback with a static function and bound pointer
00792      *  @param obj  Pointer to object to bind to function
00793      *  @param func Static function to attach
00794      *  @deprecated
00795      *      Arguments to callback have been reordered to Callback(func, arg)
00796      */
00797     template<typename T, typename U>
00798     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00799         "Arguments to callback have been reordered to Callback(func, arg)")
00800     Callback(const U *obj, R (*func)(const T*, A0)) {
00801         new (this) Callback(func, obj);
00802     }
00803 
00804     /** Create a Callback with a static function and bound pointer
00805      *  @param obj  Pointer to object to bind to function
00806      *  @param func Static function to attach
00807      *  @deprecated
00808      *      Arguments to callback have been reordered to Callback(func, arg)
00809      */
00810     template<typename T, typename U>
00811     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00812         "Arguments to callback have been reordered to Callback(func, arg)")
00813     Callback(volatile U *obj, R (*func)(volatile T*, A0)) {
00814         new (this) Callback(func, obj);
00815     }
00816 
00817     /** Create a Callback with a static function and bound pointer
00818      *  @param obj  Pointer to object to bind to function
00819      *  @param func Static function to attach
00820      *  @deprecated
00821      *      Arguments to callback have been reordered to Callback(func, arg)
00822      */
00823     template<typename T, typename U>
00824     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00825         "Arguments to callback have been reordered to Callback(func, arg)")
00826     Callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
00827         new (this) Callback(func, obj);
00828     }
00829 
00830     /** Destroy a callback
00831      */
00832     ~Callback() {
00833         if (_ops) {
00834             _ops->dtor(this);
00835         }
00836     }
00837 
00838     /** Attach a static function
00839      *  @param func     Static function to attach
00840      *  @deprecated
00841      *      Replaced by simple assignment 'Callback cb = func'
00842      */
00843     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00844         "Replaced by simple assignment 'Callback cb = func")
00845     void attach(R (*func)(A0)) {
00846         this->~Callback();
00847         new (this) Callback(func);
00848     }
00849 
00850     /** Attach a Callback
00851      *  @param func     The Callback to attach
00852      *  @deprecated
00853      *      Replaced by simple assignment 'Callback cb = func'
00854      */
00855     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00856         "Replaced by simple assignment 'Callback cb = func")
00857     void attach(const Callback<R(A0)> &func) {
00858         this->~Callback();
00859         new (this) Callback(func);
00860     }
00861 
00862     /** Attach a member function
00863      *  @param obj      Pointer to object to invoke member function on
00864      *  @param method   Member function to attach
00865      *  @deprecated
00866      *      Replaced by simple assignment 'Callback cb = func'
00867      */
00868     template<typename T, typename U>
00869     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00870         "Replaced by simple assignment 'Callback cb = func")
00871     void attach(U *obj, R (T::*method)(A0)) {
00872         this->~Callback();
00873         new (this) Callback(obj, method);
00874     }
00875 
00876     /** Attach a member function
00877      *  @param obj      Pointer to object to invoke member function on
00878      *  @param method   Member function to attach
00879      *  @deprecated
00880      *      Replaced by simple assignment 'Callback cb = func'
00881      */
00882     template<typename T, typename U>
00883     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00884         "Replaced by simple assignment 'Callback cb = func")
00885     void attach(const U *obj, R (T::*method)(A0) const) {
00886         this->~Callback();
00887         new (this) Callback(obj, method);
00888     }
00889 
00890     /** Attach a member function
00891      *  @param obj      Pointer to object to invoke member function on
00892      *  @param method   Member function to attach
00893      *  @deprecated
00894      *      Replaced by simple assignment 'Callback cb = func'
00895      */
00896     template<typename T, typename U>
00897     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00898         "Replaced by simple assignment 'Callback cb = func")
00899     void attach(volatile U *obj, R (T::*method)(A0) volatile) {
00900         this->~Callback();
00901         new (this) Callback(obj, method);
00902     }
00903 
00904     /** Attach a member function
00905      *  @param obj      Pointer to object to invoke member function on
00906      *  @param method   Member function to attach
00907      *  @deprecated
00908      *      Replaced by simple assignment 'Callback cb = func'
00909      */
00910     template<typename T, typename U>
00911     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00912         "Replaced by simple assignment 'Callback cb = func")
00913     void attach(const volatile U *obj, R (T::*method)(A0) const volatile) {
00914         this->~Callback();
00915         new (this) Callback(obj, method);
00916     }
00917 
00918     /** Attach a static function with a bound pointer
00919      *  @param func     Static function to attach
00920      *  @param arg      Pointer argument to function
00921      *  @deprecated
00922      *      Replaced by simple assignment 'Callback cb = func'
00923      */
00924     template <typename T, typename U>
00925     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00926         "Replaced by simple assignment 'Callback cb = func")
00927     void attach(R (*func)(T*, A0), U *arg) {
00928         this->~Callback();
00929         new (this) Callback(func, arg);
00930     }
00931 
00932     /** Attach a static function with a bound pointer
00933      *  @param func     Static function to attach
00934      *  @param arg      Pointer argument to function
00935      *  @deprecated
00936      *      Replaced by simple assignment 'Callback cb = func'
00937      */
00938     template <typename T, typename U>
00939     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00940         "Replaced by simple assignment 'Callback cb = func")
00941     void attach(R (*func)(const T*, A0), const U *arg) {
00942         this->~Callback();
00943         new (this) Callback(func, arg);
00944     }
00945 
00946     /** Attach a static function with a bound pointer
00947      *  @param func     Static function to attach
00948      *  @param arg      Pointer argument to function
00949      *  @deprecated
00950      *      Replaced by simple assignment 'Callback cb = func'
00951      */
00952     template <typename T, typename U>
00953     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00954         "Replaced by simple assignment 'Callback cb = func")
00955     void attach(R (*func)(volatile T*, A0), volatile U *arg) {
00956         this->~Callback();
00957         new (this) Callback(func, arg);
00958     }
00959 
00960     /** Attach a static function with a bound pointer
00961      *  @param func     Static function to attach
00962      *  @param arg      Pointer argument to function
00963      *  @deprecated
00964      *      Replaced by simple assignment 'Callback cb = func'
00965      */
00966     template <typename T, typename U>
00967     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00968         "Replaced by simple assignment 'Callback cb = func")
00969     void attach(R (*func)(const volatile T*, A0), const volatile U *arg) {
00970         this->~Callback();
00971         new (this) Callback(func, arg);
00972     }
00973 
00974     /** Attach a function object
00975      *  @param f Function object to attach
00976      *  @note The function object is limited to a single word of storage
00977      *  @deprecated
00978      *      Replaced by simple assignment 'Callback cb = func'
00979      */
00980     template <typename F>
00981     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00982         "Replaced by simple assignment 'Callback cb = func")
00983     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
00984         this->~Callback();
00985         new (this) Callback(f);
00986     }
00987 
00988     /** Attach a function object
00989      *  @param f Function object to attach
00990      *  @note The function object is limited to a single word of storage
00991      *  @deprecated
00992      *      Replaced by simple assignment 'Callback cb = func'
00993      */
00994     template <typename F>
00995     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00996         "Replaced by simple assignment 'Callback cb = func")
00997     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
00998         this->~Callback();
00999         new (this) Callback(f);
01000     }
01001 
01002     /** Attach a function object
01003      *  @param f Function object to attach
01004      *  @note The function object is limited to a single word of storage
01005      *  @deprecated
01006      *      Replaced by simple assignment 'Callback cb = func'
01007      */
01008     template <typename F>
01009     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01010         "Replaced by simple assignment 'Callback cb = func")
01011     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
01012         this->~Callback();
01013         new (this) Callback(f);
01014     }
01015 
01016     /** Attach a function object
01017      *  @param f Function object to attach
01018      *  @note The function object is limited to a single word of storage
01019      *  @deprecated
01020      *      Replaced by simple assignment 'Callback cb = func'
01021      */
01022     template <typename F>
01023     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01024         "Replaced by simple assignment 'Callback cb = func")
01025     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
01026         this->~Callback();
01027         new (this) Callback(f);
01028     }
01029 
01030     /** Attach a static function with a bound pointer
01031      *  @param obj  Pointer to object to bind to function
01032      *  @param func Static function to attach
01033      *  @deprecated
01034      *      Arguments to callback have been reordered to attach(func, arg)
01035      */
01036     template <typename T, typename U>
01037     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01038         "Arguments to callback have been reordered to attach(func, arg)")
01039     void attach(U *obj, R (*func)(T*, A0)) {
01040         this->~Callback();
01041         new (this) Callback(func, obj);
01042     }
01043 
01044     /** Attach a static function with a bound pointer
01045      *  @param obj  Pointer to object to bind to function
01046      *  @param func Static function to attach
01047      *  @deprecated
01048      *      Arguments to callback have been reordered to attach(func, arg)
01049      */
01050     template <typename T, typename U>
01051     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01052         "Arguments to callback have been reordered to attach(func, arg)")
01053     void attach(const U *obj, R (*func)(const T*, A0)) {
01054         this->~Callback();
01055         new (this) Callback(func, obj);
01056     }
01057 
01058     /** Attach a static function with a bound pointer
01059      *  @param obj  Pointer to object to bind to function
01060      *  @param func Static function to attach
01061      *  @deprecated
01062      *      Arguments to callback have been reordered to attach(func, arg)
01063      */
01064     template <typename T, typename U>
01065     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01066         "Arguments to callback have been reordered to attach(func, arg)")
01067     void attach(volatile U *obj, R (*func)(volatile T*, A0)) {
01068         this->~Callback();
01069         new (this) Callback(func, obj);
01070     }
01071 
01072     /** Attach a static function with a bound pointer
01073      *  @param obj  Pointer to object to bind to function
01074      *  @param func Static function to attach
01075      *  @deprecated
01076      *      Arguments to callback have been reordered to attach(func, arg)
01077      */
01078     template <typename T, typename U>
01079     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01080         "Arguments to callback have been reordered to attach(func, arg)")
01081     void attach(const volatile U *obj, R (*func)(const volatile T*, A0)) {
01082         this->~Callback();
01083         new (this) Callback(func, obj);
01084     }
01085 
01086     /** Assign a callback
01087      */
01088     Callback &operator=(const Callback &that) {
01089         if (this != &that) {
01090             this->~Callback();
01091             new (this) Callback(that);
01092         }
01093 
01094         return *this;
01095     }
01096 
01097     /** Call the attached function
01098      */
01099     R call(A0 a0) const {
01100         MBED_ASSERT(_ops);
01101         return _ops->call(this, a0);
01102     }
01103 
01104     /** Call the attached function
01105      */
01106     R operator()(A0 a0) const {
01107         return call(a0);
01108     }
01109 
01110     /** Test if function has been attached
01111      */
01112     operator bool() const {
01113         return _ops;
01114     }
01115 
01116     /** Test for equality
01117      */
01118     friend bool operator==(const Callback &l, const Callback &r) {
01119         return memcmp(&l, &r, sizeof(Callback)) == 0;
01120     }
01121 
01122     /** Test for inequality
01123      */
01124     friend bool operator!=(const Callback &l, const Callback &r) {
01125         return !(l == r);
01126     }
01127 
01128     /** Static thunk for passing as C-style function
01129      *  @param func Callback to call passed as void pointer
01130      *  @param a0 An argument to be called with function func
01131      *  @return the value as determined by func which is of 
01132      *      type and determined by the signiture of func
01133      */
01134     static R thunk(void *func, A0 a0) {
01135         return static_cast<Callback*>(func)->call(a0);
01136     }
01137 
01138 private:
01139     // Stored as pointer to function and pointer to optional object
01140     // Function pointer is stored as union of possible function types
01141     // to garuntee proper size and alignment
01142     struct _class;
01143     union {
01144         void (*_staticfunc)(A0);
01145         void (*_boundfunc)(_class*, A0);
01146         void (_class::*_methodfunc)(A0);
01147     } _func;
01148     void *_obj;
01149 
01150     // Dynamically dispatched operations
01151     const struct ops {
01152         R (*call)(const void*, A0);
01153         void (*move)(void*, const void*);
01154         void (*dtor)(void*);
01155     } *_ops;
01156 
01157     // Generate operations for function object
01158     template <typename F>
01159     void generate(const F &f) {
01160         static const ops ops = {
01161             &Callback::function_call<F>,
01162             &Callback::function_move<F>,
01163             &Callback::function_dtor<F>,
01164         };
01165 
01166         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
01167                 "Type F must not exceed the size of the Callback class");
01168         new (this) F(f);
01169         _ops = &ops;
01170     }
01171 
01172     // Function attributes
01173     template <typename F>
01174     static R function_call(const void *p, A0 a0) {
01175         return (*(F*)p)(a0);
01176     }
01177 
01178     template <typename F>
01179     static void function_move(void *d, const void *p) {
01180         new (d) F(*(F*)p);
01181     }
01182 
01183     template <typename F>
01184     static void function_dtor(void *p) {
01185         ((F*)p)->~F();
01186     }
01187 
01188     // Wrappers for functions with context
01189     template <typename O, typename M>
01190     struct method_context {
01191         M method;
01192         O *obj;
01193 
01194         method_context(O *obj, M method)
01195             : method(method), obj(obj) {}
01196 
01197         R operator()(A0 a0) const {
01198             return (obj->*method)(a0);
01199         }
01200     };
01201 
01202     template <typename F, typename A>
01203     struct function_context {
01204         F func;
01205         A *arg;
01206 
01207         function_context(F func, A *arg)
01208             : func(func), arg(arg) {}
01209 
01210         R operator()(A0 a0) const {
01211             return func(arg, a0);
01212         }
01213     };
01214 };
01215 
01216 /** Callback class based on template specialization
01217  *
01218  * @note Synchronization level: Not protected
01219  * @ingroup platform
01220  */
01221 template <typename R, typename A0, typename A1>
01222 class Callback<R(A0, A1)> {
01223 public:
01224     /** Create a Callback with a static function
01225      *  @param func     Static function to attach
01226      */
01227     Callback(R (*func)(A0, A1) = 0) {
01228         if (!func) {
01229             _ops = 0;
01230         } else {
01231             generate(func);
01232         }
01233     }
01234 
01235     /** Attach a Callback
01236      *  @param func     The Callback to attach
01237      */
01238     Callback(const Callback<R(A0, A1)> &func) {
01239         if (func._ops) {
01240             func._ops->move(this, &func);
01241         }
01242         _ops = func._ops;
01243     }
01244 
01245     /** Create a Callback with a member function
01246      *  @param obj      Pointer to object to invoke member function on
01247      *  @param method   Member function to attach
01248      */
01249     template<typename T, typename U>
01250     Callback(U *obj, R (T::*method)(A0, A1)) {
01251         generate(method_context<T, R (T::*)(A0, A1)>(obj, method));
01252     }
01253 
01254     /** Create a Callback with a member function
01255      *  @param obj      Pointer to object to invoke member function on
01256      *  @param method   Member function to attach
01257      */
01258     template<typename T, typename U>
01259     Callback(const U *obj, R (T::*method)(A0, A1) const) {
01260         generate(method_context<const T, R (T::*)(A0, A1) const>(obj, method));
01261     }
01262 
01263     /** Create a Callback with a member function
01264      *  @param obj      Pointer to object to invoke member function on
01265      *  @param method   Member function to attach
01266      */
01267     template<typename T, typename U>
01268     Callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
01269         generate(method_context<volatile T, R (T::*)(A0, A1) volatile>(obj, method));
01270     }
01271 
01272     /** Create a Callback with a member function
01273      *  @param obj      Pointer to object to invoke member function on
01274      *  @param method   Member function to attach
01275      */
01276     template<typename T, typename U>
01277     Callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
01278         generate(method_context<const volatile T, R (T::*)(A0, A1) const volatile>(obj, method));
01279     }
01280 
01281     /** Create a Callback with a static function and bound pointer
01282      *  @param func     Static function to attach
01283      *  @param arg      Pointer argument to function 
01284      */
01285     template<typename T, typename U>
01286     Callback(R (*func)(T*, A0, A1), U *arg) {
01287         generate(function_context<R (*)(T*, A0, A1), T>(func, arg));
01288     }
01289 
01290     /** Create a Callback with a static function and bound pointer
01291      *  @param func     Static function to attach
01292      *  @param arg      Pointer argument to function 
01293      */
01294     template<typename T, typename U>
01295     Callback(R (*func)(const T*, A0, A1), const U *arg) {
01296         generate(function_context<R (*)(const T*, A0, A1), const T>(func, arg));
01297     }
01298 
01299     /** Create a Callback with a static function and bound pointer
01300      *  @param func     Static function to attach
01301      *  @param arg      Pointer argument to function 
01302      */
01303     template<typename T, typename U>
01304     Callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
01305         generate(function_context<R (*)(volatile T*, A0, A1), volatile T>(func, arg));
01306     }
01307 
01308     /** Create a Callback with a static function and bound pointer
01309      *  @param func     Static function to attach
01310      *  @param arg      Pointer argument to function 
01311      */
01312     template<typename T, typename U>
01313     Callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
01314         generate(function_context<R (*)(const volatile T*, A0, A1), const volatile T>(func, arg));
01315     }
01316 
01317     /** Create a Callback with a function object
01318      *  @param f Function object to attach
01319      *  @note The function object is limited to a single word of storage
01320      */
01321     template <typename F>
01322     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
01323         generate(f);
01324     }
01325 
01326     /** Create a Callback with a function object
01327      *  @param f Function object to attach
01328      *  @note The function object is limited to a single word of storage
01329      */
01330     template <typename F>
01331     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
01332         generate(f);
01333     }
01334 
01335     /** Create a Callback with a function object
01336      *  @param f Function object to attach
01337      *  @note The function object is limited to a single word of storage
01338      */
01339     template <typename F>
01340     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
01341         generate(f);
01342     }
01343 
01344     /** Create a Callback with a function object
01345      *  @param f Function object to attach
01346      *  @note The function object is limited to a single word of storage
01347      */
01348     template <typename F>
01349     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
01350         generate(f);
01351     }
01352 
01353     /** Create a Callback with a static function and bound pointer
01354      *  @param obj  Pointer to object to bind to function
01355      *  @param func Static function to attach
01356      *  @deprecated
01357      *      Arguments to callback have been reordered to Callback(func, arg)
01358      */
01359     template<typename T, typename U>
01360     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01361         "Arguments to callback have been reordered to Callback(func, arg)")
01362     Callback(U *obj, R (*func)(T*, A0, A1)) {
01363         new (this) Callback(func, obj);
01364     }
01365 
01366     /** Create a Callback with a static function and bound pointer
01367      *  @param obj  Pointer to object to bind to function
01368      *  @param func Static function to attach
01369      *  @deprecated
01370      *      Arguments to callback have been reordered to Callback(func, arg)
01371      */
01372     template<typename T, typename U>
01373     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01374         "Arguments to callback have been reordered to Callback(func, arg)")
01375     Callback(const U *obj, R (*func)(const T*, A0, A1)) {
01376         new (this) Callback(func, obj);
01377     }
01378 
01379     /** Create a Callback with a static function and bound pointer
01380      *  @param obj  Pointer to object to bind to function
01381      *  @param func Static function to attach
01382      *  @deprecated
01383      *      Arguments to callback have been reordered to Callback(func, arg)
01384      */
01385     template<typename T, typename U>
01386     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01387         "Arguments to callback have been reordered to Callback(func, arg)")
01388     Callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
01389         new (this) Callback(func, obj);
01390     }
01391 
01392     /** Create a Callback with a static function and bound pointer
01393      *  @param obj  Pointer to object to bind to function
01394      *  @param func Static function to attach
01395      *  @deprecated
01396      *      Arguments to callback have been reordered to Callback(func, arg)
01397      */
01398     template<typename T, typename U>
01399     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01400         "Arguments to callback have been reordered to Callback(func, arg)")
01401     Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
01402         new (this) Callback(func, obj);
01403     }
01404 
01405     /** Destroy a callback
01406      */
01407     ~Callback() {
01408         if (_ops) {
01409             _ops->dtor(this);
01410         }
01411     }
01412 
01413     /** Attach a static function
01414      *  @param func     Static function to attach
01415      *  @deprecated
01416      *      Replaced by simple assignment 'Callback cb = func'
01417      */
01418     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01419         "Replaced by simple assignment 'Callback cb = func")
01420     void attach(R (*func)(A0, A1)) {
01421         this->~Callback();
01422         new (this) Callback(func);
01423     }
01424 
01425     /** Attach a Callback
01426      *  @param func     The Callback to attach
01427      *  @deprecated
01428      *      Replaced by simple assignment 'Callback cb = func'
01429      */
01430     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01431         "Replaced by simple assignment 'Callback cb = func")
01432     void attach(const Callback<R(A0, A1)> &func) {
01433         this->~Callback();
01434         new (this) Callback(func);
01435     }
01436 
01437     /** Attach a member function
01438      *  @param obj      Pointer to object to invoke member function on
01439      *  @param method   Member function to attach
01440      *  @deprecated
01441      *      Replaced by simple assignment 'Callback cb = func'
01442      */
01443     template<typename T, typename U>
01444     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01445         "Replaced by simple assignment 'Callback cb = func")
01446     void attach(U *obj, R (T::*method)(A0, A1)) {
01447         this->~Callback();
01448         new (this) Callback(obj, method);
01449     }
01450 
01451     /** Attach a member function
01452      *  @param obj      Pointer to object to invoke member function on
01453      *  @param method   Member function to attach
01454      *  @deprecated
01455      *      Replaced by simple assignment 'Callback cb = func'
01456      */
01457     template<typename T, typename U>
01458     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01459         "Replaced by simple assignment 'Callback cb = func")
01460     void attach(const U *obj, R (T::*method)(A0, A1) const) {
01461         this->~Callback();
01462         new (this) Callback(obj, method);
01463     }
01464 
01465     /** Attach a member function
01466      *  @param obj      Pointer to object to invoke member function on
01467      *  @param method   Member function to attach
01468      *  @deprecated
01469      *      Replaced by simple assignment 'Callback cb = func'
01470      */
01471     template<typename T, typename U>
01472     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01473         "Replaced by simple assignment 'Callback cb = func")
01474     void attach(volatile U *obj, R (T::*method)(A0, A1) volatile) {
01475         this->~Callback();
01476         new (this) Callback(obj, method);
01477     }
01478 
01479     /** Attach a member function
01480      *  @param obj      Pointer to object to invoke member function on
01481      *  @param method   Member function to attach
01482      *  @deprecated
01483      *      Replaced by simple assignment 'Callback cb = func'
01484      */
01485     template<typename T, typename U>
01486     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01487         "Replaced by simple assignment 'Callback cb = func")
01488     void attach(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
01489         this->~Callback();
01490         new (this) Callback(obj, method);
01491     }
01492 
01493     /** Attach a static function with a bound pointer
01494      *  @param func     Static function to attach
01495      *  @param arg      Pointer argument to function
01496      *  @deprecated
01497      *      Replaced by simple assignment 'Callback cb = func'
01498      */
01499     template <typename T, typename U>
01500     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01501         "Replaced by simple assignment 'Callback cb = func")
01502     void attach(R (*func)(T*, A0, A1), U *arg) {
01503         this->~Callback();
01504         new (this) Callback(func, arg);
01505     }
01506 
01507     /** Attach a static function with a bound pointer
01508      *  @param func     Static function to attach
01509      *  @param arg      Pointer argument to function
01510      *  @deprecated
01511      *      Replaced by simple assignment 'Callback cb = func'
01512      */
01513     template <typename T, typename U>
01514     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01515         "Replaced by simple assignment 'Callback cb = func")
01516     void attach(R (*func)(const T*, A0, A1), const U *arg) {
01517         this->~Callback();
01518         new (this) Callback(func, arg);
01519     }
01520 
01521     /** Attach a static function with a bound pointer
01522      *  @param func     Static function to attach
01523      *  @param arg      Pointer argument to function
01524      *  @deprecated
01525      *      Replaced by simple assignment 'Callback cb = func'
01526      */
01527     template <typename T, typename U>
01528     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01529         "Replaced by simple assignment 'Callback cb = func")
01530     void attach(R (*func)(volatile T*, A0, A1), volatile U *arg) {
01531         this->~Callback();
01532         new (this) Callback(func, arg);
01533     }
01534 
01535     /** Attach a static function with a bound pointer
01536      *  @param func     Static function to attach
01537      *  @param arg      Pointer argument to function
01538      *  @deprecated
01539      *      Replaced by simple assignment 'Callback cb = func'
01540      */
01541     template <typename T, typename U>
01542     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01543         "Replaced by simple assignment 'Callback cb = func")
01544     void attach(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
01545         this->~Callback();
01546         new (this) Callback(func, arg);
01547     }
01548 
01549     /** Attach a function object
01550      *  @param f Function object to attach
01551      *  @note The function object is limited to a single word of storage
01552      *  @deprecated
01553      *      Replaced by simple assignment 'Callback cb = func'
01554      */
01555     template <typename F>
01556     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01557         "Replaced by simple assignment 'Callback cb = func")
01558     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
01559         this->~Callback();
01560         new (this) Callback(f);
01561     }
01562 
01563     /** Attach a function object
01564      *  @param f Function object to attach
01565      *  @note The function object is limited to a single word of storage
01566      *  @deprecated
01567      *      Replaced by simple assignment 'Callback cb = func'
01568      */
01569     template <typename F>
01570     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01571         "Replaced by simple assignment 'Callback cb = func")
01572     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
01573         this->~Callback();
01574         new (this) Callback(f);
01575     }
01576 
01577     /** Attach a function object
01578      *  @param f Function object to attach
01579      *  @note The function object is limited to a single word of storage
01580      *  @deprecated
01581      *      Replaced by simple assignment 'Callback cb = func'
01582      */
01583     template <typename F>
01584     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01585         "Replaced by simple assignment 'Callback cb = func")
01586     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
01587         this->~Callback();
01588         new (this) Callback(f);
01589     }
01590 
01591     /** Attach a function object
01592      *  @param f Function object to attach
01593      *  @note The function object is limited to a single word of storage
01594      *  @deprecated
01595      *      Replaced by simple assignment 'Callback cb = func'
01596      */
01597     template <typename F>
01598     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01599         "Replaced by simple assignment 'Callback cb = func")
01600     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
01601         this->~Callback();
01602         new (this) Callback(f);
01603     }
01604 
01605     /** Attach a static function with a bound pointer
01606      *  @param obj  Pointer to object to bind to function
01607      *  @param func Static function to attach
01608      *  @deprecated
01609      *      Arguments to callback have been reordered to attach(func, arg)
01610      */
01611     template <typename T, typename U>
01612     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01613         "Arguments to callback have been reordered to attach(func, arg)")
01614     void attach(U *obj, R (*func)(T*, A0, A1)) {
01615         this->~Callback();
01616         new (this) Callback(func, obj);
01617     }
01618 
01619     /** Attach a static function with a bound pointer
01620      *  @param obj  Pointer to object to bind to function
01621      *  @param func Static function to attach
01622      *  @deprecated
01623      *      Arguments to callback have been reordered to attach(func, arg)
01624      */
01625     template <typename T, typename U>
01626     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01627         "Arguments to callback have been reordered to attach(func, arg)")
01628     void attach(const U *obj, R (*func)(const T*, A0, A1)) {
01629         this->~Callback();
01630         new (this) Callback(func, obj);
01631     }
01632 
01633     /** Attach a static function with a bound pointer
01634      *  @param obj  Pointer to object to bind to function
01635      *  @param func Static function to attach
01636      *  @deprecated
01637      *      Arguments to callback have been reordered to attach(func, arg)
01638      */
01639     template <typename T, typename U>
01640     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01641         "Arguments to callback have been reordered to attach(func, arg)")
01642     void attach(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
01643         this->~Callback();
01644         new (this) Callback(func, obj);
01645     }
01646 
01647     /** Attach a static function with a bound pointer
01648      *  @param obj  Pointer to object to bind to function
01649      *  @param func Static function to attach
01650      *  @deprecated
01651      *      Arguments to callback have been reordered to attach(func, arg)
01652      */
01653     template <typename T, typename U>
01654     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01655         "Arguments to callback have been reordered to attach(func, arg)")
01656     void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
01657         this->~Callback();
01658         new (this) Callback(func, obj);
01659     }
01660 
01661     /** Assign a callback
01662      */
01663     Callback &operator=(const Callback &that) {
01664         if (this != &that) {
01665             this->~Callback();
01666             new (this) Callback(that);
01667         }
01668 
01669         return *this;
01670     }
01671 
01672     /** Call the attached function
01673      */
01674     R call(A0 a0, A1 a1) const {
01675         MBED_ASSERT(_ops);
01676         return _ops->call(this, a0, a1);
01677     }
01678 
01679     /** Call the attached function
01680      */
01681     R operator()(A0 a0, A1 a1) const {
01682         return call(a0, a1);
01683     }
01684 
01685     /** Test if function has been attached
01686      */
01687     operator bool() const {
01688         return _ops;
01689     }
01690 
01691     /** Test for equality
01692      */
01693     friend bool operator==(const Callback &l, const Callback &r) {
01694         return memcmp(&l, &r, sizeof(Callback)) == 0;
01695     }
01696 
01697     /** Test for inequality
01698      */
01699     friend bool operator!=(const Callback &l, const Callback &r) {
01700         return !(l == r);
01701     }
01702 
01703     /** Static thunk for passing as C-style function
01704      *  @param func Callback to call passed as void pointer
01705      *  @param a0 An argument to be called with function func
01706      *  @param a1 An argument to be called with function func
01707      *  @return the value as determined by func which is of 
01708      *      type and determined by the signiture of func
01709      */
01710     static R thunk(void *func, A0 a0, A1 a1) {
01711         return static_cast<Callback*>(func)->call(a0, a1);
01712     }
01713 
01714 private:
01715     // Stored as pointer to function and pointer to optional object
01716     // Function pointer is stored as union of possible function types
01717     // to garuntee proper size and alignment
01718     struct _class;
01719     union {
01720         void (*_staticfunc)(A0, A1);
01721         void (*_boundfunc)(_class*, A0, A1);
01722         void (_class::*_methodfunc)(A0, A1);
01723     } _func;
01724     void *_obj;
01725 
01726     // Dynamically dispatched operations
01727     const struct ops {
01728         R (*call)(const void*, A0, A1);
01729         void (*move)(void*, const void*);
01730         void (*dtor)(void*);
01731     } *_ops;
01732 
01733     // Generate operations for function object
01734     template <typename F>
01735     void generate(const F &f) {
01736         static const ops ops = {
01737             &Callback::function_call<F>,
01738             &Callback::function_move<F>,
01739             &Callback::function_dtor<F>,
01740         };
01741 
01742         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
01743                 "Type F must not exceed the size of the Callback class");
01744         new (this) F(f);
01745         _ops = &ops;
01746     }
01747 
01748     // Function attributes
01749     template <typename F>
01750     static R function_call(const void *p, A0 a0, A1 a1) {
01751         return (*(F*)p)(a0, a1);
01752     }
01753 
01754     template <typename F>
01755     static void function_move(void *d, const void *p) {
01756         new (d) F(*(F*)p);
01757     }
01758 
01759     template <typename F>
01760     static void function_dtor(void *p) {
01761         ((F*)p)->~F();
01762     }
01763 
01764     // Wrappers for functions with context
01765     template <typename O, typename M>
01766     struct method_context {
01767         M method;
01768         O *obj;
01769 
01770         method_context(O *obj, M method)
01771             : method(method), obj(obj) {}
01772 
01773         R operator()(A0 a0, A1 a1) const {
01774             return (obj->*method)(a0, a1);
01775         }
01776     };
01777 
01778     template <typename F, typename A>
01779     struct function_context {
01780         F func;
01781         A *arg;
01782 
01783         function_context(F func, A *arg)
01784             : func(func), arg(arg) {}
01785 
01786         R operator()(A0 a0, A1 a1) const {
01787             return func(arg, a0, a1);
01788         }
01789     };
01790 };
01791 
01792 /** Callback class based on template specialization
01793  *
01794  * @note Synchronization level: Not protected
01795  * @ingroup platform
01796  */
01797 template <typename R, typename A0, typename A1, typename A2>
01798 class Callback<R(A0, A1, A2)> {
01799 public:
01800     /** Create a Callback with a static function
01801      *  @param func     Static function to attach
01802      */
01803     Callback(R (*func)(A0, A1, A2) = 0) {
01804         if (!func) {
01805             _ops = 0;
01806         } else {
01807             generate(func);
01808         }
01809     }
01810 
01811     /** Attach a Callback
01812      *  @param func     The Callback to attach
01813      */
01814     Callback(const Callback<R(A0, A1, A2)> &func) {
01815         if (func._ops) {
01816             func._ops->move(this, &func);
01817         }
01818         _ops = func._ops;
01819     }
01820 
01821     /** Create a Callback with a member function
01822      *  @param obj      Pointer to object to invoke member function on
01823      *  @param method   Member function to attach
01824      */
01825     template<typename T, typename U>
01826     Callback(U *obj, R (T::*method)(A0, A1, A2)) {
01827         generate(method_context<T, R (T::*)(A0, A1, A2)>(obj, method));
01828     }
01829 
01830     /** Create a Callback with a member function
01831      *  @param obj      Pointer to object to invoke member function on
01832      *  @param method   Member function to attach
01833      */
01834     template<typename T, typename U>
01835     Callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
01836         generate(method_context<const T, R (T::*)(A0, A1, A2) const>(obj, method));
01837     }
01838 
01839     /** Create a Callback with a member function
01840      *  @param obj      Pointer to object to invoke member function on
01841      *  @param method   Member function to attach
01842      */
01843     template<typename T, typename U>
01844     Callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
01845         generate(method_context<volatile T, R (T::*)(A0, A1, A2) volatile>(obj, method));
01846     }
01847 
01848     /** Create a Callback with a member function
01849      *  @param obj      Pointer to object to invoke member function on
01850      *  @param method   Member function to attach
01851      */
01852     template<typename T, typename U>
01853     Callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
01854         generate(method_context<const volatile T, R (T::*)(A0, A1, A2) const volatile>(obj, method));
01855     }
01856 
01857     /** Create a Callback with a static function and bound pointer
01858      *  @param func     Static function to attach
01859      *  @param arg      Pointer argument to function 
01860      */
01861     template<typename T, typename U>
01862     Callback(R (*func)(T*, A0, A1, A2), U *arg) {
01863         generate(function_context<R (*)(T*, A0, A1, A2), T>(func, arg));
01864     }
01865 
01866     /** Create a Callback with a static function and bound pointer
01867      *  @param func     Static function to attach
01868      *  @param arg      Pointer argument to function 
01869      */
01870     template<typename T, typename U>
01871     Callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
01872         generate(function_context<R (*)(const T*, A0, A1, A2), const T>(func, arg));
01873     }
01874 
01875     /** Create a Callback with a static function and bound pointer
01876      *  @param func     Static function to attach
01877      *  @param arg      Pointer argument to function 
01878      */
01879     template<typename T, typename U>
01880     Callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
01881         generate(function_context<R (*)(volatile T*, A0, A1, A2), volatile T>(func, arg));
01882     }
01883 
01884     /** Create a Callback with a static function and bound pointer
01885      *  @param func     Static function to attach
01886      *  @param arg      Pointer argument to function 
01887      */
01888     template<typename T, typename U>
01889     Callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
01890         generate(function_context<R (*)(const volatile T*, A0, A1, A2), const volatile T>(func, arg));
01891     }
01892 
01893     /** Create a Callback with a function object
01894      *  @param f Function object to attach
01895      *  @note The function object is limited to a single word of storage
01896      */
01897     template <typename F>
01898     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
01899         generate(f);
01900     }
01901 
01902     /** Create a Callback with a function object
01903      *  @param f Function object to attach
01904      *  @note The function object is limited to a single word of storage
01905      */
01906     template <typename F>
01907     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
01908         generate(f);
01909     }
01910 
01911     /** Create a Callback with a function object
01912      *  @param f Function object to attach
01913      *  @note The function object is limited to a single word of storage
01914      */
01915     template <typename F>
01916     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
01917         generate(f);
01918     }
01919 
01920     /** Create a Callback with a function object
01921      *  @param f Function object to attach
01922      *  @note The function object is limited to a single word of storage
01923      */
01924     template <typename F>
01925     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
01926         generate(f);
01927     }
01928 
01929     /** Create a Callback with a static function and bound pointer
01930      *  @param obj  Pointer to object to bind to function
01931      *  @param func Static function to attach
01932      *  @deprecated
01933      *      Arguments to callback have been reordered to Callback(func, arg)
01934      */
01935     template<typename T, typename U>
01936     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01937         "Arguments to callback have been reordered to Callback(func, arg)")
01938     Callback(U *obj, R (*func)(T*, A0, A1, A2)) {
01939         new (this) Callback(func, obj);
01940     }
01941 
01942     /** Create a Callback with a static function and bound pointer
01943      *  @param obj  Pointer to object to bind to function
01944      *  @param func Static function to attach
01945      *  @deprecated
01946      *      Arguments to callback have been reordered to Callback(func, arg)
01947      */
01948     template<typename T, typename U>
01949     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01950         "Arguments to callback have been reordered to Callback(func, arg)")
01951     Callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
01952         new (this) Callback(func, obj);
01953     }
01954 
01955     /** Create a Callback with a static function and bound pointer
01956      *  @param obj  Pointer to object to bind to function
01957      *  @param func Static function to attach
01958      *  @deprecated
01959      *      Arguments to callback have been reordered to Callback(func, arg)
01960      */
01961     template<typename T, typename U>
01962     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01963         "Arguments to callback have been reordered to Callback(func, arg)")
01964     Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
01965         new (this) Callback(func, obj);
01966     }
01967 
01968     /** Create a Callback with a static function and bound pointer
01969      *  @param obj  Pointer to object to bind to function
01970      *  @param func Static function to attach
01971      *  @deprecated
01972      *      Arguments to callback have been reordered to Callback(func, arg)
01973      */
01974     template<typename T, typename U>
01975     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01976         "Arguments to callback have been reordered to Callback(func, arg)")
01977     Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
01978         new (this) Callback(func, obj);
01979     }
01980 
01981     /** Destroy a callback
01982      */
01983     ~Callback() {
01984         if (_ops) {
01985             _ops->dtor(this);
01986         }
01987     }
01988 
01989     /** Attach a static function
01990      *  @param func     Static function to attach
01991      *  @deprecated
01992      *      Replaced by simple assignment 'Callback cb = func'
01993      */
01994     MBED_DEPRECATED_SINCE("mbed-os-5.4",
01995         "Replaced by simple assignment 'Callback cb = func")
01996     void attach(R (*func)(A0, A1, A2)) {
01997         this->~Callback();
01998         new (this) Callback(func);
01999     }
02000 
02001     /** Attach a Callback
02002      *  @param func     The Callback to attach
02003      *  @deprecated
02004      *      Replaced by simple assignment 'Callback cb = func'
02005      */
02006     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02007         "Replaced by simple assignment 'Callback cb = func")
02008     void attach(const Callback<R(A0, A1, A2)> &func) {
02009         this->~Callback();
02010         new (this) Callback(func);
02011     }
02012 
02013     /** Attach a member function
02014      *  @param obj      Pointer to object to invoke member function on
02015      *  @param method   Member function to attach
02016      *  @deprecated
02017      *      Replaced by simple assignment 'Callback cb = func'
02018      */
02019     template<typename T, typename U>
02020     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02021         "Replaced by simple assignment 'Callback cb = func")
02022     void attach(U *obj, R (T::*method)(A0, A1, A2)) {
02023         this->~Callback();
02024         new (this) Callback(obj, method);
02025     }
02026 
02027     /** Attach a member function
02028      *  @param obj      Pointer to object to invoke member function on
02029      *  @param method   Member function to attach
02030      *  @deprecated
02031      *      Replaced by simple assignment 'Callback cb = func'
02032      */
02033     template<typename T, typename U>
02034     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02035         "Replaced by simple assignment 'Callback cb = func")
02036     void attach(const U *obj, R (T::*method)(A0, A1, A2) const) {
02037         this->~Callback();
02038         new (this) Callback(obj, method);
02039     }
02040 
02041     /** Attach a member function
02042      *  @param obj      Pointer to object to invoke member function on
02043      *  @param method   Member function to attach
02044      *  @deprecated
02045      *      Replaced by simple assignment 'Callback cb = func'
02046      */
02047     template<typename T, typename U>
02048     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02049         "Replaced by simple assignment 'Callback cb = func")
02050     void attach(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
02051         this->~Callback();
02052         new (this) Callback(obj, method);
02053     }
02054 
02055     /** Attach a member function
02056      *  @param obj      Pointer to object to invoke member function on
02057      *  @param method   Member function to attach
02058      *  @deprecated
02059      *      Replaced by simple assignment 'Callback cb = func'
02060      */
02061     template<typename T, typename U>
02062     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02063         "Replaced by simple assignment 'Callback cb = func")
02064     void attach(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
02065         this->~Callback();
02066         new (this) Callback(obj, method);
02067     }
02068 
02069     /** Attach a static function with a bound pointer
02070      *  @param func     Static function to attach
02071      *  @param arg      Pointer argument to function
02072      *  @deprecated
02073      *      Replaced by simple assignment 'Callback cb = func'
02074      */
02075     template <typename T, typename U>
02076     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02077         "Replaced by simple assignment 'Callback cb = func")
02078     void attach(R (*func)(T*, A0, A1, A2), U *arg) {
02079         this->~Callback();
02080         new (this) Callback(func, arg);
02081     }
02082 
02083     /** Attach a static function with a bound pointer
02084      *  @param func     Static function to attach
02085      *  @param arg      Pointer argument to function
02086      *  @deprecated
02087      *      Replaced by simple assignment 'Callback cb = func'
02088      */
02089     template <typename T, typename U>
02090     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02091         "Replaced by simple assignment 'Callback cb = func")
02092     void attach(R (*func)(const T*, A0, A1, A2), const U *arg) {
02093         this->~Callback();
02094         new (this) Callback(func, arg);
02095     }
02096 
02097     /** Attach a static function with a bound pointer
02098      *  @param func     Static function to attach
02099      *  @param arg      Pointer argument to function
02100      *  @deprecated
02101      *      Replaced by simple assignment 'Callback cb = func'
02102      */
02103     template <typename T, typename U>
02104     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02105         "Replaced by simple assignment 'Callback cb = func")
02106     void attach(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
02107         this->~Callback();
02108         new (this) Callback(func, arg);
02109     }
02110 
02111     /** Attach a static function with a bound pointer
02112      *  @param func     Static function to attach
02113      *  @param arg      Pointer argument to function
02114      *  @deprecated
02115      *      Replaced by simple assignment 'Callback cb = func'
02116      */
02117     template <typename T, typename U>
02118     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02119         "Replaced by simple assignment 'Callback cb = func")
02120     void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
02121         this->~Callback();
02122         new (this) Callback(func, arg);
02123     }
02124 
02125     /** Attach a function object
02126      *  @param f Function object to attach
02127      *  @note The function object is limited to a single word of storage
02128      *  @deprecated
02129      *      Replaced by simple assignment 'Callback cb = func'
02130      */
02131     template <typename F>
02132     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02133         "Replaced by simple assignment 'Callback cb = func")
02134     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
02135         this->~Callback();
02136         new (this) Callback(f);
02137     }
02138 
02139     /** Attach a function object
02140      *  @param f Function object to attach
02141      *  @note The function object is limited to a single word of storage
02142      *  @deprecated
02143      *      Replaced by simple assignment 'Callback cb = func'
02144      */
02145     template <typename F>
02146     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02147         "Replaced by simple assignment 'Callback cb = func")
02148     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
02149         this->~Callback();
02150         new (this) Callback(f);
02151     }
02152 
02153     /** Attach a function object
02154      *  @param f Function object to attach
02155      *  @note The function object is limited to a single word of storage
02156      *  @deprecated
02157      *      Replaced by simple assignment 'Callback cb = func'
02158      */
02159     template <typename F>
02160     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02161         "Replaced by simple assignment 'Callback cb = func")
02162     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
02163         this->~Callback();
02164         new (this) Callback(f);
02165     }
02166 
02167     /** Attach a function object
02168      *  @param f Function object to attach
02169      *  @note The function object is limited to a single word of storage
02170      *  @deprecated
02171      *      Replaced by simple assignment 'Callback cb = func'
02172      */
02173     template <typename F>
02174     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02175         "Replaced by simple assignment 'Callback cb = func")
02176     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
02177         this->~Callback();
02178         new (this) Callback(f);
02179     }
02180 
02181     /** Attach a static function with a bound pointer
02182      *  @param obj  Pointer to object to bind to function
02183      *  @param func Static function to attach
02184      *  @deprecated
02185      *      Arguments to callback have been reordered to attach(func, arg)
02186      */
02187     template <typename T, typename U>
02188     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02189         "Arguments to callback have been reordered to attach(func, arg)")
02190     void attach(U *obj, R (*func)(T*, A0, A1, A2)) {
02191         this->~Callback();
02192         new (this) Callback(func, obj);
02193     }
02194 
02195     /** Attach a static function with a bound pointer
02196      *  @param obj  Pointer to object to bind to function
02197      *  @param func Static function to attach
02198      *  @deprecated
02199      *      Arguments to callback have been reordered to attach(func, arg)
02200      */
02201     template <typename T, typename U>
02202     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02203         "Arguments to callback have been reordered to attach(func, arg)")
02204     void attach(const U *obj, R (*func)(const T*, A0, A1, A2)) {
02205         this->~Callback();
02206         new (this) Callback(func, obj);
02207     }
02208 
02209     /** Attach a static function with a bound pointer
02210      *  @param obj  Pointer to object to bind to function
02211      *  @param func Static function to attach
02212      *  @deprecated
02213      *      Arguments to callback have been reordered to attach(func, arg)
02214      */
02215     template <typename T, typename U>
02216     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02217         "Arguments to callback have been reordered to attach(func, arg)")
02218     void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
02219         this->~Callback();
02220         new (this) Callback(func, obj);
02221     }
02222 
02223     /** Attach a static function with a bound pointer
02224      *  @param obj  Pointer to object to bind to function
02225      *  @param func Static function to attach
02226      *  @deprecated
02227      *      Arguments to callback have been reordered to attach(func, arg)
02228      */
02229     template <typename T, typename U>
02230     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02231         "Arguments to callback have been reordered to attach(func, arg)")
02232     void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
02233         this->~Callback();
02234         new (this) Callback(func, obj);
02235     }
02236 
02237     /** Assign a callback
02238      */
02239     Callback &operator=(const Callback &that) {
02240         if (this != &that) {
02241             this->~Callback();
02242             new (this) Callback(that);
02243         }
02244 
02245         return *this;
02246     }
02247 
02248     /** Call the attached function
02249      */
02250     R call(A0 a0, A1 a1, A2 a2) const {
02251         MBED_ASSERT(_ops);
02252         return _ops->call(this, a0, a1, a2);
02253     }
02254 
02255     /** Call the attached function
02256      */
02257     R operator()(A0 a0, A1 a1, A2 a2) const {
02258         return call(a0, a1, a2);
02259     }
02260 
02261     /** Test if function has been attached
02262      */
02263     operator bool() const {
02264         return _ops;
02265     }
02266 
02267     /** Test for equality
02268      */
02269     friend bool operator==(const Callback &l, const Callback &r) {
02270         return memcmp(&l, &r, sizeof(Callback)) == 0;
02271     }
02272 
02273     /** Test for inequality
02274      */
02275     friend bool operator!=(const Callback &l, const Callback &r) {
02276         return !(l == r);
02277     }
02278 
02279     /** Static thunk for passing as C-style function
02280      *  @param func Callback to call passed as void pointer
02281      *  @param a0 An argument to be called with function func
02282      *  @param a1 An argument to be called with function func
02283      *  @param a2 An argument to be called with function func
02284      *  @return the value as determined by func which is of 
02285      *      type and determined by the signiture of func
02286      */
02287     static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
02288         return static_cast<Callback*>(func)->call(a0, a1, a2);
02289     }
02290 
02291 private:
02292     // Stored as pointer to function and pointer to optional object
02293     // Function pointer is stored as union of possible function types
02294     // to garuntee proper size and alignment
02295     struct _class;
02296     union {
02297         void (*_staticfunc)(A0, A1, A2);
02298         void (*_boundfunc)(_class*, A0, A1, A2);
02299         void (_class::*_methodfunc)(A0, A1, A2);
02300     } _func;
02301     void *_obj;
02302 
02303     // Dynamically dispatched operations
02304     const struct ops {
02305         R (*call)(const void*, A0, A1, A2);
02306         void (*move)(void*, const void*);
02307         void (*dtor)(void*);
02308     } *_ops;
02309 
02310     // Generate operations for function object
02311     template <typename F>
02312     void generate(const F &f) {
02313         static const ops ops = {
02314             &Callback::function_call<F>,
02315             &Callback::function_move<F>,
02316             &Callback::function_dtor<F>,
02317         };
02318 
02319         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
02320                 "Type F must not exceed the size of the Callback class");
02321         new (this) F(f);
02322         _ops = &ops;
02323     }
02324 
02325     // Function attributes
02326     template <typename F>
02327     static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
02328         return (*(F*)p)(a0, a1, a2);
02329     }
02330 
02331     template <typename F>
02332     static void function_move(void *d, const void *p) {
02333         new (d) F(*(F*)p);
02334     }
02335 
02336     template <typename F>
02337     static void function_dtor(void *p) {
02338         ((F*)p)->~F();
02339     }
02340 
02341     // Wrappers for functions with context
02342     template <typename O, typename M>
02343     struct method_context {
02344         M method;
02345         O *obj;
02346 
02347         method_context(O *obj, M method)
02348             : method(method), obj(obj) {}
02349 
02350         R operator()(A0 a0, A1 a1, A2 a2) const {
02351             return (obj->*method)(a0, a1, a2);
02352         }
02353     };
02354 
02355     template <typename F, typename A>
02356     struct function_context {
02357         F func;
02358         A *arg;
02359 
02360         function_context(F func, A *arg)
02361             : func(func), arg(arg) {}
02362 
02363         R operator()(A0 a0, A1 a1, A2 a2) const {
02364             return func(arg, a0, a1, a2);
02365         }
02366     };
02367 };
02368 
02369 /** Callback class based on template specialization
02370  *
02371  * @note Synchronization level: Not protected
02372  * @ingroup platform
02373  */
02374 template <typename R, typename A0, typename A1, typename A2, typename A3>
02375 class Callback<R(A0, A1, A2, A3)> {
02376 public:
02377     /** Create a Callback with a static function
02378      *  @param func     Static function to attach
02379      */
02380     Callback(R (*func)(A0, A1, A2, A3) = 0) {
02381         if (!func) {
02382             _ops = 0;
02383         } else {
02384             generate(func);
02385         }
02386     }
02387 
02388     /** Attach a Callback
02389      *  @param func     The Callback to attach
02390      */
02391     Callback(const Callback<R(A0, A1, A2, A3)> &func) {
02392         if (func._ops) {
02393             func._ops->move(this, &func);
02394         }
02395         _ops = func._ops;
02396     }
02397 
02398     /** Create a Callback with a member function
02399      *  @param obj      Pointer to object to invoke member function on
02400      *  @param method   Member function to attach
02401      */
02402     template<typename T, typename U>
02403     Callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
02404         generate(method_context<T, R (T::*)(A0, A1, A2, A3)>(obj, method));
02405     }
02406 
02407     /** Create a Callback with a member function
02408      *  @param obj      Pointer to object to invoke member function on
02409      *  @param method   Member function to attach
02410      */
02411     template<typename T, typename U>
02412     Callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
02413         generate(method_context<const T, R (T::*)(A0, A1, A2, A3) const>(obj, method));
02414     }
02415 
02416     /** Create a Callback with a member function
02417      *  @param obj      Pointer to object to invoke member function on
02418      *  @param method   Member function to attach
02419      */
02420     template<typename T, typename U>
02421     Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
02422         generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3) volatile>(obj, method));
02423     }
02424 
02425     /** Create a Callback with a member function
02426      *  @param obj      Pointer to object to invoke member function on
02427      *  @param method   Member function to attach
02428      */
02429     template<typename T, typename U>
02430     Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
02431         generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3) const volatile>(obj, method));
02432     }
02433 
02434     /** Create a Callback with a static function and bound pointer
02435      *  @param func     Static function to attach
02436      *  @param arg      Pointer argument to function 
02437      */
02438     template<typename T, typename U>
02439     Callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
02440         generate(function_context<R (*)(T*, A0, A1, A2, A3), T>(func, arg));
02441     }
02442 
02443     /** Create a Callback with a static function and bound pointer
02444      *  @param func     Static function to attach
02445      *  @param arg      Pointer argument to function 
02446      */
02447     template<typename T, typename U>
02448     Callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
02449         generate(function_context<R (*)(const T*, A0, A1, A2, A3), const T>(func, arg));
02450     }
02451 
02452     /** Create a Callback with a static function and bound pointer
02453      *  @param func     Static function to attach
02454      *  @param arg      Pointer argument to function 
02455      */
02456     template<typename T, typename U>
02457     Callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
02458         generate(function_context<R (*)(volatile T*, A0, A1, A2, A3), volatile T>(func, arg));
02459     }
02460 
02461     /** Create a Callback with a static function and bound pointer
02462      *  @param func     Static function to attach
02463      *  @param arg      Pointer argument to function 
02464      */
02465     template<typename T, typename U>
02466     Callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
02467         generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3), const volatile T>(func, arg));
02468     }
02469 
02470     /** Create a Callback with a function object
02471      *  @param f Function object to attach
02472      *  @note The function object is limited to a single word of storage
02473      */
02474     template <typename F>
02475     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
02476         generate(f);
02477     }
02478 
02479     /** Create a Callback with a function object
02480      *  @param f Function object to attach
02481      *  @note The function object is limited to a single word of storage
02482      */
02483     template <typename F>
02484     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
02485         generate(f);
02486     }
02487 
02488     /** Create a Callback with a function object
02489      *  @param f Function object to attach
02490      *  @note The function object is limited to a single word of storage
02491      */
02492     template <typename F>
02493     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
02494         generate(f);
02495     }
02496 
02497     /** Create a Callback with a function object
02498      *  @param f Function object to attach
02499      *  @note The function object is limited to a single word of storage
02500      */
02501     template <typename F>
02502     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
02503         generate(f);
02504     }
02505 
02506     /** Create a Callback with a static function and bound pointer
02507      *  @param obj  Pointer to object to bind to function
02508      *  @param func Static function to attach
02509      *  @deprecated
02510      *      Arguments to callback have been reordered to Callback(func, arg)
02511      */
02512     template<typename T, typename U>
02513     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02514         "Arguments to callback have been reordered to Callback(func, arg)")
02515     Callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
02516         new (this) Callback(func, obj);
02517     }
02518 
02519     /** Create a Callback with a static function and bound pointer
02520      *  @param obj  Pointer to object to bind to function
02521      *  @param func Static function to attach
02522      *  @deprecated
02523      *      Arguments to callback have been reordered to Callback(func, arg)
02524      */
02525     template<typename T, typename U>
02526     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02527         "Arguments to callback have been reordered to Callback(func, arg)")
02528     Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
02529         new (this) Callback(func, obj);
02530     }
02531 
02532     /** Create a Callback with a static function and bound pointer
02533      *  @param obj  Pointer to object to bind to function
02534      *  @param func Static function to attach
02535      *  @deprecated
02536      *      Arguments to callback have been reordered to Callback(func, arg)
02537      */
02538     template<typename T, typename U>
02539     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02540         "Arguments to callback have been reordered to Callback(func, arg)")
02541     Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
02542         new (this) Callback(func, obj);
02543     }
02544 
02545     /** Create a Callback with a static function and bound pointer
02546      *  @param obj  Pointer to object to bind to function
02547      *  @param func Static function to attach
02548      *  @deprecated
02549      *      Arguments to callback have been reordered to Callback(func, arg)
02550      */
02551     template<typename T, typename U>
02552     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02553         "Arguments to callback have been reordered to Callback(func, arg)")
02554     Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
02555         new (this) Callback(func, obj);
02556     }
02557 
02558     /** Destroy a callback
02559      */
02560     ~Callback() {
02561         if (_ops) {
02562             _ops->dtor(this);
02563         }
02564     }
02565 
02566     /** Attach a static function
02567      *  @param func     Static function to attach
02568      *  @deprecated
02569      *      Replaced by simple assignment 'Callback cb = func'
02570      */
02571     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02572         "Replaced by simple assignment 'Callback cb = func")
02573     void attach(R (*func)(A0, A1, A2, A3)) {
02574         this->~Callback();
02575         new (this) Callback(func);
02576     }
02577 
02578     /** Attach a Callback
02579      *  @param func     The Callback to attach
02580      *  @deprecated
02581      *      Replaced by simple assignment 'Callback cb = func'
02582      */
02583     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02584         "Replaced by simple assignment 'Callback cb = func")
02585     void attach(const Callback<R(A0, A1, A2, A3)> &func) {
02586         this->~Callback();
02587         new (this) Callback(func);
02588     }
02589 
02590     /** Attach a member function
02591      *  @param obj      Pointer to object to invoke member function on
02592      *  @param method   Member function to attach
02593      *  @deprecated
02594      *      Replaced by simple assignment 'Callback cb = func'
02595      */
02596     template<typename T, typename U>
02597     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02598         "Replaced by simple assignment 'Callback cb = func")
02599     void attach(U *obj, R (T::*method)(A0, A1, A2, A3)) {
02600         this->~Callback();
02601         new (this) Callback(obj, method);
02602     }
02603 
02604     /** Attach a member function
02605      *  @param obj      Pointer to object to invoke member function on
02606      *  @param method   Member function to attach
02607      *  @deprecated
02608      *      Replaced by simple assignment 'Callback cb = func'
02609      */
02610     template<typename T, typename U>
02611     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02612         "Replaced by simple assignment 'Callback cb = func")
02613     void attach(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
02614         this->~Callback();
02615         new (this) Callback(obj, method);
02616     }
02617 
02618     /** Attach a member function
02619      *  @param obj      Pointer to object to invoke member function on
02620      *  @param method   Member function to attach
02621      *  @deprecated
02622      *      Replaced by simple assignment 'Callback cb = func'
02623      */
02624     template<typename T, typename U>
02625     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02626         "Replaced by simple assignment 'Callback cb = func")
02627     void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
02628         this->~Callback();
02629         new (this) Callback(obj, method);
02630     }
02631 
02632     /** Attach a member function
02633      *  @param obj      Pointer to object to invoke member function on
02634      *  @param method   Member function to attach
02635      *  @deprecated
02636      *      Replaced by simple assignment 'Callback cb = func'
02637      */
02638     template<typename T, typename U>
02639     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02640         "Replaced by simple assignment 'Callback cb = func")
02641     void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
02642         this->~Callback();
02643         new (this) Callback(obj, method);
02644     }
02645 
02646     /** Attach a static function with a bound pointer
02647      *  @param func     Static function to attach
02648      *  @param arg      Pointer argument to function
02649      *  @deprecated
02650      *      Replaced by simple assignment 'Callback cb = func'
02651      */
02652     template <typename T, typename U>
02653     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02654         "Replaced by simple assignment 'Callback cb = func")
02655     void attach(R (*func)(T*, A0, A1, A2, A3), U *arg) {
02656         this->~Callback();
02657         new (this) Callback(func, arg);
02658     }
02659 
02660     /** Attach a static function with a bound pointer
02661      *  @param func     Static function to attach
02662      *  @param arg      Pointer argument to function
02663      *  @deprecated
02664      *      Replaced by simple assignment 'Callback cb = func'
02665      */
02666     template <typename T, typename U>
02667     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02668         "Replaced by simple assignment 'Callback cb = func")
02669     void attach(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
02670         this->~Callback();
02671         new (this) Callback(func, arg);
02672     }
02673 
02674     /** Attach a static function with a bound pointer
02675      *  @param func     Static function to attach
02676      *  @param arg      Pointer argument to function
02677      *  @deprecated
02678      *      Replaced by simple assignment 'Callback cb = func'
02679      */
02680     template <typename T, typename U>
02681     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02682         "Replaced by simple assignment 'Callback cb = func")
02683     void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
02684         this->~Callback();
02685         new (this) Callback(func, arg);
02686     }
02687 
02688     /** Attach a static function with a bound pointer
02689      *  @param func     Static function to attach
02690      *  @param arg      Pointer argument to function
02691      *  @deprecated
02692      *      Replaced by simple assignment 'Callback cb = func'
02693      */
02694     template <typename T, typename U>
02695     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02696         "Replaced by simple assignment 'Callback cb = func")
02697     void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
02698         this->~Callback();
02699         new (this) Callback(func, arg);
02700     }
02701 
02702     /** Attach a function object
02703      *  @param f Function object to attach
02704      *  @note The function object is limited to a single word of storage
02705      *  @deprecated
02706      *      Replaced by simple assignment 'Callback cb = func'
02707      */
02708     template <typename F>
02709     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02710         "Replaced by simple assignment 'Callback cb = func")
02711     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
02712         this->~Callback();
02713         new (this) Callback(f);
02714     }
02715 
02716     /** Attach a function object
02717      *  @param f Function object to attach
02718      *  @note The function object is limited to a single word of storage
02719      *  @deprecated
02720      *      Replaced by simple assignment 'Callback cb = func'
02721      */
02722     template <typename F>
02723     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02724         "Replaced by simple assignment 'Callback cb = func")
02725     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
02726         this->~Callback();
02727         new (this) Callback(f);
02728     }
02729 
02730     /** Attach a function object
02731      *  @param f Function object to attach
02732      *  @note The function object is limited to a single word of storage
02733      *  @deprecated
02734      *      Replaced by simple assignment 'Callback cb = func'
02735      */
02736     template <typename F>
02737     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02738         "Replaced by simple assignment 'Callback cb = func")
02739     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
02740         this->~Callback();
02741         new (this) Callback(f);
02742     }
02743 
02744     /** Attach a function object
02745      *  @param f Function object to attach
02746      *  @note The function object is limited to a single word of storage
02747      *  @deprecated
02748      *      Replaced by simple assignment 'Callback cb = func'
02749      */
02750     template <typename F>
02751     MBED_DEPRECATED_SINCE("mbed-os-5.4",
02752         "Replaced by simple assignment 'Callback cb = func")
02753     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
02754         this->~Callback();
02755         new (this) Callback(f);
02756     }
02757 
02758     /** Attach a static function with a bound pointer
02759      *  @param obj  Pointer to object to bind to function
02760      *  @param func Static function to attach
02761      *  @deprecated
02762      *      Arguments to callback have been reordered to attach(func, arg)
02763      */
02764     template <typename T, typename U>
02765     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02766         "Arguments to callback have been reordered to attach(func, arg)")
02767     void attach(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
02768         this->~Callback();
02769         new (this) Callback(func, obj);
02770     }
02771 
02772     /** Attach a static function with a bound pointer
02773      *  @param obj  Pointer to object to bind to function
02774      *  @param func Static function to attach
02775      *  @deprecated
02776      *      Arguments to callback have been reordered to attach(func, arg)
02777      */
02778     template <typename T, typename U>
02779     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02780         "Arguments to callback have been reordered to attach(func, arg)")
02781     void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
02782         this->~Callback();
02783         new (this) Callback(func, obj);
02784     }
02785 
02786     /** Attach a static function with a bound pointer
02787      *  @param obj  Pointer to object to bind to function
02788      *  @param func Static function to attach
02789      *  @deprecated
02790      *      Arguments to callback have been reordered to attach(func, arg)
02791      */
02792     template <typename T, typename U>
02793     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02794         "Arguments to callback have been reordered to attach(func, arg)")
02795     void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
02796         this->~Callback();
02797         new (this) Callback(func, obj);
02798     }
02799 
02800     /** Attach a static function with a bound pointer
02801      *  @param obj  Pointer to object to bind to function
02802      *  @param func Static function to attach
02803      *  @deprecated
02804      *      Arguments to callback have been reordered to attach(func, arg)
02805      */
02806     template <typename T, typename U>
02807     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02808         "Arguments to callback have been reordered to attach(func, arg)")
02809     void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
02810         this->~Callback();
02811         new (this) Callback(func, obj);
02812     }
02813 
02814     /** Assign a callback
02815      */
02816     Callback &operator=(const Callback &that) {
02817         if (this != &that) {
02818             this->~Callback();
02819             new (this) Callback(that);
02820         }
02821 
02822         return *this;
02823     }
02824 
02825     /** Call the attached function
02826      */
02827     R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
02828         MBED_ASSERT(_ops);
02829         return _ops->call(this, a0, a1, a2, a3);
02830     }
02831 
02832     /** Call the attached function
02833      */
02834     R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
02835         return call(a0, a1, a2, a3);
02836     }
02837 
02838     /** Test if function has been attached
02839      */
02840     operator bool() const {
02841         return _ops;
02842     }
02843 
02844     /** Test for equality
02845      */
02846     friend bool operator==(const Callback &l, const Callback &r) {
02847         return memcmp(&l, &r, sizeof(Callback)) == 0;
02848     }
02849 
02850     /** Test for inequality
02851      */
02852     friend bool operator!=(const Callback &l, const Callback &r) {
02853         return !(l == r);
02854     }
02855 
02856     /** Static thunk for passing as C-style function
02857      *  @param func Callback to call passed as void pointer
02858      *  @param a0 An argument to be called with function func
02859      *  @param a1 An argument to be called with function func
02860      *  @param a2 An argument to be called with function func
02861      *  @param a3 An argument to be called with function func
02862      *  @return the value as determined by func which is of 
02863      *      type and determined by the signiture of func
02864      */
02865     static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02866         return static_cast<Callback*>(func)->call(a0, a1, a2, a3);
02867     }
02868 
02869 private:
02870     // Stored as pointer to function and pointer to optional object
02871     // Function pointer is stored as union of possible function types
02872     // to garuntee proper size and alignment
02873     struct _class;
02874     union {
02875         void (*_staticfunc)(A0, A1, A2, A3);
02876         void (*_boundfunc)(_class*, A0, A1, A2, A3);
02877         void (_class::*_methodfunc)(A0, A1, A2, A3);
02878     } _func;
02879     void *_obj;
02880 
02881     // Dynamically dispatched operations
02882     const struct ops {
02883         R (*call)(const void*, A0, A1, A2, A3);
02884         void (*move)(void*, const void*);
02885         void (*dtor)(void*);
02886     } *_ops;
02887 
02888     // Generate operations for function object
02889     template <typename F>
02890     void generate(const F &f) {
02891         static const ops ops = {
02892             &Callback::function_call<F>,
02893             &Callback::function_move<F>,
02894             &Callback::function_dtor<F>,
02895         };
02896 
02897         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
02898                 "Type F must not exceed the size of the Callback class");
02899         new (this) F(f);
02900         _ops = &ops;
02901     }
02902 
02903     // Function attributes
02904     template <typename F>
02905     static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
02906         return (*(F*)p)(a0, a1, a2, a3);
02907     }
02908 
02909     template <typename F>
02910     static void function_move(void *d, const void *p) {
02911         new (d) F(*(F*)p);
02912     }
02913 
02914     template <typename F>
02915     static void function_dtor(void *p) {
02916         ((F*)p)->~F();
02917     }
02918 
02919     // Wrappers for functions with context
02920     template <typename O, typename M>
02921     struct method_context {
02922         M method;
02923         O *obj;
02924 
02925         method_context(O *obj, M method)
02926             : method(method), obj(obj) {}
02927 
02928         R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
02929             return (obj->*method)(a0, a1, a2, a3);
02930         }
02931     };
02932 
02933     template <typename F, typename A>
02934     struct function_context {
02935         F func;
02936         A *arg;
02937 
02938         function_context(F func, A *arg)
02939             : func(func), arg(arg) {}
02940 
02941         R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
02942             return func(arg, a0, a1, a2, a3);
02943         }
02944     };
02945 };
02946 
02947 /** Callback class based on template specialization
02948  *
02949  * @note Synchronization level: Not protected
02950  * @ingroup platform
02951  */
02952 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
02953 class Callback<R(A0, A1, A2, A3, A4)> {
02954 public:
02955     /** Create a Callback with a static function
02956      *  @param func     Static function to attach
02957      */
02958     Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
02959         if (!func) {
02960             _ops = 0;
02961         } else {
02962             generate(func);
02963         }
02964     }
02965 
02966     /** Attach a Callback
02967      *  @param func     The Callback to attach
02968      */
02969     Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
02970         if (func._ops) {
02971             func._ops->move(this, &func);
02972         }
02973         _ops = func._ops;
02974     }
02975 
02976     /** Create a Callback with a member function
02977      *  @param obj      Pointer to object to invoke member function on
02978      *  @param method   Member function to attach
02979      */
02980     template<typename T, typename U>
02981     Callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
02982         generate(method_context<T, R (T::*)(A0, A1, A2, A3, A4)>(obj, method));
02983     }
02984 
02985     /** Create a Callback with a member function
02986      *  @param obj      Pointer to object to invoke member function on
02987      *  @param method   Member function to attach
02988      */
02989     template<typename T, typename U>
02990     Callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
02991         generate(method_context<const T, R (T::*)(A0, A1, A2, A3, A4) const>(obj, method));
02992     }
02993 
02994     /** Create a Callback with a member function
02995      *  @param obj      Pointer to object to invoke member function on
02996      *  @param method   Member function to attach
02997      */
02998     template<typename T, typename U>
02999     Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
03000         generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
03001     }
03002 
03003     /** Create a Callback with a member function
03004      *  @param obj      Pointer to object to invoke member function on
03005      *  @param method   Member function to attach
03006      */
03007     template<typename T, typename U>
03008     Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
03009         generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
03010     }
03011 
03012     /** Create a Callback with a static function and bound pointer
03013      *  @param func     Static function to attach
03014      *  @param arg      Pointer argument to function 
03015      */
03016     template<typename T, typename U>
03017     Callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
03018         generate(function_context<R (*)(T*, A0, A1, A2, A3, A4), T>(func, arg));
03019     }
03020 
03021     /** Create a Callback with a static function and bound pointer
03022      *  @param func     Static function to attach
03023      *  @param arg      Pointer argument to function 
03024      */
03025     template<typename T, typename U>
03026     Callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
03027         generate(function_context<R (*)(const T*, A0, A1, A2, A3, A4), const T>(func, arg));
03028     }
03029 
03030     /** Create a Callback with a static function and bound pointer
03031      *  @param func     Static function to attach
03032      *  @param arg      Pointer argument to function 
03033      */
03034     template<typename T, typename U>
03035     Callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
03036         generate(function_context<R (*)(volatile T*, A0, A1, A2, A3, A4), volatile T>(func, arg));
03037     }
03038 
03039     /** Create a Callback with a static function and bound pointer
03040      *  @param func     Static function to attach
03041      *  @param arg      Pointer argument to function 
03042      */
03043     template<typename T, typename U>
03044     Callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
03045         generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3, A4), const volatile T>(func, arg));
03046     }
03047 
03048     /** Create a Callback with a function object
03049      *  @param f Function object to attach
03050      *  @note The function object is limited to a single word of storage
03051      */
03052     template <typename F>
03053     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
03054         generate(f);
03055     }
03056 
03057     /** Create a Callback with a function object
03058      *  @param f Function object to attach
03059      *  @note The function object is limited to a single word of storage
03060      */
03061     template <typename F>
03062     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
03063         generate(f);
03064     }
03065 
03066     /** Create a Callback with a function object
03067      *  @param f Function object to attach
03068      *  @note The function object is limited to a single word of storage
03069      */
03070     template <typename F>
03071     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
03072         generate(f);
03073     }
03074 
03075     /** Create a Callback with a function object
03076      *  @param f Function object to attach
03077      *  @note The function object is limited to a single word of storage
03078      */
03079     template <typename F>
03080     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
03081         generate(f);
03082     }
03083 
03084     /** Create a Callback with a static function and bound pointer
03085      *  @param obj  Pointer to object to bind to function
03086      *  @param func Static function to attach
03087      *  @deprecated
03088      *      Arguments to callback have been reordered to Callback(func, arg)
03089      */
03090     template<typename T, typename U>
03091     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03092         "Arguments to callback have been reordered to Callback(func, arg)")
03093     Callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
03094         new (this) Callback(func, obj);
03095     }
03096 
03097     /** Create a Callback with a static function and bound pointer
03098      *  @param obj  Pointer to object to bind to function
03099      *  @param func Static function to attach
03100      *  @deprecated
03101      *      Arguments to callback have been reordered to Callback(func, arg)
03102      */
03103     template<typename T, typename U>
03104     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03105         "Arguments to callback have been reordered to Callback(func, arg)")
03106     Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
03107         new (this) Callback(func, obj);
03108     }
03109 
03110     /** Create a Callback with a static function and bound pointer
03111      *  @param obj  Pointer to object to bind to function
03112      *  @param func Static function to attach
03113      *  @deprecated
03114      *      Arguments to callback have been reordered to Callback(func, arg)
03115      */
03116     template<typename T, typename U>
03117     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03118         "Arguments to callback have been reordered to Callback(func, arg)")
03119     Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
03120         new (this) Callback(func, obj);
03121     }
03122 
03123     /** Create a Callback with a static function and bound pointer
03124      *  @param obj  Pointer to object to bind to function
03125      *  @param func Static function to attach
03126      *  @deprecated
03127      *      Arguments to callback have been reordered to Callback(func, arg)
03128      */
03129     template<typename T, typename U>
03130     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03131         "Arguments to callback have been reordered to Callback(func, arg)")
03132     Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
03133         new (this) Callback(func, obj);
03134     }
03135 
03136     /** Destroy a callback
03137      */
03138     ~Callback() {
03139         if (_ops) {
03140             _ops->dtor(this);
03141         }
03142     }
03143 
03144     /** Attach a static function
03145      *  @param func     Static function to attach
03146      *  @deprecated
03147      *      Replaced by simple assignment 'Callback cb = func'
03148      */
03149     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03150         "Replaced by simple assignment 'Callback cb = func")
03151     void attach(R (*func)(A0, A1, A2, A3, A4)) {
03152         this->~Callback();
03153         new (this) Callback(func);
03154     }
03155 
03156     /** Attach a Callback
03157      *  @param func     The Callback to attach
03158      *  @deprecated
03159      *      Replaced by simple assignment 'Callback cb = func'
03160      */
03161     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03162         "Replaced by simple assignment 'Callback cb = func")
03163     void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
03164         this->~Callback();
03165         new (this) Callback(func);
03166     }
03167 
03168     /** Attach a member function
03169      *  @param obj      Pointer to object to invoke member function on
03170      *  @param method   Member function to attach
03171      *  @deprecated
03172      *      Replaced by simple assignment 'Callback cb = func'
03173      */
03174     template<typename T, typename U>
03175     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03176         "Replaced by simple assignment 'Callback cb = func")
03177     void attach(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
03178         this->~Callback();
03179         new (this) Callback(obj, method);
03180     }
03181 
03182     /** Attach a member function
03183      *  @param obj      Pointer to object to invoke member function on
03184      *  @param method   Member function to attach
03185      *  @deprecated
03186      *      Replaced by simple assignment 'Callback cb = func'
03187      */
03188     template<typename T, typename U>
03189     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03190         "Replaced by simple assignment 'Callback cb = func")
03191     void attach(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
03192         this->~Callback();
03193         new (this) Callback(obj, method);
03194     }
03195 
03196     /** Attach a member function
03197      *  @param obj      Pointer to object to invoke member function on
03198      *  @param method   Member function to attach
03199      *  @deprecated
03200      *      Replaced by simple assignment 'Callback cb = func'
03201      */
03202     template<typename T, typename U>
03203     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03204         "Replaced by simple assignment 'Callback cb = func")
03205     void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
03206         this->~Callback();
03207         new (this) Callback(obj, method);
03208     }
03209 
03210     /** Attach a member function
03211      *  @param obj      Pointer to object to invoke member function on
03212      *  @param method   Member function to attach
03213      *  @deprecated
03214      *      Replaced by simple assignment 'Callback cb = func'
03215      */
03216     template<typename T, typename U>
03217     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03218         "Replaced by simple assignment 'Callback cb = func")
03219     void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
03220         this->~Callback();
03221         new (this) Callback(obj, method);
03222     }
03223 
03224     /** Attach a static function with a bound pointer
03225      *  @param func     Static function to attach
03226      *  @param arg      Pointer argument to function
03227      *  @deprecated
03228      *      Replaced by simple assignment 'Callback cb = func'
03229      */
03230     template <typename T, typename U>
03231     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03232         "Replaced by simple assignment 'Callback cb = func")
03233     void attach(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
03234         this->~Callback();
03235         new (this) Callback(func, arg);
03236     }
03237 
03238     /** Attach a static function with a bound pointer
03239      *  @param func     Static function to attach
03240      *  @param arg      Pointer argument to function
03241      *  @deprecated
03242      *      Replaced by simple assignment 'Callback cb = func'
03243      */
03244     template <typename T, typename U>
03245     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03246         "Replaced by simple assignment 'Callback cb = func")
03247     void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
03248         this->~Callback();
03249         new (this) Callback(func, arg);
03250     }
03251 
03252     /** Attach a static function with a bound pointer
03253      *  @param func     Static function to attach
03254      *  @param arg      Pointer argument to function
03255      *  @deprecated
03256      *      Replaced by simple assignment 'Callback cb = func'
03257      */
03258     template <typename T, typename U>
03259     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03260         "Replaced by simple assignment 'Callback cb = func")
03261     void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
03262         this->~Callback();
03263         new (this) Callback(func, arg);
03264     }
03265 
03266     /** Attach a static function with a bound pointer
03267      *  @param func     Static function to attach
03268      *  @param arg      Pointer argument to function
03269      *  @deprecated
03270      *      Replaced by simple assignment 'Callback cb = func'
03271      */
03272     template <typename T, typename U>
03273     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03274         "Replaced by simple assignment 'Callback cb = func")
03275     void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
03276         this->~Callback();
03277         new (this) Callback(func, arg);
03278     }
03279 
03280     /** Attach a function object
03281      *  @param f Function object to attach
03282      *  @note The function object is limited to a single word of storage
03283      *  @deprecated
03284      *      Replaced by simple assignment 'Callback cb = func'
03285      */
03286     template <typename F>
03287     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03288         "Replaced by simple assignment 'Callback cb = func")
03289     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
03290         this->~Callback();
03291         new (this) Callback(f);
03292     }
03293 
03294     /** Attach a function object
03295      *  @param f Function object to attach
03296      *  @note The function object is limited to a single word of storage
03297      *  @deprecated
03298      *      Replaced by simple assignment 'Callback cb = func'
03299      */
03300     template <typename F>
03301     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03302         "Replaced by simple assignment 'Callback cb = func")
03303     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
03304         this->~Callback();
03305         new (this) Callback(f);
03306     }
03307 
03308     /** Attach a function object
03309      *  @param f Function object to attach
03310      *  @note The function object is limited to a single word of storage
03311      *  @deprecated
03312      *      Replaced by simple assignment 'Callback cb = func'
03313      */
03314     template <typename F>
03315     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03316         "Replaced by simple assignment 'Callback cb = func")
03317     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
03318         this->~Callback();
03319         new (this) Callback(f);
03320     }
03321 
03322     /** Attach a function object
03323      *  @param f Function object to attach
03324      *  @note The function object is limited to a single word of storage
03325      *  @deprecated
03326      *      Replaced by simple assignment 'Callback cb = func'
03327      */
03328     template <typename F>
03329     MBED_DEPRECATED_SINCE("mbed-os-5.4",
03330         "Replaced by simple assignment 'Callback cb = func")
03331     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
03332         this->~Callback();
03333         new (this) Callback(f);
03334     }
03335 
03336     /** Attach a static function with a bound pointer
03337      *  @param obj  Pointer to object to bind to function
03338      *  @param func Static function to attach
03339      *  @deprecated
03340      *      Arguments to callback have been reordered to attach(func, arg)
03341      */
03342     template <typename T, typename U>
03343     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03344         "Arguments to callback have been reordered to attach(func, arg)")
03345     void attach(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
03346         this->~Callback();
03347         new (this) Callback(func, obj);
03348     }
03349 
03350     /** Attach a static function with a bound pointer
03351      *  @param obj  Pointer to object to bind to function
03352      *  @param func Static function to attach
03353      *  @deprecated
03354      *      Arguments to callback have been reordered to attach(func, arg)
03355      */
03356     template <typename T, typename U>
03357     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03358         "Arguments to callback have been reordered to attach(func, arg)")
03359     void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
03360         this->~Callback();
03361         new (this) Callback(func, obj);
03362     }
03363 
03364     /** Attach a static function with a bound pointer
03365      *  @param obj  Pointer to object to bind to function
03366      *  @param func Static function to attach
03367      *  @deprecated
03368      *      Arguments to callback have been reordered to attach(func, arg)
03369      */
03370     template <typename T, typename U>
03371     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03372         "Arguments to callback have been reordered to attach(func, arg)")
03373     void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
03374         this->~Callback();
03375         new (this) Callback(func, obj);
03376     }
03377 
03378     /** Attach a static function with a bound pointer
03379      *  @param obj  Pointer to object to bind to function
03380      *  @param func Static function to attach
03381      *  @deprecated
03382      *      Arguments to callback have been reordered to attach(func, arg)
03383      */
03384     template <typename T, typename U>
03385     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03386         "Arguments to callback have been reordered to attach(func, arg)")
03387     void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
03388         this->~Callback();
03389         new (this) Callback(func, obj);
03390     }
03391 
03392     /** Assign a callback
03393      */
03394     Callback &operator=(const Callback &that) {
03395         if (this != &that) {
03396             this->~Callback();
03397             new (this) Callback(that);
03398         }
03399 
03400         return *this;
03401     }
03402 
03403     /** Call the attached function
03404      */
03405     R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
03406         MBED_ASSERT(_ops);
03407         return _ops->call(this, a0, a1, a2, a3, a4);
03408     }
03409 
03410     /** Call the attached function
03411      */
03412     R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
03413         return call(a0, a1, a2, a3, a4);
03414     }
03415 
03416     /** Test if function has been attached
03417      */
03418     operator bool() const {
03419         return _ops;
03420     }
03421 
03422     /** Test for equality
03423      */
03424     friend bool operator==(const Callback &l, const Callback &r) {
03425         return memcmp(&l, &r, sizeof(Callback)) == 0;
03426     }
03427 
03428     /** Test for inequality
03429      */
03430     friend bool operator!=(const Callback &l, const Callback &r) {
03431         return !(l == r);
03432     }
03433 
03434     /** Static thunk for passing as C-style function
03435      *  @param func Callback to call passed as void pointer
03436      *  @param a0 An argument to be called with function func
03437      *  @param a1 An argument to be called with function func
03438      *  @param a2 An argument to be called with function func
03439      *  @param a3 An argument to be called with function func
03440      *  @param a4 An argument to be called with function func
03441      *  @return the value as determined by func which is of 
03442      *      type and determined by the signiture of func
03443      */
03444     static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
03445         return static_cast<Callback*>(func)->call(a0, a1, a2, a3, a4);
03446     }
03447 
03448 private:
03449     // Stored as pointer to function and pointer to optional object
03450     // Function pointer is stored as union of possible function types
03451     // to garuntee proper size and alignment
03452     struct _class;
03453     union {
03454         void (*_staticfunc)(A0, A1, A2, A3, A4);
03455         void (*_boundfunc)(_class*, A0, A1, A2, A3, A4);
03456         void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
03457     } _func;
03458     void *_obj;
03459 
03460     // Dynamically dispatched operations
03461     const struct ops {
03462         R (*call)(const void*, A0, A1, A2, A3, A4);
03463         void (*move)(void*, const void*);
03464         void (*dtor)(void*);
03465     } *_ops;
03466 
03467     // Generate operations for function object
03468     template <typename F>
03469     void generate(const F &f) {
03470         static const ops ops = {
03471             &Callback::function_call<F>,
03472             &Callback::function_move<F>,
03473             &Callback::function_dtor<F>,
03474         };
03475 
03476         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
03477                 "Type F must not exceed the size of the Callback class");
03478         new (this) F(f);
03479         _ops = &ops;
03480     }
03481 
03482     // Function attributes
03483     template <typename F>
03484     static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
03485         return (*(F*)p)(a0, a1, a2, a3, a4);
03486     }
03487 
03488     template <typename F>
03489     static void function_move(void *d, const void *p) {
03490         new (d) F(*(F*)p);
03491     }
03492 
03493     template <typename F>
03494     static void function_dtor(void *p) {
03495         ((F*)p)->~F();
03496     }
03497 
03498     // Wrappers for functions with context
03499     template <typename O, typename M>
03500     struct method_context {
03501         M method;
03502         O *obj;
03503 
03504         method_context(O *obj, M method)
03505             : method(method), obj(obj) {}
03506 
03507         R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
03508             return (obj->*method)(a0, a1, a2, a3, a4);
03509         }
03510     };
03511 
03512     template <typename F, typename A>
03513     struct function_context {
03514         F func;
03515         A *arg;
03516 
03517         function_context(F func, A *arg)
03518             : func(func), arg(arg) {}
03519 
03520         R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
03521             return func(arg, a0, a1, a2, a3, a4);
03522         }
03523     };
03524 };
03525 
03526 // Internally used event type
03527 typedef Callback<void(int)> event_callback_t;
03528 
03529 
03530 /** Create a callback class with type infered from the arguments
03531  *
03532  *  @param func     Static function to attach
03533  *  @return         Callback with infered type
03534  */
03535 template <typename R>
03536 Callback<R()> callback(R (*func)() = 0) {
03537     return Callback<R()>(func);
03538 }
03539 
03540 /** Create a callback class with type infered from the arguments
03541  *
03542  *  @param func     Static function to attach
03543  *  @return         Callback with infered type
03544  */
03545 template <typename R>
03546 Callback<R()> callback(const Callback<R()> &func) {
03547     return Callback<R()>(func);
03548 }
03549 
03550 /** Create a callback class with type infered from the arguments
03551  *
03552  *  @param obj      Optional pointer to object to bind to function
03553  *  @param method   Member function to attach
03554  *  @return         Callback with infered type
03555  */
03556 template<typename T, typename U, typename R>
03557 Callback<R()> callback(U *obj, R (T::*method)()) {
03558     return Callback<R()>(obj, method);
03559 }
03560 
03561 /** Create a callback class with type infered from the arguments
03562  *
03563  *  @param obj      Optional pointer to object to bind to function
03564  *  @param method   Member function to attach
03565  *  @return         Callback with infered type
03566  */
03567 template<typename T, typename U, typename R>
03568 Callback<R()> callback(const U *obj, R (T::*method)() const) {
03569     return Callback<R()>(obj, method);
03570 }
03571 
03572 /** Create a callback class with type infered from the arguments
03573  *
03574  *  @param obj      Optional pointer to object to bind to function
03575  *  @param method   Member function to attach
03576  *  @return         Callback with infered type
03577  */
03578 template<typename T, typename U, typename R>
03579 Callback<R()> callback(volatile U *obj, R (T::*method)() volatile) {
03580     return Callback<R()>(obj, method);
03581 }
03582 
03583 /** Create a callback class with type infered from the arguments
03584  *
03585  *  @param obj      Optional pointer to object to bind to function
03586  *  @param method   Member function to attach
03587  *  @return         Callback with infered type
03588  */
03589 template<typename T, typename U, typename R>
03590 Callback<R()> callback(const volatile U *obj, R (T::*method)() const volatile) {
03591     return Callback<R()>(obj, method);
03592 }
03593 
03594 /** Create a callback class with type infered from the arguments
03595  *
03596  *  @param func     Static function to attach
03597  *  @param arg      Pointer argument to function
03598  *  @return         Callback with infered type
03599  */
03600 template <typename T, typename U, typename R>
03601 Callback<R()> callback(R (*func)(T*), U *arg) {
03602     return Callback<R()>(func, arg);
03603 }
03604 
03605 /** Create a callback class with type infered from the arguments
03606  *
03607  *  @param func     Static function to attach
03608  *  @param arg      Pointer argument to function
03609  *  @return         Callback with infered type
03610  */
03611 template <typename T, typename U, typename R>
03612 Callback<R()> callback(R (*func)(const T*), const U *arg) {
03613     return Callback<R()>(func, arg);
03614 }
03615 
03616 /** Create a callback class with type infered from the arguments
03617  *
03618  *  @param func     Static function to attach
03619  *  @param arg      Pointer argument to function
03620  *  @return         Callback with infered type
03621  */
03622 template <typename T, typename U, typename R>
03623 Callback<R()> callback(R (*func)(volatile T*), volatile U *arg) {
03624     return Callback<R()>(func, arg);
03625 }
03626 
03627 /** Create a callback class with type infered from the arguments
03628  *
03629  *  @param func     Static function to attach
03630  *  @param arg      Pointer argument to function
03631  *  @return         Callback with infered type
03632  */
03633 template <typename T, typename U, typename R>
03634 Callback<R()> callback(R (*func)(const volatile T*), const volatile U *arg) {
03635     return Callback<R()>(func, arg);
03636 }
03637 
03638 /** Create a callback class with type infered from the arguments
03639  *
03640  *  @param obj  Optional pointer to object to bind to function
03641  *  @param func Static function to attach
03642  *  @return     Callback with infered type
03643  *  @deprecated
03644  *      Arguments to callback have been reordered to callback(func, arg)
03645  */
03646 template <typename T, typename U, typename R>
03647 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03648     "Arguments to callback have been reordered to callback(func, arg)")
03649 Callback<R()> callback(U *obj, R (*func)(T*)) {
03650     return Callback<R()>(func, obj);
03651 }
03652 
03653 /** Create a callback class with type infered from the arguments
03654  *
03655  *  @param obj  Optional pointer to object to bind to function
03656  *  @param func Static function to attach
03657  *  @return     Callback with infered type
03658  *  @deprecated
03659  *      Arguments to callback have been reordered to callback(func, arg)
03660  */
03661 template <typename T, typename U, typename R>
03662 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03663     "Arguments to callback have been reordered to callback(func, arg)")
03664 Callback<R()> callback(const U *obj, R (*func)(const T*)) {
03665     return Callback<R()>(func, obj);
03666 }
03667 
03668 /** Create a callback class with type infered from the arguments
03669  *
03670  *  @param obj  Optional pointer to object to bind to function
03671  *  @param func Static function to attach
03672  *  @return     Callback with infered type
03673  *  @deprecated
03674  *      Arguments to callback have been reordered to callback(func, arg)
03675  */
03676 template <typename T, typename U, typename R>
03677 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03678     "Arguments to callback have been reordered to callback(func, arg)")
03679 Callback<R()> callback(volatile U *obj, R (*func)(volatile T*)) {
03680     return Callback<R()>(func, obj);
03681 }
03682 
03683 /** Create a callback class with type infered from the arguments
03684  *
03685  *  @param obj  Optional pointer to object to bind to function
03686  *  @param func Static function to attach
03687  *  @return     Callback with infered type
03688  *  @deprecated
03689  *      Arguments to callback have been reordered to callback(func, arg)
03690  */
03691 template <typename T, typename U, typename R>
03692 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03693     "Arguments to callback have been reordered to callback(func, arg)")
03694 Callback<R()> callback(const volatile U *obj, R (*func)(const volatile T*)) {
03695     return Callback<R()>(func, obj);
03696 }
03697 
03698 
03699 /** Create a callback class with type infered from the arguments
03700  *
03701  *  @param func     Static function to attach
03702  *  @return         Callback with infered type
03703  */
03704 template <typename R, typename A0>
03705 Callback<R(A0)> callback(R (*func)(A0) = 0) {
03706     return Callback<R(A0)>(func);
03707 }
03708 
03709 /** Create a callback class with type infered from the arguments
03710  *
03711  *  @param func     Static function to attach
03712  *  @return         Callback with infered type
03713  */
03714 template <typename R, typename A0>
03715 Callback<R(A0)> callback(const Callback<R(A0)> &func) {
03716     return Callback<R(A0)>(func);
03717 }
03718 
03719 /** Create a callback class with type infered from the arguments
03720  *
03721  *  @param obj      Optional pointer to object to bind to function
03722  *  @param method   Member function to attach
03723  *  @return         Callback with infered type
03724  */
03725 template<typename T, typename U, typename R, typename A0>
03726 Callback<R(A0)> callback(U *obj, R (T::*method)(A0)) {
03727     return Callback<R(A0)>(obj, method);
03728 }
03729 
03730 /** Create a callback class with type infered from the arguments
03731  *
03732  *  @param obj      Optional pointer to object to bind to function
03733  *  @param method   Member function to attach
03734  *  @return         Callback with infered type
03735  */
03736 template<typename T, typename U, typename R, typename A0>
03737 Callback<R(A0)> callback(const U *obj, R (T::*method)(A0) const) {
03738     return Callback<R(A0)>(obj, method);
03739 }
03740 
03741 /** Create a callback class with type infered from the arguments
03742  *
03743  *  @param obj      Optional pointer to object to bind to function
03744  *  @param method   Member function to attach
03745  *  @return         Callback with infered type
03746  */
03747 template<typename T, typename U, typename R, typename A0>
03748 Callback<R(A0)> callback(volatile U *obj, R (T::*method)(A0) volatile) {
03749     return Callback<R(A0)>(obj, method);
03750 }
03751 
03752 /** Create a callback class with type infered from the arguments
03753  *
03754  *  @param obj      Optional pointer to object to bind to function
03755  *  @param method   Member function to attach
03756  *  @return         Callback with infered type
03757  */
03758 template<typename T, typename U, typename R, typename A0>
03759 Callback<R(A0)> callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
03760     return Callback<R(A0)>(obj, method);
03761 }
03762 
03763 /** Create a callback class with type infered from the arguments
03764  *
03765  *  @param func     Static function to attach
03766  *  @param arg      Pointer argument to function
03767  *  @return         Callback with infered type
03768  */
03769 template <typename T, typename U, typename R, typename A0>
03770 Callback<R(A0)> callback(R (*func)(T*, A0), U *arg) {
03771     return Callback<R(A0)>(func, arg);
03772 }
03773 
03774 /** Create a callback class with type infered from the arguments
03775  *
03776  *  @param func     Static function to attach
03777  *  @param arg      Pointer argument to function
03778  *  @return         Callback with infered type
03779  */
03780 template <typename T, typename U, typename R, typename A0>
03781 Callback<R(A0)> callback(R (*func)(const T*, A0), const U *arg) {
03782     return Callback<R(A0)>(func, arg);
03783 }
03784 
03785 /** Create a callback class with type infered from the arguments
03786  *
03787  *  @param func     Static function to attach
03788  *  @param arg      Pointer argument to function
03789  *  @return         Callback with infered type
03790  */
03791 template <typename T, typename U, typename R, typename A0>
03792 Callback<R(A0)> callback(R (*func)(volatile T*, A0), volatile U *arg) {
03793     return Callback<R(A0)>(func, arg);
03794 }
03795 
03796 /** Create a callback class with type infered from the arguments
03797  *
03798  *  @param func     Static function to attach
03799  *  @param arg      Pointer argument to function
03800  *  @return         Callback with infered type
03801  */
03802 template <typename T, typename U, typename R, typename A0>
03803 Callback<R(A0)> callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
03804     return Callback<R(A0)>(func, arg);
03805 }
03806 
03807 /** Create a callback class with type infered from the arguments
03808  *
03809  *  @param obj  Optional pointer to object to bind to function
03810  *  @param func Static function to attach
03811  *  @return     Callback with infered type
03812  *  @deprecated
03813  *      Arguments to callback have been reordered to callback(func, arg)
03814  */
03815 template <typename T, typename U, typename R, typename A0>
03816 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03817     "Arguments to callback have been reordered to callback(func, arg)")
03818 Callback<R(A0)> callback(U *obj, R (*func)(T*, A0)) {
03819     return Callback<R(A0)>(func, obj);
03820 }
03821 
03822 /** Create a callback class with type infered from the arguments
03823  *
03824  *  @param obj  Optional pointer to object to bind to function
03825  *  @param func Static function to attach
03826  *  @return     Callback with infered type
03827  *  @deprecated
03828  *      Arguments to callback have been reordered to callback(func, arg)
03829  */
03830 template <typename T, typename U, typename R, typename A0>
03831 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03832     "Arguments to callback have been reordered to callback(func, arg)")
03833 Callback<R(A0)> callback(const U *obj, R (*func)(const T*, A0)) {
03834     return Callback<R(A0)>(func, obj);
03835 }
03836 
03837 /** Create a callback class with type infered from the arguments
03838  *
03839  *  @param obj  Optional pointer to object to bind to function
03840  *  @param func Static function to attach
03841  *  @return     Callback with infered type
03842  *  @deprecated
03843  *      Arguments to callback have been reordered to callback(func, arg)
03844  */
03845 template <typename T, typename U, typename R, typename A0>
03846 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03847     "Arguments to callback have been reordered to callback(func, arg)")
03848 Callback<R(A0)> callback(volatile U *obj, R (*func)(volatile T*, A0)) {
03849     return Callback<R(A0)>(func, obj);
03850 }
03851 
03852 /** Create a callback class with type infered from the arguments
03853  *
03854  *  @param obj  Optional pointer to object to bind to function
03855  *  @param func Static function to attach
03856  *  @return     Callback with infered type
03857  *  @deprecated
03858  *      Arguments to callback have been reordered to callback(func, arg)
03859  */
03860 template <typename T, typename U, typename R, typename A0>
03861 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03862     "Arguments to callback have been reordered to callback(func, arg)")
03863 Callback<R(A0)> callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
03864     return Callback<R(A0)>(func, obj);
03865 }
03866 
03867 
03868 /** Create a callback class with type infered from the arguments
03869  *
03870  *  @param func     Static function to attach
03871  *  @return         Callback with infered type
03872  */
03873 template <typename R, typename A0, typename A1>
03874 Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
03875     return Callback<R(A0, A1)>(func);
03876 }
03877 
03878 /** Create a callback class with type infered from the arguments
03879  *
03880  *  @param func     Static function to attach
03881  *  @return         Callback with infered type
03882  */
03883 template <typename R, typename A0, typename A1>
03884 Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
03885     return Callback<R(A0, A1)>(func);
03886 }
03887 
03888 /** Create a callback class with type infered from the arguments
03889  *
03890  *  @param obj      Optional pointer to object to bind to function
03891  *  @param method   Member function to attach
03892  *  @return         Callback with infered type
03893  */
03894 template<typename T, typename U, typename R, typename A0, typename A1>
03895 Callback<R(A0, A1)> callback(U *obj, R (T::*method)(A0, A1)) {
03896     return Callback<R(A0, A1)>(obj, method);
03897 }
03898 
03899 /** Create a callback class with type infered from the arguments
03900  *
03901  *  @param obj      Optional pointer to object to bind to function
03902  *  @param method   Member function to attach
03903  *  @return         Callback with infered type
03904  */
03905 template<typename T, typename U, typename R, typename A0, typename A1>
03906 Callback<R(A0, A1)> callback(const U *obj, R (T::*method)(A0, A1) const) {
03907     return Callback<R(A0, A1)>(obj, method);
03908 }
03909 
03910 /** Create a callback class with type infered from the arguments
03911  *
03912  *  @param obj      Optional pointer to object to bind to function
03913  *  @param method   Member function to attach
03914  *  @return         Callback with infered type
03915  */
03916 template<typename T, typename U, typename R, typename A0, typename A1>
03917 Callback<R(A0, A1)> callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
03918     return Callback<R(A0, A1)>(obj, method);
03919 }
03920 
03921 /** Create a callback class with type infered from the arguments
03922  *
03923  *  @param obj      Optional pointer to object to bind to function
03924  *  @param method   Member function to attach
03925  *  @return         Callback with infered type
03926  */
03927 template<typename T, typename U, typename R, typename A0, typename A1>
03928 Callback<R(A0, A1)> callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
03929     return Callback<R(A0, A1)>(obj, method);
03930 }
03931 
03932 /** Create a callback class with type infered from the arguments
03933  *
03934  *  @param func     Static function to attach
03935  *  @param arg      Pointer argument to function
03936  *  @return         Callback with infered type
03937  */
03938 template <typename T, typename U, typename R, typename A0, typename A1>
03939 Callback<R(A0, A1)> callback(R (*func)(T*, A0, A1), U *arg) {
03940     return Callback<R(A0, A1)>(func, arg);
03941 }
03942 
03943 /** Create a callback class with type infered from the arguments
03944  *
03945  *  @param func     Static function to attach
03946  *  @param arg      Pointer argument to function
03947  *  @return         Callback with infered type
03948  */
03949 template <typename T, typename U, typename R, typename A0, typename A1>
03950 Callback<R(A0, A1)> callback(R (*func)(const T*, A0, A1), const U *arg) {
03951     return Callback<R(A0, A1)>(func, arg);
03952 }
03953 
03954 /** Create a callback class with type infered from the arguments
03955  *
03956  *  @param func     Static function to attach
03957  *  @param arg      Pointer argument to function
03958  *  @return         Callback with infered type
03959  */
03960 template <typename T, typename U, typename R, typename A0, typename A1>
03961 Callback<R(A0, A1)> callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
03962     return Callback<R(A0, A1)>(func, arg);
03963 }
03964 
03965 /** Create a callback class with type infered from the arguments
03966  *
03967  *  @param func     Static function to attach
03968  *  @param arg      Pointer argument to function
03969  *  @return         Callback with infered type
03970  */
03971 template <typename T, typename U, typename R, typename A0, typename A1>
03972 Callback<R(A0, A1)> callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
03973     return Callback<R(A0, A1)>(func, arg);
03974 }
03975 
03976 /** Create a callback class with type infered from the arguments
03977  *
03978  *  @param obj  Optional pointer to object to bind to function
03979  *  @param func Static function to attach
03980  *  @return     Callback with infered type
03981  *  @deprecated
03982  *      Arguments to callback have been reordered to callback(func, arg)
03983  */
03984 template <typename T, typename U, typename R, typename A0, typename A1>
03985 MBED_DEPRECATED_SINCE("mbed-os-5.1",
03986     "Arguments to callback have been reordered to callback(func, arg)")
03987 Callback<R(A0, A1)> callback(U *obj, R (*func)(T*, A0, A1)) {
03988     return Callback<R(A0, A1)>(func, obj);
03989 }
03990 
03991 /** Create a callback class with type infered from the arguments
03992  *
03993  *  @param obj  Optional pointer to object to bind to function
03994  *  @param func Static function to attach
03995  *  @return     Callback with infered type
03996  *  @deprecated
03997  *      Arguments to callback have been reordered to callback(func, arg)
03998  */
03999 template <typename T, typename U, typename R, typename A0, typename A1>
04000 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04001     "Arguments to callback have been reordered to callback(func, arg)")
04002 Callback<R(A0, A1)> callback(const U *obj, R (*func)(const T*, A0, A1)) {
04003     return Callback<R(A0, A1)>(func, obj);
04004 }
04005 
04006 /** Create a callback class with type infered from the arguments
04007  *
04008  *  @param obj  Optional pointer to object to bind to function
04009  *  @param func Static function to attach
04010  *  @return     Callback with infered type
04011  *  @deprecated
04012  *      Arguments to callback have been reordered to callback(func, arg)
04013  */
04014 template <typename T, typename U, typename R, typename A0, typename A1>
04015 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04016     "Arguments to callback have been reordered to callback(func, arg)")
04017 Callback<R(A0, A1)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
04018     return Callback<R(A0, A1)>(func, obj);
04019 }
04020 
04021 /** Create a callback class with type infered from the arguments
04022  *
04023  *  @param obj  Optional pointer to object to bind to function
04024  *  @param func Static function to attach
04025  *  @return     Callback with infered type
04026  *  @deprecated
04027  *      Arguments to callback have been reordered to callback(func, arg)
04028  */
04029 template <typename T, typename U, typename R, typename A0, typename A1>
04030 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04031     "Arguments to callback have been reordered to callback(func, arg)")
04032 Callback<R(A0, A1)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
04033     return Callback<R(A0, A1)>(func, obj);
04034 }
04035 
04036 
04037 /** Create a callback class with type infered from the arguments
04038  *
04039  *  @param func     Static function to attach
04040  *  @return         Callback with infered type
04041  */
04042 template <typename R, typename A0, typename A1, typename A2>
04043 Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
04044     return Callback<R(A0, A1, A2)>(func);
04045 }
04046 
04047 /** Create a callback class with type infered from the arguments
04048  *
04049  *  @param func     Static function to attach
04050  *  @return         Callback with infered type
04051  */
04052 template <typename R, typename A0, typename A1, typename A2>
04053 Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
04054     return Callback<R(A0, A1, A2)>(func);
04055 }
04056 
04057 /** Create a callback class with type infered from the arguments
04058  *
04059  *  @param obj      Optional pointer to object to bind to function
04060  *  @param method   Member function to attach
04061  *  @return         Callback with infered type
04062  */
04063 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
04064 Callback<R(A0, A1, A2)> callback(U *obj, R (T::*method)(A0, A1, A2)) {
04065     return Callback<R(A0, A1, A2)>(obj, method);
04066 }
04067 
04068 /** Create a callback class with type infered from the arguments
04069  *
04070  *  @param obj      Optional pointer to object to bind to function
04071  *  @param method   Member function to attach
04072  *  @return         Callback with infered type
04073  */
04074 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
04075 Callback<R(A0, A1, A2)> callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
04076     return Callback<R(A0, A1, A2)>(obj, method);
04077 }
04078 
04079 /** Create a callback class with type infered from the arguments
04080  *
04081  *  @param obj      Optional pointer to object to bind to function
04082  *  @param method   Member function to attach
04083  *  @return         Callback with infered type
04084  */
04085 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
04086 Callback<R(A0, A1, A2)> callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
04087     return Callback<R(A0, A1, A2)>(obj, method);
04088 }
04089 
04090 /** Create a callback class with type infered from the arguments
04091  *
04092  *  @param obj      Optional pointer to object to bind to function
04093  *  @param method   Member function to attach
04094  *  @return         Callback with infered type
04095  */
04096 template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
04097 Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
04098     return Callback<R(A0, A1, A2)>(obj, method);
04099 }
04100 
04101 /** Create a callback class with type infered from the arguments
04102  *
04103  *  @param func     Static function to attach
04104  *  @param arg      Pointer argument to function
04105  *  @return         Callback with infered type
04106  */
04107 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04108 Callback<R(A0, A1, A2)> callback(R (*func)(T*, A0, A1, A2), U *arg) {
04109     return Callback<R(A0, A1, A2)>(func, arg);
04110 }
04111 
04112 /** Create a callback class with type infered from the arguments
04113  *
04114  *  @param func     Static function to attach
04115  *  @param arg      Pointer argument to function
04116  *  @return         Callback with infered type
04117  */
04118 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04119 Callback<R(A0, A1, A2)> callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
04120     return Callback<R(A0, A1, A2)>(func, arg);
04121 }
04122 
04123 /** Create a callback class with type infered from the arguments
04124  *
04125  *  @param func     Static function to attach
04126  *  @param arg      Pointer argument to function
04127  *  @return         Callback with infered type
04128  */
04129 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04130 Callback<R(A0, A1, A2)> callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
04131     return Callback<R(A0, A1, A2)>(func, arg);
04132 }
04133 
04134 /** Create a callback class with type infered from the arguments
04135  *
04136  *  @param func     Static function to attach
04137  *  @param arg      Pointer argument to function
04138  *  @return         Callback with infered type
04139  */
04140 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04141 Callback<R(A0, A1, A2)> callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
04142     return Callback<R(A0, A1, A2)>(func, arg);
04143 }
04144 
04145 /** Create a callback class with type infered from the arguments
04146  *
04147  *  @param obj  Optional pointer to object to bind to function
04148  *  @param func Static function to attach
04149  *  @return     Callback with infered type
04150  *  @deprecated
04151  *      Arguments to callback have been reordered to callback(func, arg)
04152  */
04153 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04154 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04155     "Arguments to callback have been reordered to callback(func, arg)")
04156 Callback<R(A0, A1, A2)> callback(U *obj, R (*func)(T*, A0, A1, A2)) {
04157     return Callback<R(A0, A1, A2)>(func, obj);
04158 }
04159 
04160 /** Create a callback class with type infered from the arguments
04161  *
04162  *  @param obj  Optional pointer to object to bind to function
04163  *  @param func Static function to attach
04164  *  @return     Callback with infered type
04165  *  @deprecated
04166  *      Arguments to callback have been reordered to callback(func, arg)
04167  */
04168 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04169 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04170     "Arguments to callback have been reordered to callback(func, arg)")
04171 Callback<R(A0, A1, A2)> callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
04172     return Callback<R(A0, A1, A2)>(func, obj);
04173 }
04174 
04175 /** Create a callback class with type infered from the arguments
04176  *
04177  *  @param obj  Optional pointer to object to bind to function
04178  *  @param func Static function to attach
04179  *  @return     Callback with infered type
04180  *  @deprecated
04181  *      Arguments to callback have been reordered to callback(func, arg)
04182  */
04183 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04184 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04185     "Arguments to callback have been reordered to callback(func, arg)")
04186 Callback<R(A0, A1, A2)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
04187     return Callback<R(A0, A1, A2)>(func, obj);
04188 }
04189 
04190 /** Create a callback class with type infered from the arguments
04191  *
04192  *  @param obj  Optional pointer to object to bind to function
04193  *  @param func Static function to attach
04194  *  @return     Callback with infered type
04195  *  @deprecated
04196  *      Arguments to callback have been reordered to callback(func, arg)
04197  */
04198 template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
04199 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04200     "Arguments to callback have been reordered to callback(func, arg)")
04201 Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
04202     return Callback<R(A0, A1, A2)>(func, obj);
04203 }
04204 
04205 
04206 /** Create a callback class with type infered from the arguments
04207  *
04208  *  @param func     Static function to attach
04209  *  @return         Callback with infered type
04210  */
04211 template <typename R, typename A0, typename A1, typename A2, typename A3>
04212 Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
04213     return Callback<R(A0, A1, A2, A3)>(func);
04214 }
04215 
04216 /** Create a callback class with type infered from the arguments
04217  *
04218  *  @param func     Static function to attach
04219  *  @return         Callback with infered type
04220  */
04221 template <typename R, typename A0, typename A1, typename A2, typename A3>
04222 Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
04223     return Callback<R(A0, A1, A2, A3)>(func);
04224 }
04225 
04226 /** Create a callback class with type infered from the arguments
04227  *
04228  *  @param obj      Optional pointer to object to bind to function
04229  *  @param method   Member function to attach
04230  *  @return         Callback with infered type
04231  */
04232 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04233 Callback<R(A0, A1, A2, A3)> callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
04234     return Callback<R(A0, A1, A2, A3)>(obj, method);
04235 }
04236 
04237 /** Create a callback class with type infered from the arguments
04238  *
04239  *  @param obj      Optional pointer to object to bind to function
04240  *  @param method   Member function to attach
04241  *  @return         Callback with infered type
04242  */
04243 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04244 Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
04245     return Callback<R(A0, A1, A2, A3)>(obj, method);
04246 }
04247 
04248 /** Create a callback class with type infered from the arguments
04249  *
04250  *  @param obj      Optional pointer to object to bind to function
04251  *  @param method   Member function to attach
04252  *  @return         Callback with infered type
04253  */
04254 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04255 Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
04256     return Callback<R(A0, A1, A2, A3)>(obj, method);
04257 }
04258 
04259 /** Create a callback class with type infered from the arguments
04260  *
04261  *  @param obj      Optional pointer to object to bind to function
04262  *  @param method   Member function to attach
04263  *  @return         Callback with infered type
04264  */
04265 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04266 Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
04267     return Callback<R(A0, A1, A2, A3)>(obj, method);
04268 }
04269 
04270 /** Create a callback class with type infered from the arguments
04271  *
04272  *  @param func     Static function to attach
04273  *  @param arg      Pointer argument to function
04274  *  @return         Callback with infered type
04275  */
04276 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04277 Callback<R(A0, A1, A2, A3)> callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
04278     return Callback<R(A0, A1, A2, A3)>(func, arg);
04279 }
04280 
04281 /** Create a callback class with type infered from the arguments
04282  *
04283  *  @param func     Static function to attach
04284  *  @param arg      Pointer argument to function
04285  *  @return         Callback with infered type
04286  */
04287 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04288 Callback<R(A0, A1, A2, A3)> callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
04289     return Callback<R(A0, A1, A2, A3)>(func, arg);
04290 }
04291 
04292 /** Create a callback class with type infered from the arguments
04293  *
04294  *  @param func     Static function to attach
04295  *  @param arg      Pointer argument to function
04296  *  @return         Callback with infered type
04297  */
04298 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04299 Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
04300     return Callback<R(A0, A1, A2, A3)>(func, arg);
04301 }
04302 
04303 /** Create a callback class with type infered from the arguments
04304  *
04305  *  @param func     Static function to attach
04306  *  @param arg      Pointer argument to function
04307  *  @return         Callback with infered type
04308  */
04309 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04310 Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
04311     return Callback<R(A0, A1, A2, A3)>(func, arg);
04312 }
04313 
04314 /** Create a callback class with type infered from the arguments
04315  *
04316  *  @param obj  Optional pointer to object to bind to function
04317  *  @param func Static function to attach
04318  *  @return     Callback with infered type
04319  *  @deprecated
04320  *      Arguments to callback have been reordered to callback(func, arg)
04321  */
04322 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04323 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04324     "Arguments to callback have been reordered to callback(func, arg)")
04325 Callback<R(A0, A1, A2, A3)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
04326     return Callback<R(A0, A1, A2, A3)>(func, obj);
04327 }
04328 
04329 /** Create a callback class with type infered from the arguments
04330  *
04331  *  @param obj  Optional pointer to object to bind to function
04332  *  @param func Static function to attach
04333  *  @return     Callback with infered type
04334  *  @deprecated
04335  *      Arguments to callback have been reordered to callback(func, arg)
04336  */
04337 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04338 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04339     "Arguments to callback have been reordered to callback(func, arg)")
04340 Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
04341     return Callback<R(A0, A1, A2, A3)>(func, obj);
04342 }
04343 
04344 /** Create a callback class with type infered from the arguments
04345  *
04346  *  @param obj  Optional pointer to object to bind to function
04347  *  @param func Static function to attach
04348  *  @return     Callback with infered type
04349  *  @deprecated
04350  *      Arguments to callback have been reordered to callback(func, arg)
04351  */
04352 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04353 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04354     "Arguments to callback have been reordered to callback(func, arg)")
04355 Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
04356     return Callback<R(A0, A1, A2, A3)>(func, obj);
04357 }
04358 
04359 /** Create a callback class with type infered from the arguments
04360  *
04361  *  @param obj  Optional pointer to object to bind to function
04362  *  @param func Static function to attach
04363  *  @return     Callback with infered type
04364  *  @deprecated
04365  *      Arguments to callback have been reordered to callback(func, arg)
04366  */
04367 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
04368 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04369     "Arguments to callback have been reordered to callback(func, arg)")
04370 Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
04371     return Callback<R(A0, A1, A2, A3)>(func, obj);
04372 }
04373 
04374 
04375 /** Create a callback class with type infered from the arguments
04376  *
04377  *  @param func     Static function to attach
04378  *  @return         Callback with infered type
04379  */
04380 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04381 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
04382     return Callback<R(A0, A1, A2, A3, A4)>(func);
04383 }
04384 
04385 /** Create a callback class with type infered from the arguments
04386  *
04387  *  @param func     Static function to attach
04388  *  @return         Callback with infered type
04389  */
04390 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04391 Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
04392     return Callback<R(A0, A1, A2, A3, A4)>(func);
04393 }
04394 
04395 /** Create a callback class with type infered from the arguments
04396  *
04397  *  @param obj      Optional pointer to object to bind to function
04398  *  @param method   Member function to attach
04399  *  @return         Callback with infered type
04400  */
04401 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04402 Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
04403     return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
04404 }
04405 
04406 /** Create a callback class with type infered from the arguments
04407  *
04408  *  @param obj      Optional pointer to object to bind to function
04409  *  @param method   Member function to attach
04410  *  @return         Callback with infered type
04411  */
04412 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04413 Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
04414     return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
04415 }
04416 
04417 /** Create a callback class with type infered from the arguments
04418  *
04419  *  @param obj      Optional pointer to object to bind to function
04420  *  @param method   Member function to attach
04421  *  @return         Callback with infered type
04422  */
04423 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04424 Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
04425     return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
04426 }
04427 
04428 /** Create a callback class with type infered from the arguments
04429  *
04430  *  @param obj      Optional pointer to object to bind to function
04431  *  @param method   Member function to attach
04432  *  @return         Callback with infered type
04433  */
04434 template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04435 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
04436     return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
04437 }
04438 
04439 /** Create a callback class with type infered from the arguments
04440  *
04441  *  @param func     Static function to attach
04442  *  @param arg      Pointer argument to function
04443  *  @return         Callback with infered type
04444  */
04445 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04446 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
04447     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
04448 }
04449 
04450 /** Create a callback class with type infered from the arguments
04451  *
04452  *  @param func     Static function to attach
04453  *  @param arg      Pointer argument to function
04454  *  @return         Callback with infered type
04455  */
04456 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04457 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
04458     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
04459 }
04460 
04461 /** Create a callback class with type infered from the arguments
04462  *
04463  *  @param func     Static function to attach
04464  *  @param arg      Pointer argument to function
04465  *  @return         Callback with infered type
04466  */
04467 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04468 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
04469     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
04470 }
04471 
04472 /** Create a callback class with type infered from the arguments
04473  *
04474  *  @param func     Static function to attach
04475  *  @param arg      Pointer argument to function
04476  *  @return         Callback with infered type
04477  */
04478 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04479 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
04480     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
04481 }
04482 
04483 /** Create a callback class with type infered from the arguments
04484  *
04485  *  @param obj  Optional pointer to object to bind to function
04486  *  @param func Static function to attach
04487  *  @return     Callback with infered type
04488  *  @deprecated
04489  *      Arguments to callback have been reordered to callback(func, arg)
04490  */
04491 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04492 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04493     "Arguments to callback have been reordered to callback(func, arg)")
04494 Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
04495     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
04496 }
04497 
04498 /** Create a callback class with type infered from the arguments
04499  *
04500  *  @param obj  Optional pointer to object to bind to function
04501  *  @param func Static function to attach
04502  *  @return     Callback with infered type
04503  *  @deprecated
04504  *      Arguments to callback have been reordered to callback(func, arg)
04505  */
04506 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04507 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04508     "Arguments to callback have been reordered to callback(func, arg)")
04509 Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
04510     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
04511 }
04512 
04513 /** Create a callback class with type infered from the arguments
04514  *
04515  *  @param obj  Optional pointer to object to bind to function
04516  *  @param func Static function to attach
04517  *  @return     Callback with infered type
04518  *  @deprecated
04519  *      Arguments to callback have been reordered to callback(func, arg)
04520  */
04521 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04522 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04523     "Arguments to callback have been reordered to callback(func, arg)")
04524 Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
04525     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
04526 }
04527 
04528 /** Create a callback class with type infered from the arguments
04529  *
04530  *  @param obj  Optional pointer to object to bind to function
04531  *  @param func Static function to attach
04532  *  @return     Callback with infered type
04533  *  @deprecated
04534  *      Arguments to callback have been reordered to callback(func, arg)
04535  */
04536 template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
04537 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04538     "Arguments to callback have been reordered to callback(func, arg)")
04539 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
04540     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
04541 }
04542 
04543 
04544 } // namespace mbed
04545 
04546 #endif