This is the final version of Mini Gateway for Automation and Security desgined for Renesas GR Peach Design Contest

Dependencies:   GR-PEACH_video GraphicsFramework HTTPServer R_BSP mbed-rpc mbed-rtos Socket lwip-eth lwip-sys lwip FATFileSystem

Fork of mbed-os-example-mbed5-blinky by mbed-os-examples

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