Ben Katz / mbed-dev_spine

Dependents:   SPIne CH_Communicatuin_Test CH_Communicatuin_Test2 MCP_SPIne ... more

Fork of mbed-dev-f303 by Ben Katz

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Callback.h Source File

Callback.h

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