f

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Callback-A.h Source File

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