Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

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