takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Callback.h Source File

Callback.h

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