mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

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>
00094     Callback(T *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>
00103     Callback(const T *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>
00112     Callback(volatile T *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>
00121     Callback(const volatile T *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     Callback(R (*func)(void*), void *arg) {
00130         generate(function_context<R (*)(void*), void>(func, arg));
00131     }
00132 
00133     /** Create a Callback with a static function and bound pointer
00134      *  @param func     Static function to attach
00135      *  @param arg      Pointer argument to function
00136      */
00137     Callback(R (*func)(const void*), const void *arg) {
00138         generate(function_context<R (*)(const void*), const void>(func, arg));
00139     }
00140 
00141     /** Create a Callback with a static function and bound pointer
00142      *  @param func     Static function to attach
00143      *  @param arg      Pointer argument to function
00144      */
00145     Callback(R (*func)(volatile void*), volatile void *arg) {
00146         generate(function_context<R (*)(volatile void*), volatile void>(func, arg));
00147     }
00148 
00149     /** Create a Callback with a static function and bound pointer
00150      *  @param func     Static function to attach
00151      *  @param arg      Pointer argument to function
00152      */
00153     Callback(R (*func)(const volatile void*), const volatile void *arg) {
00154         generate(function_context<R (*)(const volatile void*), const volatile void>(func, arg));
00155     }
00156 
00157     /** Create a Callback with a static function and bound pointer
00158      *  @param func     Static function to attach
00159      *  @param arg      Pointer argument to function 
00160      */
00161     template<typename T>
00162     Callback(R (*func)(T*), T *arg) {
00163         generate(function_context<R (*)(T*), T>(func, arg));
00164     }
00165 
00166     /** Create a Callback with a static function and bound pointer
00167      *  @param func     Static function to attach
00168      *  @param arg      Pointer argument to function 
00169      */
00170     template<typename T>
00171     Callback(R (*func)(const T*), const T *arg) {
00172         generate(function_context<R (*)(const T*), const T>(func, arg));
00173     }
00174 
00175     /** Create a Callback with a static function and bound pointer
00176      *  @param func     Static function to attach
00177      *  @param arg      Pointer argument to function 
00178      */
00179     template<typename T>
00180     Callback(R (*func)(volatile T*), volatile T *arg) {
00181         generate(function_context<R (*)(volatile T*), volatile T>(func, arg));
00182     }
00183 
00184     /** Create a Callback with a static function and bound pointer
00185      *  @param func     Static function to attach
00186      *  @param arg      Pointer argument to function 
00187      */
00188     template<typename T>
00189     Callback(R (*func)(const volatile T*), const volatile T *arg) {
00190         generate(function_context<R (*)(const volatile T*), const volatile T>(func, arg));
00191     }
00192 
00193     /** Create a Callback with a function object
00194      *  @param func     Function object to attach
00195      *  @note The function object is limited to a single word of storage
00196      */
00197     template <typename F>
00198     Callback(F f, typename detail::enable_if<
00199                 detail::is_type<R (F::*)(), &F::operator()>::value &&
00200                 sizeof(F) <= sizeof(uintptr_t)
00201             >::type = detail::nil()) {
00202         generate(f);
00203     }
00204 
00205     /** Create a Callback with a function object
00206      *  @param func     Function object to attach
00207      *  @note The function object is limited to a single word of storage
00208      */
00209     template <typename F>
00210     Callback(const F f, typename detail::enable_if<
00211                 detail::is_type<R (F::*)() const, &F::operator()>::value &&
00212                 sizeof(F) <= sizeof(uintptr_t)
00213             >::type = detail::nil()) {
00214         generate(f);
00215     }
00216 
00217     /** Create a Callback with a function object
00218      *  @param func     Function object to attach
00219      *  @note The function object is limited to a single word of storage
00220      */
00221     template <typename F>
00222     Callback(volatile F f, typename detail::enable_if<
00223                 detail::is_type<R (F::*)() volatile, &F::operator()>::value &&
00224                 sizeof(F) <= sizeof(uintptr_t)
00225             >::type = detail::nil()) {
00226         generate(f);
00227     }
00228 
00229     /** Create a Callback with a function object
00230      *  @param func     Function object to attach
00231      *  @note The function object is limited to a single word of storage
00232      */
00233     template <typename F>
00234     Callback(const volatile F f, typename detail::enable_if<
00235                 detail::is_type<R (F::*)() const volatile, &F::operator()>::value &&
00236                 sizeof(F) <= sizeof(uintptr_t)
00237             >::type = detail::nil()) {
00238         generate(f);
00239     }
00240 
00241     /** Create a Callback with a static function and bound pointer
00242      *  @param obj  Pointer to object to bind to function
00243      *  @param func Static function to attach
00244      *  @deprecated
00245      *      Arguments to callback have been reordered to Callback(func, arg)
00246      */
00247     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00248         "Arguments to callback have been reordered to Callback(func, arg)")
00249     Callback(void *obj, R (*func)(void*)) {
00250         new (this) Callback(func, obj);
00251     }
00252 
00253     /** Create a Callback with a static function and bound pointer
00254      *  @param obj  Pointer to object to bind to function
00255      *  @param func Static function to attach
00256      *  @deprecated
00257      *      Arguments to callback have been reordered to Callback(func, arg)
00258      */
00259     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00260         "Arguments to callback have been reordered to Callback(func, arg)")
00261     Callback(const void *obj, R (*func)(const void*)) {
00262         new (this) Callback(func, obj);
00263     }
00264 
00265     /** Create a Callback with a static function and bound pointer
00266      *  @param obj  Pointer to object to bind to function
00267      *  @param func Static function to attach
00268      *  @deprecated
00269      *      Arguments to callback have been reordered to Callback(func, arg)
00270      */
00271     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00272         "Arguments to callback have been reordered to Callback(func, arg)")
00273     Callback(volatile void *obj, R (*func)(volatile void*)) {
00274         new (this) Callback(func, obj);
00275     }
00276 
00277     /** Create a Callback with a static function and bound pointer
00278      *  @param obj  Pointer to object to bind to function
00279      *  @param func Static function to attach
00280      *  @deprecated
00281      *      Arguments to callback have been reordered to Callback(func, arg)
00282      */
00283     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00284         "Arguments to callback have been reordered to Callback(func, arg)")
00285     Callback(const volatile void *obj, R (*func)(const volatile void*)) {
00286         new (this) Callback(func, obj);
00287     }
00288 
00289     /** Create a Callback with a static function and bound pointer
00290      *  @param obj  Pointer to object to bind to function
00291      *  @param func Static function to attach
00292      *  @deprecated
00293      *      Arguments to callback have been reordered to Callback(func, arg)
00294      */
00295     template<typename T>
00296     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00297         "Arguments to callback have been reordered to Callback(func, arg)")
00298     Callback(T *obj, R (*func)(T*)) {
00299         new (this) Callback(func, obj);
00300     }
00301 
00302     /** Create a Callback with a static function and bound pointer
00303      *  @param obj  Pointer to object to bind to function
00304      *  @param func Static function to attach
00305      *  @deprecated
00306      *      Arguments to callback have been reordered to Callback(func, arg)
00307      */
00308     template<typename T>
00309     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00310         "Arguments to callback have been reordered to Callback(func, arg)")
00311     Callback(const T *obj, R (*func)(const T*)) {
00312         new (this) Callback(func, obj);
00313     }
00314 
00315     /** Create a Callback with a static function and bound pointer
00316      *  @param obj  Pointer to object to bind to function
00317      *  @param func Static function to attach
00318      *  @deprecated
00319      *      Arguments to callback have been reordered to Callback(func, arg)
00320      */
00321     template<typename T>
00322     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00323         "Arguments to callback have been reordered to Callback(func, arg)")
00324     Callback(volatile T *obj, R (*func)(volatile T*)) {
00325         new (this) Callback(func, obj);
00326     }
00327 
00328     /** Create a Callback with a static function and bound pointer
00329      *  @param obj  Pointer to object to bind to function
00330      *  @param func Static function to attach
00331      *  @deprecated
00332      *      Arguments to callback have been reordered to Callback(func, arg)
00333      */
00334     template<typename T>
00335     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00336         "Arguments to callback have been reordered to Callback(func, arg)")
00337     Callback(const volatile T *obj, R (*func)(const volatile T*)) {
00338         new (this) Callback(func, obj);
00339     }
00340 
00341     /** Destroy a callback
00342      */
00343     ~Callback() {
00344         if (_ops) {
00345             _ops->dtor(this);
00346         }
00347     }
00348 
00349     /** Attach a static function
00350      *  @param func     Static function to attach
00351      */
00352     void attach(R (*func)()) {
00353         this->~Callback();
00354         new (this) Callback(func);
00355     }
00356 
00357     /** Attach a Callback
00358      *  @param func     The Callback to attach
00359      */
00360     void attach(const Callback<R()> &func) {
00361         this->~Callback();
00362         new (this) Callback(func);
00363     }
00364 
00365     /** Attach a member function
00366      *  @param obj      Pointer to object to invoke member function on
00367      *  @param method   Member function to attach
00368      */
00369     template<typename T>
00370     void attach(T *obj, R (T::*method)()) {
00371         this->~Callback();
00372         new (this) Callback(obj, method);
00373     }
00374 
00375     /** Attach a member function
00376      *  @param obj      Pointer to object to invoke member function on
00377      *  @param method   Member function to attach
00378      */
00379     template<typename T>
00380     void attach(const T *obj, R (T::*method)() const) {
00381         this->~Callback();
00382         new (this) Callback(obj, method);
00383     }
00384 
00385     /** Attach a member function
00386      *  @param obj      Pointer to object to invoke member function on
00387      *  @param method   Member function to attach
00388      */
00389     template<typename T>
00390     void attach(volatile T *obj, R (T::*method)() volatile) {
00391         this->~Callback();
00392         new (this) Callback(obj, method);
00393     }
00394 
00395     /** Attach a member function
00396      *  @param obj      Pointer to object to invoke member function on
00397      *  @param method   Member function to attach
00398      */
00399     template<typename T>
00400     void attach(const volatile T *obj, R (T::*method)() const volatile) {
00401         this->~Callback();
00402         new (this) Callback(obj, method);
00403     }
00404 
00405     /** Attach a static function with a bound pointer
00406      *  @param func     Static function to attach
00407      *  @param arg      Pointer argument to function
00408      */
00409     void attach(R (*func)(void*), void *arg) {
00410         this->~Callback();
00411         new (this) Callback(func, arg);
00412     }
00413 
00414     /** Attach a static function with a bound pointer
00415      *  @param func     Static function to attach
00416      *  @param arg      Pointer argument to function
00417      */
00418     void attach(R (*func)(const void*), const void *arg) {
00419         this->~Callback();
00420         new (this) Callback(func, arg);
00421     }
00422 
00423     /** Attach a static function with a bound pointer
00424      *  @param func     Static function to attach
00425      *  @param arg      Pointer argument to function
00426      */
00427     void attach(R (*func)(volatile void*), volatile void *arg) {
00428         this->~Callback();
00429         new (this) Callback(func, arg);
00430     }
00431 
00432     /** Attach a static function with a bound pointer
00433      *  @param func     Static function to attach
00434      *  @param arg      Pointer argument to function
00435      */
00436     void attach(R (*func)(const volatile void*), const volatile void *arg) {
00437         this->~Callback();
00438         new (this) Callback(func, arg);
00439     }
00440 
00441     /** Attach a static function with a bound pointer
00442      *  @param func     Static function to attach
00443      *  @param arg      Pointer argument to function
00444      */
00445     template <typename T>
00446     void attach(R (*func)(T*), T *arg) {
00447         this->~Callback();
00448         new (this) Callback(func, arg);
00449     }
00450 
00451     /** Attach a static function with a bound pointer
00452      *  @param func     Static function to attach
00453      *  @param arg      Pointer argument to function
00454      */
00455     template <typename T>
00456     void attach(R (*func)(const T*), const T *arg) {
00457         this->~Callback();
00458         new (this) Callback(func, arg);
00459     }
00460 
00461     /** Attach a static function with a bound pointer
00462      *  @param func     Static function to attach
00463      *  @param arg      Pointer argument to function
00464      */
00465     template <typename T>
00466     void attach(R (*func)(volatile T*), volatile T *arg) {
00467         this->~Callback();
00468         new (this) Callback(func, arg);
00469     }
00470 
00471     /** Attach a static function with a bound pointer
00472      *  @param func     Static function to attach
00473      *  @param arg      Pointer argument to function
00474      */
00475     template <typename T>
00476     void attach(R (*func)(const volatile T*), const volatile T *arg) {
00477         this->~Callback();
00478         new (this) Callback(func, arg);
00479     }
00480 
00481     /** Attach a function object
00482      *  @param func     Function object to attach
00483      *  @note The function object is limited to a single word of storage
00484      */
00485     template <typename F>
00486     void attach(F f, typename detail::enable_if<
00487                 detail::is_type<R (F::*)(), &F::operator()>::value &&
00488                 sizeof(F) <= sizeof(uintptr_t)
00489             >::type = detail::nil()) {
00490         this->~Callback();
00491         new (this) Callback(f);
00492     }
00493 
00494     /** Attach a function object
00495      *  @param func     Function object to attach
00496      *  @note The function object is limited to a single word of storage
00497      */
00498     template <typename F>
00499     void attach(const F f, typename detail::enable_if<
00500                 detail::is_type<R (F::*)() const, &F::operator()>::value &&
00501                 sizeof(F) <= sizeof(uintptr_t)
00502             >::type = detail::nil()) {
00503         this->~Callback();
00504         new (this) Callback(f);
00505     }
00506 
00507     /** Attach a function object
00508      *  @param func     Function object to attach
00509      *  @note The function object is limited to a single word of storage
00510      */
00511     template <typename F>
00512     void attach(volatile F f, typename detail::enable_if<
00513                 detail::is_type<R (F::*)() volatile, &F::operator()>::value &&
00514                 sizeof(F) <= sizeof(uintptr_t)
00515             >::type = detail::nil()) {
00516         this->~Callback();
00517         new (this) Callback(f);
00518     }
00519 
00520     /** Attach a function object
00521      *  @param func     Function object to attach
00522      *  @note The function object is limited to a single word of storage
00523      */
00524     template <typename F>
00525     void attach(const volatile F f, typename detail::enable_if<
00526                 detail::is_type<R (F::*)() const volatile, &F::operator()>::value &&
00527                 sizeof(F) <= sizeof(uintptr_t)
00528             >::type = detail::nil()) {
00529         this->~Callback();
00530         new (this) Callback(f);
00531     }
00532 
00533     /** Attach a static function with a bound pointer
00534      *  @param obj  Pointer to object to bind to function
00535      *  @param func Static function to attach
00536      *  @deprecated
00537      *      Arguments to callback have been reordered to attach(func, arg)
00538      */
00539     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00540         "Arguments to callback have been reordered to attach(func, arg)")
00541     void attach(void *obj, R (*func)(void*)) {
00542         this->~Callback();
00543         new (this) Callback(func, obj);
00544     }
00545 
00546     /** Attach a static function with a bound pointer
00547      *  @param obj  Pointer to object to bind to function
00548      *  @param func Static function to attach
00549      *  @deprecated
00550      *      Arguments to callback have been reordered to attach(func, arg)
00551      */
00552     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00553         "Arguments to callback have been reordered to attach(func, arg)")
00554     void attach(const void *obj, R (*func)(const void*)) {
00555         this->~Callback();
00556         new (this) Callback(func, obj);
00557     }
00558 
00559     /** Attach a static function with a bound pointer
00560      *  @param obj  Pointer to object to bind to function
00561      *  @param func Static function to attach
00562      *  @deprecated
00563      *      Arguments to callback have been reordered to attach(func, arg)
00564      */
00565     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00566         "Arguments to callback have been reordered to attach(func, arg)")
00567     void attach(volatile void *obj, R (*func)(volatile void*)) {
00568         this->~Callback();
00569         new (this) Callback(func, obj);
00570     }
00571 
00572     /** Attach a static function with a bound pointer
00573      *  @param obj  Pointer to object to bind to function
00574      *  @param func Static function to attach
00575      *  @deprecated
00576      *      Arguments to callback have been reordered to attach(func, arg)
00577      */
00578     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00579         "Arguments to callback have been reordered to attach(func, arg)")
00580     void attach(const volatile void *obj, R (*func)(const volatile void*)) {
00581         this->~Callback();
00582         new (this) Callback(func, obj);
00583     }
00584 
00585     /** Attach a static function with a bound pointer
00586      *  @param obj  Pointer to object to bind to function
00587      *  @param func Static function to attach
00588      *  @deprecated
00589      *      Arguments to callback have been reordered to attach(func, arg)
00590      */
00591     template <typename T>
00592     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00593         "Arguments to callback have been reordered to attach(func, arg)")
00594     void attach(T *obj, R (*func)(T*)) {
00595         this->~Callback();
00596         new (this) Callback(func, obj);
00597     }
00598 
00599     /** Attach a static function with a bound pointer
00600      *  @param obj  Pointer to object to bind to function
00601      *  @param func Static function to attach
00602      *  @deprecated
00603      *      Arguments to callback have been reordered to attach(func, arg)
00604      */
00605     template <typename T>
00606     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00607         "Arguments to callback have been reordered to attach(func, arg)")
00608     void attach(const T *obj, R (*func)(const T*)) {
00609         this->~Callback();
00610         new (this) Callback(func, obj);
00611     }
00612 
00613     /** Attach a static function with a bound pointer
00614      *  @param obj  Pointer to object to bind to function
00615      *  @param func Static function to attach
00616      *  @deprecated
00617      *      Arguments to callback have been reordered to attach(func, arg)
00618      */
00619     template <typename T>
00620     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00621         "Arguments to callback have been reordered to attach(func, arg)")
00622     void attach(volatile T *obj, R (*func)(volatile T*)) {
00623         this->~Callback();
00624         new (this) Callback(func, obj);
00625     }
00626 
00627     /** Attach a static function with a bound pointer
00628      *  @param obj  Pointer to object to bind to function
00629      *  @param func Static function to attach
00630      *  @deprecated
00631      *      Arguments to callback have been reordered to attach(func, arg)
00632      */
00633     template <typename T>
00634     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00635         "Arguments to callback have been reordered to attach(func, arg)")
00636     void attach(const volatile T *obj, R (*func)(const volatile T*)) {
00637         this->~Callback();
00638         new (this) Callback(func, obj);
00639     }
00640 
00641     /** Assign a callback
00642      */
00643     Callback &operator=(const Callback &that) {
00644         if (this != &that) {
00645             this->~Callback();
00646             new (this) Callback(that);
00647         }
00648 
00649         return *this;
00650     }
00651 
00652     /** Call the attached function
00653      */
00654     R call() const {
00655         MBED_ASSERT(_ops);
00656         return _ops->call(this);
00657     }
00658 
00659     /** Call the attached function
00660      */
00661     R operator()() const {
00662         return call();
00663     }
00664 
00665     /** Test if function has been attached
00666      */
00667     operator bool() const {
00668         return _ops;
00669     }
00670 
00671     /** Test for equality
00672      */
00673     friend bool operator==(const Callback &l, const Callback &r) {
00674         return memcmp(&l, &r, sizeof(Callback)) == 0;
00675     }
00676 
00677     /** Test for inequality
00678      */
00679     friend bool operator!=(const Callback &l, const Callback &r) {
00680         return !(l == r);
00681     }
00682 
00683     /** Static thunk for passing as C-style function
00684      *  @param func Callback to call passed as void pointer
00685      */
00686     static R thunk(void *func) {
00687         return static_cast<Callback*>(func)->call();
00688     }
00689 
00690 private:
00691     // Stored as pointer to function and pointer to optional object
00692     // Function pointer is stored as union of possible function types
00693     // to garuntee proper size and alignment
00694     struct _class;
00695     union {
00696         void (*_staticfunc)();
00697         void (*_boundfunc)(_class*);
00698         void (_class::*_methodfunc)();
00699     } _func;
00700     void *_obj;
00701 
00702     // Dynamically dispatched operations
00703     const struct ops {
00704         R (*call)(const void*);
00705         void (*move)(void*, const void*);
00706         void (*dtor)(void*);
00707     } *_ops;
00708 
00709     // Generate operations for function object
00710     template <typename F>
00711     void generate(const F &f) {
00712         static const ops ops = {
00713             &Callback::function_call<F>,
00714             &Callback::function_move<F>,
00715             &Callback::function_dtor<F>,
00716         };
00717 
00718         MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
00719         new (this) F(f);
00720         _ops = &ops;
00721     }
00722 
00723     // Function attributes
00724     template <typename F>
00725     static R function_call(const void *p) {
00726         return (*(F*)p)();
00727     }
00728 
00729     template <typename F>
00730     static void function_move(void *d, const void *p) {
00731         new (d) F(*(F*)p);
00732     }
00733 
00734     template <typename F>
00735     static void function_dtor(void *p) {
00736         ((F*)p)->~F();
00737     }
00738 
00739     // Wrappers for functions with context
00740     template <typename O, typename M>
00741     struct method_context {
00742         M method;
00743         O *obj;
00744 
00745         method_context(O *obj, M method)
00746             : method(method), obj(obj) {}
00747 
00748         R operator()() const {
00749             return (obj->*method)();
00750         }
00751     };
00752 
00753     template <typename F, typename A>
00754     struct function_context {
00755         F func;
00756         A *arg;
00757 
00758         function_context(F func, A *arg)
00759             : func(func), arg(arg) {}
00760 
00761         R operator()() const {
00762             return func(arg);
00763         }
00764     };
00765 };
00766 
00767 /** Callback class based on template specialization
00768  *
00769  * @Note Synchronization level: Not protected
00770  */
00771 template <typename R, typename A0>
00772 class Callback<R(A0)> {
00773 public:
00774     /** Create a Callback with a static function
00775      *  @param func     Static function to attach
00776      */
00777     Callback(R (*func)(A0) = 0) {
00778         if (!func) {
00779             _ops = 0;
00780         } else {
00781             generate(func);
00782         }
00783     }
00784 
00785     /** Attach a Callback
00786      *  @param func     The Callback to attach
00787      */
00788     Callback(const Callback<R(A0)> &func) {
00789         if (func._ops) {
00790             func._ops->move(this, &func);
00791         }
00792         _ops = func._ops;
00793     }
00794 
00795     /** Create a Callback with a member function
00796      *  @param obj      Pointer to object to invoke member function on
00797      *  @param method   Member function to attach
00798      */
00799     template<typename T>
00800     Callback(T *obj, R (T::*method)(A0)) {
00801         generate(method_context<T, R (T::*)(A0)>(obj, method));
00802     }
00803 
00804     /** Create a Callback with a member function
00805      *  @param obj      Pointer to object to invoke member function on
00806      *  @param method   Member function to attach
00807      */
00808     template<typename T>
00809     Callback(const T *obj, R (T::*method)(A0) const) {
00810         generate(method_context<const T, R (T::*)(A0) const>(obj, method));
00811     }
00812 
00813     /** Create a Callback with a member function
00814      *  @param obj      Pointer to object to invoke member function on
00815      *  @param method   Member function to attach
00816      */
00817     template<typename T>
00818     Callback(volatile T *obj, R (T::*method)(A0) volatile) {
00819         generate(method_context<volatile T, R (T::*)(A0) volatile>(obj, method));
00820     }
00821 
00822     /** Create a Callback with a member function
00823      *  @param obj      Pointer to object to invoke member function on
00824      *  @param method   Member function to attach
00825      */
00826     template<typename T>
00827     Callback(const volatile T *obj, R (T::*method)(A0) const volatile) {
00828         generate(method_context<const volatile T, R (T::*)(A0) const volatile>(obj, method));
00829     }
00830 
00831     /** Create a Callback with a static function and bound pointer
00832      *  @param func     Static function to attach
00833      *  @param arg      Pointer argument to function
00834      */
00835     Callback(R (*func)(void*, A0), void *arg) {
00836         generate(function_context<R (*)(void*, A0), void>(func, arg));
00837     }
00838 
00839     /** Create a Callback with a static function and bound pointer
00840      *  @param func     Static function to attach
00841      *  @param arg      Pointer argument to function
00842      */
00843     Callback(R (*func)(const void*, A0), const void *arg) {
00844         generate(function_context<R (*)(const void*, A0), const void>(func, arg));
00845     }
00846 
00847     /** Create a Callback with a static function and bound pointer
00848      *  @param func     Static function to attach
00849      *  @param arg      Pointer argument to function
00850      */
00851     Callback(R (*func)(volatile void*, A0), volatile void *arg) {
00852         generate(function_context<R (*)(volatile void*, A0), volatile void>(func, arg));
00853     }
00854 
00855     /** Create a Callback with a static function and bound pointer
00856      *  @param func     Static function to attach
00857      *  @param arg      Pointer argument to function
00858      */
00859     Callback(R (*func)(const volatile void*, A0), const volatile void *arg) {
00860         generate(function_context<R (*)(const volatile void*, A0), const volatile void>(func, arg));
00861     }
00862 
00863     /** Create a Callback with a static function and bound pointer
00864      *  @param func     Static function to attach
00865      *  @param arg      Pointer argument to function 
00866      */
00867     template<typename T>
00868     Callback(R (*func)(T*, A0), T *arg) {
00869         generate(function_context<R (*)(T*, A0), T>(func, arg));
00870     }
00871 
00872     /** Create a Callback with a static function and bound pointer
00873      *  @param func     Static function to attach
00874      *  @param arg      Pointer argument to function 
00875      */
00876     template<typename T>
00877     Callback(R (*func)(const T*, A0), const T *arg) {
00878         generate(function_context<R (*)(const T*, A0), const T>(func, arg));
00879     }
00880 
00881     /** Create a Callback with a static function and bound pointer
00882      *  @param func     Static function to attach
00883      *  @param arg      Pointer argument to function 
00884      */
00885     template<typename T>
00886     Callback(R (*func)(volatile T*, A0), volatile T *arg) {
00887         generate(function_context<R (*)(volatile T*, A0), volatile T>(func, arg));
00888     }
00889 
00890     /** Create a Callback with a static function and bound pointer
00891      *  @param func     Static function to attach
00892      *  @param arg      Pointer argument to function 
00893      */
00894     template<typename T>
00895     Callback(R (*func)(const volatile T*, A0), const volatile T *arg) {
00896         generate(function_context<R (*)(const volatile T*, A0), const volatile T>(func, arg));
00897     }
00898 
00899     /** Create a Callback with a function object
00900      *  @param func     Function object to attach
00901      *  @note The function object is limited to a single word of storage
00902      */
00903     template <typename F>
00904     Callback(F f, typename detail::enable_if<
00905                 detail::is_type<R (F::*)(A0), &F::operator()>::value &&
00906                 sizeof(F) <= sizeof(uintptr_t)
00907             >::type = detail::nil()) {
00908         generate(f);
00909     }
00910 
00911     /** Create a Callback with a function object
00912      *  @param func     Function object to attach
00913      *  @note The function object is limited to a single word of storage
00914      */
00915     template <typename F>
00916     Callback(const F f, typename detail::enable_if<
00917                 detail::is_type<R (F::*)(A0) const, &F::operator()>::value &&
00918                 sizeof(F) <= sizeof(uintptr_t)
00919             >::type = detail::nil()) {
00920         generate(f);
00921     }
00922 
00923     /** Create a Callback with a function object
00924      *  @param func     Function object to attach
00925      *  @note The function object is limited to a single word of storage
00926      */
00927     template <typename F>
00928     Callback(volatile F f, typename detail::enable_if<
00929                 detail::is_type<R (F::*)(A0) volatile, &F::operator()>::value &&
00930                 sizeof(F) <= sizeof(uintptr_t)
00931             >::type = detail::nil()) {
00932         generate(f);
00933     }
00934 
00935     /** Create a Callback with a function object
00936      *  @param func     Function object to attach
00937      *  @note The function object is limited to a single word of storage
00938      */
00939     template <typename F>
00940     Callback(const volatile F f, typename detail::enable_if<
00941                 detail::is_type<R (F::*)(A0) const volatile, &F::operator()>::value &&
00942                 sizeof(F) <= sizeof(uintptr_t)
00943             >::type = detail::nil()) {
00944         generate(f);
00945     }
00946 
00947     /** Create a Callback with a static function and bound pointer
00948      *  @param obj  Pointer to object to bind to function
00949      *  @param func Static function to attach
00950      *  @deprecated
00951      *      Arguments to callback have been reordered to Callback(func, arg)
00952      */
00953     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00954         "Arguments to callback have been reordered to Callback(func, arg)")
00955     Callback(void *obj, R (*func)(void*, A0)) {
00956         new (this) Callback(func, obj);
00957     }
00958 
00959     /** Create a Callback with a static function and bound pointer
00960      *  @param obj  Pointer to object to bind to function
00961      *  @param func Static function to attach
00962      *  @deprecated
00963      *      Arguments to callback have been reordered to Callback(func, arg)
00964      */
00965     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00966         "Arguments to callback have been reordered to Callback(func, arg)")
00967     Callback(const void *obj, R (*func)(const void*, A0)) {
00968         new (this) Callback(func, obj);
00969     }
00970 
00971     /** Create a Callback with a static function and bound pointer
00972      *  @param obj  Pointer to object to bind to function
00973      *  @param func Static function to attach
00974      *  @deprecated
00975      *      Arguments to callback have been reordered to Callback(func, arg)
00976      */
00977     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00978         "Arguments to callback have been reordered to Callback(func, arg)")
00979     Callback(volatile void *obj, R (*func)(volatile void*, A0)) {
00980         new (this) Callback(func, obj);
00981     }
00982 
00983     /** Create a Callback with a static function and bound pointer
00984      *  @param obj  Pointer to object to bind to function
00985      *  @param func Static function to attach
00986      *  @deprecated
00987      *      Arguments to callback have been reordered to Callback(func, arg)
00988      */
00989     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00990         "Arguments to callback have been reordered to Callback(func, arg)")
00991     Callback(const volatile void *obj, R (*func)(const volatile void*, A0)) {
00992         new (this) Callback(func, obj);
00993     }
00994 
00995     /** Create a Callback with a static function and bound pointer
00996      *  @param obj  Pointer to object to bind to function
00997      *  @param func Static function to attach
00998      *  @deprecated
00999      *      Arguments to callback have been reordered to Callback(func, arg)
01000      */
01001     template<typename T>
01002     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01003         "Arguments to callback have been reordered to Callback(func, arg)")
01004     Callback(T *obj, R (*func)(T*, A0)) {
01005         new (this) Callback(func, obj);
01006     }
01007 
01008     /** Create a Callback with a static function and bound pointer
01009      *  @param obj  Pointer to object to bind to function
01010      *  @param func Static function to attach
01011      *  @deprecated
01012      *      Arguments to callback have been reordered to Callback(func, arg)
01013      */
01014     template<typename T>
01015     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01016         "Arguments to callback have been reordered to Callback(func, arg)")
01017     Callback(const T *obj, R (*func)(const T*, A0)) {
01018         new (this) Callback(func, obj);
01019     }
01020 
01021     /** Create a Callback with a static function and bound pointer
01022      *  @param obj  Pointer to object to bind to function
01023      *  @param func Static function to attach
01024      *  @deprecated
01025      *      Arguments to callback have been reordered to Callback(func, arg)
01026      */
01027     template<typename T>
01028     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01029         "Arguments to callback have been reordered to Callback(func, arg)")
01030     Callback(volatile T *obj, R (*func)(volatile T*, A0)) {
01031         new (this) Callback(func, obj);
01032     }
01033 
01034     /** Create a Callback with a static function and bound pointer
01035      *  @param obj  Pointer to object to bind to function
01036      *  @param func Static function to attach
01037      *  @deprecated
01038      *      Arguments to callback have been reordered to Callback(func, arg)
01039      */
01040     template<typename T>
01041     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01042         "Arguments to callback have been reordered to Callback(func, arg)")
01043     Callback(const volatile T *obj, R (*func)(const volatile T*, A0)) {
01044         new (this) Callback(func, obj);
01045     }
01046 
01047     /** Destroy a callback
01048      */
01049     ~Callback() {
01050         if (_ops) {
01051             _ops->dtor(this);
01052         }
01053     }
01054 
01055     /** Attach a static function
01056      *  @param func     Static function to attach
01057      */
01058     void attach(R (*func)(A0)) {
01059         this->~Callback();
01060         new (this) Callback(func);
01061     }
01062 
01063     /** Attach a Callback
01064      *  @param func     The Callback to attach
01065      */
01066     void attach(const Callback<R(A0)> &func) {
01067         this->~Callback();
01068         new (this) Callback(func);
01069     }
01070 
01071     /** Attach a member function
01072      *  @param obj      Pointer to object to invoke member function on
01073      *  @param method   Member function to attach
01074      */
01075     template<typename T>
01076     void attach(T *obj, R (T::*method)(A0)) {
01077         this->~Callback();
01078         new (this) Callback(obj, method);
01079     }
01080 
01081     /** Attach a member function
01082      *  @param obj      Pointer to object to invoke member function on
01083      *  @param method   Member function to attach
01084      */
01085     template<typename T>
01086     void attach(const T *obj, R (T::*method)(A0) const) {
01087         this->~Callback();
01088         new (this) Callback(obj, method);
01089     }
01090 
01091     /** Attach a member function
01092      *  @param obj      Pointer to object to invoke member function on
01093      *  @param method   Member function to attach
01094      */
01095     template<typename T>
01096     void attach(volatile T *obj, R (T::*method)(A0) volatile) {
01097         this->~Callback();
01098         new (this) Callback(obj, method);
01099     }
01100 
01101     /** Attach a member function
01102      *  @param obj      Pointer to object to invoke member function on
01103      *  @param method   Member function to attach
01104      */
01105     template<typename T>
01106     void attach(const volatile T *obj, R (T::*method)(A0) const volatile) {
01107         this->~Callback();
01108         new (this) Callback(obj, method);
01109     }
01110 
01111     /** Attach a static function with a bound pointer
01112      *  @param func     Static function to attach
01113      *  @param arg      Pointer argument to function
01114      */
01115     void attach(R (*func)(void*, A0), void *arg) {
01116         this->~Callback();
01117         new (this) Callback(func, arg);
01118     }
01119 
01120     /** Attach a static function with a bound pointer
01121      *  @param func     Static function to attach
01122      *  @param arg      Pointer argument to function
01123      */
01124     void attach(R (*func)(const void*, A0), const void *arg) {
01125         this->~Callback();
01126         new (this) Callback(func, arg);
01127     }
01128 
01129     /** Attach a static function with a bound pointer
01130      *  @param func     Static function to attach
01131      *  @param arg      Pointer argument to function
01132      */
01133     void attach(R (*func)(volatile void*, A0), volatile void *arg) {
01134         this->~Callback();
01135         new (this) Callback(func, arg);
01136     }
01137 
01138     /** Attach a static function with a bound pointer
01139      *  @param func     Static function to attach
01140      *  @param arg      Pointer argument to function
01141      */
01142     void attach(R (*func)(const volatile void*, A0), const volatile void *arg) {
01143         this->~Callback();
01144         new (this) Callback(func, arg);
01145     }
01146 
01147     /** Attach a static function with a bound pointer
01148      *  @param func     Static function to attach
01149      *  @param arg      Pointer argument to function
01150      */
01151     template <typename T>
01152     void attach(R (*func)(T*, A0), T *arg) {
01153         this->~Callback();
01154         new (this) Callback(func, arg);
01155     }
01156 
01157     /** Attach a static function with a bound pointer
01158      *  @param func     Static function to attach
01159      *  @param arg      Pointer argument to function
01160      */
01161     template <typename T>
01162     void attach(R (*func)(const T*, A0), const T *arg) {
01163         this->~Callback();
01164         new (this) Callback(func, arg);
01165     }
01166 
01167     /** Attach a static function with a bound pointer
01168      *  @param func     Static function to attach
01169      *  @param arg      Pointer argument to function
01170      */
01171     template <typename T>
01172     void attach(R (*func)(volatile T*, A0), volatile T *arg) {
01173         this->~Callback();
01174         new (this) Callback(func, arg);
01175     }
01176 
01177     /** Attach a static function with a bound pointer
01178      *  @param func     Static function to attach
01179      *  @param arg      Pointer argument to function
01180      */
01181     template <typename T>
01182     void attach(R (*func)(const volatile T*, A0), const volatile T *arg) {
01183         this->~Callback();
01184         new (this) Callback(func, arg);
01185     }
01186 
01187     /** Attach a function object
01188      *  @param func     Function object to attach
01189      *  @note The function object is limited to a single word of storage
01190      */
01191     template <typename F>
01192     void attach(F f, typename detail::enable_if<
01193                 detail::is_type<R (F::*)(A0), &F::operator()>::value &&
01194                 sizeof(F) <= sizeof(uintptr_t)
01195             >::type = detail::nil()) {
01196         this->~Callback();
01197         new (this) Callback(f);
01198     }
01199 
01200     /** Attach a function object
01201      *  @param func     Function object to attach
01202      *  @note The function object is limited to a single word of storage
01203      */
01204     template <typename F>
01205     void attach(const F f, typename detail::enable_if<
01206                 detail::is_type<R (F::*)(A0) const, &F::operator()>::value &&
01207                 sizeof(F) <= sizeof(uintptr_t)
01208             >::type = detail::nil()) {
01209         this->~Callback();
01210         new (this) Callback(f);
01211     }
01212 
01213     /** Attach a function object
01214      *  @param func     Function object to attach
01215      *  @note The function object is limited to a single word of storage
01216      */
01217     template <typename F>
01218     void attach(volatile F f, typename detail::enable_if<
01219                 detail::is_type<R (F::*)(A0) volatile, &F::operator()>::value &&
01220                 sizeof(F) <= sizeof(uintptr_t)
01221             >::type = detail::nil()) {
01222         this->~Callback();
01223         new (this) Callback(f);
01224     }
01225 
01226     /** Attach a function object
01227      *  @param func     Function object to attach
01228      *  @note The function object is limited to a single word of storage
01229      */
01230     template <typename F>
01231     void attach(const volatile F f, typename detail::enable_if<
01232                 detail::is_type<R (F::*)(A0) const volatile, &F::operator()>::value &&
01233                 sizeof(F) <= sizeof(uintptr_t)
01234             >::type = detail::nil()) {
01235         this->~Callback();
01236         new (this) Callback(f);
01237     }
01238 
01239     /** Attach a static function with a bound pointer
01240      *  @param obj  Pointer to object to bind to function
01241      *  @param func Static function to attach
01242      *  @deprecated
01243      *      Arguments to callback have been reordered to attach(func, arg)
01244      */
01245     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01246         "Arguments to callback have been reordered to attach(func, arg)")
01247     void attach(void *obj, R (*func)(void*, A0)) {
01248         this->~Callback();
01249         new (this) Callback(func, obj);
01250     }
01251 
01252     /** Attach a static function with a bound pointer
01253      *  @param obj  Pointer to object to bind to function
01254      *  @param func Static function to attach
01255      *  @deprecated
01256      *      Arguments to callback have been reordered to attach(func, arg)
01257      */
01258     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01259         "Arguments to callback have been reordered to attach(func, arg)")
01260     void attach(const void *obj, R (*func)(const void*, A0)) {
01261         this->~Callback();
01262         new (this) Callback(func, obj);
01263     }
01264 
01265     /** Attach a static function with a bound pointer
01266      *  @param obj  Pointer to object to bind to function
01267      *  @param func Static function to attach
01268      *  @deprecated
01269      *      Arguments to callback have been reordered to attach(func, arg)
01270      */
01271     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01272         "Arguments to callback have been reordered to attach(func, arg)")
01273     void attach(volatile void *obj, R (*func)(volatile void*, A0)) {
01274         this->~Callback();
01275         new (this) Callback(func, obj);
01276     }
01277 
01278     /** Attach a static function with a bound pointer
01279      *  @param obj  Pointer to object to bind to function
01280      *  @param func Static function to attach
01281      *  @deprecated
01282      *      Arguments to callback have been reordered to attach(func, arg)
01283      */
01284     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01285         "Arguments to callback have been reordered to attach(func, arg)")
01286     void attach(const volatile void *obj, R (*func)(const volatile void*, A0)) {
01287         this->~Callback();
01288         new (this) Callback(func, obj);
01289     }
01290 
01291     /** Attach a static function with a bound pointer
01292      *  @param obj  Pointer to object to bind to function
01293      *  @param func Static function to attach
01294      *  @deprecated
01295      *      Arguments to callback have been reordered to attach(func, arg)
01296      */
01297     template <typename T>
01298     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01299         "Arguments to callback have been reordered to attach(func, arg)")
01300     void attach(T *obj, R (*func)(T*, A0)) {
01301         this->~Callback();
01302         new (this) Callback(func, obj);
01303     }
01304 
01305     /** Attach a static function with a bound pointer
01306      *  @param obj  Pointer to object to bind to function
01307      *  @param func Static function to attach
01308      *  @deprecated
01309      *      Arguments to callback have been reordered to attach(func, arg)
01310      */
01311     template <typename T>
01312     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01313         "Arguments to callback have been reordered to attach(func, arg)")
01314     void attach(const T *obj, R (*func)(const T*, A0)) {
01315         this->~Callback();
01316         new (this) Callback(func, obj);
01317     }
01318 
01319     /** Attach a static function with a bound pointer
01320      *  @param obj  Pointer to object to bind to function
01321      *  @param func Static function to attach
01322      *  @deprecated
01323      *      Arguments to callback have been reordered to attach(func, arg)
01324      */
01325     template <typename T>
01326     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01327         "Arguments to callback have been reordered to attach(func, arg)")
01328     void attach(volatile T *obj, R (*func)(volatile T*, A0)) {
01329         this->~Callback();
01330         new (this) Callback(func, obj);
01331     }
01332 
01333     /** Attach a static function with a bound pointer
01334      *  @param obj  Pointer to object to bind to function
01335      *  @param func Static function to attach
01336      *  @deprecated
01337      *      Arguments to callback have been reordered to attach(func, arg)
01338      */
01339     template <typename T>
01340     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01341         "Arguments to callback have been reordered to attach(func, arg)")
01342     void attach(const volatile T *obj, R (*func)(const volatile T*, A0)) {
01343         this->~Callback();
01344         new (this) Callback(func, obj);
01345     }
01346 
01347     /** Assign a callback
01348      */
01349     Callback &operator=(const Callback &that) {
01350         if (this != &that) {
01351             this->~Callback();
01352             new (this) Callback(that);
01353         }
01354 
01355         return *this;
01356     }
01357 
01358     /** Call the attached function
01359      */
01360     R call(A0 a0) const {
01361         MBED_ASSERT(_ops);
01362         return _ops->call(this, a0);
01363     }
01364 
01365     /** Call the attached function
01366      */
01367     R operator()(A0 a0) const {
01368         return call(a0);
01369     }
01370 
01371     /** Test if function has been attached
01372      */
01373     operator bool() const {
01374         return _ops;
01375     }
01376 
01377     /** Test for equality
01378      */
01379     friend bool operator==(const Callback &l, const Callback &r) {
01380         return memcmp(&l, &r, sizeof(Callback)) == 0;
01381     }
01382 
01383     /** Test for inequality
01384      */
01385     friend bool operator!=(const Callback &l, const Callback &r) {
01386         return !(l == r);
01387     }
01388 
01389     /** Static thunk for passing as C-style function
01390      *  @param func Callback to call passed as void pointer
01391      */
01392     static R thunk(void *func, A0 a0) {
01393         return static_cast<Callback*>(func)->call(a0);
01394     }
01395 
01396 private:
01397     // Stored as pointer to function and pointer to optional object
01398     // Function pointer is stored as union of possible function types
01399     // to garuntee proper size and alignment
01400     struct _class;
01401     union {
01402         void (*_staticfunc)(A0);
01403         void (*_boundfunc)(_class*, A0);
01404         void (_class::*_methodfunc)(A0);
01405     } _func;
01406     void *_obj;
01407 
01408     // Dynamically dispatched operations
01409     const struct ops {
01410         R (*call)(const void*, A0);
01411         void (*move)(void*, const void*);
01412         void (*dtor)(void*);
01413     } *_ops;
01414 
01415     // Generate operations for function object
01416     template <typename F>
01417     void generate(const F &f) {
01418         static const ops ops = {
01419             &Callback::function_call<F>,
01420             &Callback::function_move<F>,
01421             &Callback::function_dtor<F>,
01422         };
01423 
01424         MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
01425         new (this) F(f);
01426         _ops = &ops;
01427     }
01428 
01429     // Function attributes
01430     template <typename F>
01431     static R function_call(const void *p, A0 a0) {
01432         return (*(F*)p)(a0);
01433     }
01434 
01435     template <typename F>
01436     static void function_move(void *d, const void *p) {
01437         new (d) F(*(F*)p);
01438     }
01439 
01440     template <typename F>
01441     static void function_dtor(void *p) {
01442         ((F*)p)->~F();
01443     }
01444 
01445     // Wrappers for functions with context
01446     template <typename O, typename M>
01447     struct method_context {
01448         M method;
01449         O *obj;
01450 
01451         method_context(O *obj, M method)
01452             : method(method), obj(obj) {}
01453 
01454         R operator()(A0 a0) const {
01455             return (obj->*method)(a0);
01456         }
01457     };
01458 
01459     template <typename F, typename A>
01460     struct function_context {
01461         F func;
01462         A *arg;
01463 
01464         function_context(F func, A *arg)
01465             : func(func), arg(arg) {}
01466 
01467         R operator()(A0 a0) const {
01468             return func(arg, a0);
01469         }
01470     };
01471 };
01472 
01473 /** Callback class based on template specialization
01474  *
01475  * @Note Synchronization level: Not protected
01476  */
01477 template <typename R, typename A0, typename A1>
01478 class Callback<R(A0, A1)> {
01479 public:
01480     /** Create a Callback with a static function
01481      *  @param func     Static function to attach
01482      */
01483     Callback(R (*func)(A0, A1) = 0) {
01484         if (!func) {
01485             _ops = 0;
01486         } else {
01487             generate(func);
01488         }
01489     }
01490 
01491     /** Attach a Callback
01492      *  @param func     The Callback to attach
01493      */
01494     Callback(const Callback<R(A0, A1)> &func) {
01495         if (func._ops) {
01496             func._ops->move(this, &func);
01497         }
01498         _ops = func._ops;
01499     }
01500 
01501     /** Create a Callback with a member function
01502      *  @param obj      Pointer to object to invoke member function on
01503      *  @param method   Member function to attach
01504      */
01505     template<typename T>
01506     Callback(T *obj, R (T::*method)(A0, A1)) {
01507         generate(method_context<T, R (T::*)(A0, A1)>(obj, method));
01508     }
01509 
01510     /** Create a Callback with a member function
01511      *  @param obj      Pointer to object to invoke member function on
01512      *  @param method   Member function to attach
01513      */
01514     template<typename T>
01515     Callback(const T *obj, R (T::*method)(A0, A1) const) {
01516         generate(method_context<const T, R (T::*)(A0, A1) const>(obj, method));
01517     }
01518 
01519     /** Create a Callback with a member function
01520      *  @param obj      Pointer to object to invoke member function on
01521      *  @param method   Member function to attach
01522      */
01523     template<typename T>
01524     Callback(volatile T *obj, R (T::*method)(A0, A1) volatile) {
01525         generate(method_context<volatile T, R (T::*)(A0, A1) volatile>(obj, method));
01526     }
01527 
01528     /** Create a Callback with a member function
01529      *  @param obj      Pointer to object to invoke member function on
01530      *  @param method   Member function to attach
01531      */
01532     template<typename T>
01533     Callback(const volatile T *obj, R (T::*method)(A0, A1) const volatile) {
01534         generate(method_context<const volatile T, R (T::*)(A0, A1) const volatile>(obj, method));
01535     }
01536 
01537     /** Create a Callback with a static function and bound pointer
01538      *  @param func     Static function to attach
01539      *  @param arg      Pointer argument to function
01540      */
01541     Callback(R (*func)(void*, A0, A1), void *arg) {
01542         generate(function_context<R (*)(void*, A0, A1), void>(func, arg));
01543     }
01544 
01545     /** Create a Callback with a static function and bound pointer
01546      *  @param func     Static function to attach
01547      *  @param arg      Pointer argument to function
01548      */
01549     Callback(R (*func)(const void*, A0, A1), const void *arg) {
01550         generate(function_context<R (*)(const void*, A0, A1), const void>(func, arg));
01551     }
01552 
01553     /** Create a Callback with a static function and bound pointer
01554      *  @param func     Static function to attach
01555      *  @param arg      Pointer argument to function
01556      */
01557     Callback(R (*func)(volatile void*, A0, A1), volatile void *arg) {
01558         generate(function_context<R (*)(volatile void*, A0, A1), volatile void>(func, arg));
01559     }
01560 
01561     /** Create a Callback with a static function and bound pointer
01562      *  @param func     Static function to attach
01563      *  @param arg      Pointer argument to function
01564      */
01565     Callback(R (*func)(const volatile void*, A0, A1), const volatile void *arg) {
01566         generate(function_context<R (*)(const volatile void*, A0, A1), const volatile void>(func, arg));
01567     }
01568 
01569     /** Create a Callback with a static function and bound pointer
01570      *  @param func     Static function to attach
01571      *  @param arg      Pointer argument to function 
01572      */
01573     template<typename T>
01574     Callback(R (*func)(T*, A0, A1), T *arg) {
01575         generate(function_context<R (*)(T*, A0, A1), T>(func, arg));
01576     }
01577 
01578     /** Create a Callback with a static function and bound pointer
01579      *  @param func     Static function to attach
01580      *  @param arg      Pointer argument to function 
01581      */
01582     template<typename T>
01583     Callback(R (*func)(const T*, A0, A1), const T *arg) {
01584         generate(function_context<R (*)(const T*, A0, A1), const T>(func, arg));
01585     }
01586 
01587     /** Create a Callback with a static function and bound pointer
01588      *  @param func     Static function to attach
01589      *  @param arg      Pointer argument to function 
01590      */
01591     template<typename T>
01592     Callback(R (*func)(volatile T*, A0, A1), volatile T *arg) {
01593         generate(function_context<R (*)(volatile T*, A0, A1), volatile T>(func, arg));
01594     }
01595 
01596     /** Create a Callback with a static function and bound pointer
01597      *  @param func     Static function to attach
01598      *  @param arg      Pointer argument to function 
01599      */
01600     template<typename T>
01601     Callback(R (*func)(const volatile T*, A0, A1), const volatile T *arg) {
01602         generate(function_context<R (*)(const volatile T*, A0, A1), const volatile T>(func, arg));
01603     }
01604 
01605     /** Create a Callback with a function object
01606      *  @param func     Function object to attach
01607      *  @note The function object is limited to a single word of storage
01608      */
01609     template <typename F>
01610     Callback(F f, typename detail::enable_if<
01611                 detail::is_type<R (F::*)(A0, A1), &F::operator()>::value &&
01612                 sizeof(F) <= sizeof(uintptr_t)
01613             >::type = detail::nil()) {
01614         generate(f);
01615     }
01616 
01617     /** Create a Callback with a function object
01618      *  @param func     Function object to attach
01619      *  @note The function object is limited to a single word of storage
01620      */
01621     template <typename F>
01622     Callback(const F f, typename detail::enable_if<
01623                 detail::is_type<R (F::*)(A0, A1) const, &F::operator()>::value &&
01624                 sizeof(F) <= sizeof(uintptr_t)
01625             >::type = detail::nil()) {
01626         generate(f);
01627     }
01628 
01629     /** Create a Callback with a function object
01630      *  @param func     Function object to attach
01631      *  @note The function object is limited to a single word of storage
01632      */
01633     template <typename F>
01634     Callback(volatile F f, typename detail::enable_if<
01635                 detail::is_type<R (F::*)(A0, A1) volatile, &F::operator()>::value &&
01636                 sizeof(F) <= sizeof(uintptr_t)
01637             >::type = detail::nil()) {
01638         generate(f);
01639     }
01640 
01641     /** Create a Callback with a function object
01642      *  @param func     Function object to attach
01643      *  @note The function object is limited to a single word of storage
01644      */
01645     template <typename F>
01646     Callback(const volatile F f, typename detail::enable_if<
01647                 detail::is_type<R (F::*)(A0, A1) const volatile, &F::operator()>::value &&
01648                 sizeof(F) <= sizeof(uintptr_t)
01649             >::type = detail::nil()) {
01650         generate(f);
01651     }
01652 
01653     /** Create a Callback with a static function and bound pointer
01654      *  @param obj  Pointer to object to bind to function
01655      *  @param func Static function to attach
01656      *  @deprecated
01657      *      Arguments to callback have been reordered to Callback(func, arg)
01658      */
01659     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01660         "Arguments to callback have been reordered to Callback(func, arg)")
01661     Callback(void *obj, R (*func)(void*, A0, A1)) {
01662         new (this) Callback(func, obj);
01663     }
01664 
01665     /** Create a Callback with a static function and bound pointer
01666      *  @param obj  Pointer to object to bind to function
01667      *  @param func Static function to attach
01668      *  @deprecated
01669      *      Arguments to callback have been reordered to Callback(func, arg)
01670      */
01671     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01672         "Arguments to callback have been reordered to Callback(func, arg)")
01673     Callback(const void *obj, R (*func)(const void*, A0, A1)) {
01674         new (this) Callback(func, obj);
01675     }
01676 
01677     /** Create a Callback with a static function and bound pointer
01678      *  @param obj  Pointer to object to bind to function
01679      *  @param func Static function to attach
01680      *  @deprecated
01681      *      Arguments to callback have been reordered to Callback(func, arg)
01682      */
01683     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01684         "Arguments to callback have been reordered to Callback(func, arg)")
01685     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1)) {
01686         new (this) Callback(func, obj);
01687     }
01688 
01689     /** Create a Callback with a static function and bound pointer
01690      *  @param obj  Pointer to object to bind to function
01691      *  @param func Static function to attach
01692      *  @deprecated
01693      *      Arguments to callback have been reordered to Callback(func, arg)
01694      */
01695     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01696         "Arguments to callback have been reordered to Callback(func, arg)")
01697     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) {
01698         new (this) Callback(func, obj);
01699     }
01700 
01701     /** Create a Callback with a static function and bound pointer
01702      *  @param obj  Pointer to object to bind to function
01703      *  @param func Static function to attach
01704      *  @deprecated
01705      *      Arguments to callback have been reordered to Callback(func, arg)
01706      */
01707     template<typename T>
01708     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01709         "Arguments to callback have been reordered to Callback(func, arg)")
01710     Callback(T *obj, R (*func)(T*, A0, A1)) {
01711         new (this) Callback(func, obj);
01712     }
01713 
01714     /** Create a Callback with a static function and bound pointer
01715      *  @param obj  Pointer to object to bind to function
01716      *  @param func Static function to attach
01717      *  @deprecated
01718      *      Arguments to callback have been reordered to Callback(func, arg)
01719      */
01720     template<typename T>
01721     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01722         "Arguments to callback have been reordered to Callback(func, arg)")
01723     Callback(const T *obj, R (*func)(const T*, A0, A1)) {
01724         new (this) Callback(func, obj);
01725     }
01726 
01727     /** Create a Callback with a static function and bound pointer
01728      *  @param obj  Pointer to object to bind to function
01729      *  @param func Static function to attach
01730      *  @deprecated
01731      *      Arguments to callback have been reordered to Callback(func, arg)
01732      */
01733     template<typename T>
01734     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01735         "Arguments to callback have been reordered to Callback(func, arg)")
01736     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1)) {
01737         new (this) Callback(func, obj);
01738     }
01739 
01740     /** Create a Callback with a static function and bound pointer
01741      *  @param obj  Pointer to object to bind to function
01742      *  @param func Static function to attach
01743      *  @deprecated
01744      *      Arguments to callback have been reordered to Callback(func, arg)
01745      */
01746     template<typename T>
01747     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01748         "Arguments to callback have been reordered to Callback(func, arg)")
01749     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) {
01750         new (this) Callback(func, obj);
01751     }
01752 
01753     /** Destroy a callback
01754      */
01755     ~Callback() {
01756         if (_ops) {
01757             _ops->dtor(this);
01758         }
01759     }
01760 
01761     /** Attach a static function
01762      *  @param func     Static function to attach
01763      */
01764     void attach(R (*func)(A0, A1)) {
01765         this->~Callback();
01766         new (this) Callback(func);
01767     }
01768 
01769     /** Attach a Callback
01770      *  @param func     The Callback to attach
01771      */
01772     void attach(const Callback<R(A0, A1)> &func) {
01773         this->~Callback();
01774         new (this) Callback(func);
01775     }
01776 
01777     /** Attach a member function
01778      *  @param obj      Pointer to object to invoke member function on
01779      *  @param method   Member function to attach
01780      */
01781     template<typename T>
01782     void attach(T *obj, R (T::*method)(A0, A1)) {
01783         this->~Callback();
01784         new (this) Callback(obj, method);
01785     }
01786 
01787     /** Attach a member function
01788      *  @param obj      Pointer to object to invoke member function on
01789      *  @param method   Member function to attach
01790      */
01791     template<typename T>
01792     void attach(const T *obj, R (T::*method)(A0, A1) const) {
01793         this->~Callback();
01794         new (this) Callback(obj, method);
01795     }
01796 
01797     /** Attach a member function
01798      *  @param obj      Pointer to object to invoke member function on
01799      *  @param method   Member function to attach
01800      */
01801     template<typename T>
01802     void attach(volatile T *obj, R (T::*method)(A0, A1) volatile) {
01803         this->~Callback();
01804         new (this) Callback(obj, method);
01805     }
01806 
01807     /** Attach a member function
01808      *  @param obj      Pointer to object to invoke member function on
01809      *  @param method   Member function to attach
01810      */
01811     template<typename T>
01812     void attach(const volatile T *obj, R (T::*method)(A0, A1) const volatile) {
01813         this->~Callback();
01814         new (this) Callback(obj, method);
01815     }
01816 
01817     /** Attach a static function with a bound pointer
01818      *  @param func     Static function to attach
01819      *  @param arg      Pointer argument to function
01820      */
01821     void attach(R (*func)(void*, A0, A1), void *arg) {
01822         this->~Callback();
01823         new (this) Callback(func, arg);
01824     }
01825 
01826     /** Attach a static function with a bound pointer
01827      *  @param func     Static function to attach
01828      *  @param arg      Pointer argument to function
01829      */
01830     void attach(R (*func)(const void*, A0, A1), const void *arg) {
01831         this->~Callback();
01832         new (this) Callback(func, arg);
01833     }
01834 
01835     /** Attach a static function with a bound pointer
01836      *  @param func     Static function to attach
01837      *  @param arg      Pointer argument to function
01838      */
01839     void attach(R (*func)(volatile void*, A0, A1), volatile void *arg) {
01840         this->~Callback();
01841         new (this) Callback(func, arg);
01842     }
01843 
01844     /** Attach a static function with a bound pointer
01845      *  @param func     Static function to attach
01846      *  @param arg      Pointer argument to function
01847      */
01848     void attach(R (*func)(const volatile void*, A0, A1), const volatile void *arg) {
01849         this->~Callback();
01850         new (this) Callback(func, arg);
01851     }
01852 
01853     /** Attach a static function with a bound pointer
01854      *  @param func     Static function to attach
01855      *  @param arg      Pointer argument to function
01856      */
01857     template <typename T>
01858     void attach(R (*func)(T*, A0, A1), T *arg) {
01859         this->~Callback();
01860         new (this) Callback(func, arg);
01861     }
01862 
01863     /** Attach a static function with a bound pointer
01864      *  @param func     Static function to attach
01865      *  @param arg      Pointer argument to function
01866      */
01867     template <typename T>
01868     void attach(R (*func)(const T*, A0, A1), const T *arg) {
01869         this->~Callback();
01870         new (this) Callback(func, arg);
01871     }
01872 
01873     /** Attach a static function with a bound pointer
01874      *  @param func     Static function to attach
01875      *  @param arg      Pointer argument to function
01876      */
01877     template <typename T>
01878     void attach(R (*func)(volatile T*, A0, A1), volatile T *arg) {
01879         this->~Callback();
01880         new (this) Callback(func, arg);
01881     }
01882 
01883     /** Attach a static function with a bound pointer
01884      *  @param func     Static function to attach
01885      *  @param arg      Pointer argument to function
01886      */
01887     template <typename T>
01888     void attach(R (*func)(const volatile T*, A0, A1), const volatile T *arg) {
01889         this->~Callback();
01890         new (this) Callback(func, arg);
01891     }
01892 
01893     /** Attach a function object
01894      *  @param func     Function object to attach
01895      *  @note The function object is limited to a single word of storage
01896      */
01897     template <typename F>
01898     void attach(F f, typename detail::enable_if<
01899                 detail::is_type<R (F::*)(A0, A1), &F::operator()>::value &&
01900                 sizeof(F) <= sizeof(uintptr_t)
01901             >::type = detail::nil()) {
01902         this->~Callback();
01903         new (this) Callback(f);
01904     }
01905 
01906     /** Attach a function object
01907      *  @param func     Function object to attach
01908      *  @note The function object is limited to a single word of storage
01909      */
01910     template <typename F>
01911     void attach(const F f, typename detail::enable_if<
01912                 detail::is_type<R (F::*)(A0, A1) const, &F::operator()>::value &&
01913                 sizeof(F) <= sizeof(uintptr_t)
01914             >::type = detail::nil()) {
01915         this->~Callback();
01916         new (this) Callback(f);
01917     }
01918 
01919     /** Attach a function object
01920      *  @param func     Function object to attach
01921      *  @note The function object is limited to a single word of storage
01922      */
01923     template <typename F>
01924     void attach(volatile F f, typename detail::enable_if<
01925                 detail::is_type<R (F::*)(A0, A1) volatile, &F::operator()>::value &&
01926                 sizeof(F) <= sizeof(uintptr_t)
01927             >::type = detail::nil()) {
01928         this->~Callback();
01929         new (this) Callback(f);
01930     }
01931 
01932     /** Attach a function object
01933      *  @param func     Function object to attach
01934      *  @note The function object is limited to a single word of storage
01935      */
01936     template <typename F>
01937     void attach(const volatile F f, typename detail::enable_if<
01938                 detail::is_type<R (F::*)(A0, A1) const volatile, &F::operator()>::value &&
01939                 sizeof(F) <= sizeof(uintptr_t)
01940             >::type = detail::nil()) {
01941         this->~Callback();
01942         new (this) Callback(f);
01943     }
01944 
01945     /** Attach a static function with a bound pointer
01946      *  @param obj  Pointer to object to bind to function
01947      *  @param func Static function to attach
01948      *  @deprecated
01949      *      Arguments to callback have been reordered to attach(func, arg)
01950      */
01951     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01952         "Arguments to callback have been reordered to attach(func, arg)")
01953     void attach(void *obj, R (*func)(void*, A0, A1)) {
01954         this->~Callback();
01955         new (this) Callback(func, obj);
01956     }
01957 
01958     /** Attach a static function with a bound pointer
01959      *  @param obj  Pointer to object to bind to function
01960      *  @param func Static function to attach
01961      *  @deprecated
01962      *      Arguments to callback have been reordered to attach(func, arg)
01963      */
01964     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01965         "Arguments to callback have been reordered to attach(func, arg)")
01966     void attach(const void *obj, R (*func)(const void*, A0, A1)) {
01967         this->~Callback();
01968         new (this) Callback(func, obj);
01969     }
01970 
01971     /** Attach a static function with a bound pointer
01972      *  @param obj  Pointer to object to bind to function
01973      *  @param func Static function to attach
01974      *  @deprecated
01975      *      Arguments to callback have been reordered to attach(func, arg)
01976      */
01977     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01978         "Arguments to callback have been reordered to attach(func, arg)")
01979     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1)) {
01980         this->~Callback();
01981         new (this) Callback(func, obj);
01982     }
01983 
01984     /** Attach a static function with a bound pointer
01985      *  @param obj  Pointer to object to bind to function
01986      *  @param func Static function to attach
01987      *  @deprecated
01988      *      Arguments to callback have been reordered to attach(func, arg)
01989      */
01990     MBED_DEPRECATED_SINCE("mbed-os-5.1",
01991         "Arguments to callback have been reordered to attach(func, arg)")
01992     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) {
01993         this->~Callback();
01994         new (this) Callback(func, obj);
01995     }
01996 
01997     /** Attach a static function with a bound pointer
01998      *  @param obj  Pointer to object to bind to function
01999      *  @param func Static function to attach
02000      *  @deprecated
02001      *      Arguments to callback have been reordered to attach(func, arg)
02002      */
02003     template <typename T>
02004     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02005         "Arguments to callback have been reordered to attach(func, arg)")
02006     void attach(T *obj, R (*func)(T*, A0, A1)) {
02007         this->~Callback();
02008         new (this) Callback(func, obj);
02009     }
02010 
02011     /** Attach a static function with a bound pointer
02012      *  @param obj  Pointer to object to bind to function
02013      *  @param func Static function to attach
02014      *  @deprecated
02015      *      Arguments to callback have been reordered to attach(func, arg)
02016      */
02017     template <typename T>
02018     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02019         "Arguments to callback have been reordered to attach(func, arg)")
02020     void attach(const T *obj, R (*func)(const T*, A0, A1)) {
02021         this->~Callback();
02022         new (this) Callback(func, obj);
02023     }
02024 
02025     /** Attach a static function with a bound pointer
02026      *  @param obj  Pointer to object to bind to function
02027      *  @param func Static function to attach
02028      *  @deprecated
02029      *      Arguments to callback have been reordered to attach(func, arg)
02030      */
02031     template <typename T>
02032     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02033         "Arguments to callback have been reordered to attach(func, arg)")
02034     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1)) {
02035         this->~Callback();
02036         new (this) Callback(func, obj);
02037     }
02038 
02039     /** Attach a static function with a bound pointer
02040      *  @param obj  Pointer to object to bind to function
02041      *  @param func Static function to attach
02042      *  @deprecated
02043      *      Arguments to callback have been reordered to attach(func, arg)
02044      */
02045     template <typename T>
02046     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02047         "Arguments to callback have been reordered to attach(func, arg)")
02048     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) {
02049         this->~Callback();
02050         new (this) Callback(func, obj);
02051     }
02052 
02053     /** Assign a callback
02054      */
02055     Callback &operator=(const Callback &that) {
02056         if (this != &that) {
02057             this->~Callback();
02058             new (this) Callback(that);
02059         }
02060 
02061         return *this;
02062     }
02063 
02064     /** Call the attached function
02065      */
02066     R call(A0 a0, A1 a1) const {
02067         MBED_ASSERT(_ops);
02068         return _ops->call(this, a0, a1);
02069     }
02070 
02071     /** Call the attached function
02072      */
02073     R operator()(A0 a0, A1 a1) const {
02074         return call(a0, a1);
02075     }
02076 
02077     /** Test if function has been attached
02078      */
02079     operator bool() const {
02080         return _ops;
02081     }
02082 
02083     /** Test for equality
02084      */
02085     friend bool operator==(const Callback &l, const Callback &r) {
02086         return memcmp(&l, &r, sizeof(Callback)) == 0;
02087     }
02088 
02089     /** Test for inequality
02090      */
02091     friend bool operator!=(const Callback &l, const Callback &r) {
02092         return !(l == r);
02093     }
02094 
02095     /** Static thunk for passing as C-style function
02096      *  @param func Callback to call passed as void pointer
02097      */
02098     static R thunk(void *func, A0 a0, A1 a1) {
02099         return static_cast<Callback*>(func)->call(a0, a1);
02100     }
02101 
02102 private:
02103     // Stored as pointer to function and pointer to optional object
02104     // Function pointer is stored as union of possible function types
02105     // to garuntee proper size and alignment
02106     struct _class;
02107     union {
02108         void (*_staticfunc)(A0, A1);
02109         void (*_boundfunc)(_class*, A0, A1);
02110         void (_class::*_methodfunc)(A0, A1);
02111     } _func;
02112     void *_obj;
02113 
02114     // Dynamically dispatched operations
02115     const struct ops {
02116         R (*call)(const void*, A0, A1);
02117         void (*move)(void*, const void*);
02118         void (*dtor)(void*);
02119     } *_ops;
02120 
02121     // Generate operations for function object
02122     template <typename F>
02123     void generate(const F &f) {
02124         static const ops ops = {
02125             &Callback::function_call<F>,
02126             &Callback::function_move<F>,
02127             &Callback::function_dtor<F>,
02128         };
02129 
02130         MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
02131         new (this) F(f);
02132         _ops = &ops;
02133     }
02134 
02135     // Function attributes
02136     template <typename F>
02137     static R function_call(const void *p, A0 a0, A1 a1) {
02138         return (*(F*)p)(a0, a1);
02139     }
02140 
02141     template <typename F>
02142     static void function_move(void *d, const void *p) {
02143         new (d) F(*(F*)p);
02144     }
02145 
02146     template <typename F>
02147     static void function_dtor(void *p) {
02148         ((F*)p)->~F();
02149     }
02150 
02151     // Wrappers for functions with context
02152     template <typename O, typename M>
02153     struct method_context {
02154         M method;
02155         O *obj;
02156 
02157         method_context(O *obj, M method)
02158             : method(method), obj(obj) {}
02159 
02160         R operator()(A0 a0, A1 a1) const {
02161             return (obj->*method)(a0, a1);
02162         }
02163     };
02164 
02165     template <typename F, typename A>
02166     struct function_context {
02167         F func;
02168         A *arg;
02169 
02170         function_context(F func, A *arg)
02171             : func(func), arg(arg) {}
02172 
02173         R operator()(A0 a0, A1 a1) const {
02174             return func(arg, a0, a1);
02175         }
02176     };
02177 };
02178 
02179 /** Callback class based on template specialization
02180  *
02181  * @Note Synchronization level: Not protected
02182  */
02183 template <typename R, typename A0, typename A1, typename A2>
02184 class Callback<R(A0, A1, A2)> {
02185 public:
02186     /** Create a Callback with a static function
02187      *  @param func     Static function to attach
02188      */
02189     Callback(R (*func)(A0, A1, A2) = 0) {
02190         if (!func) {
02191             _ops = 0;
02192         } else {
02193             generate(func);
02194         }
02195     }
02196 
02197     /** Attach a Callback
02198      *  @param func     The Callback to attach
02199      */
02200     Callback(const Callback<R(A0, A1, A2)> &func) {
02201         if (func._ops) {
02202             func._ops->move(this, &func);
02203         }
02204         _ops = func._ops;
02205     }
02206 
02207     /** Create a Callback with a member function
02208      *  @param obj      Pointer to object to invoke member function on
02209      *  @param method   Member function to attach
02210      */
02211     template<typename T>
02212     Callback(T *obj, R (T::*method)(A0, A1, A2)) {
02213         generate(method_context<T, R (T::*)(A0, A1, A2)>(obj, method));
02214     }
02215 
02216     /** Create a Callback with a member function
02217      *  @param obj      Pointer to object to invoke member function on
02218      *  @param method   Member function to attach
02219      */
02220     template<typename T>
02221     Callback(const T *obj, R (T::*method)(A0, A1, A2) const) {
02222         generate(method_context<const T, R (T::*)(A0, A1, A2) const>(obj, method));
02223     }
02224 
02225     /** Create a Callback with a member function
02226      *  @param obj      Pointer to object to invoke member function on
02227      *  @param method   Member function to attach
02228      */
02229     template<typename T>
02230     Callback(volatile T *obj, R (T::*method)(A0, A1, A2) volatile) {
02231         generate(method_context<volatile T, R (T::*)(A0, A1, A2) volatile>(obj, method));
02232     }
02233 
02234     /** Create a Callback with a member function
02235      *  @param obj      Pointer to object to invoke member function on
02236      *  @param method   Member function to attach
02237      */
02238     template<typename T>
02239     Callback(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile) {
02240         generate(method_context<const volatile T, R (T::*)(A0, A1, A2) const volatile>(obj, method));
02241     }
02242 
02243     /** Create a Callback with a static function and bound pointer
02244      *  @param func     Static function to attach
02245      *  @param arg      Pointer argument to function
02246      */
02247     Callback(R (*func)(void*, A0, A1, A2), void *arg) {
02248         generate(function_context<R (*)(void*, A0, A1, A2), void>(func, arg));
02249     }
02250 
02251     /** Create a Callback with a static function and bound pointer
02252      *  @param func     Static function to attach
02253      *  @param arg      Pointer argument to function
02254      */
02255     Callback(R (*func)(const void*, A0, A1, A2), const void *arg) {
02256         generate(function_context<R (*)(const void*, A0, A1, A2), const void>(func, arg));
02257     }
02258 
02259     /** Create a Callback with a static function and bound pointer
02260      *  @param func     Static function to attach
02261      *  @param arg      Pointer argument to function
02262      */
02263     Callback(R (*func)(volatile void*, A0, A1, A2), volatile void *arg) {
02264         generate(function_context<R (*)(volatile void*, A0, A1, A2), volatile void>(func, arg));
02265     }
02266 
02267     /** Create a Callback with a static function and bound pointer
02268      *  @param func     Static function to attach
02269      *  @param arg      Pointer argument to function
02270      */
02271     Callback(R (*func)(const volatile void*, A0, A1, A2), const volatile void *arg) {
02272         generate(function_context<R (*)(const volatile void*, A0, A1, A2), const volatile void>(func, arg));
02273     }
02274 
02275     /** Create a Callback with a static function and bound pointer
02276      *  @param func     Static function to attach
02277      *  @param arg      Pointer argument to function 
02278      */
02279     template<typename T>
02280     Callback(R (*func)(T*, A0, A1, A2), T *arg) {
02281         generate(function_context<R (*)(T*, A0, A1, A2), T>(func, arg));
02282     }
02283 
02284     /** Create a Callback with a static function and bound pointer
02285      *  @param func     Static function to attach
02286      *  @param arg      Pointer argument to function 
02287      */
02288     template<typename T>
02289     Callback(R (*func)(const T*, A0, A1, A2), const T *arg) {
02290         generate(function_context<R (*)(const T*, A0, A1, A2), const T>(func, arg));
02291     }
02292 
02293     /** Create a Callback with a static function and bound pointer
02294      *  @param func     Static function to attach
02295      *  @param arg      Pointer argument to function 
02296      */
02297     template<typename T>
02298     Callback(R (*func)(volatile T*, A0, A1, A2), volatile T *arg) {
02299         generate(function_context<R (*)(volatile T*, A0, A1, A2), volatile T>(func, arg));
02300     }
02301 
02302     /** Create a Callback with a static function and bound pointer
02303      *  @param func     Static function to attach
02304      *  @param arg      Pointer argument to function 
02305      */
02306     template<typename T>
02307     Callback(R (*func)(const volatile T*, A0, A1, A2), const volatile T *arg) {
02308         generate(function_context<R (*)(const volatile T*, A0, A1, A2), const volatile T>(func, arg));
02309     }
02310 
02311     /** Create a Callback with a function object
02312      *  @param func     Function object to attach
02313      *  @note The function object is limited to a single word of storage
02314      */
02315     template <typename F>
02316     Callback(F f, typename detail::enable_if<
02317                 detail::is_type<R (F::*)(A0, A1, A2), &F::operator()>::value &&
02318                 sizeof(F) <= sizeof(uintptr_t)
02319             >::type = detail::nil()) {
02320         generate(f);
02321     }
02322 
02323     /** Create a Callback with a function object
02324      *  @param func     Function object to attach
02325      *  @note The function object is limited to a single word of storage
02326      */
02327     template <typename F>
02328     Callback(const F f, typename detail::enable_if<
02329                 detail::is_type<R (F::*)(A0, A1, A2) const, &F::operator()>::value &&
02330                 sizeof(F) <= sizeof(uintptr_t)
02331             >::type = detail::nil()) {
02332         generate(f);
02333     }
02334 
02335     /** Create a Callback with a function object
02336      *  @param func     Function object to attach
02337      *  @note The function object is limited to a single word of storage
02338      */
02339     template <typename F>
02340     Callback(volatile F f, typename detail::enable_if<
02341                 detail::is_type<R (F::*)(A0, A1, A2) volatile, &F::operator()>::value &&
02342                 sizeof(F) <= sizeof(uintptr_t)
02343             >::type = detail::nil()) {
02344         generate(f);
02345     }
02346 
02347     /** Create a Callback with a function object
02348      *  @param func     Function object to attach
02349      *  @note The function object is limited to a single word of storage
02350      */
02351     template <typename F>
02352     Callback(const volatile F f, typename detail::enable_if<
02353                 detail::is_type<R (F::*)(A0, A1, A2) const volatile, &F::operator()>::value &&
02354                 sizeof(F) <= sizeof(uintptr_t)
02355             >::type = detail::nil()) {
02356         generate(f);
02357     }
02358 
02359     /** Create a Callback with a static function and bound pointer
02360      *  @param obj  Pointer to object to bind to function
02361      *  @param func Static function to attach
02362      *  @deprecated
02363      *      Arguments to callback have been reordered to Callback(func, arg)
02364      */
02365     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02366         "Arguments to callback have been reordered to Callback(func, arg)")
02367     Callback(void *obj, R (*func)(void*, A0, A1, A2)) {
02368         new (this) Callback(func, obj);
02369     }
02370 
02371     /** Create a Callback with a static function and bound pointer
02372      *  @param obj  Pointer to object to bind to function
02373      *  @param func Static function to attach
02374      *  @deprecated
02375      *      Arguments to callback have been reordered to Callback(func, arg)
02376      */
02377     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02378         "Arguments to callback have been reordered to Callback(func, arg)")
02379     Callback(const void *obj, R (*func)(const void*, A0, A1, A2)) {
02380         new (this) Callback(func, obj);
02381     }
02382 
02383     /** Create a Callback with a static function and bound pointer
02384      *  @param obj  Pointer to object to bind to function
02385      *  @param func Static function to attach
02386      *  @deprecated
02387      *      Arguments to callback have been reordered to Callback(func, arg)
02388      */
02389     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02390         "Arguments to callback have been reordered to Callback(func, arg)")
02391     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) {
02392         new (this) Callback(func, obj);
02393     }
02394 
02395     /** Create a Callback with a static function and bound pointer
02396      *  @param obj  Pointer to object to bind to function
02397      *  @param func Static function to attach
02398      *  @deprecated
02399      *      Arguments to callback have been reordered to Callback(func, arg)
02400      */
02401     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02402         "Arguments to callback have been reordered to Callback(func, arg)")
02403     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) {
02404         new (this) Callback(func, obj);
02405     }
02406 
02407     /** Create a Callback with a static function and bound pointer
02408      *  @param obj  Pointer to object to bind to function
02409      *  @param func Static function to attach
02410      *  @deprecated
02411      *      Arguments to callback have been reordered to Callback(func, arg)
02412      */
02413     template<typename T>
02414     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02415         "Arguments to callback have been reordered to Callback(func, arg)")
02416     Callback(T *obj, R (*func)(T*, A0, A1, A2)) {
02417         new (this) Callback(func, obj);
02418     }
02419 
02420     /** Create a Callback with a static function and bound pointer
02421      *  @param obj  Pointer to object to bind to function
02422      *  @param func Static function to attach
02423      *  @deprecated
02424      *      Arguments to callback have been reordered to Callback(func, arg)
02425      */
02426     template<typename T>
02427     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02428         "Arguments to callback have been reordered to Callback(func, arg)")
02429     Callback(const T *obj, R (*func)(const T*, A0, A1, A2)) {
02430         new (this) Callback(func, obj);
02431     }
02432 
02433     /** Create a Callback with a static function and bound pointer
02434      *  @param obj  Pointer to object to bind to function
02435      *  @param func Static function to attach
02436      *  @deprecated
02437      *      Arguments to callback have been reordered to Callback(func, arg)
02438      */
02439     template<typename T>
02440     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02441         "Arguments to callback have been reordered to Callback(func, arg)")
02442     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) {
02443         new (this) Callback(func, obj);
02444     }
02445 
02446     /** Create a Callback with a static function and bound pointer
02447      *  @param obj  Pointer to object to bind to function
02448      *  @param func Static function to attach
02449      *  @deprecated
02450      *      Arguments to callback have been reordered to Callback(func, arg)
02451      */
02452     template<typename T>
02453     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02454         "Arguments to callback have been reordered to Callback(func, arg)")
02455     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) {
02456         new (this) Callback(func, obj);
02457     }
02458 
02459     /** Destroy a callback
02460      */
02461     ~Callback() {
02462         if (_ops) {
02463             _ops->dtor(this);
02464         }
02465     }
02466 
02467     /** Attach a static function
02468      *  @param func     Static function to attach
02469      */
02470     void attach(R (*func)(A0, A1, A2)) {
02471         this->~Callback();
02472         new (this) Callback(func);
02473     }
02474 
02475     /** Attach a Callback
02476      *  @param func     The Callback to attach
02477      */
02478     void attach(const Callback<R(A0, A1, A2)> &func) {
02479         this->~Callback();
02480         new (this) Callback(func);
02481     }
02482 
02483     /** Attach a member function
02484      *  @param obj      Pointer to object to invoke member function on
02485      *  @param method   Member function to attach
02486      */
02487     template<typename T>
02488     void attach(T *obj, R (T::*method)(A0, A1, A2)) {
02489         this->~Callback();
02490         new (this) Callback(obj, method);
02491     }
02492 
02493     /** Attach a member function
02494      *  @param obj      Pointer to object to invoke member function on
02495      *  @param method   Member function to attach
02496      */
02497     template<typename T>
02498     void attach(const T *obj, R (T::*method)(A0, A1, A2) const) {
02499         this->~Callback();
02500         new (this) Callback(obj, method);
02501     }
02502 
02503     /** Attach a member function
02504      *  @param obj      Pointer to object to invoke member function on
02505      *  @param method   Member function to attach
02506      */
02507     template<typename T>
02508     void attach(volatile T *obj, R (T::*method)(A0, A1, A2) volatile) {
02509         this->~Callback();
02510         new (this) Callback(obj, method);
02511     }
02512 
02513     /** Attach a member function
02514      *  @param obj      Pointer to object to invoke member function on
02515      *  @param method   Member function to attach
02516      */
02517     template<typename T>
02518     void attach(const volatile T *obj, R (T::*method)(A0, A1, A2) const volatile) {
02519         this->~Callback();
02520         new (this) Callback(obj, method);
02521     }
02522 
02523     /** Attach a static function with a bound pointer
02524      *  @param func     Static function to attach
02525      *  @param arg      Pointer argument to function
02526      */
02527     void attach(R (*func)(void*, A0, A1, A2), void *arg) {
02528         this->~Callback();
02529         new (this) Callback(func, arg);
02530     }
02531 
02532     /** Attach a static function with a bound pointer
02533      *  @param func     Static function to attach
02534      *  @param arg      Pointer argument to function
02535      */
02536     void attach(R (*func)(const void*, A0, A1, A2), const void *arg) {
02537         this->~Callback();
02538         new (this) Callback(func, arg);
02539     }
02540 
02541     /** Attach a static function with a bound pointer
02542      *  @param func     Static function to attach
02543      *  @param arg      Pointer argument to function
02544      */
02545     void attach(R (*func)(volatile void*, A0, A1, A2), volatile void *arg) {
02546         this->~Callback();
02547         new (this) Callback(func, arg);
02548     }
02549 
02550     /** Attach a static function with a bound pointer
02551      *  @param func     Static function to attach
02552      *  @param arg      Pointer argument to function
02553      */
02554     void attach(R (*func)(const volatile void*, A0, A1, A2), const volatile void *arg) {
02555         this->~Callback();
02556         new (this) Callback(func, arg);
02557     }
02558 
02559     /** Attach a static function with a bound pointer
02560      *  @param func     Static function to attach
02561      *  @param arg      Pointer argument to function
02562      */
02563     template <typename T>
02564     void attach(R (*func)(T*, A0, A1, A2), T *arg) {
02565         this->~Callback();
02566         new (this) Callback(func, arg);
02567     }
02568 
02569     /** Attach a static function with a bound pointer
02570      *  @param func     Static function to attach
02571      *  @param arg      Pointer argument to function
02572      */
02573     template <typename T>
02574     void attach(R (*func)(const T*, A0, A1, A2), const T *arg) {
02575         this->~Callback();
02576         new (this) Callback(func, arg);
02577     }
02578 
02579     /** Attach a static function with a bound pointer
02580      *  @param func     Static function to attach
02581      *  @param arg      Pointer argument to function
02582      */
02583     template <typename T>
02584     void attach(R (*func)(volatile T*, A0, A1, A2), volatile T *arg) {
02585         this->~Callback();
02586         new (this) Callback(func, arg);
02587     }
02588 
02589     /** Attach a static function with a bound pointer
02590      *  @param func     Static function to attach
02591      *  @param arg      Pointer argument to function
02592      */
02593     template <typename T>
02594     void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile T *arg) {
02595         this->~Callback();
02596         new (this) Callback(func, arg);
02597     }
02598 
02599     /** Attach a function object
02600      *  @param func     Function object to attach
02601      *  @note The function object is limited to a single word of storage
02602      */
02603     template <typename F>
02604     void attach(F f, typename detail::enable_if<
02605                 detail::is_type<R (F::*)(A0, A1, A2), &F::operator()>::value &&
02606                 sizeof(F) <= sizeof(uintptr_t)
02607             >::type = detail::nil()) {
02608         this->~Callback();
02609         new (this) Callback(f);
02610     }
02611 
02612     /** Attach a function object
02613      *  @param func     Function object to attach
02614      *  @note The function object is limited to a single word of storage
02615      */
02616     template <typename F>
02617     void attach(const F f, typename detail::enable_if<
02618                 detail::is_type<R (F::*)(A0, A1, A2) const, &F::operator()>::value &&
02619                 sizeof(F) <= sizeof(uintptr_t)
02620             >::type = detail::nil()) {
02621         this->~Callback();
02622         new (this) Callback(f);
02623     }
02624 
02625     /** Attach a function object
02626      *  @param func     Function object to attach
02627      *  @note The function object is limited to a single word of storage
02628      */
02629     template <typename F>
02630     void attach(volatile F f, typename detail::enable_if<
02631                 detail::is_type<R (F::*)(A0, A1, A2) volatile, &F::operator()>::value &&
02632                 sizeof(F) <= sizeof(uintptr_t)
02633             >::type = detail::nil()) {
02634         this->~Callback();
02635         new (this) Callback(f);
02636     }
02637 
02638     /** Attach a function object
02639      *  @param func     Function object to attach
02640      *  @note The function object is limited to a single word of storage
02641      */
02642     template <typename F>
02643     void attach(const volatile F f, typename detail::enable_if<
02644                 detail::is_type<R (F::*)(A0, A1, A2) const volatile, &F::operator()>::value &&
02645                 sizeof(F) <= sizeof(uintptr_t)
02646             >::type = detail::nil()) {
02647         this->~Callback();
02648         new (this) Callback(f);
02649     }
02650 
02651     /** Attach a static function with a bound pointer
02652      *  @param obj  Pointer to object to bind to function
02653      *  @param func Static function to attach
02654      *  @deprecated
02655      *      Arguments to callback have been reordered to attach(func, arg)
02656      */
02657     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02658         "Arguments to callback have been reordered to attach(func, arg)")
02659     void attach(void *obj, R (*func)(void*, A0, A1, A2)) {
02660         this->~Callback();
02661         new (this) Callback(func, obj);
02662     }
02663 
02664     /** Attach a static function with a bound pointer
02665      *  @param obj  Pointer to object to bind to function
02666      *  @param func Static function to attach
02667      *  @deprecated
02668      *      Arguments to callback have been reordered to attach(func, arg)
02669      */
02670     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02671         "Arguments to callback have been reordered to attach(func, arg)")
02672     void attach(const void *obj, R (*func)(const void*, A0, A1, A2)) {
02673         this->~Callback();
02674         new (this) Callback(func, obj);
02675     }
02676 
02677     /** Attach a static function with a bound pointer
02678      *  @param obj  Pointer to object to bind to function
02679      *  @param func Static function to attach
02680      *  @deprecated
02681      *      Arguments to callback have been reordered to attach(func, arg)
02682      */
02683     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02684         "Arguments to callback have been reordered to attach(func, arg)")
02685     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) {
02686         this->~Callback();
02687         new (this) Callback(func, obj);
02688     }
02689 
02690     /** Attach a static function with a bound pointer
02691      *  @param obj  Pointer to object to bind to function
02692      *  @param func Static function to attach
02693      *  @deprecated
02694      *      Arguments to callback have been reordered to attach(func, arg)
02695      */
02696     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02697         "Arguments to callback have been reordered to attach(func, arg)")
02698     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) {
02699         this->~Callback();
02700         new (this) Callback(func, obj);
02701     }
02702 
02703     /** Attach a static function with a bound pointer
02704      *  @param obj  Pointer to object to bind to function
02705      *  @param func Static function to attach
02706      *  @deprecated
02707      *      Arguments to callback have been reordered to attach(func, arg)
02708      */
02709     template <typename T>
02710     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02711         "Arguments to callback have been reordered to attach(func, arg)")
02712     void attach(T *obj, R (*func)(T*, A0, A1, A2)) {
02713         this->~Callback();
02714         new (this) Callback(func, obj);
02715     }
02716 
02717     /** Attach a static function with a bound pointer
02718      *  @param obj  Pointer to object to bind to function
02719      *  @param func Static function to attach
02720      *  @deprecated
02721      *      Arguments to callback have been reordered to attach(func, arg)
02722      */
02723     template <typename T>
02724     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02725         "Arguments to callback have been reordered to attach(func, arg)")
02726     void attach(const T *obj, R (*func)(const T*, A0, A1, A2)) {
02727         this->~Callback();
02728         new (this) Callback(func, obj);
02729     }
02730 
02731     /** Attach a static function with a bound pointer
02732      *  @param obj  Pointer to object to bind to function
02733      *  @param func Static function to attach
02734      *  @deprecated
02735      *      Arguments to callback have been reordered to attach(func, arg)
02736      */
02737     template <typename T>
02738     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02739         "Arguments to callback have been reordered to attach(func, arg)")
02740     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) {
02741         this->~Callback();
02742         new (this) Callback(func, obj);
02743     }
02744 
02745     /** Attach a static function with a bound pointer
02746      *  @param obj  Pointer to object to bind to function
02747      *  @param func Static function to attach
02748      *  @deprecated
02749      *      Arguments to callback have been reordered to attach(func, arg)
02750      */
02751     template <typename T>
02752     MBED_DEPRECATED_SINCE("mbed-os-5.1",
02753         "Arguments to callback have been reordered to attach(func, arg)")
02754     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) {
02755         this->~Callback();
02756         new (this) Callback(func, obj);
02757     }
02758 
02759     /** Assign a callback
02760      */
02761     Callback &operator=(const Callback &that) {
02762         if (this != &that) {
02763             this->~Callback();
02764             new (this) Callback(that);
02765         }
02766 
02767         return *this;
02768     }
02769 
02770     /** Call the attached function
02771      */
02772     R call(A0 a0, A1 a1, A2 a2) const {
02773         MBED_ASSERT(_ops);
02774         return _ops->call(this, a0, a1, a2);
02775     }
02776 
02777     /** Call the attached function
02778      */
02779     R operator()(A0 a0, A1 a1, A2 a2) const {
02780         return call(a0, a1, a2);
02781     }
02782 
02783     /** Test if function has been attached
02784      */
02785     operator bool() const {
02786         return _ops;
02787     }
02788 
02789     /** Test for equality
02790      */
02791     friend bool operator==(const Callback &l, const Callback &r) {
02792         return memcmp(&l, &r, sizeof(Callback)) == 0;
02793     }
02794 
02795     /** Test for inequality
02796      */
02797     friend bool operator!=(const Callback &l, const Callback &r) {
02798         return !(l == r);
02799     }
02800 
02801     /** Static thunk for passing as C-style function
02802      *  @param func Callback to call passed as void pointer
02803      */
02804     static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
02805         return static_cast<Callback*>(func)->call(a0, a1, a2);
02806     }
02807 
02808 private:
02809     // Stored as pointer to function and pointer to optional object
02810     // Function pointer is stored as union of possible function types
02811     // to garuntee proper size and alignment
02812     struct _class;
02813     union {
02814         void (*_staticfunc)(A0, A1, A2);
02815         void (*_boundfunc)(_class*, A0, A1, A2);
02816         void (_class::*_methodfunc)(A0, A1, A2);
02817     } _func;
02818     void *_obj;
02819 
02820     // Dynamically dispatched operations
02821     const struct ops {
02822         R (*call)(const void*, A0, A1, A2);
02823         void (*move)(void*, const void*);
02824         void (*dtor)(void*);
02825     } *_ops;
02826 
02827     // Generate operations for function object
02828     template <typename F>
02829     void generate(const F &f) {
02830         static const ops ops = {
02831             &Callback::function_call<F>,
02832             &Callback::function_move<F>,
02833             &Callback::function_dtor<F>,
02834         };
02835 
02836         MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
02837         new (this) F(f);
02838         _ops = &ops;
02839     }
02840 
02841     // Function attributes
02842     template <typename F>
02843     static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
02844         return (*(F*)p)(a0, a1, a2);
02845     }
02846 
02847     template <typename F>
02848     static void function_move(void *d, const void *p) {
02849         new (d) F(*(F*)p);
02850     }
02851 
02852     template <typename F>
02853     static void function_dtor(void *p) {
02854         ((F*)p)->~F();
02855     }
02856 
02857     // Wrappers for functions with context
02858     template <typename O, typename M>
02859     struct method_context {
02860         M method;
02861         O *obj;
02862 
02863         method_context(O *obj, M method)
02864             : method(method), obj(obj) {}
02865 
02866         R operator()(A0 a0, A1 a1, A2 a2) const {
02867             return (obj->*method)(a0, a1, a2);
02868         }
02869     };
02870 
02871     template <typename F, typename A>
02872     struct function_context {
02873         F func;
02874         A *arg;
02875 
02876         function_context(F func, A *arg)
02877             : func(func), arg(arg) {}
02878 
02879         R operator()(A0 a0, A1 a1, A2 a2) const {
02880             return func(arg, a0, a1, a2);
02881         }
02882     };
02883 };
02884 
02885 /** Callback class based on template specialization
02886  *
02887  * @Note Synchronization level: Not protected
02888  */
02889 template <typename R, typename A0, typename A1, typename A2, typename A3>
02890 class Callback<R(A0, A1, A2, A3)> {
02891 public:
02892     /** Create a Callback with a static function
02893      *  @param func     Static function to attach
02894      */
02895     Callback(R (*func)(A0, A1, A2, A3) = 0) {
02896         if (!func) {
02897             _ops = 0;
02898         } else {
02899             generate(func);
02900         }
02901     }
02902 
02903     /** Attach a Callback
02904      *  @param func     The Callback to attach
02905      */
02906     Callback(const Callback<R(A0, A1, A2, A3)> &func) {
02907         if (func._ops) {
02908             func._ops->move(this, &func);
02909         }
02910         _ops = func._ops;
02911     }
02912 
02913     /** Create a Callback with a member function
02914      *  @param obj      Pointer to object to invoke member function on
02915      *  @param method   Member function to attach
02916      */
02917     template<typename T>
02918     Callback(T *obj, R (T::*method)(A0, A1, A2, A3)) {
02919         generate(method_context<T, R (T::*)(A0, A1, A2, A3)>(obj, method));
02920     }
02921 
02922     /** Create a Callback with a member function
02923      *  @param obj      Pointer to object to invoke member function on
02924      *  @param method   Member function to attach
02925      */
02926     template<typename T>
02927     Callback(const T *obj, R (T::*method)(A0, A1, A2, A3) const) {
02928         generate(method_context<const T, R (T::*)(A0, A1, A2, A3) const>(obj, method));
02929     }
02930 
02931     /** Create a Callback with a member function
02932      *  @param obj      Pointer to object to invoke member function on
02933      *  @param method   Member function to attach
02934      */
02935     template<typename T>
02936     Callback(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
02937         generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3) volatile>(obj, method));
02938     }
02939 
02940     /** Create a Callback with a member function
02941      *  @param obj      Pointer to object to invoke member function on
02942      *  @param method   Member function to attach
02943      */
02944     template<typename T>
02945     Callback(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
02946         generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3) const volatile>(obj, method));
02947     }
02948 
02949     /** Create a Callback with a static function and bound pointer
02950      *  @param func     Static function to attach
02951      *  @param arg      Pointer argument to function
02952      */
02953     Callback(R (*func)(void*, A0, A1, A2, A3), void *arg) {
02954         generate(function_context<R (*)(void*, A0, A1, A2, A3), void>(func, arg));
02955     }
02956 
02957     /** Create a Callback with a static function and bound pointer
02958      *  @param func     Static function to attach
02959      *  @param arg      Pointer argument to function
02960      */
02961     Callback(R (*func)(const void*, A0, A1, A2, A3), const void *arg) {
02962         generate(function_context<R (*)(const void*, A0, A1, A2, A3), const void>(func, arg));
02963     }
02964 
02965     /** Create a Callback with a static function and bound pointer
02966      *  @param func     Static function to attach
02967      *  @param arg      Pointer argument to function
02968      */
02969     Callback(R (*func)(volatile void*, A0, A1, A2, A3), volatile void *arg) {
02970         generate(function_context<R (*)(volatile void*, A0, A1, A2, A3), volatile void>(func, arg));
02971     }
02972 
02973     /** Create a Callback with a static function and bound pointer
02974      *  @param func     Static function to attach
02975      *  @param arg      Pointer argument to function
02976      */
02977     Callback(R (*func)(const volatile void*, A0, A1, A2, A3), const volatile void *arg) {
02978         generate(function_context<R (*)(const volatile void*, A0, A1, A2, A3), const volatile void>(func, arg));
02979     }
02980 
02981     /** Create a Callback with a static function and bound pointer
02982      *  @param func     Static function to attach
02983      *  @param arg      Pointer argument to function 
02984      */
02985     template<typename T>
02986     Callback(R (*func)(T*, A0, A1, A2, A3), T *arg) {
02987         generate(function_context<R (*)(T*, A0, A1, A2, A3), T>(func, arg));
02988     }
02989 
02990     /** Create a Callback with a static function and bound pointer
02991      *  @param func     Static function to attach
02992      *  @param arg      Pointer argument to function 
02993      */
02994     template<typename T>
02995     Callback(R (*func)(const T*, A0, A1, A2, A3), const T *arg) {
02996         generate(function_context<R (*)(const T*, A0, A1, A2, A3), const T>(func, arg));
02997     }
02998 
02999     /** Create a Callback with a static function and bound pointer
03000      *  @param func     Static function to attach
03001      *  @param arg      Pointer argument to function 
03002      */
03003     template<typename T>
03004     Callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile T *arg) {
03005         generate(function_context<R (*)(volatile T*, A0, A1, A2, A3), volatile T>(func, arg));
03006     }
03007 
03008     /** Create a Callback with a static function and bound pointer
03009      *  @param func     Static function to attach
03010      *  @param arg      Pointer argument to function 
03011      */
03012     template<typename T>
03013     Callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile T *arg) {
03014         generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3), const volatile T>(func, arg));
03015     }
03016 
03017     /** Create a Callback with a function object
03018      *  @param func     Function object to attach
03019      *  @note The function object is limited to a single word of storage
03020      */
03021     template <typename F>
03022     Callback(F f, typename detail::enable_if<
03023                 detail::is_type<R (F::*)(A0, A1, A2, A3), &F::operator()>::value &&
03024                 sizeof(F) <= sizeof(uintptr_t)
03025             >::type = detail::nil()) {
03026         generate(f);
03027     }
03028 
03029     /** Create a Callback with a function object
03030      *  @param func     Function object to attach
03031      *  @note The function object is limited to a single word of storage
03032      */
03033     template <typename F>
03034     Callback(const F f, typename detail::enable_if<
03035                 detail::is_type<R (F::*)(A0, A1, A2, A3) const, &F::operator()>::value &&
03036                 sizeof(F) <= sizeof(uintptr_t)
03037             >::type = detail::nil()) {
03038         generate(f);
03039     }
03040 
03041     /** Create a Callback with a function object
03042      *  @param func     Function object to attach
03043      *  @note The function object is limited to a single word of storage
03044      */
03045     template <typename F>
03046     Callback(volatile F f, typename detail::enable_if<
03047                 detail::is_type<R (F::*)(A0, A1, A2, A3) volatile, &F::operator()>::value &&
03048                 sizeof(F) <= sizeof(uintptr_t)
03049             >::type = detail::nil()) {
03050         generate(f);
03051     }
03052 
03053     /** Create a Callback with a function object
03054      *  @param func     Function object to attach
03055      *  @note The function object is limited to a single word of storage
03056      */
03057     template <typename F>
03058     Callback(const volatile F f, typename detail::enable_if<
03059                 detail::is_type<R (F::*)(A0, A1, A2, A3) const volatile, &F::operator()>::value &&
03060                 sizeof(F) <= sizeof(uintptr_t)
03061             >::type = detail::nil()) {
03062         generate(f);
03063     }
03064 
03065     /** Create a Callback with a static function and bound pointer
03066      *  @param obj  Pointer to object to bind to function
03067      *  @param func Static function to attach
03068      *  @deprecated
03069      *      Arguments to callback have been reordered to Callback(func, arg)
03070      */
03071     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03072         "Arguments to callback have been reordered to Callback(func, arg)")
03073     Callback(void *obj, R (*func)(void*, A0, A1, A2, A3)) {
03074         new (this) Callback(func, obj);
03075     }
03076 
03077     /** Create a Callback with a static function and bound pointer
03078      *  @param obj  Pointer to object to bind to function
03079      *  @param func Static function to attach
03080      *  @deprecated
03081      *      Arguments to callback have been reordered to Callback(func, arg)
03082      */
03083     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03084         "Arguments to callback have been reordered to Callback(func, arg)")
03085     Callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) {
03086         new (this) Callback(func, obj);
03087     }
03088 
03089     /** Create a Callback with a static function and bound pointer
03090      *  @param obj  Pointer to object to bind to function
03091      *  @param func Static function to attach
03092      *  @deprecated
03093      *      Arguments to callback have been reordered to Callback(func, arg)
03094      */
03095     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03096         "Arguments to callback have been reordered to Callback(func, arg)")
03097     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) {
03098         new (this) Callback(func, obj);
03099     }
03100 
03101     /** Create a Callback with a static function and bound pointer
03102      *  @param obj  Pointer to object to bind to function
03103      *  @param func Static function to attach
03104      *  @deprecated
03105      *      Arguments to callback have been reordered to Callback(func, arg)
03106      */
03107     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03108         "Arguments to callback have been reordered to Callback(func, arg)")
03109     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) {
03110         new (this) Callback(func, obj);
03111     }
03112 
03113     /** Create a Callback with a static function and bound pointer
03114      *  @param obj  Pointer to object to bind to function
03115      *  @param func Static function to attach
03116      *  @deprecated
03117      *      Arguments to callback have been reordered to Callback(func, arg)
03118      */
03119     template<typename T>
03120     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03121         "Arguments to callback have been reordered to Callback(func, arg)")
03122     Callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
03123         new (this) Callback(func, obj);
03124     }
03125 
03126     /** Create a Callback with a static function and 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 Callback(func, arg)
03131      */
03132     template<typename T>
03133     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03134         "Arguments to callback have been reordered to Callback(func, arg)")
03135     Callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) {
03136         new (this) Callback(func, obj);
03137     }
03138 
03139     /** Create a Callback with a static function and bound pointer
03140      *  @param obj  Pointer to object to bind to function
03141      *  @param func Static function to attach
03142      *  @deprecated
03143      *      Arguments to callback have been reordered to Callback(func, arg)
03144      */
03145     template<typename T>
03146     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03147         "Arguments to callback have been reordered to Callback(func, arg)")
03148     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
03149         new (this) Callback(func, obj);
03150     }
03151 
03152     /** Create a Callback with a static function and bound pointer
03153      *  @param obj  Pointer to object to bind to function
03154      *  @param func Static function to attach
03155      *  @deprecated
03156      *      Arguments to callback have been reordered to Callback(func, arg)
03157      */
03158     template<typename T>
03159     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03160         "Arguments to callback have been reordered to Callback(func, arg)")
03161     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
03162         new (this) Callback(func, obj);
03163     }
03164 
03165     /** Destroy a callback
03166      */
03167     ~Callback() {
03168         if (_ops) {
03169             _ops->dtor(this);
03170         }
03171     }
03172 
03173     /** Attach a static function
03174      *  @param func     Static function to attach
03175      */
03176     void attach(R (*func)(A0, A1, A2, A3)) {
03177         this->~Callback();
03178         new (this) Callback(func);
03179     }
03180 
03181     /** Attach a Callback
03182      *  @param func     The Callback to attach
03183      */
03184     void attach(const Callback<R(A0, A1, A2, A3)> &func) {
03185         this->~Callback();
03186         new (this) Callback(func);
03187     }
03188 
03189     /** Attach a member function
03190      *  @param obj      Pointer to object to invoke member function on
03191      *  @param method   Member function to attach
03192      */
03193     template<typename T>
03194     void attach(T *obj, R (T::*method)(A0, A1, A2, A3)) {
03195         this->~Callback();
03196         new (this) Callback(obj, method);
03197     }
03198 
03199     /** Attach a member function
03200      *  @param obj      Pointer to object to invoke member function on
03201      *  @param method   Member function to attach
03202      */
03203     template<typename T>
03204     void attach(const T *obj, R (T::*method)(A0, A1, A2, A3) const) {
03205         this->~Callback();
03206         new (this) Callback(obj, method);
03207     }
03208 
03209     /** Attach a member function
03210      *  @param obj      Pointer to object to invoke member function on
03211      *  @param method   Member function to attach
03212      */
03213     template<typename T>
03214     void attach(volatile T *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
03215         this->~Callback();
03216         new (this) Callback(obj, method);
03217     }
03218 
03219     /** Attach a member function
03220      *  @param obj      Pointer to object to invoke member function on
03221      *  @param method   Member function to attach
03222      */
03223     template<typename T>
03224     void attach(const volatile T *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
03225         this->~Callback();
03226         new (this) Callback(obj, method);
03227     }
03228 
03229     /** Attach a static function with a bound pointer
03230      *  @param func     Static function to attach
03231      *  @param arg      Pointer argument to function
03232      */
03233     void attach(R (*func)(void*, A0, A1, A2, A3), void *arg) {
03234         this->~Callback();
03235         new (this) Callback(func, arg);
03236     }
03237 
03238     /** Attach a static function with a bound pointer
03239      *  @param func     Static function to attach
03240      *  @param arg      Pointer argument to function
03241      */
03242     void attach(R (*func)(const void*, A0, A1, A2, A3), const void *arg) {
03243         this->~Callback();
03244         new (this) Callback(func, arg);
03245     }
03246 
03247     /** Attach a static function with a bound pointer
03248      *  @param func     Static function to attach
03249      *  @param arg      Pointer argument to function
03250      */
03251     void attach(R (*func)(volatile void*, A0, A1, A2, A3), volatile void *arg) {
03252         this->~Callback();
03253         new (this) Callback(func, arg);
03254     }
03255 
03256     /** Attach a static function with a bound pointer
03257      *  @param func     Static function to attach
03258      *  @param arg      Pointer argument to function
03259      */
03260     void attach(R (*func)(const volatile void*, A0, A1, A2, A3), const volatile void *arg) {
03261         this->~Callback();
03262         new (this) Callback(func, arg);
03263     }
03264 
03265     /** Attach a static function with a bound pointer
03266      *  @param func     Static function to attach
03267      *  @param arg      Pointer argument to function
03268      */
03269     template <typename T>
03270     void attach(R (*func)(T*, A0, A1, A2, A3), T *arg) {
03271         this->~Callback();
03272         new (this) Callback(func, arg);
03273     }
03274 
03275     /** Attach a static function with a bound pointer
03276      *  @param func     Static function to attach
03277      *  @param arg      Pointer argument to function
03278      */
03279     template <typename T>
03280     void attach(R (*func)(const T*, A0, A1, A2, A3), const T *arg) {
03281         this->~Callback();
03282         new (this) Callback(func, arg);
03283     }
03284 
03285     /** Attach a static function with a bound pointer
03286      *  @param func     Static function to attach
03287      *  @param arg      Pointer argument to function
03288      */
03289     template <typename T>
03290     void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile T *arg) {
03291         this->~Callback();
03292         new (this) Callback(func, arg);
03293     }
03294 
03295     /** Attach a static function with a bound pointer
03296      *  @param func     Static function to attach
03297      *  @param arg      Pointer argument to function
03298      */
03299     template <typename T>
03300     void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile T *arg) {
03301         this->~Callback();
03302         new (this) Callback(func, arg);
03303     }
03304 
03305     /** Attach a function object
03306      *  @param func     Function object to attach
03307      *  @note The function object is limited to a single word of storage
03308      */
03309     template <typename F>
03310     void attach(F f, typename detail::enable_if<
03311                 detail::is_type<R (F::*)(A0, A1, A2, A3), &F::operator()>::value &&
03312                 sizeof(F) <= sizeof(uintptr_t)
03313             >::type = detail::nil()) {
03314         this->~Callback();
03315         new (this) Callback(f);
03316     }
03317 
03318     /** Attach a function object
03319      *  @param func     Function object to attach
03320      *  @note The function object is limited to a single word of storage
03321      */
03322     template <typename F>
03323     void attach(const F f, typename detail::enable_if<
03324                 detail::is_type<R (F::*)(A0, A1, A2, A3) const, &F::operator()>::value &&
03325                 sizeof(F) <= sizeof(uintptr_t)
03326             >::type = detail::nil()) {
03327         this->~Callback();
03328         new (this) Callback(f);
03329     }
03330 
03331     /** Attach a function object
03332      *  @param func     Function object to attach
03333      *  @note The function object is limited to a single word of storage
03334      */
03335     template <typename F>
03336     void attach(volatile F f, typename detail::enable_if<
03337                 detail::is_type<R (F::*)(A0, A1, A2, A3) volatile, &F::operator()>::value &&
03338                 sizeof(F) <= sizeof(uintptr_t)
03339             >::type = detail::nil()) {
03340         this->~Callback();
03341         new (this) Callback(f);
03342     }
03343 
03344     /** Attach a function object
03345      *  @param func     Function object to attach
03346      *  @note The function object is limited to a single word of storage
03347      */
03348     template <typename F>
03349     void attach(const volatile F f, typename detail::enable_if<
03350                 detail::is_type<R (F::*)(A0, A1, A2, A3) const volatile, &F::operator()>::value &&
03351                 sizeof(F) <= sizeof(uintptr_t)
03352             >::type = detail::nil()) {
03353         this->~Callback();
03354         new (this) Callback(f);
03355     }
03356 
03357     /** Attach a static function with a bound pointer
03358      *  @param obj  Pointer to object to bind to function
03359      *  @param func Static function to attach
03360      *  @deprecated
03361      *      Arguments to callback have been reordered to attach(func, arg)
03362      */
03363     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03364         "Arguments to callback have been reordered to attach(func, arg)")
03365     void attach(void *obj, R (*func)(void*, A0, A1, A2, A3)) {
03366         this->~Callback();
03367         new (this) Callback(func, obj);
03368     }
03369 
03370     /** Attach a static function with a bound pointer
03371      *  @param obj  Pointer to object to bind to function
03372      *  @param func Static function to attach
03373      *  @deprecated
03374      *      Arguments to callback have been reordered to attach(func, arg)
03375      */
03376     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03377         "Arguments to callback have been reordered to attach(func, arg)")
03378     void attach(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) {
03379         this->~Callback();
03380         new (this) Callback(func, obj);
03381     }
03382 
03383     /** Attach a static function with a bound pointer
03384      *  @param obj  Pointer to object to bind to function
03385      *  @param func Static function to attach
03386      *  @deprecated
03387      *      Arguments to callback have been reordered to attach(func, arg)
03388      */
03389     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03390         "Arguments to callback have been reordered to attach(func, arg)")
03391     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) {
03392         this->~Callback();
03393         new (this) Callback(func, obj);
03394     }
03395 
03396     /** Attach a static function with a bound pointer
03397      *  @param obj  Pointer to object to bind to function
03398      *  @param func Static function to attach
03399      *  @deprecated
03400      *      Arguments to callback have been reordered to attach(func, arg)
03401      */
03402     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03403         "Arguments to callback have been reordered to attach(func, arg)")
03404     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) {
03405         this->~Callback();
03406         new (this) Callback(func, obj);
03407     }
03408 
03409     /** Attach a static function with a bound pointer
03410      *  @param obj  Pointer to object to bind to function
03411      *  @param func Static function to attach
03412      *  @deprecated
03413      *      Arguments to callback have been reordered to attach(func, arg)
03414      */
03415     template <typename T>
03416     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03417         "Arguments to callback have been reordered to attach(func, arg)")
03418     void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
03419         this->~Callback();
03420         new (this) Callback(func, obj);
03421     }
03422 
03423     /** Attach a static function with a bound pointer
03424      *  @param obj  Pointer to object to bind to function
03425      *  @param func Static function to attach
03426      *  @deprecated
03427      *      Arguments to callback have been reordered to attach(func, arg)
03428      */
03429     template <typename T>
03430     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03431         "Arguments to callback have been reordered to attach(func, arg)")
03432     void attach(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) {
03433         this->~Callback();
03434         new (this) Callback(func, obj);
03435     }
03436 
03437     /** Attach a static function with a bound pointer
03438      *  @param obj  Pointer to object to bind to function
03439      *  @param func Static function to attach
03440      *  @deprecated
03441      *      Arguments to callback have been reordered to attach(func, arg)
03442      */
03443     template <typename T>
03444     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03445         "Arguments to callback have been reordered to attach(func, arg)")
03446     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
03447         this->~Callback();
03448         new (this) Callback(func, obj);
03449     }
03450 
03451     /** Attach a static function with a bound pointer
03452      *  @param obj  Pointer to object to bind to function
03453      *  @param func Static function to attach
03454      *  @deprecated
03455      *      Arguments to callback have been reordered to attach(func, arg)
03456      */
03457     template <typename T>
03458     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03459         "Arguments to callback have been reordered to attach(func, arg)")
03460     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
03461         this->~Callback();
03462         new (this) Callback(func, obj);
03463     }
03464 
03465     /** Assign a callback
03466      */
03467     Callback &operator=(const Callback &that) {
03468         if (this != &that) {
03469             this->~Callback();
03470             new (this) Callback(that);
03471         }
03472 
03473         return *this;
03474     }
03475 
03476     /** Call the attached function
03477      */
03478     R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
03479         MBED_ASSERT(_ops);
03480         return _ops->call(this, a0, a1, a2, a3);
03481     }
03482 
03483     /** Call the attached function
03484      */
03485     R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
03486         return call(a0, a1, a2, a3);
03487     }
03488 
03489     /** Test if function has been attached
03490      */
03491     operator bool() const {
03492         return _ops;
03493     }
03494 
03495     /** Test for equality
03496      */
03497     friend bool operator==(const Callback &l, const Callback &r) {
03498         return memcmp(&l, &r, sizeof(Callback)) == 0;
03499     }
03500 
03501     /** Test for inequality
03502      */
03503     friend bool operator!=(const Callback &l, const Callback &r) {
03504         return !(l == r);
03505     }
03506 
03507     /** Static thunk for passing as C-style function
03508      *  @param func Callback to call passed as void pointer
03509      */
03510     static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
03511         return static_cast<Callback*>(func)->call(a0, a1, a2, a3);
03512     }
03513 
03514 private:
03515     // Stored as pointer to function and pointer to optional object
03516     // Function pointer is stored as union of possible function types
03517     // to garuntee proper size and alignment
03518     struct _class;
03519     union {
03520         void (*_staticfunc)(A0, A1, A2, A3);
03521         void (*_boundfunc)(_class*, A0, A1, A2, A3);
03522         void (_class::*_methodfunc)(A0, A1, A2, A3);
03523     } _func;
03524     void *_obj;
03525 
03526     // Dynamically dispatched operations
03527     const struct ops {
03528         R (*call)(const void*, A0, A1, A2, A3);
03529         void (*move)(void*, const void*);
03530         void (*dtor)(void*);
03531     } *_ops;
03532 
03533     // Generate operations for function object
03534     template <typename F>
03535     void generate(const F &f) {
03536         static const ops ops = {
03537             &Callback::function_call<F>,
03538             &Callback::function_move<F>,
03539             &Callback::function_dtor<F>,
03540         };
03541 
03542         MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
03543         new (this) F(f);
03544         _ops = &ops;
03545     }
03546 
03547     // Function attributes
03548     template <typename F>
03549     static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
03550         return (*(F*)p)(a0, a1, a2, a3);
03551     }
03552 
03553     template <typename F>
03554     static void function_move(void *d, const void *p) {
03555         new (d) F(*(F*)p);
03556     }
03557 
03558     template <typename F>
03559     static void function_dtor(void *p) {
03560         ((F*)p)->~F();
03561     }
03562 
03563     // Wrappers for functions with context
03564     template <typename O, typename M>
03565     struct method_context {
03566         M method;
03567         O *obj;
03568 
03569         method_context(O *obj, M method)
03570             : method(method), obj(obj) {}
03571 
03572         R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
03573             return (obj->*method)(a0, a1, a2, a3);
03574         }
03575     };
03576 
03577     template <typename F, typename A>
03578     struct function_context {
03579         F func;
03580         A *arg;
03581 
03582         function_context(F func, A *arg)
03583             : func(func), arg(arg) {}
03584 
03585         R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
03586             return func(arg, a0, a1, a2, a3);
03587         }
03588     };
03589 };
03590 
03591 /** Callback class based on template specialization
03592  *
03593  * @Note Synchronization level: Not protected
03594  */
03595 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03596 class Callback<R(A0, A1, A2, A3, A4)> {
03597 public:
03598     /** Create a Callback with a static function
03599      *  @param func     Static function to attach
03600      */
03601     Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
03602         if (!func) {
03603             _ops = 0;
03604         } else {
03605             generate(func);
03606         }
03607     }
03608 
03609     /** Attach a Callback
03610      *  @param func     The Callback to attach
03611      */
03612     Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
03613         if (func._ops) {
03614             func._ops->move(this, &func);
03615         }
03616         _ops = func._ops;
03617     }
03618 
03619     /** Create a Callback with a member function
03620      *  @param obj      Pointer to object to invoke member function on
03621      *  @param method   Member function to attach
03622      */
03623     template<typename T>
03624     Callback(T *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
03625         generate(method_context<T, R (T::*)(A0, A1, A2, A3, A4)>(obj, method));
03626     }
03627 
03628     /** Create a Callback with a member function
03629      *  @param obj      Pointer to object to invoke member function on
03630      *  @param method   Member function to attach
03631      */
03632     template<typename T>
03633     Callback(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
03634         generate(method_context<const T, R (T::*)(A0, A1, A2, A3, A4) const>(obj, method));
03635     }
03636 
03637     /** Create a Callback with a member function
03638      *  @param obj      Pointer to object to invoke member function on
03639      *  @param method   Member function to attach
03640      */
03641     template<typename T>
03642     Callback(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
03643         generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
03644     }
03645 
03646     /** Create a Callback with a member function
03647      *  @param obj      Pointer to object to invoke member function on
03648      *  @param method   Member function to attach
03649      */
03650     template<typename T>
03651     Callback(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
03652         generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
03653     }
03654 
03655     /** Create a Callback with a static function and bound pointer
03656      *  @param func     Static function to attach
03657      *  @param arg      Pointer argument to function
03658      */
03659     Callback(R (*func)(void*, A0, A1, A2, A3, A4), void *arg) {
03660         generate(function_context<R (*)(void*, A0, A1, A2, A3, A4), void>(func, arg));
03661     }
03662 
03663     /** Create a Callback with a static function and bound pointer
03664      *  @param func     Static function to attach
03665      *  @param arg      Pointer argument to function
03666      */
03667     Callback(R (*func)(const void*, A0, A1, A2, A3, A4), const void *arg) {
03668         generate(function_context<R (*)(const void*, A0, A1, A2, A3, A4), const void>(func, arg));
03669     }
03670 
03671     /** Create a Callback with a static function and bound pointer
03672      *  @param func     Static function to attach
03673      *  @param arg      Pointer argument to function
03674      */
03675     Callback(R (*func)(volatile void*, A0, A1, A2, A3, A4), volatile void *arg) {
03676         generate(function_context<R (*)(volatile void*, A0, A1, A2, A3, A4), volatile void>(func, arg));
03677     }
03678 
03679     /** Create a Callback with a static function and bound pointer
03680      *  @param func     Static function to attach
03681      *  @param arg      Pointer argument to function
03682      */
03683     Callback(R (*func)(const volatile void*, A0, A1, A2, A3, A4), const volatile void *arg) {
03684         generate(function_context<R (*)(const volatile void*, A0, A1, A2, A3, A4), const volatile void>(func, arg));
03685     }
03686 
03687     /** Create a Callback with a static function and bound pointer
03688      *  @param func     Static function to attach
03689      *  @param arg      Pointer argument to function 
03690      */
03691     template<typename T>
03692     Callback(R (*func)(T*, A0, A1, A2, A3, A4), T *arg) {
03693         generate(function_context<R (*)(T*, A0, A1, A2, A3, A4), T>(func, arg));
03694     }
03695 
03696     /** Create a Callback with a static function and bound pointer
03697      *  @param func     Static function to attach
03698      *  @param arg      Pointer argument to function 
03699      */
03700     template<typename T>
03701     Callback(R (*func)(const T*, A0, A1, A2, A3, A4), const T *arg) {
03702         generate(function_context<R (*)(const T*, A0, A1, A2, A3, A4), const T>(func, arg));
03703     }
03704 
03705     /** Create a Callback with a static function and bound pointer
03706      *  @param func     Static function to attach
03707      *  @param arg      Pointer argument to function 
03708      */
03709     template<typename T>
03710     Callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile T *arg) {
03711         generate(function_context<R (*)(volatile T*, A0, A1, A2, A3, A4), volatile T>(func, arg));
03712     }
03713 
03714     /** Create a Callback with a static function and bound pointer
03715      *  @param func     Static function to attach
03716      *  @param arg      Pointer argument to function 
03717      */
03718     template<typename T>
03719     Callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile T *arg) {
03720         generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3, A4), const volatile T>(func, arg));
03721     }
03722 
03723     /** Create a Callback with a function object
03724      *  @param func     Function object to attach
03725      *  @note The function object is limited to a single word of storage
03726      */
03727     template <typename F>
03728     Callback(F f, typename detail::enable_if<
03729                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4), &F::operator()>::value &&
03730                 sizeof(F) <= sizeof(uintptr_t)
03731             >::type = detail::nil()) {
03732         generate(f);
03733     }
03734 
03735     /** Create a Callback with a function object
03736      *  @param func     Function object to attach
03737      *  @note The function object is limited to a single word of storage
03738      */
03739     template <typename F>
03740     Callback(const F f, typename detail::enable_if<
03741                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const, &F::operator()>::value &&
03742                 sizeof(F) <= sizeof(uintptr_t)
03743             >::type = detail::nil()) {
03744         generate(f);
03745     }
03746 
03747     /** Create a Callback with a function object
03748      *  @param func     Function object to attach
03749      *  @note The function object is limited to a single word of storage
03750      */
03751     template <typename F>
03752     Callback(volatile F f, typename detail::enable_if<
03753                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4) volatile, &F::operator()>::value &&
03754                 sizeof(F) <= sizeof(uintptr_t)
03755             >::type = detail::nil()) {
03756         generate(f);
03757     }
03758 
03759     /** Create a Callback with a function object
03760      *  @param func     Function object to attach
03761      *  @note The function object is limited to a single word of storage
03762      */
03763     template <typename F>
03764     Callback(const volatile F f, typename detail::enable_if<
03765                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const volatile, &F::operator()>::value &&
03766                 sizeof(F) <= sizeof(uintptr_t)
03767             >::type = detail::nil()) {
03768         generate(f);
03769     }
03770 
03771     /** Create a Callback with a static function and bound pointer
03772      *  @param obj  Pointer to object to bind to function
03773      *  @param func Static function to attach
03774      *  @deprecated
03775      *      Arguments to callback have been reordered to Callback(func, arg)
03776      */
03777     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03778         "Arguments to callback have been reordered to Callback(func, arg)")
03779     Callback(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) {
03780         new (this) Callback(func, obj);
03781     }
03782 
03783     /** Create a Callback with a static function and bound pointer
03784      *  @param obj  Pointer to object to bind to function
03785      *  @param func Static function to attach
03786      *  @deprecated
03787      *      Arguments to callback have been reordered to Callback(func, arg)
03788      */
03789     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03790         "Arguments to callback have been reordered to Callback(func, arg)")
03791     Callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) {
03792         new (this) Callback(func, obj);
03793     }
03794 
03795     /** Create a Callback with a static function and bound pointer
03796      *  @param obj  Pointer to object to bind to function
03797      *  @param func Static function to attach
03798      *  @deprecated
03799      *      Arguments to callback have been reordered to Callback(func, arg)
03800      */
03801     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03802         "Arguments to callback have been reordered to Callback(func, arg)")
03803     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) {
03804         new (this) Callback(func, obj);
03805     }
03806 
03807     /** Create a Callback with a static function and bound pointer
03808      *  @param obj  Pointer to object to bind to function
03809      *  @param func Static function to attach
03810      *  @deprecated
03811      *      Arguments to callback have been reordered to Callback(func, arg)
03812      */
03813     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03814         "Arguments to callback have been reordered to Callback(func, arg)")
03815     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) {
03816         new (this) Callback(func, obj);
03817     }
03818 
03819     /** Create a Callback with a static function and bound pointer
03820      *  @param obj  Pointer to object to bind to function
03821      *  @param func Static function to attach
03822      *  @deprecated
03823      *      Arguments to callback have been reordered to Callback(func, arg)
03824      */
03825     template<typename T>
03826     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03827         "Arguments to callback have been reordered to Callback(func, arg)")
03828     Callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
03829         new (this) Callback(func, obj);
03830     }
03831 
03832     /** Create a Callback with a static function and bound pointer
03833      *  @param obj  Pointer to object to bind to function
03834      *  @param func Static function to attach
03835      *  @deprecated
03836      *      Arguments to callback have been reordered to Callback(func, arg)
03837      */
03838     template<typename T>
03839     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03840         "Arguments to callback have been reordered to Callback(func, arg)")
03841     Callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
03842         new (this) Callback(func, obj);
03843     }
03844 
03845     /** Create a Callback with a static function and bound pointer
03846      *  @param obj  Pointer to object to bind to function
03847      *  @param func Static function to attach
03848      *  @deprecated
03849      *      Arguments to callback have been reordered to Callback(func, arg)
03850      */
03851     template<typename T>
03852     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03853         "Arguments to callback have been reordered to Callback(func, arg)")
03854     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
03855         new (this) Callback(func, obj);
03856     }
03857 
03858     /** Create a Callback with a static function and bound pointer
03859      *  @param obj  Pointer to object to bind to function
03860      *  @param func Static function to attach
03861      *  @deprecated
03862      *      Arguments to callback have been reordered to Callback(func, arg)
03863      */
03864     template<typename T>
03865     MBED_DEPRECATED_SINCE("mbed-os-5.1",
03866         "Arguments to callback have been reordered to Callback(func, arg)")
03867     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
03868         new (this) Callback(func, obj);
03869     }
03870 
03871     /** Destroy a callback
03872      */
03873     ~Callback() {
03874         if (_ops) {
03875             _ops->dtor(this);
03876         }
03877     }
03878 
03879     /** Attach a static function
03880      *  @param func     Static function to attach
03881      */
03882     void attach(R (*func)(A0, A1, A2, A3, A4)) {
03883         this->~Callback();
03884         new (this) Callback(func);
03885     }
03886 
03887     /** Attach a Callback
03888      *  @param func     The Callback to attach
03889      */
03890     void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
03891         this->~Callback();
03892         new (this) Callback(func);
03893     }
03894 
03895     /** Attach a member function
03896      *  @param obj      Pointer to object to invoke member function on
03897      *  @param method   Member function to attach
03898      */
03899     template<typename T>
03900     void attach(T *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
03901         this->~Callback();
03902         new (this) Callback(obj, method);
03903     }
03904 
03905     /** Attach a member function
03906      *  @param obj      Pointer to object to invoke member function on
03907      *  @param method   Member function to attach
03908      */
03909     template<typename T>
03910     void attach(const T *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
03911         this->~Callback();
03912         new (this) Callback(obj, method);
03913     }
03914 
03915     /** Attach a member function
03916      *  @param obj      Pointer to object to invoke member function on
03917      *  @param method   Member function to attach
03918      */
03919     template<typename T>
03920     void attach(volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
03921         this->~Callback();
03922         new (this) Callback(obj, method);
03923     }
03924 
03925     /** Attach a member function
03926      *  @param obj      Pointer to object to invoke member function on
03927      *  @param method   Member function to attach
03928      */
03929     template<typename T>
03930     void attach(const volatile T *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
03931         this->~Callback();
03932         new (this) Callback(obj, method);
03933     }
03934 
03935     /** Attach a static function with a bound pointer
03936      *  @param func     Static function to attach
03937      *  @param arg      Pointer argument to function
03938      */
03939     void attach(R (*func)(void*, A0, A1, A2, A3, A4), void *arg) {
03940         this->~Callback();
03941         new (this) Callback(func, arg);
03942     }
03943 
03944     /** Attach a static function with a bound pointer
03945      *  @param func     Static function to attach
03946      *  @param arg      Pointer argument to function
03947      */
03948     void attach(R (*func)(const void*, A0, A1, A2, A3, A4), const void *arg) {
03949         this->~Callback();
03950         new (this) Callback(func, arg);
03951     }
03952 
03953     /** Attach a static function with a bound pointer
03954      *  @param func     Static function to attach
03955      *  @param arg      Pointer argument to function
03956      */
03957     void attach(R (*func)(volatile void*, A0, A1, A2, A3, A4), volatile void *arg) {
03958         this->~Callback();
03959         new (this) Callback(func, arg);
03960     }
03961 
03962     /** Attach a static function with a bound pointer
03963      *  @param func     Static function to attach
03964      *  @param arg      Pointer argument to function
03965      */
03966     void attach(R (*func)(const volatile void*, A0, A1, A2, A3, A4), const volatile void *arg) {
03967         this->~Callback();
03968         new (this) Callback(func, arg);
03969     }
03970 
03971     /** Attach a static function with a bound pointer
03972      *  @param func     Static function to attach
03973      *  @param arg      Pointer argument to function
03974      */
03975     template <typename T>
03976     void attach(R (*func)(T*, A0, A1, A2, A3, A4), T *arg) {
03977         this->~Callback();
03978         new (this) Callback(func, arg);
03979     }
03980 
03981     /** Attach a static function with a bound pointer
03982      *  @param func     Static function to attach
03983      *  @param arg      Pointer argument to function
03984      */
03985     template <typename T>
03986     void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const T *arg) {
03987         this->~Callback();
03988         new (this) Callback(func, arg);
03989     }
03990 
03991     /** Attach a static function with a bound pointer
03992      *  @param func     Static function to attach
03993      *  @param arg      Pointer argument to function
03994      */
03995     template <typename T>
03996     void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile T *arg) {
03997         this->~Callback();
03998         new (this) Callback(func, arg);
03999     }
04000 
04001     /** Attach a static function with a bound pointer
04002      *  @param func     Static function to attach
04003      *  @param arg      Pointer argument to function
04004      */
04005     template <typename T>
04006     void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile T *arg) {
04007         this->~Callback();
04008         new (this) Callback(func, arg);
04009     }
04010 
04011     /** Attach a function object
04012      *  @param func     Function object to attach
04013      *  @note The function object is limited to a single word of storage
04014      */
04015     template <typename F>
04016     void attach(F f, typename detail::enable_if<
04017                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4), &F::operator()>::value &&
04018                 sizeof(F) <= sizeof(uintptr_t)
04019             >::type = detail::nil()) {
04020         this->~Callback();
04021         new (this) Callback(f);
04022     }
04023 
04024     /** Attach a function object
04025      *  @param func     Function object to attach
04026      *  @note The function object is limited to a single word of storage
04027      */
04028     template <typename F>
04029     void attach(const F f, typename detail::enable_if<
04030                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const, &F::operator()>::value &&
04031                 sizeof(F) <= sizeof(uintptr_t)
04032             >::type = detail::nil()) {
04033         this->~Callback();
04034         new (this) Callback(f);
04035     }
04036 
04037     /** Attach a function object
04038      *  @param func     Function object to attach
04039      *  @note The function object is limited to a single word of storage
04040      */
04041     template <typename F>
04042     void attach(volatile F f, typename detail::enable_if<
04043                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4) volatile, &F::operator()>::value &&
04044                 sizeof(F) <= sizeof(uintptr_t)
04045             >::type = detail::nil()) {
04046         this->~Callback();
04047         new (this) Callback(f);
04048     }
04049 
04050     /** Attach a function object
04051      *  @param func     Function object to attach
04052      *  @note The function object is limited to a single word of storage
04053      */
04054     template <typename F>
04055     void attach(const volatile F f, typename detail::enable_if<
04056                 detail::is_type<R (F::*)(A0, A1, A2, A3, A4) const volatile, &F::operator()>::value &&
04057                 sizeof(F) <= sizeof(uintptr_t)
04058             >::type = detail::nil()) {
04059         this->~Callback();
04060         new (this) Callback(f);
04061     }
04062 
04063     /** Attach a static function with a bound pointer
04064      *  @param obj  Pointer to object to bind to function
04065      *  @param func Static function to attach
04066      *  @deprecated
04067      *      Arguments to callback have been reordered to attach(func, arg)
04068      */
04069     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04070         "Arguments to callback have been reordered to attach(func, arg)")
04071     void attach(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) {
04072         this->~Callback();
04073         new (this) Callback(func, obj);
04074     }
04075 
04076     /** Attach a static function with a bound pointer
04077      *  @param obj  Pointer to object to bind to function
04078      *  @param func Static function to attach
04079      *  @deprecated
04080      *      Arguments to callback have been reordered to attach(func, arg)
04081      */
04082     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04083         "Arguments to callback have been reordered to attach(func, arg)")
04084     void attach(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) {
04085         this->~Callback();
04086         new (this) Callback(func, obj);
04087     }
04088 
04089     /** Attach a static function with a bound pointer
04090      *  @param obj  Pointer to object to bind to function
04091      *  @param func Static function to attach
04092      *  @deprecated
04093      *      Arguments to callback have been reordered to attach(func, arg)
04094      */
04095     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04096         "Arguments to callback have been reordered to attach(func, arg)")
04097     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) {
04098         this->~Callback();
04099         new (this) Callback(func, obj);
04100     }
04101 
04102     /** Attach a static function with a bound pointer
04103      *  @param obj  Pointer to object to bind to function
04104      *  @param func Static function to attach
04105      *  @deprecated
04106      *      Arguments to callback have been reordered to attach(func, arg)
04107      */
04108     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04109         "Arguments to callback have been reordered to attach(func, arg)")
04110     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) {
04111         this->~Callback();
04112         new (this) Callback(func, obj);
04113     }
04114 
04115     /** Attach a static function with a bound pointer
04116      *  @param obj  Pointer to object to bind to function
04117      *  @param func Static function to attach
04118      *  @deprecated
04119      *      Arguments to callback have been reordered to attach(func, arg)
04120      */
04121     template <typename T>
04122     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04123         "Arguments to callback have been reordered to attach(func, arg)")
04124     void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
04125         this->~Callback();
04126         new (this) Callback(func, obj);
04127     }
04128 
04129     /** Attach a static function with a bound pointer
04130      *  @param obj  Pointer to object to bind to function
04131      *  @param func Static function to attach
04132      *  @deprecated
04133      *      Arguments to callback have been reordered to attach(func, arg)
04134      */
04135     template <typename T>
04136     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04137         "Arguments to callback have been reordered to attach(func, arg)")
04138     void attach(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
04139         this->~Callback();
04140         new (this) Callback(func, obj);
04141     }
04142 
04143     /** Attach a static function with a bound pointer
04144      *  @param obj  Pointer to object to bind to function
04145      *  @param func Static function to attach
04146      *  @deprecated
04147      *      Arguments to callback have been reordered to attach(func, arg)
04148      */
04149     template <typename T>
04150     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04151         "Arguments to callback have been reordered to attach(func, arg)")
04152     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
04153         this->~Callback();
04154         new (this) Callback(func, obj);
04155     }
04156 
04157     /** Attach a static function with a bound pointer
04158      *  @param obj  Pointer to object to bind to function
04159      *  @param func Static function to attach
04160      *  @deprecated
04161      *      Arguments to callback have been reordered to attach(func, arg)
04162      */
04163     template <typename T>
04164     MBED_DEPRECATED_SINCE("mbed-os-5.1",
04165         "Arguments to callback have been reordered to attach(func, arg)")
04166     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
04167         this->~Callback();
04168         new (this) Callback(func, obj);
04169     }
04170 
04171     /** Assign a callback
04172      */
04173     Callback &operator=(const Callback &that) {
04174         if (this != &that) {
04175             this->~Callback();
04176             new (this) Callback(that);
04177         }
04178 
04179         return *this;
04180     }
04181 
04182     /** Call the attached function
04183      */
04184     R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
04185         MBED_ASSERT(_ops);
04186         return _ops->call(this, a0, a1, a2, a3, a4);
04187     }
04188 
04189     /** Call the attached function
04190      */
04191     R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
04192         return call(a0, a1, a2, a3, a4);
04193     }
04194 
04195     /** Test if function has been attached
04196      */
04197     operator bool() const {
04198         return _ops;
04199     }
04200 
04201     /** Test for equality
04202      */
04203     friend bool operator==(const Callback &l, const Callback &r) {
04204         return memcmp(&l, &r, sizeof(Callback)) == 0;
04205     }
04206 
04207     /** Test for inequality
04208      */
04209     friend bool operator!=(const Callback &l, const Callback &r) {
04210         return !(l == r);
04211     }
04212 
04213     /** Static thunk for passing as C-style function
04214      *  @param func Callback to call passed as void pointer
04215      */
04216     static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
04217         return static_cast<Callback*>(func)->call(a0, a1, a2, a3, a4);
04218     }
04219 
04220 private:
04221     // Stored as pointer to function and pointer to optional object
04222     // Function pointer is stored as union of possible function types
04223     // to garuntee proper size and alignment
04224     struct _class;
04225     union {
04226         void (*_staticfunc)(A0, A1, A2, A3, A4);
04227         void (*_boundfunc)(_class*, A0, A1, A2, A3, A4);
04228         void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
04229     } _func;
04230     void *_obj;
04231 
04232     // Dynamically dispatched operations
04233     const struct ops {
04234         R (*call)(const void*, A0, A1, A2, A3, A4);
04235         void (*move)(void*, const void*);
04236         void (*dtor)(void*);
04237     } *_ops;
04238 
04239     // Generate operations for function object
04240     template <typename F>
04241     void generate(const F &f) {
04242         static const ops ops = {
04243             &Callback::function_call<F>,
04244             &Callback::function_move<F>,
04245             &Callback::function_dtor<F>,
04246         };
04247 
04248         MBED_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F));
04249         new (this) F(f);
04250         _ops = &ops;
04251     }
04252 
04253     // Function attributes
04254     template <typename F>
04255     static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
04256         return (*(F*)p)(a0, a1, a2, a3, a4);
04257     }
04258 
04259     template <typename F>
04260     static void function_move(void *d, const void *p) {
04261         new (d) F(*(F*)p);
04262     }
04263 
04264     template <typename F>
04265     static void function_dtor(void *p) {
04266         ((F*)p)->~F();
04267     }
04268 
04269     // Wrappers for functions with context
04270     template <typename O, typename M>
04271     struct method_context {
04272         M method;
04273         O *obj;
04274 
04275         method_context(O *obj, M method)
04276             : method(method), obj(obj) {}
04277 
04278         R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
04279             return (obj->*method)(a0, a1, a2, a3, a4);
04280         }
04281     };
04282 
04283     template <typename F, typename A>
04284     struct function_context {
04285         F func;
04286         A *arg;
04287 
04288         function_context(F func, A *arg)
04289             : func(func), arg(arg) {}
04290 
04291         R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
04292             return func(arg, a0, a1, a2, a3, a4);
04293         }
04294     };
04295 };
04296 
04297 // Internally used event type
04298 typedef Callback<void(int)> event_callback_t;
04299 
04300 
04301 /** Create a callback class with type infered from the arguments
04302  *
04303  *  @param func     Static function to attach
04304  *  @return         Callback with infered type
04305  */
04306 template <typename R>
04307 Callback<R()> callback(R (*func)() = 0) {
04308     return Callback<R()>(func);
04309 }
04310 
04311 /** Create a callback class with type infered from the arguments
04312  *
04313  *  @param func     Static function to attach
04314  *  @return         Callback with infered type
04315  */
04316 template <typename R>
04317 Callback<R()> callback(const Callback<R()> &func) {
04318     return Callback<R()>(func);
04319 }
04320 
04321 /** Create a callback class with type infered from the arguments
04322  *
04323  *  @param obj      Optional pointer to object to bind to function
04324  *  @param method   Member function to attach
04325  *  @return         Callback with infered type
04326  */
04327 template<typename T, typename R>
04328 Callback<R()> callback(T *obj, R (T::*func)()) {
04329     return Callback<R()>(obj, func);
04330 }
04331 
04332 /** Create a callback class with type infered from the arguments
04333  *
04334  *  @param obj      Optional pointer to object to bind to function
04335  *  @param method   Member function to attach
04336  *  @return         Callback with infered type
04337  */
04338 template<typename T, typename R>
04339 Callback<R()> callback(const T *obj, R (T::*func)() const) {
04340     return Callback<R()>(obj, func);
04341 }
04342 
04343 /** Create a callback class with type infered from the arguments
04344  *
04345  *  @param obj      Optional pointer to object to bind to function
04346  *  @param method   Member function to attach
04347  *  @return         Callback with infered type
04348  */
04349 template<typename T, typename R>
04350 Callback<R()> callback(volatile T *obj, R (T::*func)() volatile) {
04351     return Callback<R()>(obj, func);
04352 }
04353 
04354 /** Create a callback class with type infered from the arguments
04355  *
04356  *  @param obj      Optional pointer to object to bind to function
04357  *  @param method   Member function to attach
04358  *  @return         Callback with infered type
04359  */
04360 template<typename T, typename R>
04361 Callback<R()> callback(const volatile T *obj, R (T::*func)() const volatile) {
04362     return Callback<R()>(obj, func);
04363 }
04364 
04365 /** Create a callback class with type infered from the arguments
04366  *
04367  *  @param func     Static function to attach
04368  *  @param arg      Pointer argument to function
04369  *  @return         Callback with infered type
04370  */
04371 template <typename R>
04372 Callback<R()> callback(R (*func)(void*), void *arg) {
04373     return Callback<R()>(func, arg);
04374 }
04375 
04376 /** Create a callback class with type infered from the arguments
04377  *
04378  *  @param func     Static function to attach
04379  *  @param arg      Pointer argument to function
04380  *  @return         Callback with infered type
04381  */
04382 template <typename R>
04383 Callback<R()> callback(R (*func)(const void*), const void *arg) {
04384     return Callback<R()>(func, arg);
04385 }
04386 
04387 /** Create a callback class with type infered from the arguments
04388  *
04389  *  @param func     Static function to attach
04390  *  @param arg      Pointer argument to function
04391  *  @return         Callback with infered type
04392  */
04393 template <typename R>
04394 Callback<R()> callback(R (*func)(volatile void*), volatile void *arg) {
04395     return Callback<R()>(func, arg);
04396 }
04397 
04398 /** Create a callback class with type infered from the arguments
04399  *
04400  *  @param func     Static function to attach
04401  *  @param arg      Pointer argument to function
04402  *  @return         Callback with infered type
04403  */
04404 template <typename R>
04405 Callback<R()> callback(R (*func)(const volatile void*), const volatile void *arg) {
04406     return Callback<R()>(func, arg);
04407 }
04408 
04409 /** Create a callback class with type infered from the arguments
04410  *
04411  *  @param func     Static function to attach
04412  *  @param arg      Pointer argument to function
04413  *  @return         Callback with infered type
04414  */
04415 template <typename T, typename R>
04416 Callback<R()> callback(R (*func)(T*), T *arg) {
04417     return Callback<R()>(func, arg);
04418 }
04419 
04420 /** Create a callback class with type infered from the arguments
04421  *
04422  *  @param func     Static function to attach
04423  *  @param arg      Pointer argument to function
04424  *  @return         Callback with infered type
04425  */
04426 template <typename T, typename R>
04427 Callback<R()> callback(R (*func)(const T*), const T *arg) {
04428     return Callback<R()>(func, arg);
04429 }
04430 
04431 /** Create a callback class with type infered from the arguments
04432  *
04433  *  @param func     Static function to attach
04434  *  @param arg      Pointer argument to function
04435  *  @return         Callback with infered type
04436  */
04437 template <typename T, typename R>
04438 Callback<R()> callback(R (*func)(volatile T*), volatile T *arg) {
04439     return Callback<R()>(func, arg);
04440 }
04441 
04442 /** Create a callback class with type infered from the arguments
04443  *
04444  *  @param func     Static function to attach
04445  *  @param arg      Pointer argument to function
04446  *  @return         Callback with infered type
04447  */
04448 template <typename T, typename R>
04449 Callback<R()> callback(R (*func)(const volatile T*), const volatile T *arg) {
04450     return Callback<R()>(func, arg);
04451 }
04452 
04453 /** Create a callback class with type infered from the arguments
04454  *
04455  *  @param obj  Optional pointer to object to bind to function
04456  *  @param func Static function to attach
04457  *  @return     Callback with infered type
04458  *  @deprecated
04459  *      Arguments to callback have been reordered to callback(func, arg)
04460  */
04461 template <typename R>
04462 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04463     "Arguments to callback have been reordered to callback(func, arg)")
04464 Callback<R()> callback(void *obj, R (*func)(void*)) {
04465     return Callback<R()>(func, obj);
04466 }
04467 
04468 /** Create a callback class with type infered from the arguments
04469  *
04470  *  @param obj  Optional pointer to object to bind to function
04471  *  @param func Static function to attach
04472  *  @return     Callback with infered type
04473  *  @deprecated
04474  *      Arguments to callback have been reordered to callback(func, arg)
04475  */
04476 template <typename R>
04477 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04478     "Arguments to callback have been reordered to callback(func, arg)")
04479 Callback<R()> callback(const void *obj, R (*func)(const void*)) {
04480     return Callback<R()>(func, obj);
04481 }
04482 
04483 /** Create a callback class with type infered from the arguments
04484  *
04485  *  @param obj  Optional pointer to object to bind to function
04486  *  @param func Static function to attach
04487  *  @return     Callback with infered type
04488  *  @deprecated
04489  *      Arguments to callback have been reordered to callback(func, arg)
04490  */
04491 template <typename R>
04492 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04493     "Arguments to callback have been reordered to callback(func, arg)")
04494 Callback<R()> callback(volatile void *obj, R (*func)(volatile void*)) {
04495     return Callback<R()>(func, obj);
04496 }
04497 
04498 /** Create a callback class with type infered from the arguments
04499  *
04500  *  @param obj  Optional pointer to object to bind to function
04501  *  @param func Static function to attach
04502  *  @return     Callback with infered type
04503  *  @deprecated
04504  *      Arguments to callback have been reordered to callback(func, arg)
04505  */
04506 template <typename R>
04507 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04508     "Arguments to callback have been reordered to callback(func, arg)")
04509 Callback<R()> callback(const volatile void *obj, R (*func)(const volatile void*)) {
04510     return Callback<R()>(func, obj);
04511 }
04512 
04513 /** Create a callback class with type infered from the arguments
04514  *
04515  *  @param obj  Optional pointer to object to bind to function
04516  *  @param func Static function to attach
04517  *  @return     Callback with infered type
04518  *  @deprecated
04519  *      Arguments to callback have been reordered to callback(func, arg)
04520  */
04521 template <typename T, typename R>
04522 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04523     "Arguments to callback have been reordered to callback(func, arg)")
04524 Callback<R()> callback(T *obj, R (*func)(T*)) {
04525     return Callback<R()>(func, obj);
04526 }
04527 
04528 /** Create a callback class with type infered from the arguments
04529  *
04530  *  @param obj  Optional pointer to object to bind to function
04531  *  @param func Static function to attach
04532  *  @return     Callback with infered type
04533  *  @deprecated
04534  *      Arguments to callback have been reordered to callback(func, arg)
04535  */
04536 template <typename T, typename R>
04537 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04538     "Arguments to callback have been reordered to callback(func, arg)")
04539 Callback<R()> callback(const T *obj, R (*func)(const T*)) {
04540     return Callback<R()>(func, obj);
04541 }
04542 
04543 /** Create a callback class with type infered from the arguments
04544  *
04545  *  @param obj  Optional pointer to object to bind to function
04546  *  @param func Static function to attach
04547  *  @return     Callback with infered type
04548  *  @deprecated
04549  *      Arguments to callback have been reordered to callback(func, arg)
04550  */
04551 template <typename T, typename R>
04552 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04553     "Arguments to callback have been reordered to callback(func, arg)")
04554 Callback<R()> callback(volatile T *obj, R (*func)(volatile T*)) {
04555     return Callback<R()>(func, obj);
04556 }
04557 
04558 /** Create a callback class with type infered from the arguments
04559  *
04560  *  @param obj  Optional pointer to object to bind to function
04561  *  @param func Static function to attach
04562  *  @return     Callback with infered type
04563  *  @deprecated
04564  *      Arguments to callback have been reordered to callback(func, arg)
04565  */
04566 template <typename T, typename R>
04567 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04568     "Arguments to callback have been reordered to callback(func, arg)")
04569 Callback<R()> callback(const volatile T *obj, R (*func)(const volatile T*)) {
04570     return Callback<R()>(func, obj);
04571 }
04572 
04573 
04574 /** Create a callback class with type infered from the arguments
04575  *
04576  *  @param func     Static function to attach
04577  *  @return         Callback with infered type
04578  */
04579 template <typename R, typename A0>
04580 Callback<R(A0)> callback(R (*func)(A0) = 0) {
04581     return Callback<R(A0)>(func);
04582 }
04583 
04584 /** Create a callback class with type infered from the arguments
04585  *
04586  *  @param func     Static function to attach
04587  *  @return         Callback with infered type
04588  */
04589 template <typename R, typename A0>
04590 Callback<R(A0)> callback(const Callback<R(A0)> &func) {
04591     return Callback<R(A0)>(func);
04592 }
04593 
04594 /** Create a callback class with type infered from the arguments
04595  *
04596  *  @param obj      Optional pointer to object to bind to function
04597  *  @param method   Member function to attach
04598  *  @return         Callback with infered type
04599  */
04600 template<typename T, typename R, typename A0>
04601 Callback<R(A0)> callback(T *obj, R (T::*func)(A0)) {
04602     return Callback<R(A0)>(obj, func);
04603 }
04604 
04605 /** Create a callback class with type infered from the arguments
04606  *
04607  *  @param obj      Optional pointer to object to bind to function
04608  *  @param method   Member function to attach
04609  *  @return         Callback with infered type
04610  */
04611 template<typename T, typename R, typename A0>
04612 Callback<R(A0)> callback(const T *obj, R (T::*func)(A0) const) {
04613     return Callback<R(A0)>(obj, func);
04614 }
04615 
04616 /** Create a callback class with type infered from the arguments
04617  *
04618  *  @param obj      Optional pointer to object to bind to function
04619  *  @param method   Member function to attach
04620  *  @return         Callback with infered type
04621  */
04622 template<typename T, typename R, typename A0>
04623 Callback<R(A0)> callback(volatile T *obj, R (T::*func)(A0) volatile) {
04624     return Callback<R(A0)>(obj, func);
04625 }
04626 
04627 /** Create a callback class with type infered from the arguments
04628  *
04629  *  @param obj      Optional pointer to object to bind to function
04630  *  @param method   Member function to attach
04631  *  @return         Callback with infered type
04632  */
04633 template<typename T, typename R, typename A0>
04634 Callback<R(A0)> callback(const volatile T *obj, R (T::*func)(A0) const volatile) {
04635     return Callback<R(A0)>(obj, func);
04636 }
04637 
04638 /** Create a callback class with type infered from the arguments
04639  *
04640  *  @param func     Static function to attach
04641  *  @param arg      Pointer argument to function
04642  *  @return         Callback with infered type
04643  */
04644 template <typename R, typename A0>
04645 Callback<R(A0)> callback(R (*func)(void*, A0), void *arg) {
04646     return Callback<R(A0)>(func, arg);
04647 }
04648 
04649 /** Create a callback class with type infered from the arguments
04650  *
04651  *  @param func     Static function to attach
04652  *  @param arg      Pointer argument to function
04653  *  @return         Callback with infered type
04654  */
04655 template <typename R, typename A0>
04656 Callback<R(A0)> callback(R (*func)(const void*, A0), const void *arg) {
04657     return Callback<R(A0)>(func, arg);
04658 }
04659 
04660 /** Create a callback class with type infered from the arguments
04661  *
04662  *  @param func     Static function to attach
04663  *  @param arg      Pointer argument to function
04664  *  @return         Callback with infered type
04665  */
04666 template <typename R, typename A0>
04667 Callback<R(A0)> callback(R (*func)(volatile void*, A0), volatile void *arg) {
04668     return Callback<R(A0)>(func, arg);
04669 }
04670 
04671 /** Create a callback class with type infered from the arguments
04672  *
04673  *  @param func     Static function to attach
04674  *  @param arg      Pointer argument to function
04675  *  @return         Callback with infered type
04676  */
04677 template <typename R, typename A0>
04678 Callback<R(A0)> callback(R (*func)(const volatile void*, A0), const volatile void *arg) {
04679     return Callback<R(A0)>(func, arg);
04680 }
04681 
04682 /** Create a callback class with type infered from the arguments
04683  *
04684  *  @param func     Static function to attach
04685  *  @param arg      Pointer argument to function
04686  *  @return         Callback with infered type
04687  */
04688 template <typename T, typename R, typename A0>
04689 Callback<R(A0)> callback(R (*func)(T*, A0), T *arg) {
04690     return Callback<R(A0)>(func, arg);
04691 }
04692 
04693 /** Create a callback class with type infered from the arguments
04694  *
04695  *  @param func     Static function to attach
04696  *  @param arg      Pointer argument to function
04697  *  @return         Callback with infered type
04698  */
04699 template <typename T, typename R, typename A0>
04700 Callback<R(A0)> callback(R (*func)(const T*, A0), const T *arg) {
04701     return Callback<R(A0)>(func, arg);
04702 }
04703 
04704 /** Create a callback class with type infered from the arguments
04705  *
04706  *  @param func     Static function to attach
04707  *  @param arg      Pointer argument to function
04708  *  @return         Callback with infered type
04709  */
04710 template <typename T, typename R, typename A0>
04711 Callback<R(A0)> callback(R (*func)(volatile T*, A0), volatile T *arg) {
04712     return Callback<R(A0)>(func, arg);
04713 }
04714 
04715 /** Create a callback class with type infered from the arguments
04716  *
04717  *  @param func     Static function to attach
04718  *  @param arg      Pointer argument to function
04719  *  @return         Callback with infered type
04720  */
04721 template <typename T, typename R, typename A0>
04722 Callback<R(A0)> callback(R (*func)(const volatile T*, A0), const volatile T *arg) {
04723     return Callback<R(A0)>(func, arg);
04724 }
04725 
04726 /** Create a callback class with type infered from the arguments
04727  *
04728  *  @param obj  Optional pointer to object to bind to function
04729  *  @param func Static function to attach
04730  *  @return     Callback with infered type
04731  *  @deprecated
04732  *      Arguments to callback have been reordered to callback(func, arg)
04733  */
04734 template <typename R, typename A0>
04735 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04736     "Arguments to callback have been reordered to callback(func, arg)")
04737 Callback<R(A0)> callback(void *obj, R (*func)(void*, A0)) {
04738     return Callback<R(A0)>(func, obj);
04739 }
04740 
04741 /** Create a callback class with type infered from the arguments
04742  *
04743  *  @param obj  Optional pointer to object to bind to function
04744  *  @param func Static function to attach
04745  *  @return     Callback with infered type
04746  *  @deprecated
04747  *      Arguments to callback have been reordered to callback(func, arg)
04748  */
04749 template <typename R, typename A0>
04750 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04751     "Arguments to callback have been reordered to callback(func, arg)")
04752 Callback<R(A0)> callback(const void *obj, R (*func)(const void*, A0)) {
04753     return Callback<R(A0)>(func, obj);
04754 }
04755 
04756 /** Create a callback class with type infered from the arguments
04757  *
04758  *  @param obj  Optional pointer to object to bind to function
04759  *  @param func Static function to attach
04760  *  @return     Callback with infered type
04761  *  @deprecated
04762  *      Arguments to callback have been reordered to callback(func, arg)
04763  */
04764 template <typename R, typename A0>
04765 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04766     "Arguments to callback have been reordered to callback(func, arg)")
04767 Callback<R(A0)> callback(volatile void *obj, R (*func)(volatile void*, A0)) {
04768     return Callback<R(A0)>(func, obj);
04769 }
04770 
04771 /** Create a callback class with type infered from the arguments
04772  *
04773  *  @param obj  Optional pointer to object to bind to function
04774  *  @param func Static function to attach
04775  *  @return     Callback with infered type
04776  *  @deprecated
04777  *      Arguments to callback have been reordered to callback(func, arg)
04778  */
04779 template <typename R, typename A0>
04780 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04781     "Arguments to callback have been reordered to callback(func, arg)")
04782 Callback<R(A0)> callback(const volatile void *obj, R (*func)(const volatile void*, A0)) {
04783     return Callback<R(A0)>(func, obj);
04784 }
04785 
04786 /** Create a callback class with type infered from the arguments
04787  *
04788  *  @param obj  Optional pointer to object to bind to function
04789  *  @param func Static function to attach
04790  *  @return     Callback with infered type
04791  *  @deprecated
04792  *      Arguments to callback have been reordered to callback(func, arg)
04793  */
04794 template <typename T, typename R, typename A0>
04795 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04796     "Arguments to callback have been reordered to callback(func, arg)")
04797 Callback<R(A0)> callback(T *obj, R (*func)(T*, A0)) {
04798     return Callback<R(A0)>(func, obj);
04799 }
04800 
04801 /** Create a callback class with type infered from the arguments
04802  *
04803  *  @param obj  Optional pointer to object to bind to function
04804  *  @param func Static function to attach
04805  *  @return     Callback with infered type
04806  *  @deprecated
04807  *      Arguments to callback have been reordered to callback(func, arg)
04808  */
04809 template <typename T, typename R, typename A0>
04810 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04811     "Arguments to callback have been reordered to callback(func, arg)")
04812 Callback<R(A0)> callback(const T *obj, R (*func)(const T*, A0)) {
04813     return Callback<R(A0)>(func, obj);
04814 }
04815 
04816 /** Create a callback class with type infered from the arguments
04817  *
04818  *  @param obj  Optional pointer to object to bind to function
04819  *  @param func Static function to attach
04820  *  @return     Callback with infered type
04821  *  @deprecated
04822  *      Arguments to callback have been reordered to callback(func, arg)
04823  */
04824 template <typename T, typename R, typename A0>
04825 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04826     "Arguments to callback have been reordered to callback(func, arg)")
04827 Callback<R(A0)> callback(volatile T *obj, R (*func)(volatile T*, A0)) {
04828     return Callback<R(A0)>(func, obj);
04829 }
04830 
04831 /** Create a callback class with type infered from the arguments
04832  *
04833  *  @param obj  Optional pointer to object to bind to function
04834  *  @param func Static function to attach
04835  *  @return     Callback with infered type
04836  *  @deprecated
04837  *      Arguments to callback have been reordered to callback(func, arg)
04838  */
04839 template <typename T, typename R, typename A0>
04840 MBED_DEPRECATED_SINCE("mbed-os-5.1",
04841     "Arguments to callback have been reordered to callback(func, arg)")
04842 Callback<R(A0)> callback(const volatile T *obj, R (*func)(const volatile T*, A0)) {
04843     return Callback<R(A0)>(func, obj);
04844 }
04845 
04846 
04847 /** Create a callback class with type infered from the arguments
04848  *
04849  *  @param func     Static function to attach
04850  *  @return         Callback with infered type
04851  */
04852 template <typename R, typename A0, typename A1>
04853 Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
04854     return Callback<R(A0, A1)>(func);
04855 }
04856 
04857 /** Create a callback class with type infered from the arguments
04858  *
04859  *  @param func     Static function to attach
04860  *  @return         Callback with infered type
04861  */
04862 template <typename R, typename A0, typename A1>
04863 Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
04864     return Callback<R(A0, A1)>(func);
04865 }
04866 
04867 /** Create a callback class with type infered from the arguments
04868  *
04869  *  @param obj      Optional pointer to object to bind to function
04870  *  @param method   Member function to attach
04871  *  @return         Callback with infered type
04872  */
04873 template<typename T, typename R, typename A0, typename A1>
04874 Callback<R(A0, A1)> callback(T *obj, R (T::*func)(A0, A1)) {
04875     return Callback<R(A0, A1)>(obj, func);
04876 }
04877 
04878 /** Create a callback class with type infered from the arguments
04879  *
04880  *  @param obj      Optional pointer to object to bind to function
04881  *  @param method   Member function to attach
04882  *  @return         Callback with infered type
04883  */
04884 template<typename T, typename R, typename A0, typename A1>
04885 Callback<R(A0, A1)> callback(const T *obj, R (T::*func)(A0, A1) const) {
04886     return Callback<R(A0, A1)>(obj, func);
04887 }
04888 
04889 /** Create a callback class with type infered from the arguments
04890  *
04891  *  @param obj      Optional pointer to object to bind to function
04892  *  @param method   Member function to attach
04893  *  @return         Callback with infered type
04894  */
04895 template<typename T, typename R, typename A0, typename A1>
04896 Callback<R(A0, A1)> callback(volatile T *obj, R (T::*func)(A0, A1) volatile) {
04897     return Callback<R(A0, A1)>(obj, func);
04898 }
04899 
04900 /** Create a callback class with type infered from the arguments
04901  *
04902  *  @param obj      Optional pointer to object to bind to function
04903  *  @param method   Member function to attach
04904  *  @return         Callback with infered type
04905  */
04906 template<typename T, typename R, typename A0, typename A1>
04907 Callback<R(A0, A1)> callback(const volatile T *obj, R (T::*func)(A0, A1) const volatile) {
04908     return Callback<R(A0, A1)>(obj, func);
04909 }
04910 
04911 /** Create a callback class with type infered from the arguments
04912  *
04913  *  @param func     Static function to attach
04914  *  @param arg      Pointer argument to function
04915  *  @return         Callback with infered type
04916  */
04917 template <typename R, typename A0, typename A1>
04918 Callback<R(A0, A1)> callback(R (*func)(void*, A0, A1), void *arg) {
04919     return Callback<R(A0, A1)>(func, arg);
04920 }
04921 
04922 /** Create a callback class with type infered from the arguments
04923  *
04924  *  @param func     Static function to attach
04925  *  @param arg      Pointer argument to function
04926  *  @return         Callback with infered type
04927  */
04928 template <typename R, typename A0, typename A1>
04929 Callback<R(A0, A1)> callback(R (*func)(const void*, A0, A1), const void *arg) {
04930     return Callback<R(A0, A1)>(func, arg);
04931 }
04932 
04933 /** Create a callback class with type infered from the arguments
04934  *
04935  *  @param func     Static function to attach
04936  *  @param arg      Pointer argument to function
04937  *  @return         Callback with infered type
04938  */
04939 template <typename R, typename A0, typename A1>
04940 Callback<R(A0, A1)> callback(R (*func)(volatile void*, A0, A1), volatile void *arg) {
04941     return Callback<R(A0, A1)>(func, arg);
04942 }
04943 
04944 /** Create a callback class with type infered from the arguments
04945  *
04946  *  @param func     Static function to attach
04947  *  @param arg      Pointer argument to function
04948  *  @return         Callback with infered type
04949  */
04950 template <typename R, typename A0, typename A1>
04951 Callback<R(A0, A1)> callback(R (*func)(const volatile void*, A0, A1), const volatile void *arg) {
04952     return Callback<R(A0, A1)>(func, arg);
04953 }
04954 
04955 /** Create a callback class with type infered from the arguments
04956  *
04957  *  @param func     Static function to attach
04958  *  @param arg      Pointer argument to function
04959  *  @return         Callback with infered type
04960  */
04961 template <typename T, typename R, typename A0, typename A1>
04962 Callback<R(A0, A1)> callback(R (*func)(T*, A0, A1), T *arg) {
04963     return Callback<R(A0, A1)>(func, arg);
04964 }
04965 
04966 /** Create a callback class with type infered from the arguments
04967  *
04968  *  @param func     Static function to attach
04969  *  @param arg      Pointer argument to function
04970  *  @return         Callback with infered type
04971  */
04972 template <typename T, typename R, typename A0, typename A1>
04973 Callback<R(A0, A1)> callback(R (*func)(const T*, A0, A1), const T *arg) {
04974     return Callback<R(A0, A1)>(func, arg);
04975 }
04976 
04977 /** Create a callback class with type infered from the arguments
04978  *
04979  *  @param func     Static function to attach
04980  *  @param arg      Pointer argument to function
04981  *  @return         Callback with infered type
04982  */
04983 template <typename T, typename R, typename A0, typename A1>
04984 Callback<R(A0, A1)> callback(R (*func)(volatile T*, A0, A1), volatile T *arg) {
04985     return Callback<R(A0, A1)>(func, arg);
04986 }
04987 
04988 /** Create a callback class with type infered from the arguments
04989  *
04990  *  @param func     Static function to attach
04991  *  @param arg      Pointer argument to function
04992  *  @return         Callback with infered type
04993  */
04994 template <typename T, typename R, typename A0, typename A1>
04995 Callback<R(A0, A1)> callback(R (*func)(const volatile T*, A0, A1), const volatile T *arg) {
04996     return Callback<R(A0, A1)>(func, arg);
04997 }
04998 
04999 /** Create a callback class with type infered from the arguments
05000  *
05001  *  @param obj  Optional pointer to object to bind to function
05002  *  @param func Static function to attach
05003  *  @return     Callback with infered type
05004  *  @deprecated
05005  *      Arguments to callback have been reordered to callback(func, arg)
05006  */
05007 template <typename R, typename A0, typename A1>
05008 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05009     "Arguments to callback have been reordered to callback(func, arg)")
05010 Callback<R(A0, A1)> callback(void *obj, R (*func)(void*, A0, A1)) {
05011     return Callback<R(A0, A1)>(func, obj);
05012 }
05013 
05014 /** Create a callback class with type infered from the arguments
05015  *
05016  *  @param obj  Optional pointer to object to bind to function
05017  *  @param func Static function to attach
05018  *  @return     Callback with infered type
05019  *  @deprecated
05020  *      Arguments to callback have been reordered to callback(func, arg)
05021  */
05022 template <typename R, typename A0, typename A1>
05023 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05024     "Arguments to callback have been reordered to callback(func, arg)")
05025 Callback<R(A0, A1)> callback(const void *obj, R (*func)(const void*, A0, A1)) {
05026     return Callback<R(A0, A1)>(func, obj);
05027 }
05028 
05029 /** Create a callback class with type infered from the arguments
05030  *
05031  *  @param obj  Optional pointer to object to bind to function
05032  *  @param func Static function to attach
05033  *  @return     Callback with infered type
05034  *  @deprecated
05035  *      Arguments to callback have been reordered to callback(func, arg)
05036  */
05037 template <typename R, typename A0, typename A1>
05038 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05039     "Arguments to callback have been reordered to callback(func, arg)")
05040 Callback<R(A0, A1)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1)) {
05041     return Callback<R(A0, A1)>(func, obj);
05042 }
05043 
05044 /** Create a callback class with type infered from the arguments
05045  *
05046  *  @param obj  Optional pointer to object to bind to function
05047  *  @param func Static function to attach
05048  *  @return     Callback with infered type
05049  *  @deprecated
05050  *      Arguments to callback have been reordered to callback(func, arg)
05051  */
05052 template <typename R, typename A0, typename A1>
05053 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05054     "Arguments to callback have been reordered to callback(func, arg)")
05055 Callback<R(A0, A1)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) {
05056     return Callback<R(A0, A1)>(func, obj);
05057 }
05058 
05059 /** Create a callback class with type infered from the arguments
05060  *
05061  *  @param obj  Optional pointer to object to bind to function
05062  *  @param func Static function to attach
05063  *  @return     Callback with infered type
05064  *  @deprecated
05065  *      Arguments to callback have been reordered to callback(func, arg)
05066  */
05067 template <typename T, typename R, typename A0, typename A1>
05068 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05069     "Arguments to callback have been reordered to callback(func, arg)")
05070 Callback<R(A0, A1)> callback(T *obj, R (*func)(T*, A0, A1)) {
05071     return Callback<R(A0, A1)>(func, obj);
05072 }
05073 
05074 /** Create a callback class with type infered from the arguments
05075  *
05076  *  @param obj  Optional pointer to object to bind to function
05077  *  @param func Static function to attach
05078  *  @return     Callback with infered type
05079  *  @deprecated
05080  *      Arguments to callback have been reordered to callback(func, arg)
05081  */
05082 template <typename T, typename R, typename A0, typename A1>
05083 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05084     "Arguments to callback have been reordered to callback(func, arg)")
05085 Callback<R(A0, A1)> callback(const T *obj, R (*func)(const T*, A0, A1)) {
05086     return Callback<R(A0, A1)>(func, obj);
05087 }
05088 
05089 /** Create a callback class with type infered from the arguments
05090  *
05091  *  @param obj  Optional pointer to object to bind to function
05092  *  @param func Static function to attach
05093  *  @return     Callback with infered type
05094  *  @deprecated
05095  *      Arguments to callback have been reordered to callback(func, arg)
05096  */
05097 template <typename T, typename R, typename A0, typename A1>
05098 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05099     "Arguments to callback have been reordered to callback(func, arg)")
05100 Callback<R(A0, A1)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1)) {
05101     return Callback<R(A0, A1)>(func, obj);
05102 }
05103 
05104 /** Create a callback class with type infered from the arguments
05105  *
05106  *  @param obj  Optional pointer to object to bind to function
05107  *  @param func Static function to attach
05108  *  @return     Callback with infered type
05109  *  @deprecated
05110  *      Arguments to callback have been reordered to callback(func, arg)
05111  */
05112 template <typename T, typename R, typename A0, typename A1>
05113 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05114     "Arguments to callback have been reordered to callback(func, arg)")
05115 Callback<R(A0, A1)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) {
05116     return Callback<R(A0, A1)>(func, obj);
05117 }
05118 
05119 
05120 /** Create a callback class with type infered from the arguments
05121  *
05122  *  @param func     Static function to attach
05123  *  @return         Callback with infered type
05124  */
05125 template <typename R, typename A0, typename A1, typename A2>
05126 Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
05127     return Callback<R(A0, A1, A2)>(func);
05128 }
05129 
05130 /** Create a callback class with type infered from the arguments
05131  *
05132  *  @param func     Static function to attach
05133  *  @return         Callback with infered type
05134  */
05135 template <typename R, typename A0, typename A1, typename A2>
05136 Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
05137     return Callback<R(A0, A1, A2)>(func);
05138 }
05139 
05140 /** Create a callback class with type infered from the arguments
05141  *
05142  *  @param obj      Optional pointer to object to bind to function
05143  *  @param method   Member function to attach
05144  *  @return         Callback with infered type
05145  */
05146 template<typename T, typename R, typename A0, typename A1, typename A2>
05147 Callback<R(A0, A1, A2)> callback(T *obj, R (T::*func)(A0, A1, A2)) {
05148     return Callback<R(A0, A1, A2)>(obj, func);
05149 }
05150 
05151 /** Create a callback class with type infered from the arguments
05152  *
05153  *  @param obj      Optional pointer to object to bind to function
05154  *  @param method   Member function to attach
05155  *  @return         Callback with infered type
05156  */
05157 template<typename T, typename R, typename A0, typename A1, typename A2>
05158 Callback<R(A0, A1, A2)> callback(const T *obj, R (T::*func)(A0, A1, A2) const) {
05159     return Callback<R(A0, A1, A2)>(obj, func);
05160 }
05161 
05162 /** Create a callback class with type infered from the arguments
05163  *
05164  *  @param obj      Optional pointer to object to bind to function
05165  *  @param method   Member function to attach
05166  *  @return         Callback with infered type
05167  */
05168 template<typename T, typename R, typename A0, typename A1, typename A2>
05169 Callback<R(A0, A1, A2)> callback(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) {
05170     return Callback<R(A0, A1, A2)>(obj, func);
05171 }
05172 
05173 /** Create a callback class with type infered from the arguments
05174  *
05175  *  @param obj      Optional pointer to object to bind to function
05176  *  @param method   Member function to attach
05177  *  @return         Callback with infered type
05178  */
05179 template<typename T, typename R, typename A0, typename A1, typename A2>
05180 Callback<R(A0, A1, A2)> callback(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) {
05181     return Callback<R(A0, A1, A2)>(obj, func);
05182 }
05183 
05184 /** Create a callback class with type infered from the arguments
05185  *
05186  *  @param func     Static function to attach
05187  *  @param arg      Pointer argument to function
05188  *  @return         Callback with infered type
05189  */
05190 template <typename R, typename A0, typename A1, typename A2>
05191 Callback<R(A0, A1, A2)> callback(R (*func)(void*, A0, A1, A2), void *arg) {
05192     return Callback<R(A0, A1, A2)>(func, arg);
05193 }
05194 
05195 /** Create a callback class with type infered from the arguments
05196  *
05197  *  @param func     Static function to attach
05198  *  @param arg      Pointer argument to function
05199  *  @return         Callback with infered type
05200  */
05201 template <typename R, typename A0, typename A1, typename A2>
05202 Callback<R(A0, A1, A2)> callback(R (*func)(const void*, A0, A1, A2), const void *arg) {
05203     return Callback<R(A0, A1, A2)>(func, arg);
05204 }
05205 
05206 /** Create a callback class with type infered from the arguments
05207  *
05208  *  @param func     Static function to attach
05209  *  @param arg      Pointer argument to function
05210  *  @return         Callback with infered type
05211  */
05212 template <typename R, typename A0, typename A1, typename A2>
05213 Callback<R(A0, A1, A2)> callback(R (*func)(volatile void*, A0, A1, A2), volatile void *arg) {
05214     return Callback<R(A0, A1, A2)>(func, arg);
05215 }
05216 
05217 /** Create a callback class with type infered from the arguments
05218  *
05219  *  @param func     Static function to attach
05220  *  @param arg      Pointer argument to function
05221  *  @return         Callback with infered type
05222  */
05223 template <typename R, typename A0, typename A1, typename A2>
05224 Callback<R(A0, A1, A2)> callback(R (*func)(const volatile void*, A0, A1, A2), const volatile void *arg) {
05225     return Callback<R(A0, A1, A2)>(func, arg);
05226 }
05227 
05228 /** Create a callback class with type infered from the arguments
05229  *
05230  *  @param func     Static function to attach
05231  *  @param arg      Pointer argument to function
05232  *  @return         Callback with infered type
05233  */
05234 template <typename T, typename R, typename A0, typename A1, typename A2>
05235 Callback<R(A0, A1, A2)> callback(R (*func)(T*, A0, A1, A2), T *arg) {
05236     return Callback<R(A0, A1, A2)>(func, arg);
05237 }
05238 
05239 /** Create a callback class with type infered from the arguments
05240  *
05241  *  @param func     Static function to attach
05242  *  @param arg      Pointer argument to function
05243  *  @return         Callback with infered type
05244  */
05245 template <typename T, typename R, typename A0, typename A1, typename A2>
05246 Callback<R(A0, A1, A2)> callback(R (*func)(const T*, A0, A1, A2), const T *arg) {
05247     return Callback<R(A0, A1, A2)>(func, arg);
05248 }
05249 
05250 /** Create a callback class with type infered from the arguments
05251  *
05252  *  @param func     Static function to attach
05253  *  @param arg      Pointer argument to function
05254  *  @return         Callback with infered type
05255  */
05256 template <typename T, typename R, typename A0, typename A1, typename A2>
05257 Callback<R(A0, A1, A2)> callback(R (*func)(volatile T*, A0, A1, A2), volatile T *arg) {
05258     return Callback<R(A0, A1, A2)>(func, arg);
05259 }
05260 
05261 /** Create a callback class with type infered from the arguments
05262  *
05263  *  @param func     Static function to attach
05264  *  @param arg      Pointer argument to function
05265  *  @return         Callback with infered type
05266  */
05267 template <typename T, typename R, typename A0, typename A1, typename A2>
05268 Callback<R(A0, A1, A2)> callback(R (*func)(const volatile T*, A0, A1, A2), const volatile T *arg) {
05269     return Callback<R(A0, A1, A2)>(func, arg);
05270 }
05271 
05272 /** Create a callback class with type infered from the arguments
05273  *
05274  *  @param obj  Optional pointer to object to bind to function
05275  *  @param func Static function to attach
05276  *  @return     Callback with infered type
05277  *  @deprecated
05278  *      Arguments to callback have been reordered to callback(func, arg)
05279  */
05280 template <typename R, typename A0, typename A1, typename A2>
05281 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05282     "Arguments to callback have been reordered to callback(func, arg)")
05283 Callback<R(A0, A1, A2)> callback(void *obj, R (*func)(void*, A0, A1, A2)) {
05284     return Callback<R(A0, A1, A2)>(func, obj);
05285 }
05286 
05287 /** Create a callback class with type infered from the arguments
05288  *
05289  *  @param obj  Optional pointer to object to bind to function
05290  *  @param func Static function to attach
05291  *  @return     Callback with infered type
05292  *  @deprecated
05293  *      Arguments to callback have been reordered to callback(func, arg)
05294  */
05295 template <typename R, typename A0, typename A1, typename A2>
05296 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05297     "Arguments to callback have been reordered to callback(func, arg)")
05298 Callback<R(A0, A1, A2)> callback(const void *obj, R (*func)(const void*, A0, A1, A2)) {
05299     return Callback<R(A0, A1, A2)>(func, obj);
05300 }
05301 
05302 /** Create a callback class with type infered from the arguments
05303  *
05304  *  @param obj  Optional pointer to object to bind to function
05305  *  @param func Static function to attach
05306  *  @return     Callback with infered type
05307  *  @deprecated
05308  *      Arguments to callback have been reordered to callback(func, arg)
05309  */
05310 template <typename R, typename A0, typename A1, typename A2>
05311 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05312     "Arguments to callback have been reordered to callback(func, arg)")
05313 Callback<R(A0, A1, A2)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) {
05314     return Callback<R(A0, A1, A2)>(func, obj);
05315 }
05316 
05317 /** Create a callback class with type infered from the arguments
05318  *
05319  *  @param obj  Optional pointer to object to bind to function
05320  *  @param func Static function to attach
05321  *  @return     Callback with infered type
05322  *  @deprecated
05323  *      Arguments to callback have been reordered to callback(func, arg)
05324  */
05325 template <typename R, typename A0, typename A1, typename A2>
05326 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05327     "Arguments to callback have been reordered to callback(func, arg)")
05328 Callback<R(A0, A1, A2)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) {
05329     return Callback<R(A0, A1, A2)>(func, obj);
05330 }
05331 
05332 /** Create a callback class with type infered from the arguments
05333  *
05334  *  @param obj  Optional pointer to object to bind to function
05335  *  @param func Static function to attach
05336  *  @return     Callback with infered type
05337  *  @deprecated
05338  *      Arguments to callback have been reordered to callback(func, arg)
05339  */
05340 template <typename T, typename R, typename A0, typename A1, typename A2>
05341 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05342     "Arguments to callback have been reordered to callback(func, arg)")
05343 Callback<R(A0, A1, A2)> callback(T *obj, R (*func)(T*, A0, A1, A2)) {
05344     return Callback<R(A0, A1, A2)>(func, obj);
05345 }
05346 
05347 /** Create a callback class with type infered from the arguments
05348  *
05349  *  @param obj  Optional pointer to object to bind to function
05350  *  @param func Static function to attach
05351  *  @return     Callback with infered type
05352  *  @deprecated
05353  *      Arguments to callback have been reordered to callback(func, arg)
05354  */
05355 template <typename T, typename R, typename A0, typename A1, typename A2>
05356 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05357     "Arguments to callback have been reordered to callback(func, arg)")
05358 Callback<R(A0, A1, A2)> callback(const T *obj, R (*func)(const T*, A0, A1, A2)) {
05359     return Callback<R(A0, A1, A2)>(func, obj);
05360 }
05361 
05362 /** Create a callback class with type infered from the arguments
05363  *
05364  *  @param obj  Optional pointer to object to bind to function
05365  *  @param func Static function to attach
05366  *  @return     Callback with infered type
05367  *  @deprecated
05368  *      Arguments to callback have been reordered to callback(func, arg)
05369  */
05370 template <typename T, typename R, typename A0, typename A1, typename A2>
05371 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05372     "Arguments to callback have been reordered to callback(func, arg)")
05373 Callback<R(A0, A1, A2)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) {
05374     return Callback<R(A0, A1, A2)>(func, obj);
05375 }
05376 
05377 /** Create a callback class with type infered from the arguments
05378  *
05379  *  @param obj  Optional pointer to object to bind to function
05380  *  @param func Static function to attach
05381  *  @return     Callback with infered type
05382  *  @deprecated
05383  *      Arguments to callback have been reordered to callback(func, arg)
05384  */
05385 template <typename T, typename R, typename A0, typename A1, typename A2>
05386 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05387     "Arguments to callback have been reordered to callback(func, arg)")
05388 Callback<R(A0, A1, A2)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) {
05389     return Callback<R(A0, A1, A2)>(func, obj);
05390 }
05391 
05392 
05393 /** Create a callback class with type infered from the arguments
05394  *
05395  *  @param func     Static function to attach
05396  *  @return         Callback with infered type
05397  */
05398 template <typename R, typename A0, typename A1, typename A2, typename A3>
05399 Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
05400     return Callback<R(A0, A1, A2, A3)>(func);
05401 }
05402 
05403 /** Create a callback class with type infered from the arguments
05404  *
05405  *  @param func     Static function to attach
05406  *  @return         Callback with infered type
05407  */
05408 template <typename R, typename A0, typename A1, typename A2, typename A3>
05409 Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
05410     return Callback<R(A0, A1, A2, A3)>(func);
05411 }
05412 
05413 /** Create a callback class with type infered from the arguments
05414  *
05415  *  @param obj      Optional pointer to object to bind to function
05416  *  @param method   Member function to attach
05417  *  @return         Callback with infered type
05418  */
05419 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05420 Callback<R(A0, A1, A2, A3)> callback(T *obj, R (T::*func)(A0, A1, A2, A3)) {
05421     return Callback<R(A0, A1, A2, A3)>(obj, func);
05422 }
05423 
05424 /** Create a callback class with type infered from the arguments
05425  *
05426  *  @param obj      Optional pointer to object to bind to function
05427  *  @param method   Member function to attach
05428  *  @return         Callback with infered type
05429  */
05430 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05431 Callback<R(A0, A1, A2, A3)> callback(const T *obj, R (T::*func)(A0, A1, A2, A3) const) {
05432     return Callback<R(A0, A1, A2, A3)>(obj, func);
05433 }
05434 
05435 /** Create a callback class with type infered from the arguments
05436  *
05437  *  @param obj      Optional pointer to object to bind to function
05438  *  @param method   Member function to attach
05439  *  @return         Callback with infered type
05440  */
05441 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05442 Callback<R(A0, A1, A2, A3)> callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) {
05443     return Callback<R(A0, A1, A2, A3)>(obj, func);
05444 }
05445 
05446 /** Create a callback class with type infered from the arguments
05447  *
05448  *  @param obj      Optional pointer to object to bind to function
05449  *  @param method   Member function to attach
05450  *  @return         Callback with infered type
05451  */
05452 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05453 Callback<R(A0, A1, A2, A3)> callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) {
05454     return Callback<R(A0, A1, A2, A3)>(obj, func);
05455 }
05456 
05457 /** Create a callback class with type infered from the arguments
05458  *
05459  *  @param func     Static function to attach
05460  *  @param arg      Pointer argument to function
05461  *  @return         Callback with infered type
05462  */
05463 template <typename R, typename A0, typename A1, typename A2, typename A3>
05464 Callback<R(A0, A1, A2, A3)> callback(R (*func)(void*, A0, A1, A2, A3), void *arg) {
05465     return Callback<R(A0, A1, A2, A3)>(func, arg);
05466 }
05467 
05468 /** Create a callback class with type infered from the arguments
05469  *
05470  *  @param func     Static function to attach
05471  *  @param arg      Pointer argument to function
05472  *  @return         Callback with infered type
05473  */
05474 template <typename R, typename A0, typename A1, typename A2, typename A3>
05475 Callback<R(A0, A1, A2, A3)> callback(R (*func)(const void*, A0, A1, A2, A3), const void *arg) {
05476     return Callback<R(A0, A1, A2, A3)>(func, arg);
05477 }
05478 
05479 /** Create a callback class with type infered from the arguments
05480  *
05481  *  @param func     Static function to attach
05482  *  @param arg      Pointer argument to function
05483  *  @return         Callback with infered type
05484  */
05485 template <typename R, typename A0, typename A1, typename A2, typename A3>
05486 Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile void*, A0, A1, A2, A3), volatile void *arg) {
05487     return Callback<R(A0, A1, A2, A3)>(func, arg);
05488 }
05489 
05490 /** Create a callback class with type infered from the arguments
05491  *
05492  *  @param func     Static function to attach
05493  *  @param arg      Pointer argument to function
05494  *  @return         Callback with infered type
05495  */
05496 template <typename R, typename A0, typename A1, typename A2, typename A3>
05497 Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile void*, A0, A1, A2, A3), const volatile void *arg) {
05498     return Callback<R(A0, A1, A2, A3)>(func, arg);
05499 }
05500 
05501 /** Create a callback class with type infered from the arguments
05502  *
05503  *  @param func     Static function to attach
05504  *  @param arg      Pointer argument to function
05505  *  @return         Callback with infered type
05506  */
05507 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05508 Callback<R(A0, A1, A2, A3)> callback(R (*func)(T*, A0, A1, A2, A3), T *arg) {
05509     return Callback<R(A0, A1, A2, A3)>(func, arg);
05510 }
05511 
05512 /** Create a callback class with type infered from the arguments
05513  *
05514  *  @param func     Static function to attach
05515  *  @param arg      Pointer argument to function
05516  *  @return         Callback with infered type
05517  */
05518 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05519 Callback<R(A0, A1, A2, A3)> callback(R (*func)(const T*, A0, A1, A2, A3), const T *arg) {
05520     return Callback<R(A0, A1, A2, A3)>(func, arg);
05521 }
05522 
05523 /** Create a callback class with type infered from the arguments
05524  *
05525  *  @param func     Static function to attach
05526  *  @param arg      Pointer argument to function
05527  *  @return         Callback with infered type
05528  */
05529 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05530 Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile T *arg) {
05531     return Callback<R(A0, A1, A2, A3)>(func, arg);
05532 }
05533 
05534 /** Create a callback class with type infered from the arguments
05535  *
05536  *  @param func     Static function to attach
05537  *  @param arg      Pointer argument to function
05538  *  @return         Callback with infered type
05539  */
05540 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05541 Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile T *arg) {
05542     return Callback<R(A0, A1, A2, A3)>(func, arg);
05543 }
05544 
05545 /** Create a callback class with type infered from the arguments
05546  *
05547  *  @param obj  Optional pointer to object to bind to function
05548  *  @param func Static function to attach
05549  *  @return     Callback with infered type
05550  *  @deprecated
05551  *      Arguments to callback have been reordered to callback(func, arg)
05552  */
05553 template <typename R, typename A0, typename A1, typename A2, typename A3>
05554 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05555     "Arguments to callback have been reordered to callback(func, arg)")
05556 Callback<R(A0, A1, A2, A3)> callback(void *obj, R (*func)(void*, A0, A1, A2, A3)) {
05557     return Callback<R(A0, A1, A2, A3)>(func, obj);
05558 }
05559 
05560 /** Create a callback class with type infered from the arguments
05561  *
05562  *  @param obj  Optional pointer to object to bind to function
05563  *  @param func Static function to attach
05564  *  @return     Callback with infered type
05565  *  @deprecated
05566  *      Arguments to callback have been reordered to callback(func, arg)
05567  */
05568 template <typename R, typename A0, typename A1, typename A2, typename A3>
05569 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05570     "Arguments to callback have been reordered to callback(func, arg)")
05571 Callback<R(A0, A1, A2, A3)> callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) {
05572     return Callback<R(A0, A1, A2, A3)>(func, obj);
05573 }
05574 
05575 /** Create a callback class with type infered from the arguments
05576  *
05577  *  @param obj  Optional pointer to object to bind to function
05578  *  @param func Static function to attach
05579  *  @return     Callback with infered type
05580  *  @deprecated
05581  *      Arguments to callback have been reordered to callback(func, arg)
05582  */
05583 template <typename R, typename A0, typename A1, typename A2, typename A3>
05584 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05585     "Arguments to callback have been reordered to callback(func, arg)")
05586 Callback<R(A0, A1, A2, A3)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) {
05587     return Callback<R(A0, A1, A2, A3)>(func, obj);
05588 }
05589 
05590 /** Create a callback class with type infered from the arguments
05591  *
05592  *  @param obj  Optional pointer to object to bind to function
05593  *  @param func Static function to attach
05594  *  @return     Callback with infered type
05595  *  @deprecated
05596  *      Arguments to callback have been reordered to callback(func, arg)
05597  */
05598 template <typename R, typename A0, typename A1, typename A2, typename A3>
05599 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05600     "Arguments to callback have been reordered to callback(func, arg)")
05601 Callback<R(A0, A1, A2, A3)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) {
05602     return Callback<R(A0, A1, A2, A3)>(func, obj);
05603 }
05604 
05605 /** Create a callback class with type infered from the arguments
05606  *
05607  *  @param obj  Optional pointer to object to bind to function
05608  *  @param func Static function to attach
05609  *  @return     Callback with infered type
05610  *  @deprecated
05611  *      Arguments to callback have been reordered to callback(func, arg)
05612  */
05613 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05614 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05615     "Arguments to callback have been reordered to callback(func, arg)")
05616 Callback<R(A0, A1, A2, A3)> callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
05617     return Callback<R(A0, A1, A2, A3)>(func, obj);
05618 }
05619 
05620 /** Create a callback class with type infered from the arguments
05621  *
05622  *  @param obj  Optional pointer to object to bind to function
05623  *  @param func Static function to attach
05624  *  @return     Callback with infered type
05625  *  @deprecated
05626  *      Arguments to callback have been reordered to callback(func, arg)
05627  */
05628 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05629 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05630     "Arguments to callback have been reordered to callback(func, arg)")
05631 Callback<R(A0, A1, A2, A3)> callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) {
05632     return Callback<R(A0, A1, A2, A3)>(func, obj);
05633 }
05634 
05635 /** Create a callback class with type infered from the arguments
05636  *
05637  *  @param obj  Optional pointer to object to bind to function
05638  *  @param func Static function to attach
05639  *  @return     Callback with infered type
05640  *  @deprecated
05641  *      Arguments to callback have been reordered to callback(func, arg)
05642  */
05643 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05644 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05645     "Arguments to callback have been reordered to callback(func, arg)")
05646 Callback<R(A0, A1, A2, A3)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
05647     return Callback<R(A0, A1, A2, A3)>(func, obj);
05648 }
05649 
05650 /** Create a callback class with type infered from the arguments
05651  *
05652  *  @param obj  Optional pointer to object to bind to function
05653  *  @param func Static function to attach
05654  *  @return     Callback with infered type
05655  *  @deprecated
05656  *      Arguments to callback have been reordered to callback(func, arg)
05657  */
05658 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
05659 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05660     "Arguments to callback have been reordered to callback(func, arg)")
05661 Callback<R(A0, A1, A2, A3)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
05662     return Callback<R(A0, A1, A2, A3)>(func, obj);
05663 }
05664 
05665 
05666 /** Create a callback class with type infered from the arguments
05667  *
05668  *  @param func     Static function to attach
05669  *  @return         Callback with infered type
05670  */
05671 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05672 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
05673     return Callback<R(A0, A1, A2, A3, A4)>(func);
05674 }
05675 
05676 /** Create a callback class with type infered from the arguments
05677  *
05678  *  @param func     Static function to attach
05679  *  @return         Callback with infered type
05680  */
05681 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05682 Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
05683     return Callback<R(A0, A1, A2, A3, A4)>(func);
05684 }
05685 
05686 /** Create a callback class with type infered from the arguments
05687  *
05688  *  @param obj      Optional pointer to object to bind to function
05689  *  @param method   Member function to attach
05690  *  @return         Callback with infered type
05691  */
05692 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05693 Callback<R(A0, A1, A2, A3, A4)> callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
05694     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
05695 }
05696 
05697 /** Create a callback class with type infered from the arguments
05698  *
05699  *  @param obj      Optional pointer to object to bind to function
05700  *  @param method   Member function to attach
05701  *  @return         Callback with infered type
05702  */
05703 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05704 Callback<R(A0, A1, A2, A3, A4)> callback(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) {
05705     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
05706 }
05707 
05708 /** Create a callback class with type infered from the arguments
05709  *
05710  *  @param obj      Optional pointer to object to bind to function
05711  *  @param method   Member function to attach
05712  *  @return         Callback with infered type
05713  */
05714 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05715 Callback<R(A0, A1, A2, A3, A4)> callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) {
05716     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
05717 }
05718 
05719 /** Create a callback class with type infered from the arguments
05720  *
05721  *  @param obj      Optional pointer to object to bind to function
05722  *  @param method   Member function to attach
05723  *  @return         Callback with infered type
05724  */
05725 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05726 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) {
05727     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
05728 }
05729 
05730 /** Create a callback class with type infered from the arguments
05731  *
05732  *  @param func     Static function to attach
05733  *  @param arg      Pointer argument to function
05734  *  @return         Callback with infered type
05735  */
05736 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05737 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(void*, A0, A1, A2, A3, A4), void *arg) {
05738     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05739 }
05740 
05741 /** Create a callback class with type infered from the arguments
05742  *
05743  *  @param func     Static function to attach
05744  *  @param arg      Pointer argument to function
05745  *  @return         Callback with infered type
05746  */
05747 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05748 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const void*, A0, A1, A2, A3, A4), const void *arg) {
05749     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05750 }
05751 
05752 /** Create a callback class with type infered from the arguments
05753  *
05754  *  @param func     Static function to attach
05755  *  @param arg      Pointer argument to function
05756  *  @return         Callback with infered type
05757  */
05758 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05759 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile void*, A0, A1, A2, A3, A4), volatile void *arg) {
05760     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05761 }
05762 
05763 /** Create a callback class with type infered from the arguments
05764  *
05765  *  @param func     Static function to attach
05766  *  @param arg      Pointer argument to function
05767  *  @return         Callback with infered type
05768  */
05769 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05770 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile void*, A0, A1, A2, A3, A4), const volatile void *arg) {
05771     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05772 }
05773 
05774 /** Create a callback class with type infered from the arguments
05775  *
05776  *  @param func     Static function to attach
05777  *  @param arg      Pointer argument to function
05778  *  @return         Callback with infered type
05779  */
05780 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05781 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(T*, A0, A1, A2, A3, A4), T *arg) {
05782     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05783 }
05784 
05785 /** Create a callback class with type infered from the arguments
05786  *
05787  *  @param func     Static function to attach
05788  *  @param arg      Pointer argument to function
05789  *  @return         Callback with infered type
05790  */
05791 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05792 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const T*, A0, A1, A2, A3, A4), const T *arg) {
05793     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05794 }
05795 
05796 /** Create a callback class with type infered from the arguments
05797  *
05798  *  @param func     Static function to attach
05799  *  @param arg      Pointer argument to function
05800  *  @return         Callback with infered type
05801  */
05802 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05803 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile T *arg) {
05804     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05805 }
05806 
05807 /** Create a callback class with type infered from the arguments
05808  *
05809  *  @param func     Static function to attach
05810  *  @param arg      Pointer argument to function
05811  *  @return         Callback with infered type
05812  */
05813 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05814 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile T *arg) {
05815     return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
05816 }
05817 
05818 /** Create a callback class with type infered from the arguments
05819  *
05820  *  @param obj  Optional pointer to object to bind to function
05821  *  @param func Static function to attach
05822  *  @return     Callback with infered type
05823  *  @deprecated
05824  *      Arguments to callback have been reordered to callback(func, arg)
05825  */
05826 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05827 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05828     "Arguments to callback have been reordered to callback(func, arg)")
05829 Callback<R(A0, A1, A2, A3, A4)> callback(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) {
05830     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05831 }
05832 
05833 /** Create a callback class with type infered from the arguments
05834  *
05835  *  @param obj  Optional pointer to object to bind to function
05836  *  @param func Static function to attach
05837  *  @return     Callback with infered type
05838  *  @deprecated
05839  *      Arguments to callback have been reordered to callback(func, arg)
05840  */
05841 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05842 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05843     "Arguments to callback have been reordered to callback(func, arg)")
05844 Callback<R(A0, A1, A2, A3, A4)> callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) {
05845     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05846 }
05847 
05848 /** Create a callback class with type infered from the arguments
05849  *
05850  *  @param obj  Optional pointer to object to bind to function
05851  *  @param func Static function to attach
05852  *  @return     Callback with infered type
05853  *  @deprecated
05854  *      Arguments to callback have been reordered to callback(func, arg)
05855  */
05856 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05857 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05858     "Arguments to callback have been reordered to callback(func, arg)")
05859 Callback<R(A0, A1, A2, A3, A4)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) {
05860     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05861 }
05862 
05863 /** Create a callback class with type infered from the arguments
05864  *
05865  *  @param obj  Optional pointer to object to bind to function
05866  *  @param func Static function to attach
05867  *  @return     Callback with infered type
05868  *  @deprecated
05869  *      Arguments to callback have been reordered to callback(func, arg)
05870  */
05871 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05872 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05873     "Arguments to callback have been reordered to callback(func, arg)")
05874 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) {
05875     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05876 }
05877 
05878 /** Create a callback class with type infered from the arguments
05879  *
05880  *  @param obj  Optional pointer to object to bind to function
05881  *  @param func Static function to attach
05882  *  @return     Callback with infered type
05883  *  @deprecated
05884  *      Arguments to callback have been reordered to callback(func, arg)
05885  */
05886 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05887 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05888     "Arguments to callback have been reordered to callback(func, arg)")
05889 Callback<R(A0, A1, A2, A3, A4)> callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
05890     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05891 }
05892 
05893 /** Create a callback class with type infered from the arguments
05894  *
05895  *  @param obj  Optional pointer to object to bind to function
05896  *  @param func Static function to attach
05897  *  @return     Callback with infered type
05898  *  @deprecated
05899  *      Arguments to callback have been reordered to callback(func, arg)
05900  */
05901 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05902 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05903     "Arguments to callback have been reordered to callback(func, arg)")
05904 Callback<R(A0, A1, A2, A3, A4)> callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
05905     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05906 }
05907 
05908 /** Create a callback class with type infered from the arguments
05909  *
05910  *  @param obj  Optional pointer to object to bind to function
05911  *  @param func Static function to attach
05912  *  @return     Callback with infered type
05913  *  @deprecated
05914  *      Arguments to callback have been reordered to callback(func, arg)
05915  */
05916 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05917 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05918     "Arguments to callback have been reordered to callback(func, arg)")
05919 Callback<R(A0, A1, A2, A3, A4)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
05920     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05921 }
05922 
05923 /** Create a callback class with type infered from the arguments
05924  *
05925  *  @param obj  Optional pointer to object to bind to function
05926  *  @param func Static function to attach
05927  *  @return     Callback with infered type
05928  *  @deprecated
05929  *      Arguments to callback have been reordered to callback(func, arg)
05930  */
05931 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
05932 MBED_DEPRECATED_SINCE("mbed-os-5.1",
05933     "Arguments to callback have been reordered to callback(func, arg)")
05934 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
05935     return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
05936 }
05937 
05938 
05939 } // namespace mbed
05940 
05941 #endif
05942 
05943 
05944 /** @}*/