Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

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