ok

Dependents:   I2C

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  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #ifndef MBED_CALLBACK_H
00018 #define MBED_CALLBACK_H
00019 
00020 #include <string.h>
00021 #include <stdint.h>
00022 #include <new>
00023 #include "platform/mbed_assert.h"
00024 #include "platform/mbed_toolchain.h"
00025 
00026 namespace mbed {
00027 /** \addtogroup platform */
00028 /** @{*/
00029 /**
00030  * \defgroup platform_Callback Callback class
00031  * @{
00032  */
00033 
00034 /** Callback class based on template specialization
00035  *
00036  * @note Synchronization level: Not protected
00037  */
00038 template <typename F>
00039 class Callback;
00040 
00041 // Internal sfinae declarations
00042 //
00043 // These are used to eliminate overloads based on type attributes
00044 // 1. Does a function object have a call operator
00045 // 2. Does a function object fit in the available storage
00046 //
00047 // These eliminations are handled cleanly by the compiler and avoid
00048 // massive and misleading error messages when confronted with an
00049 // invalid type (or worse, runtime failures)
00050 namespace detail {
00051 struct nil {};
00052 
00053 template <bool B, typename R = nil>
00054 struct enable_if {
00055     typedef R type;
00056 };
00057 
00058 template <typename R>
00059 struct enable_if<false, R> {};
00060 
00061 template <typename M, M>
00062 struct is_type {
00063     static const bool value = true;
00064 };
00065 }
00066 
00067 #define MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M)                            \
00068     typename detail::enable_if<                                             \
00069             detail::is_type<M, &F::operator()>::value &&                    \
00070             sizeof(F) <= sizeof(uintptr_t)                                  \
00071         >::type = detail::nil()
00072 
00073 /** Callback class based on template specialization
00074  *
00075  * @note Synchronization level: Not protected
00076  */
00077 template <typename R, typename... ArgTs>
00078 class Callback<R(ArgTs...)> {
00079 public:
00080     /** Create a Callback with a static function
00081      *  @param func     Static function to attach
00082      */
00083     Callback(R(*func)(ArgTs...) = 0)
00084     {
00085         if (!func) {
00086             memset(this, 0, sizeof(Callback));
00087         } else {
00088             generate(func);
00089         }
00090     }
00091 
00092     /** Attach a Callback
00093      *  @param func     The Callback to attach
00094      */
00095     Callback(const Callback<R(ArgTs...)> &func)
00096     {
00097         memset(this, 0, sizeof(Callback));
00098         if (func._ops) {
00099             func._ops->move(this, &func);
00100         }
00101         _ops = func._ops;
00102     }
00103 
00104     /** Create a Callback with a member function
00105      *  @param obj      Pointer to object to invoke member function on
00106      *  @param method   Member function to attach
00107      */
00108     template<typename T, typename U>
00109     Callback(U *obj, R(T::*method)(ArgTs...))
00110     {
00111         generate(method_context<T, R(T::*)(ArgTs...)>(obj, method));
00112     }
00113 
00114     /** Create a Callback with a member function
00115      *  @param obj      Pointer to object to invoke member function on
00116      *  @param method   Member function to attach
00117      */
00118     template<typename T, typename U>
00119     Callback(const U *obj, R(T::*method)(ArgTs...) const)
00120     {
00121         generate(method_context<const T, R(T::*)(ArgTs...) const>(obj, method));
00122     }
00123 
00124     /** Create a Callback with a member function
00125      *  @param obj      Pointer to object to invoke member function on
00126      *  @param method   Member function to attach
00127      */
00128     template<typename T, typename U>
00129     Callback(volatile U *obj, R(T::*method)(ArgTs...) volatile)
00130     {
00131         generate(method_context<volatile T, R(T::*)(ArgTs...) volatile>(obj, method));
00132     }
00133 
00134     /** Create a Callback with a member function
00135      *  @param obj      Pointer to object to invoke member function on
00136      *  @param method   Member function to attach
00137      */
00138     template<typename T, typename U>
00139     Callback(const volatile U *obj, R(T::*method)(ArgTs...) const volatile)
00140     {
00141         generate(method_context<const volatile T, R(T::*)(ArgTs...) const volatile>(obj, method));
00142     }
00143 
00144     /** Create a Callback with a static function and bound pointer
00145      *  @param func     Static function to attach
00146      *  @param arg      Pointer argument to function
00147      */
00148     template<typename T, typename U>
00149     Callback(R(*func)(T *, ArgTs...), U *arg)
00150     {
00151         generate(function_context<R(*)(T *, ArgTs...), T>(func, arg));
00152     }
00153 
00154     /** Create a Callback with a static function and bound pointer
00155      *  @param func     Static function to attach
00156      *  @param arg      Pointer argument to function
00157      */
00158     template<typename T, typename U>
00159     Callback(R(*func)(const T *, ArgTs...), const U *arg)
00160     {
00161         generate(function_context<R(*)(const T *, ArgTs...), const T>(func, arg));
00162     }
00163 
00164     /** Create a Callback with a static function and bound pointer
00165      *  @param func     Static function to attach
00166      *  @param arg      Pointer argument to function
00167      */
00168     template<typename T, typename U>
00169     Callback(R(*func)(volatile T *, ArgTs...), volatile U *arg)
00170     {
00171         generate(function_context<R(*)(volatile T *, ArgTs...), volatile T>(func, arg));
00172     }
00173 
00174     /** Create a Callback with a static function and bound pointer
00175      *  @param func     Static function to attach
00176      *  @param arg      Pointer argument to function
00177      */
00178     template<typename T, typename U>
00179     Callback(R(*func)(const volatile T *, ArgTs...), const volatile U *arg)
00180     {
00181         generate(function_context<R(*)(const volatile T *, ArgTs...), const volatile T>(func, arg));
00182     }
00183 
00184     /** Create a Callback with a function object
00185      *  @param f Function object to attach
00186      *  @note The function object is limited to a single word of storage
00187      */
00188     template <typename F>
00189     Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)))
00190     {
00191         generate(f);
00192     }
00193 
00194     /** Create a Callback with a function object
00195      *  @param f Function object to attach
00196      *  @note The function object is limited to a single word of storage
00197      */
00198     template <typename F>
00199     Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) const))
00200     {
00201         generate(f);
00202     }
00203 
00204     /** Create a Callback with a function object
00205      *  @param f Function object to attach
00206      *  @note The function object is limited to a single word of storage
00207      */
00208     template <typename F>
00209     Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) volatile))
00210     {
00211         generate(f);
00212     }
00213 
00214     /** Create a Callback with a function object
00215      *  @param f Function object to attach
00216      *  @note The function object is limited to a single word of storage
00217      */
00218     template <typename F>
00219     Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) const volatile))
00220     {
00221         generate(f);
00222     }
00223 
00224     /** Create a Callback with a static function and bound pointer
00225      *  @param obj  Pointer to object to bind to function
00226      *  @param func Static function to attach
00227      *  @deprecated
00228      *      Arguments to callback have been reordered to Callback(func, arg)
00229      */
00230     template<typename T, typename U>
00231     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00232                           "Arguments to callback have been reordered to Callback(func, arg)")
00233     Callback(U *obj, R(*func)(T *, ArgTs...))
00234     {
00235         new (this) Callback(func, obj);
00236     }
00237 
00238     /** Create a Callback with a static function and bound pointer
00239      *  @param obj  Pointer to object to bind to function
00240      *  @param func Static function to attach
00241      *  @deprecated
00242      *      Arguments to callback have been reordered to Callback(func, arg)
00243      */
00244     template<typename T, typename U>
00245     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00246                           "Arguments to callback have been reordered to Callback(func, arg)")
00247     Callback(const U *obj, R(*func)(const T *, ArgTs...))
00248     {
00249         new (this) Callback(func, obj);
00250     }
00251 
00252     /** Create a Callback with a static function and bound pointer
00253      *  @param obj  Pointer to object to bind to function
00254      *  @param func Static function to attach
00255      *  @deprecated
00256      *      Arguments to callback have been reordered to Callback(func, arg)
00257      */
00258     template<typename T, typename U>
00259     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00260                           "Arguments to callback have been reordered to Callback(func, arg)")
00261     Callback(volatile U *obj, R(*func)(volatile T *, ArgTs...))
00262     {
00263         new (this) Callback(func, obj);
00264     }
00265 
00266     /** Create a Callback with a static function and bound pointer
00267      *  @param obj  Pointer to object to bind to function
00268      *  @param func Static function to attach
00269      *  @deprecated
00270      *      Arguments to callback have been reordered to Callback(func, arg)
00271      */
00272     template<typename T, typename U>
00273     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00274                           "Arguments to callback have been reordered to Callback(func, arg)")
00275     Callback(const volatile U *obj, R(*func)(const volatile T *, ArgTs...))
00276     {
00277         new (this) Callback(func, obj);
00278     }
00279 
00280     /** Destroy a callback
00281      */
00282     ~Callback()
00283     {
00284         if (_ops) {
00285             _ops->dtor(this);
00286         }
00287     }
00288 
00289     /** Attach a static function
00290      *  @param func     Static function to attach
00291      *  @deprecated
00292      *      Replaced by simple assignment 'Callback cb = func'
00293      */
00294     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00295                           "Replaced by simple assignment 'Callback cb = func")
00296     void attach(R(*func)(ArgTs...))
00297     {
00298         this->~Callback();
00299         new (this) Callback(func);
00300     }
00301 
00302     /** Attach a Callback
00303      *  @param func     The Callback to attach
00304      *  @deprecated
00305      *      Replaced by simple assignment 'Callback cb = func'
00306      */
00307     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00308                           "Replaced by simple assignment 'Callback cb = func")
00309     void attach(const Callback<R(ArgTs...)> &func)
00310     {
00311         this->~Callback();
00312         new (this) Callback(func);
00313     }
00314 
00315     /** Attach a member function
00316      *  @param obj      Pointer to object to invoke member function on
00317      *  @param method   Member function to attach
00318      *  @deprecated
00319      *      Replaced by simple assignment 'Callback cb = func'
00320      */
00321     template<typename T, typename U>
00322     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00323                           "Replaced by simple assignment 'Callback cb = func")
00324     void attach(U *obj, R(T::*method)(ArgTs...))
00325     {
00326         this->~Callback();
00327         new (this) Callback(obj, method);
00328     }
00329 
00330     /** Attach a member function
00331      *  @param obj      Pointer to object to invoke member function on
00332      *  @param method   Member function to attach
00333      *  @deprecated
00334      *      Replaced by simple assignment 'Callback cb = func'
00335      */
00336     template<typename T, typename U>
00337     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00338                           "Replaced by simple assignment 'Callback cb = func")
00339     void attach(const U *obj, R(T::*method)(ArgTs...) const)
00340     {
00341         this->~Callback();
00342         new (this) Callback(obj, method);
00343     }
00344 
00345     /** Attach a member function
00346      *  @param obj      Pointer to object to invoke member function on
00347      *  @param method   Member function to attach
00348      *  @deprecated
00349      *      Replaced by simple assignment 'Callback cb = func'
00350      */
00351     template<typename T, typename U>
00352     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00353                           "Replaced by simple assignment 'Callback cb = func")
00354     void attach(volatile U *obj, R(T::*method)(ArgTs...) volatile)
00355     {
00356         this->~Callback();
00357         new (this) Callback(obj, method);
00358     }
00359 
00360     /** Attach a member function
00361      *  @param obj      Pointer to object to invoke member function on
00362      *  @param method   Member function to attach
00363      *  @deprecated
00364      *      Replaced by simple assignment 'Callback cb = func'
00365      */
00366     template<typename T, typename U>
00367     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00368                           "Replaced by simple assignment 'Callback cb = func")
00369     void attach(const volatile U *obj, R(T::*method)(ArgTs...) const volatile)
00370     {
00371         this->~Callback();
00372         new (this) Callback(obj, method);
00373     }
00374 
00375     /** Attach a static function with a bound pointer
00376      *  @param func     Static function to attach
00377      *  @param arg      Pointer argument to function
00378      *  @deprecated
00379      *      Replaced by simple assignment 'Callback cb = func'
00380      */
00381     template <typename T, typename U>
00382     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00383                           "Replaced by simple assignment 'Callback cb = func")
00384     void attach(R(*func)(T *, ArgTs...), U *arg)
00385     {
00386         this->~Callback();
00387         new (this) Callback(func, arg);
00388     }
00389 
00390     /** Attach a static function with a bound pointer
00391      *  @param func     Static function to attach
00392      *  @param arg      Pointer argument to function
00393      *  @deprecated
00394      *      Replaced by simple assignment 'Callback cb = func'
00395      */
00396     template <typename T, typename U>
00397     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00398                           "Replaced by simple assignment 'Callback cb = func")
00399     void attach(R(*func)(const T *, ArgTs...), const U *arg)
00400     {
00401         this->~Callback();
00402         new (this) Callback(func, arg);
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      *  @deprecated
00409      *      Replaced by simple assignment 'Callback cb = func'
00410      */
00411     template <typename T, typename U>
00412     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00413                           "Replaced by simple assignment 'Callback cb = func")
00414     void attach(R(*func)(volatile T *, ArgTs...), volatile U *arg)
00415     {
00416         this->~Callback();
00417         new (this) Callback(func, arg);
00418     }
00419 
00420     /** Attach a static function with a bound pointer
00421      *  @param func     Static function to attach
00422      *  @param arg      Pointer argument to function
00423      *  @deprecated
00424      *      Replaced by simple assignment 'Callback cb = func'
00425      */
00426     template <typename T, typename U>
00427     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00428                           "Replaced by simple assignment 'Callback cb = func")
00429     void attach(R(*func)(const volatile T *, ArgTs...), const volatile U *arg)
00430     {
00431         this->~Callback();
00432         new (this) Callback(func, arg);
00433     }
00434 
00435     /** Attach a function object
00436      *  @param f Function object to attach
00437      *  @note The function object is limited to a single word of storage
00438      *  @deprecated
00439      *      Replaced by simple assignment 'Callback cb = func'
00440      */
00441     template <typename F>
00442     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00443                           "Replaced by simple assignment 'Callback cb = func")
00444     void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...)))
00445     {
00446         this->~Callback();
00447         new (this) Callback(f);
00448     }
00449 
00450     /** Attach a function object
00451      *  @param f Function object to attach
00452      *  @note The function object is limited to a single word of storage
00453      *  @deprecated
00454      *      Replaced by simple assignment 'Callback cb = func'
00455      */
00456     template <typename F>
00457     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00458                           "Replaced by simple assignment 'Callback cb = func")
00459     void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) const))
00460     {
00461         this->~Callback();
00462         new (this) Callback(f);
00463     }
00464 
00465     /** Attach a function object
00466      *  @param f Function object to attach
00467      *  @note The function object is limited to a single word of storage
00468      *  @deprecated
00469      *      Replaced by simple assignment 'Callback cb = func'
00470      */
00471     template <typename F>
00472     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00473                           "Replaced by simple assignment 'Callback cb = func")
00474     void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) volatile))
00475     {
00476         this->~Callback();
00477         new (this) Callback(f);
00478     }
00479 
00480     /** Attach a function object
00481      *  @param f Function object to attach
00482      *  @note The function object is limited to a single word of storage
00483      *  @deprecated
00484      *      Replaced by simple assignment 'Callback cb = func'
00485      */
00486     template <typename F>
00487     MBED_DEPRECATED_SINCE("mbed-os-5.4",
00488                           "Replaced by simple assignment 'Callback cb = func")
00489     void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R(F::*)(ArgTs...) const volatile))
00490     {
00491         this->~Callback();
00492         new (this) Callback(f);
00493     }
00494 
00495     /** Attach a static function with a bound pointer
00496      *  @param obj  Pointer to object to bind to function
00497      *  @param func Static function to attach
00498      *  @deprecated
00499      *      Arguments to callback have been reordered to attach(func, arg)
00500      */
00501     template <typename T, typename U>
00502     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00503                           "Arguments to callback have been reordered to attach(func, arg)")
00504     void attach(U *obj, R(*func)(T *, ArgTs...))
00505     {
00506         this->~Callback();
00507         new (this) Callback(func, obj);
00508     }
00509 
00510     /** Attach a static function with a bound pointer
00511      *  @param obj  Pointer to object to bind to function
00512      *  @param func Static function to attach
00513      *  @deprecated
00514      *      Arguments to callback have been reordered to attach(func, arg)
00515      */
00516     template <typename T, typename U>
00517     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00518                           "Arguments to callback have been reordered to attach(func, arg)")
00519     void attach(const U *obj, R(*func)(const T *, ArgTs...))
00520     {
00521         this->~Callback();
00522         new (this) Callback(func, obj);
00523     }
00524 
00525     /** Attach a static function with a bound pointer
00526      *  @param obj  Pointer to object to bind to function
00527      *  @param func Static function to attach
00528      *  @deprecated
00529      *      Arguments to callback have been reordered to attach(func, arg)
00530      */
00531     template <typename T, typename U>
00532     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00533                           "Arguments to callback have been reordered to attach(func, arg)")
00534     void attach(volatile U *obj, R(*func)(volatile T *, ArgTs...))
00535     {
00536         this->~Callback();
00537         new (this) Callback(func, obj);
00538     }
00539 
00540     /** Attach a static function with a bound pointer
00541      *  @param obj  Pointer to object to bind to function
00542      *  @param func Static function to attach
00543      *  @deprecated
00544      *      Arguments to callback have been reordered to attach(func, arg)
00545      */
00546     template <typename T, typename U>
00547     MBED_DEPRECATED_SINCE("mbed-os-5.1",
00548                           "Arguments to callback have been reordered to attach(func, arg)")
00549     void attach(const volatile U *obj, R(*func)(const volatile T *, ArgTs...))
00550     {
00551         this->~Callback();
00552         new (this) Callback(func, obj);
00553     }
00554 
00555     /** Assign a callback
00556      */
00557     Callback &operator=(const Callback &that)
00558     {
00559         if (this != &that) {
00560             this->~Callback();
00561             new (this) Callback(that);
00562         }
00563 
00564         return *this;
00565     }
00566 
00567     /** Call the attached function
00568      */
00569     R call(ArgTs... args) const
00570     {
00571         MBED_ASSERT(_ops);
00572         return _ops->call(this, args...);
00573     }
00574 
00575     /** Call the attached function
00576      */
00577     R operator()(ArgTs... args) const
00578     {
00579         return call(args...);
00580     }
00581 
00582     /** Test if function has been attached
00583      */
00584     operator bool() const
00585     {
00586         return _ops;
00587     }
00588 
00589     /** Test for equality
00590      */
00591     friend bool operator==(const Callback &l, const Callback &r)
00592     {
00593         return memcmp(&l, &r, sizeof(Callback)) == 0;
00594     }
00595 
00596     /** Test for inequality
00597      */
00598     friend bool operator!=(const Callback &l, const Callback &r)
00599     {
00600         return !(l == r);
00601     }
00602 
00603     /** Static thunk for passing as C-style function
00604      *  @param func Callback to call passed as void pointer
00605      *  @param args Arguments to be called with function func
00606      *  @return the value as determined by func which is of
00607      *      type and determined by the signature of func
00608      */
00609     static R thunk(void *func, ArgTs... args)
00610     {
00611         return static_cast<Callback *>(func)->call(args...);
00612     }
00613 
00614 private:
00615     // Stored as pointer to function and pointer to optional object
00616     // Function pointer is stored as union of possible function types
00617     // to guarantee proper size and alignment
00618     struct _class;
00619     union {
00620         void (*_staticfunc)(ArgTs...);
00621         void (*_boundfunc)(_class *, ArgTs...);
00622         void (_class::*_methodfunc)(ArgTs...);
00623     } _func;
00624     void *_obj;
00625 
00626     // Dynamically dispatched operations
00627     const struct ops {
00628         R(*call)(const void *, ArgTs...);
00629         void (*move)(void *, const void *);
00630         void (*dtor)(void *);
00631     } *_ops;
00632 
00633     // Generate operations for function object
00634     template <typename F>
00635     void generate(const F &f)
00636     {
00637         static const ops ops = {
00638             &Callback::function_call<F>,
00639             &Callback::function_move<F>,
00640             &Callback::function_dtor<F>,
00641         };
00642 
00643         MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
00644                            "Type F must not exceed the size of the Callback class");
00645         memset(this, 0, sizeof(Callback));
00646         new (this) F(f);
00647         _ops = &ops;
00648     }
00649 
00650     // Function attributes
00651     template <typename F>
00652     static R function_call(const void *p, ArgTs... args)
00653     {
00654         return (*(F *)p)(args...);
00655     }
00656 
00657     template <typename F>
00658     static void function_move(void *d, const void *p)
00659     {
00660         new (d) F(*(F *)p);
00661     }
00662 
00663     template <typename F>
00664     static void function_dtor(void *p)
00665     {
00666         ((F *)p)->~F();
00667     }
00668 
00669     // Wrappers for functions with context
00670     template <typename O, typename M>
00671     struct method_context {
00672         M method;
00673         O *obj;
00674 
00675         method_context(O *obj, M method)
00676             : method(method), obj(obj) {}
00677 
00678         R operator()(ArgTs... args) const
00679         {
00680             return (obj->*method)(args...);
00681         }
00682     };
00683 
00684     template <typename F, typename A>
00685     struct function_context {
00686         F func;
00687         A *arg;
00688 
00689         function_context(F func, A *arg)
00690             : func(func), arg(arg) {}
00691 
00692         R operator()(ArgTs... args) const
00693         {
00694             return func(arg, args...);
00695         }
00696     };
00697 };
00698 
00699 // Internally used event type
00700 typedef Callback<void(int)> event_callback_t;
00701 
00702 
00703 /** Create a callback class with type inferred from the arguments
00704  *
00705  *  @param func     Static function to attach
00706  *  @return         Callback with inferred type
00707  */
00708 template <typename R, typename... ArgTs>
00709 Callback<R(ArgTs...)> callback(R(*func)(ArgTs...) = 0)
00710 {
00711     return Callback<R(ArgTs...)>(func);
00712 }
00713 
00714 /** Create a callback class with type inferred from the arguments
00715  *
00716  *  @param func     Static function to attach
00717  *  @return         Callback with inferred type
00718  */
00719 template <typename R, typename... ArgTs>
00720 Callback<R(ArgTs...)> callback(const Callback<R(ArgTs...)> &func)
00721 {
00722     return Callback<R(ArgTs...)>(func);
00723 }
00724 
00725 /** Create a callback class with type inferred from the arguments
00726  *
00727  *  @param obj      Optional pointer to object to bind to function
00728  *  @param method   Member function to attach
00729  *  @return         Callback with inferred type
00730  */
00731 template<typename T, typename U, typename R, typename... ArgTs>
00732 Callback<R(ArgTs...)> callback(U *obj, R(T::*method)(ArgTs...))
00733 {
00734     return Callback<R(ArgTs...)>(obj, method);
00735 }
00736 
00737 /** Create a callback class with type inferred from the arguments
00738  *
00739  *  @param obj      Optional pointer to object to bind to function
00740  *  @param method   Member function to attach
00741  *  @return         Callback with inferred type
00742  */
00743 template<typename T, typename U, typename R, typename... ArgTs>
00744 Callback<R(ArgTs...)> callback(const U *obj, R(T::*method)(ArgTs...) const)
00745 {
00746     return Callback<R(ArgTs...)>(obj, method);
00747 }
00748 
00749 /** Create a callback class with type inferred from the arguments
00750  *
00751  *  @param obj      Optional pointer to object to bind to function
00752  *  @param method   Member function to attach
00753  *  @return         Callback with inferred type
00754  */
00755 template<typename T, typename U, typename R, typename... ArgTs>
00756 Callback<R(ArgTs...)> callback(volatile U *obj, R(T::*method)(ArgTs...) volatile)
00757 {
00758     return Callback<R(ArgTs...)>(obj, method);
00759 }
00760 
00761 /** Create a callback class with type inferred from the arguments
00762  *
00763  *  @param obj      Optional pointer to object to bind to function
00764  *  @param method   Member function to attach
00765  *  @return         Callback with inferred type
00766  */
00767 template<typename T, typename U, typename R, typename... ArgTs>
00768 Callback<R(ArgTs...)> callback(const volatile U *obj, R(T::*method)(ArgTs...) const volatile)
00769 {
00770     return Callback<R(ArgTs...)>(obj, method);
00771 }
00772 
00773 /** Create a callback class with type inferred from the arguments
00774  *
00775  *  @param func     Static function to attach
00776  *  @param arg      Pointer argument to function
00777  *  @return         Callback with inferred type
00778  */
00779 template <typename T, typename U, typename R, typename... ArgTs>
00780 Callback<R(ArgTs...)> callback(R(*func)(T *, ArgTs...), U *arg)
00781 {
00782     return Callback<R(ArgTs...)>(func, arg);
00783 }
00784 
00785 /** Create a callback class with type inferred from the arguments
00786  *
00787  *  @param func     Static function to attach
00788  *  @param arg      Pointer argument to function
00789  *  @return         Callback with inferred type
00790  */
00791 template <typename T, typename U, typename R, typename... ArgTs>
00792 Callback<R(ArgTs...)> callback(R(*func)(const T *, ArgTs...), const U *arg)
00793 {
00794     return Callback<R(ArgTs...)>(func, arg);
00795 }
00796 
00797 /** Create a callback class with type inferred from the arguments
00798  *
00799  *  @param func     Static function to attach
00800  *  @param arg      Pointer argument to function
00801  *  @return         Callback with inferred type
00802  */
00803 template <typename T, typename U, typename R, typename... ArgTs>
00804 Callback<R(ArgTs...)> callback(R(*func)(volatile T *, ArgTs...), volatile U *arg)
00805 {
00806     return Callback<R(ArgTs...)>(func, arg);
00807 }
00808 
00809 /** Create a callback class with type inferred from the arguments
00810  *
00811  *  @param func     Static function to attach
00812  *  @param arg      Pointer argument to function
00813  *  @return         Callback with inferred type
00814  */
00815 template <typename T, typename U, typename R, typename... ArgTs>
00816 Callback<R(ArgTs...)> callback(R(*func)(const volatile T *, ArgTs...), const volatile U *arg)
00817 {
00818     return Callback<R(ArgTs...)>(func, arg);
00819 }
00820 
00821 /** Create a callback class with type inferred from the arguments
00822  *
00823  *  @param obj  Optional pointer to object to bind to function
00824  *  @param func Static function to attach
00825  *  @return     Callback with inferred type
00826  *  @deprecated
00827  *      Arguments to callback have been reordered to callback(func, arg)
00828  */
00829 template <typename T, typename U, typename R, typename... ArgTs>
00830 MBED_DEPRECATED_SINCE("mbed-os-5.1",
00831                       "Arguments to callback have been reordered to callback(func, arg)")
00832 Callback<R(ArgTs...)> callback(U *obj, R(*func)(T *, ArgTs...))
00833 {
00834     return Callback<R(ArgTs...)>(func, obj);
00835 }
00836 
00837 /** Create a callback class with type inferred from the arguments
00838  *
00839  *  @param obj  Optional pointer to object to bind to function
00840  *  @param func Static function to attach
00841  *  @return     Callback with inferred type
00842  *  @deprecated
00843  *      Arguments to callback have been reordered to callback(func, arg)
00844  */
00845 template <typename T, typename U, typename R, typename... ArgTs>
00846 MBED_DEPRECATED_SINCE("mbed-os-5.1",
00847                       "Arguments to callback have been reordered to callback(func, arg)")
00848 Callback<R(ArgTs...)> callback(const U *obj, R(*func)(const T *, ArgTs...))
00849 {
00850     return Callback<R(ArgTs...)>(func, obj);
00851 }
00852 
00853 /** Create a callback class with type inferred from the arguments
00854  *
00855  *  @param obj  Optional pointer to object to bind to function
00856  *  @param func Static function to attach
00857  *  @return     Callback with inferred type
00858  *  @deprecated
00859  *      Arguments to callback have been reordered to callback(func, arg)
00860  */
00861 template <typename T, typename U, typename R, typename... ArgTs>
00862 MBED_DEPRECATED_SINCE("mbed-os-5.1",
00863                       "Arguments to callback have been reordered to callback(func, arg)")
00864 Callback<R(ArgTs...)> callback(volatile U *obj, R(*func)(volatile T *, ArgTs...))
00865 {
00866     return Callback<R(ArgTs...)>(func, obj);
00867 }
00868 
00869 /** Create a callback class with type inferred from the arguments
00870  *
00871  *  @param obj  Optional pointer to object to bind to function
00872  *  @param func Static function to attach
00873  *  @return     Callback with inferred type
00874  *  @deprecated
00875  *      Arguments to callback have been reordered to callback(func, arg)
00876  */
00877 template <typename T, typename U, typename R, typename... ArgTs>
00878 MBED_DEPRECATED_SINCE("mbed-os-5.1",
00879                       "Arguments to callback have been reordered to callback(func, arg)")
00880 Callback<R(ArgTs...)> callback(const volatile U *obj, R(*func)(const volatile T *, ArgTs...))
00881 {
00882     return Callback<R(ArgTs...)>(func, obj);
00883 }
00884 
00885 /**@}*/
00886 
00887 /**@}*/
00888 
00889 } // namespace mbed
00890 
00891 #endif