Rtos API example

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