update

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