joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Callback.h Source File

Callback.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2015 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #ifndef MBED_CALLBACK_H
00017 #define MBED_CALLBACK_H
00018 
00019 #include <string.h>
00020 #include <stdint.h>
00021 #include "mbed_assert.h"
00022 
00023 namespace mbed {
00024 
00025 
00026 /** Callback class based on template specialization
00027  *
00028  * @Note Synchronization level: Not protected
00029  */
00030 template <typename F>
00031 class Callback;
00032 
00033 /** Callback class based on template specialization
00034  *
00035  * @Note Synchronization level: Not protected
00036  */
00037 template <typename R>
00038 class Callback<R()> {
00039 public:
00040     /** Create a Callback with a static function
00041      *  @param func Static function to attach
00042      */
00043     Callback(R (*func)() = 0) {
00044         attach(func);
00045     }
00046 
00047     /** Create a Callback with a static function and bound pointer
00048      *  @param obj  Pointer to object to bind to function
00049      *  @param func Static function to attach
00050      */
00051     Callback(void *obj, R (*func)(void*)) {
00052         attach(obj, func);
00053     }
00054 
00055     /** Create a Callback with a static function and bound pointer
00056      *  @param obj  Pointer to object to bind to function
00057      *  @param func Static function to attach
00058      */
00059     Callback(const void *obj, R (*func)(const void*)) {
00060         attach(obj, func);
00061     }
00062 
00063     /** Create a Callback with a static function and bound pointer
00064      *  @param obj  Pointer to object to bind to function
00065      *  @param func Static function to attach
00066      */
00067     Callback(volatile void *obj, R (*func)(volatile void*)) {
00068         attach(obj, func);
00069     }
00070 
00071     /** Create a Callback with a static function and bound pointer
00072      *  @param obj  Pointer to object to bind to function
00073      *  @param func Static function to attach
00074      */
00075     Callback(const volatile void *obj, R (*func)(const volatile void*)) {
00076         attach(obj, func);
00077     }
00078 
00079     /** Create a Callback with a static function and bound pointer
00080      *  @param obj  Pointer to object to bind to function
00081      *  @param func Static function to attach
00082      */
00083     template<typename T>
00084     Callback(T *obj, R (*func)(T*)) {
00085         attach(obj, func);
00086     }
00087 
00088     /** Create a Callback with a static function and bound pointer
00089      *  @param obj  Pointer to object to bind to function
00090      *  @param func Static function to attach
00091      */
00092     template<typename T>
00093     Callback(const T *obj, R (*func)(const T*)) {
00094         attach(obj, func);
00095     }
00096 
00097     /** Create a Callback with a static function and bound pointer
00098      *  @param obj  Pointer to object to bind to function
00099      *  @param func Static function to attach
00100      */
00101     template<typename T>
00102     Callback(volatile T *obj, R (*func)(volatile T*)) {
00103         attach(obj, func);
00104     }
00105 
00106     /** Create a Callback with a static function and bound pointer
00107      *  @param obj  Pointer to object to bind to function
00108      *  @param func Static function to attach
00109      */
00110     template<typename T>
00111     Callback(const volatile T *obj, R (*func)(const volatile T*)) {
00112         attach(obj, func);
00113     }
00114 
00115     /** Create a Callback with a member function
00116      *  @param obj  Pointer to object to invoke member function on
00117      *  @param func Member function to attach
00118      */
00119     template<typename T>
00120     Callback(T *obj, R (T::*func)()) {
00121         attach(obj, func);
00122     }
00123 
00124     /** Create a Callback with a member function
00125      *  @param obj  Pointer to object to invoke member function on
00126      *  @param func Member function to attach
00127      */
00128     template<typename T>
00129     Callback(const T *obj, R (T::*func)() const) {
00130         attach(obj, func);
00131     }
00132 
00133     /** Create a Callback with a member function
00134      *  @param obj  Pointer to object to invoke member function on
00135      *  @param func Member function to attach
00136      */
00137     template<typename T>
00138     Callback(volatile T *obj, R (T::*func)() volatile) {
00139         attach(obj, func);
00140     }
00141 
00142     /** Create a Callback with a member function
00143      *  @param obj  Pointer to object to invoke member function on
00144      *  @param func Member function to attach
00145      */
00146     template<typename T>
00147     Callback(const volatile T *obj, R (T::*func)() const volatile) {
00148         attach(obj, func);
00149     }
00150 
00151     /** Attach a static function
00152      *  @param func Static function to attach
00153      */
00154     void attach(R (*func)()) {
00155         struct local {
00156             static R _thunk(void*, const void *func) {
00157                 return (*static_cast<R (*const *)()>(func))(
00158                         );
00159             }
00160         };
00161 
00162         memset(&_func, 0, sizeof _func);
00163         memcpy(&_func, &func, sizeof func);
00164         _obj = 0;
00165         _thunk = func ? &local::_thunk : 0;
00166     }
00167 
00168     /** Attach a Callback
00169      *  @param func The Callback to attach
00170      */
00171     void attach(const Callback<R()> &func) {
00172         memset(&_func, 0, sizeof _func);
00173         memcpy(&_func, &func._func, sizeof func);
00174         _obj = func._obj;
00175         _thunk = func._thunk;
00176     }
00177 
00178     /** Attach a static function with a bound pointer
00179      *  @param obj  Pointer to object to bind to function
00180      *  @param func Static function to attach
00181      */
00182     void attach(void *obj, R (*func)(void*)) {
00183         struct local {
00184             static R _thunk(void *obj, const void *func) {
00185                 return (*static_cast<R (*const *)(void*)>(func))(
00186                         (void*)obj);
00187             }
00188         };
00189 
00190         memset(&_func, 0, sizeof _func);
00191         memcpy(&_func, &func, sizeof func);
00192         _obj = (void*)obj;
00193         _thunk = &local::_thunk;
00194     }
00195 
00196     /** Attach a static function with a bound pointer
00197      *  @param obj  Pointer to object to bind to function
00198      *  @param func Static function to attach
00199      */
00200     void attach(const void *obj, R (*func)(const void*)) {
00201         struct local {
00202             static R _thunk(void *obj, const void *func) {
00203                 return (*static_cast<R (*const *)(const void*)>(func))(
00204                         (const void*)obj);
00205             }
00206         };
00207 
00208         memset(&_func, 0, sizeof _func);
00209         memcpy(&_func, &func, sizeof func);
00210         _obj = (void*)obj;
00211         _thunk = &local::_thunk;
00212     }
00213 
00214     /** Attach a static function with a bound pointer
00215      *  @param obj  Pointer to object to bind to function
00216      *  @param func Static function to attach
00217      */
00218     void attach(volatile void *obj, R (*func)(volatile void*)) {
00219         struct local {
00220             static R _thunk(void *obj, const void *func) {
00221                 return (*static_cast<R (*const *)(volatile void*)>(func))(
00222                         (volatile void*)obj);
00223             }
00224         };
00225 
00226         memset(&_func, 0, sizeof _func);
00227         memcpy(&_func, &func, sizeof func);
00228         _obj = (void*)obj;
00229         _thunk = &local::_thunk;
00230     }
00231 
00232     /** Attach a static function with a bound pointer
00233      *  @param obj  Pointer to object to bind to function
00234      *  @param func Static function to attach
00235      */
00236     void attach(const volatile void *obj, R (*func)(const volatile void*)) {
00237         struct local {
00238             static R _thunk(void *obj, const void *func) {
00239                 return (*static_cast<R (*const *)(const volatile void*)>(func))(
00240                         (const volatile void*)obj);
00241             }
00242         };
00243 
00244         memset(&_func, 0, sizeof _func);
00245         memcpy(&_func, &func, sizeof func);
00246         _obj = (void*)obj;
00247         _thunk = &local::_thunk;
00248     }
00249 
00250     /** Attach a static function with a bound pointer
00251      *  @param obj  Pointer to object to bind to function
00252      *  @param func Static function to attach
00253      */
00254     template <typename T>
00255     void attach(T *obj, R (*func)(T*)) {
00256         struct local {
00257             static R _thunk(void *obj, const void *func) {
00258                 return (*static_cast<R (*const *)(T*)>(func))(
00259                         (T*)obj);
00260             }
00261         };
00262 
00263         memset(&_func, 0, sizeof _func);
00264         memcpy(&_func, &func, sizeof func);
00265         _obj = (void*)obj;
00266         _thunk = &local::_thunk;
00267     }
00268 
00269     /** Attach a static function with a bound pointer
00270      *  @param obj  Pointer to object to bind to function
00271      *  @param func Static function to attach
00272      */
00273     template <typename T>
00274     void attach(const T *obj, R (*func)(const T*)) {
00275         struct local {
00276             static R _thunk(void *obj, const void *func) {
00277                 return (*static_cast<R (*const *)(const T*)>(func))(
00278                         (const T*)obj);
00279             }
00280         };
00281 
00282         memset(&_func, 0, sizeof _func);
00283         memcpy(&_func, &func, sizeof func);
00284         _obj = (void*)obj;
00285         _thunk = &local::_thunk;
00286     }
00287 
00288     /** Attach a static function with a bound pointer
00289      *  @param obj  Pointer to object to bind to function
00290      *  @param func Static function to attach
00291      */
00292     template <typename T>
00293     void attach(volatile T *obj, R (*func)(volatile T*)) {
00294         struct local {
00295             static R _thunk(void *obj, const void *func) {
00296                 return (*static_cast<R (*const *)(volatile T*)>(func))(
00297                         (volatile T*)obj);
00298             }
00299         };
00300 
00301         memset(&_func, 0, sizeof _func);
00302         memcpy(&_func, &func, sizeof func);
00303         _obj = (void*)obj;
00304         _thunk = &local::_thunk;
00305     }
00306 
00307     /** Attach a static function with a bound pointer
00308      *  @param obj  Pointer to object to bind to function
00309      *  @param func Static function to attach
00310      */
00311     template <typename T>
00312     void attach(const volatile T *obj, R (*func)(const volatile T*)) {
00313         struct local {
00314             static R _thunk(void *obj, const void *func) {
00315                 return (*static_cast<R (*const *)(const volatile T*)>(func))(
00316                         (const volatile T*)obj);
00317             }
00318         };
00319 
00320         memset(&_func, 0, sizeof _func);
00321         memcpy(&_func, &func, sizeof func);
00322         _obj = (void*)obj;
00323         _thunk = &local::_thunk;
00324     }
00325 
00326     /** Attach a member function
00327      *  @param obj  Pointer to object to invoke member function on
00328      *  @param func Member function to attach
00329      */
00330     template<typename T>
00331     void attach(T *obj, R (T::*func)()) {
00332         struct local {
00333             static R _thunk(void *obj, const void *func) {
00334                 return (((T*)obj)->*
00335                         (*static_cast<R (T::*const *)()>(func)))(
00336                         );
00337             }
00338         };
00339 
00340         memset(&_func, 0, sizeof _func);
00341         memcpy(&_func, &func, sizeof func);
00342         _obj = (void*)obj;
00343         _thunk = &local::_thunk;
00344     }
00345 
00346     /** Attach a member function
00347      *  @param obj  Pointer to object to invoke member function on
00348      *  @param func Member function to attach
00349      */
00350     template<typename T>
00351     void attach(const T *obj, R (T::*func)() const) {
00352         struct local {
00353             static R _thunk(void *obj, const void *func) {
00354                 return (((const T*)obj)->*
00355                         (*static_cast<R (T::*const *)() const>(func)))(
00356                         );
00357             }
00358         };
00359 
00360         memset(&_func, 0, sizeof _func);
00361         memcpy(&_func, &func, sizeof func);
00362         _obj = (void*)obj;
00363         _thunk = &local::_thunk;
00364     }
00365 
00366     /** Attach a member function
00367      *  @param obj  Pointer to object to invoke member function on
00368      *  @param func Member function to attach
00369      */
00370     template<typename T>
00371     void attach(volatile T *obj, R (T::*func)() volatile) {
00372         struct local {
00373             static R _thunk(void *obj, const void *func) {
00374                 return (((volatile T*)obj)->*
00375                         (*static_cast<R (T::*const *)() volatile>(func)))(
00376                         );
00377             }
00378         };
00379 
00380         memset(&_func, 0, sizeof _func);
00381         memcpy(&_func, &func, sizeof func);
00382         _obj = (void*)obj;
00383         _thunk = &local::_thunk;
00384     }
00385 
00386     /** Attach a member function
00387      *  @param obj  Pointer to object to invoke member function on
00388      *  @param func Member function to attach
00389      */
00390     template<typename T>
00391     void attach(const volatile T *obj, R (T::*func)() const volatile) {
00392         struct local {
00393             static R _thunk(void *obj, const void *func) {
00394                 return (((const volatile T*)obj)->*
00395                         (*static_cast<R (T::*const *)() const volatile>(func)))(
00396                         );
00397             }
00398         };
00399 
00400         memset(&_func, 0, sizeof _func);
00401         memcpy(&_func, &func, sizeof func);
00402         _obj = (void*)obj;
00403         _thunk = &local::_thunk;
00404     }
00405 
00406     /** Call the attached function
00407      */
00408     R call() const {
00409         MBED_ASSERT(_thunk);
00410         return _thunk(_obj, &_func);
00411     }
00412 
00413     /** Call the attached function
00414      */
00415     R operator()() const {
00416         return call();
00417     }
00418 
00419     /** Test if function has been attached
00420      */
00421     operator bool() const {
00422         return _thunk;
00423     }
00424 
00425     /** Test for equality
00426      */
00427     friend bool operator==(const Callback &l, const Callback &r) {
00428         return memcmp(&l, &r, sizeof(Callback)) == 0;
00429     }
00430 
00431     /** Test for inequality
00432      */
00433     friend bool operator!=(const Callback &l, const Callback &r) {
00434         return !(l == r);
00435     }
00436 
00437     /** Static thunk for passing as C-style function
00438      *  @param func Callback to call passed as void pointer
00439      */
00440     static R thunk(void *func) {
00441         return static_cast<Callback<R()>*>(func)->call(
00442                 );
00443     }
00444 
00445 private:
00446     // Stored as pointer to function and pointer to optional object
00447     // Function pointer is stored as union of possible function types
00448     // to garuntee proper size and alignment
00449     struct _class;
00450     union {
00451         void (*_staticfunc)();
00452         void (*_boundfunc)(_class *);
00453         void (_class::*_methodfunc)();
00454     } _func;
00455 
00456     void *_obj;
00457 
00458     // Thunk registered on attach to dispatch calls
00459     R (*_thunk)(void*, const void*);
00460 };
00461 
00462 /** Callback class based on template specialization
00463  *
00464  * @Note Synchronization level: Not protected
00465  */
00466 template <typename R, typename A0>
00467 class Callback<R(A0)> {
00468 public:
00469     /** Create a Callback with a static function
00470      *  @param func Static function to attach
00471      */
00472     Callback(R (*func)(A0) = 0) {
00473         attach(func);
00474     }
00475 
00476     /** Create a Callback with a static function and bound pointer
00477      *  @param obj  Pointer to object to bind to function
00478      *  @param func Static function to attach
00479      */
00480     Callback(void *obj, R (*func)(void*, A0)) {
00481         attach(obj, func);
00482     }
00483 
00484     /** Create a Callback with a static function and bound pointer
00485      *  @param obj  Pointer to object to bind to function
00486      *  @param func Static function to attach
00487      */
00488     Callback(const void *obj, R (*func)(const void*, A0)) {
00489         attach(obj, func);
00490     }
00491 
00492     /** Create a Callback with a static function and bound pointer
00493      *  @param obj  Pointer to object to bind to function
00494      *  @param func Static function to attach
00495      */
00496     Callback(volatile void *obj, R (*func)(volatile void*, A0)) {
00497         attach(obj, func);
00498     }
00499 
00500     /** Create a Callback with a static function and bound pointer
00501      *  @param obj  Pointer to object to bind to function
00502      *  @param func Static function to attach
00503      */
00504     Callback(const volatile void *obj, R (*func)(const volatile void*, A0)) {
00505         attach(obj, func);
00506     }
00507 
00508     /** Create a Callback with a static function and bound pointer
00509      *  @param obj  Pointer to object to bind to function
00510      *  @param func Static function to attach
00511      */
00512     template<typename T>
00513     Callback(T *obj, R (*func)(T*, A0)) {
00514         attach(obj, func);
00515     }
00516 
00517     /** Create a Callback with a static function and bound pointer
00518      *  @param obj  Pointer to object to bind to function
00519      *  @param func Static function to attach
00520      */
00521     template<typename T>
00522     Callback(const T *obj, R (*func)(const T*, A0)) {
00523         attach(obj, func);
00524     }
00525 
00526     /** Create a Callback with a static function and bound pointer
00527      *  @param obj  Pointer to object to bind to function
00528      *  @param func Static function to attach
00529      */
00530     template<typename T>
00531     Callback(volatile T *obj, R (*func)(volatile T*, A0)) {
00532         attach(obj, func);
00533     }
00534 
00535     /** Create a Callback with a static function and bound pointer
00536      *  @param obj  Pointer to object to bind to function
00537      *  @param func Static function to attach
00538      */
00539     template<typename T>
00540     Callback(const volatile T *obj, R (*func)(const volatile T*, A0)) {
00541         attach(obj, func);
00542     }
00543 
00544     /** Create a Callback with a member function
00545      *  @param obj  Pointer to object to invoke member function on
00546      *  @param func Member function to attach
00547      */
00548     template<typename T>
00549     Callback(T *obj, R (T::*func)(A0)) {
00550         attach(obj, func);
00551     }
00552 
00553     /** Create a Callback with a member function
00554      *  @param obj  Pointer to object to invoke member function on
00555      *  @param func Member function to attach
00556      */
00557     template<typename T>
00558     Callback(const T *obj, R (T::*func)(A0) const) {
00559         attach(obj, func);
00560     }
00561 
00562     /** Create a Callback with a member function
00563      *  @param obj  Pointer to object to invoke member function on
00564      *  @param func Member function to attach
00565      */
00566     template<typename T>
00567     Callback(volatile T *obj, R (T::*func)(A0) volatile) {
00568         attach(obj, func);
00569     }
00570 
00571     /** Create a Callback with a member function
00572      *  @param obj  Pointer to object to invoke member function on
00573      *  @param func Member function to attach
00574      */
00575     template<typename T>
00576     Callback(const volatile T *obj, R (T::*func)(A0) const volatile) {
00577         attach(obj, func);
00578     }
00579 
00580     /** Attach a static function
00581      *  @param func Static function to attach
00582      */
00583     void attach(R (*func)(A0)) {
00584         struct local {
00585             static R _thunk(void*, const void *func, A0 a0) {
00586                 return (*static_cast<R (*const *)(A0)>(func))(
00587                         a0);
00588             }
00589         };
00590 
00591         memset(&_func, 0, sizeof _func);
00592         memcpy(&_func, &func, sizeof func);
00593         _obj = 0;
00594         _thunk = func ? &local::_thunk : 0;
00595     }
00596 
00597     /** Attach a Callback
00598      *  @param func The Callback to attach
00599      */
00600     void attach(const Callback<R(A0)> &func) {
00601         memset(&_func, 0, sizeof _func);
00602         memcpy(&_func, &func._func, sizeof func);
00603         _obj = func._obj;
00604         _thunk = func._thunk;
00605     }
00606 
00607     /** Attach a static function with a bound pointer
00608      *  @param obj  Pointer to object to bind to function
00609      *  @param func Static function to attach
00610      */
00611     void attach(void *obj, R (*func)(void*, A0)) {
00612         struct local {
00613             static R _thunk(void *obj, const void *func, A0 a0) {
00614                 return (*static_cast<R (*const *)(void*, A0)>(func))(
00615                         (void*)obj, a0);
00616             }
00617         };
00618 
00619         memset(&_func, 0, sizeof _func);
00620         memcpy(&_func, &func, sizeof func);
00621         _obj = (void*)obj;
00622         _thunk = &local::_thunk;
00623     }
00624 
00625     /** Attach a static function with a bound pointer
00626      *  @param obj  Pointer to object to bind to function
00627      *  @param func Static function to attach
00628      */
00629     void attach(const void *obj, R (*func)(const void*, A0)) {
00630         struct local {
00631             static R _thunk(void *obj, const void *func, A0 a0) {
00632                 return (*static_cast<R (*const *)(const void*, A0)>(func))(
00633                         (const void*)obj, a0);
00634             }
00635         };
00636 
00637         memset(&_func, 0, sizeof _func);
00638         memcpy(&_func, &func, sizeof func);
00639         _obj = (void*)obj;
00640         _thunk = &local::_thunk;
00641     }
00642 
00643     /** Attach a static function with a bound pointer
00644      *  @param obj  Pointer to object to bind to function
00645      *  @param func Static function to attach
00646      */
00647     void attach(volatile void *obj, R (*func)(volatile void*, A0)) {
00648         struct local {
00649             static R _thunk(void *obj, const void *func, A0 a0) {
00650                 return (*static_cast<R (*const *)(volatile void*, A0)>(func))(
00651                         (volatile void*)obj, a0);
00652             }
00653         };
00654 
00655         memset(&_func, 0, sizeof _func);
00656         memcpy(&_func, &func, sizeof func);
00657         _obj = (void*)obj;
00658         _thunk = &local::_thunk;
00659     }
00660 
00661     /** Attach a static function with a bound pointer
00662      *  @param obj  Pointer to object to bind to function
00663      *  @param func Static function to attach
00664      */
00665     void attach(const volatile void *obj, R (*func)(const volatile void*, A0)) {
00666         struct local {
00667             static R _thunk(void *obj, const void *func, A0 a0) {
00668                 return (*static_cast<R (*const *)(const volatile void*, A0)>(func))(
00669                         (const volatile void*)obj, a0);
00670             }
00671         };
00672 
00673         memset(&_func, 0, sizeof _func);
00674         memcpy(&_func, &func, sizeof func);
00675         _obj = (void*)obj;
00676         _thunk = &local::_thunk;
00677     }
00678 
00679     /** Attach a static function with a bound pointer
00680      *  @param obj  Pointer to object to bind to function
00681      *  @param func Static function to attach
00682      */
00683     template <typename T>
00684     void attach(T *obj, R (*func)(T*, A0)) {
00685         struct local {
00686             static R _thunk(void *obj, const void *func, A0 a0) {
00687                 return (*static_cast<R (*const *)(T*, A0)>(func))(
00688                         (T*)obj, a0);
00689             }
00690         };
00691 
00692         memset(&_func, 0, sizeof _func);
00693         memcpy(&_func, &func, sizeof func);
00694         _obj = (void*)obj;
00695         _thunk = &local::_thunk;
00696     }
00697 
00698     /** Attach a static function with a bound pointer
00699      *  @param obj  Pointer to object to bind to function
00700      *  @param func Static function to attach
00701      */
00702     template <typename T>
00703     void attach(const T *obj, R (*func)(const T*, A0)) {
00704         struct local {
00705             static R _thunk(void *obj, const void *func, A0 a0) {
00706                 return (*static_cast<R (*const *)(const T*, A0)>(func))(
00707                         (const T*)obj, a0);
00708             }
00709         };
00710 
00711         memset(&_func, 0, sizeof _func);
00712         memcpy(&_func, &func, sizeof func);
00713         _obj = (void*)obj;
00714         _thunk = &local::_thunk;
00715     }
00716 
00717     /** Attach a static function with a bound pointer
00718      *  @param obj  Pointer to object to bind to function
00719      *  @param func Static function to attach
00720      */
00721     template <typename T>
00722     void attach(volatile T *obj, R (*func)(volatile T*, A0)) {
00723         struct local {
00724             static R _thunk(void *obj, const void *func, A0 a0) {
00725                 return (*static_cast<R (*const *)(volatile T*, A0)>(func))(
00726                         (volatile T*)obj, a0);
00727             }
00728         };
00729 
00730         memset(&_func, 0, sizeof _func);
00731         memcpy(&_func, &func, sizeof func);
00732         _obj = (void*)obj;
00733         _thunk = &local::_thunk;
00734     }
00735 
00736     /** Attach a static function with a bound pointer
00737      *  @param obj  Pointer to object to bind to function
00738      *  @param func Static function to attach
00739      */
00740     template <typename T>
00741     void attach(const volatile T *obj, R (*func)(const volatile T*, A0)) {
00742         struct local {
00743             static R _thunk(void *obj, const void *func, A0 a0) {
00744                 return (*static_cast<R (*const *)(const volatile T*, A0)>(func))(
00745                         (const volatile T*)obj, a0);
00746             }
00747         };
00748 
00749         memset(&_func, 0, sizeof _func);
00750         memcpy(&_func, &func, sizeof func);
00751         _obj = (void*)obj;
00752         _thunk = &local::_thunk;
00753     }
00754 
00755     /** Attach a member function
00756      *  @param obj  Pointer to object to invoke member function on
00757      *  @param func Member function to attach
00758      */
00759     template<typename T>
00760     void attach(T *obj, R (T::*func)(A0)) {
00761         struct local {
00762             static R _thunk(void *obj, const void *func, A0 a0) {
00763                 return (((T*)obj)->*
00764                         (*static_cast<R (T::*const *)(A0)>(func)))(
00765                         a0);
00766             }
00767         };
00768 
00769         memset(&_func, 0, sizeof _func);
00770         memcpy(&_func, &func, sizeof func);
00771         _obj = (void*)obj;
00772         _thunk = &local::_thunk;
00773     }
00774 
00775     /** Attach a member function
00776      *  @param obj  Pointer to object to invoke member function on
00777      *  @param func Member function to attach
00778      */
00779     template<typename T>
00780     void attach(const T *obj, R (T::*func)(A0) const) {
00781         struct local {
00782             static R _thunk(void *obj, const void *func, A0 a0) {
00783                 return (((const T*)obj)->*
00784                         (*static_cast<R (T::*const *)(A0) const>(func)))(
00785                         a0);
00786             }
00787         };
00788 
00789         memset(&_func, 0, sizeof _func);
00790         memcpy(&_func, &func, sizeof func);
00791         _obj = (void*)obj;
00792         _thunk = &local::_thunk;
00793     }
00794 
00795     /** Attach a member function
00796      *  @param obj  Pointer to object to invoke member function on
00797      *  @param func Member function to attach
00798      */
00799     template<typename T>
00800     void attach(volatile T *obj, R (T::*func)(A0) volatile) {
00801         struct local {
00802             static R _thunk(void *obj, const void *func, A0 a0) {
00803                 return (((volatile T*)obj)->*
00804                         (*static_cast<R (T::*const *)(A0) volatile>(func)))(
00805                         a0);
00806             }
00807         };
00808 
00809         memset(&_func, 0, sizeof _func);
00810         memcpy(&_func, &func, sizeof func);
00811         _obj = (void*)obj;
00812         _thunk = &local::_thunk;
00813     }
00814 
00815     /** Attach a member function
00816      *  @param obj  Pointer to object to invoke member function on
00817      *  @param func Member function to attach
00818      */
00819     template<typename T>
00820     void attach(const volatile T *obj, R (T::*func)(A0) const volatile) {
00821         struct local {
00822             static R _thunk(void *obj, const void *func, A0 a0) {
00823                 return (((const volatile T*)obj)->*
00824                         (*static_cast<R (T::*const *)(A0) const volatile>(func)))(
00825                         a0);
00826             }
00827         };
00828 
00829         memset(&_func, 0, sizeof _func);
00830         memcpy(&_func, &func, sizeof func);
00831         _obj = (void*)obj;
00832         _thunk = &local::_thunk;
00833     }
00834 
00835     /** Call the attached function
00836      */
00837     R call(A0 a0) const {
00838         MBED_ASSERT(_thunk);
00839         return _thunk(_obj, &_func, a0);
00840     }
00841 
00842     /** Call the attached function
00843      */
00844     R operator()(A0 a0) const {
00845         return call(a0);
00846     }
00847 
00848     /** Test if function has been attached
00849      */
00850     operator bool() const {
00851         return _thunk;
00852     }
00853 
00854     /** Test for equality
00855      */
00856     friend bool operator==(const Callback &l, const Callback &r) {
00857         return memcmp(&l, &r, sizeof(Callback)) == 0;
00858     }
00859 
00860     /** Test for inequality
00861      */
00862     friend bool operator!=(const Callback &l, const Callback &r) {
00863         return !(l == r);
00864     }
00865 
00866     /** Static thunk for passing as C-style function
00867      *  @param func Callback to call passed as void pointer
00868      */
00869     static R thunk(void *func, A0 a0) {
00870         return static_cast<Callback<R(A0)>*>(func)->call(
00871                 a0);
00872     }
00873 
00874 private:
00875     // Stored as pointer to function and pointer to optional object
00876     // Function pointer is stored as union of possible function types
00877     // to garuntee proper size and alignment
00878     struct _class;
00879     union {
00880         void (*_staticfunc)();
00881         void (*_boundfunc)(_class *);
00882         void (_class::*_methodfunc)();
00883     } _func;
00884 
00885     void *_obj;
00886 
00887     // Thunk registered on attach to dispatch calls
00888     R (*_thunk)(void*, const void*, A0);
00889 };
00890 
00891 /** Callback class based on template specialization
00892  *
00893  * @Note Synchronization level: Not protected
00894  */
00895 template <typename R, typename A0, typename A1>
00896 class Callback<R(A0, A1)> {
00897 public:
00898     /** Create a Callback with a static function
00899      *  @param func Static function to attach
00900      */
00901     Callback(R (*func)(A0, A1) = 0) {
00902         attach(func);
00903     }
00904 
00905     /** Create a Callback with a static function and bound pointer
00906      *  @param obj  Pointer to object to bind to function
00907      *  @param func Static function to attach
00908      */
00909     Callback(void *obj, R (*func)(void*, A0, A1)) {
00910         attach(obj, func);
00911     }
00912 
00913     /** Create a Callback with a static function and bound pointer
00914      *  @param obj  Pointer to object to bind to function
00915      *  @param func Static function to attach
00916      */
00917     Callback(const void *obj, R (*func)(const void*, A0, A1)) {
00918         attach(obj, func);
00919     }
00920 
00921     /** Create a Callback with a static function and bound pointer
00922      *  @param obj  Pointer to object to bind to function
00923      *  @param func Static function to attach
00924      */
00925     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1)) {
00926         attach(obj, func);
00927     }
00928 
00929     /** Create a Callback with a static function and bound pointer
00930      *  @param obj  Pointer to object to bind to function
00931      *  @param func Static function to attach
00932      */
00933     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) {
00934         attach(obj, func);
00935     }
00936 
00937     /** Create a Callback with a static function and bound pointer
00938      *  @param obj  Pointer to object to bind to function
00939      *  @param func Static function to attach
00940      */
00941     template<typename T>
00942     Callback(T *obj, R (*func)(T*, A0, A1)) {
00943         attach(obj, func);
00944     }
00945 
00946     /** Create a Callback with a static function and bound pointer
00947      *  @param obj  Pointer to object to bind to function
00948      *  @param func Static function to attach
00949      */
00950     template<typename T>
00951     Callback(const T *obj, R (*func)(const T*, A0, A1)) {
00952         attach(obj, func);
00953     }
00954 
00955     /** Create a Callback with a static function and bound pointer
00956      *  @param obj  Pointer to object to bind to function
00957      *  @param func Static function to attach
00958      */
00959     template<typename T>
00960     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1)) {
00961         attach(obj, func);
00962     }
00963 
00964     /** Create a Callback with a static function and bound pointer
00965      *  @param obj  Pointer to object to bind to function
00966      *  @param func Static function to attach
00967      */
00968     template<typename T>
00969     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) {
00970         attach(obj, func);
00971     }
00972 
00973     /** Create a Callback with a member function
00974      *  @param obj  Pointer to object to invoke member function on
00975      *  @param func Member function to attach
00976      */
00977     template<typename T>
00978     Callback(T *obj, R (T::*func)(A0, A1)) {
00979         attach(obj, func);
00980     }
00981 
00982     /** Create a Callback with a member function
00983      *  @param obj  Pointer to object to invoke member function on
00984      *  @param func Member function to attach
00985      */
00986     template<typename T>
00987     Callback(const T *obj, R (T::*func)(A0, A1) const) {
00988         attach(obj, func);
00989     }
00990 
00991     /** Create a Callback with a member function
00992      *  @param obj  Pointer to object to invoke member function on
00993      *  @param func Member function to attach
00994      */
00995     template<typename T>
00996     Callback(volatile T *obj, R (T::*func)(A0, A1) volatile) {
00997         attach(obj, func);
00998     }
00999 
01000     /** Create a Callback with a member function
01001      *  @param obj  Pointer to object to invoke member function on
01002      *  @param func Member function to attach
01003      */
01004     template<typename T>
01005     Callback(const volatile T *obj, R (T::*func)(A0, A1) const volatile) {
01006         attach(obj, func);
01007     }
01008 
01009     /** Attach a static function
01010      *  @param func Static function to attach
01011      */
01012     void attach(R (*func)(A0, A1)) {
01013         struct local {
01014             static R _thunk(void*, const void *func, A0 a0, A1 a1) {
01015                 return (*static_cast<R (*const *)(A0, A1)>(func))(
01016                         a0, a1);
01017             }
01018         };
01019 
01020         memset(&_func, 0, sizeof _func);
01021         memcpy(&_func, &func, sizeof func);
01022         _obj = 0;
01023         _thunk = func ? &local::_thunk : 0;
01024     }
01025 
01026     /** Attach a Callback
01027      *  @param func The Callback to attach
01028      */
01029     void attach(const Callback<R(A0, A1)> &func) {
01030         memset(&_func, 0, sizeof _func);
01031         memcpy(&_func, &func._func, sizeof func);
01032         _obj = func._obj;
01033         _thunk = func._thunk;
01034     }
01035 
01036     /** Attach a static function with a bound pointer
01037      *  @param obj  Pointer to object to bind to function
01038      *  @param func Static function to attach
01039      */
01040     void attach(void *obj, R (*func)(void*, A0, A1)) {
01041         struct local {
01042             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01043                 return (*static_cast<R (*const *)(void*, A0, A1)>(func))(
01044                         (void*)obj, a0, a1);
01045             }
01046         };
01047 
01048         memset(&_func, 0, sizeof _func);
01049         memcpy(&_func, &func, sizeof func);
01050         _obj = (void*)obj;
01051         _thunk = &local::_thunk;
01052     }
01053 
01054     /** Attach a static function with a bound pointer
01055      *  @param obj  Pointer to object to bind to function
01056      *  @param func Static function to attach
01057      */
01058     void attach(const void *obj, R (*func)(const void*, A0, A1)) {
01059         struct local {
01060             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01061                 return (*static_cast<R (*const *)(const void*, A0, A1)>(func))(
01062                         (const void*)obj, a0, a1);
01063             }
01064         };
01065 
01066         memset(&_func, 0, sizeof _func);
01067         memcpy(&_func, &func, sizeof func);
01068         _obj = (void*)obj;
01069         _thunk = &local::_thunk;
01070     }
01071 
01072     /** Attach a static function with a bound pointer
01073      *  @param obj  Pointer to object to bind to function
01074      *  @param func Static function to attach
01075      */
01076     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1)) {
01077         struct local {
01078             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01079                 return (*static_cast<R (*const *)(volatile void*, A0, A1)>(func))(
01080                         (volatile void*)obj, a0, a1);
01081             }
01082         };
01083 
01084         memset(&_func, 0, sizeof _func);
01085         memcpy(&_func, &func, sizeof func);
01086         _obj = (void*)obj;
01087         _thunk = &local::_thunk;
01088     }
01089 
01090     /** Attach a static function with a bound pointer
01091      *  @param obj  Pointer to object to bind to function
01092      *  @param func Static function to attach
01093      */
01094     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) {
01095         struct local {
01096             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01097                 return (*static_cast<R (*const *)(const volatile void*, A0, A1)>(func))(
01098                         (const volatile void*)obj, a0, a1);
01099             }
01100         };
01101 
01102         memset(&_func, 0, sizeof _func);
01103         memcpy(&_func, &func, sizeof func);
01104         _obj = (void*)obj;
01105         _thunk = &local::_thunk;
01106     }
01107 
01108     /** Attach a static function with a bound pointer
01109      *  @param obj  Pointer to object to bind to function
01110      *  @param func Static function to attach
01111      */
01112     template <typename T>
01113     void attach(T *obj, R (*func)(T*, A0, A1)) {
01114         struct local {
01115             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01116                 return (*static_cast<R (*const *)(T*, A0, A1)>(func))(
01117                         (T*)obj, a0, a1);
01118             }
01119         };
01120 
01121         memset(&_func, 0, sizeof _func);
01122         memcpy(&_func, &func, sizeof func);
01123         _obj = (void*)obj;
01124         _thunk = &local::_thunk;
01125     }
01126 
01127     /** Attach a static function with a bound pointer
01128      *  @param obj  Pointer to object to bind to function
01129      *  @param func Static function to attach
01130      */
01131     template <typename T>
01132     void attach(const T *obj, R (*func)(const T*, A0, A1)) {
01133         struct local {
01134             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01135                 return (*static_cast<R (*const *)(const T*, A0, A1)>(func))(
01136                         (const T*)obj, a0, a1);
01137             }
01138         };
01139 
01140         memset(&_func, 0, sizeof _func);
01141         memcpy(&_func, &func, sizeof func);
01142         _obj = (void*)obj;
01143         _thunk = &local::_thunk;
01144     }
01145 
01146     /** Attach a static function with a bound pointer
01147      *  @param obj  Pointer to object to bind to function
01148      *  @param func Static function to attach
01149      */
01150     template <typename T>
01151     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1)) {
01152         struct local {
01153             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01154                 return (*static_cast<R (*const *)(volatile T*, A0, A1)>(func))(
01155                         (volatile T*)obj, a0, a1);
01156             }
01157         };
01158 
01159         memset(&_func, 0, sizeof _func);
01160         memcpy(&_func, &func, sizeof func);
01161         _obj = (void*)obj;
01162         _thunk = &local::_thunk;
01163     }
01164 
01165     /** Attach a static function with a bound pointer
01166      *  @param obj  Pointer to object to bind to function
01167      *  @param func Static function to attach
01168      */
01169     template <typename T>
01170     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) {
01171         struct local {
01172             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01173                 return (*static_cast<R (*const *)(const volatile T*, A0, A1)>(func))(
01174                         (const volatile T*)obj, a0, a1);
01175             }
01176         };
01177 
01178         memset(&_func, 0, sizeof _func);
01179         memcpy(&_func, &func, sizeof func);
01180         _obj = (void*)obj;
01181         _thunk = &local::_thunk;
01182     }
01183 
01184     /** Attach a member function
01185      *  @param obj  Pointer to object to invoke member function on
01186      *  @param func Member function to attach
01187      */
01188     template<typename T>
01189     void attach(T *obj, R (T::*func)(A0, A1)) {
01190         struct local {
01191             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01192                 return (((T*)obj)->*
01193                         (*static_cast<R (T::*const *)(A0, A1)>(func)))(
01194                         a0, a1);
01195             }
01196         };
01197 
01198         memset(&_func, 0, sizeof _func);
01199         memcpy(&_func, &func, sizeof func);
01200         _obj = (void*)obj;
01201         _thunk = &local::_thunk;
01202     }
01203 
01204     /** Attach a member function
01205      *  @param obj  Pointer to object to invoke member function on
01206      *  @param func Member function to attach
01207      */
01208     template<typename T>
01209     void attach(const T *obj, R (T::*func)(A0, A1) const) {
01210         struct local {
01211             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01212                 return (((const T*)obj)->*
01213                         (*static_cast<R (T::*const *)(A0, A1) const>(func)))(
01214                         a0, a1);
01215             }
01216         };
01217 
01218         memset(&_func, 0, sizeof _func);
01219         memcpy(&_func, &func, sizeof func);
01220         _obj = (void*)obj;
01221         _thunk = &local::_thunk;
01222     }
01223 
01224     /** Attach a member function
01225      *  @param obj  Pointer to object to invoke member function on
01226      *  @param func Member function to attach
01227      */
01228     template<typename T>
01229     void attach(volatile T *obj, R (T::*func)(A0, A1) volatile) {
01230         struct local {
01231             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01232                 return (((volatile T*)obj)->*
01233                         (*static_cast<R (T::*const *)(A0, A1) volatile>(func)))(
01234                         a0, a1);
01235             }
01236         };
01237 
01238         memset(&_func, 0, sizeof _func);
01239         memcpy(&_func, &func, sizeof func);
01240         _obj = (void*)obj;
01241         _thunk = &local::_thunk;
01242     }
01243 
01244     /** Attach a member function
01245      *  @param obj  Pointer to object to invoke member function on
01246      *  @param func Member function to attach
01247      */
01248     template<typename T>
01249     void attach(const volatile T *obj, R (T::*func)(A0, A1) const volatile) {
01250         struct local {
01251             static R _thunk(void *obj, const void *func, A0 a0, A1 a1) {
01252                 return (((const volatile T*)obj)->*
01253                         (*static_cast<R (T::*const *)(A0, A1) const volatile>(func)))(
01254                         a0, a1);
01255             }
01256         };
01257 
01258         memset(&_func, 0, sizeof _func);
01259         memcpy(&_func, &func, sizeof func);
01260         _obj = (void*)obj;
01261         _thunk = &local::_thunk;
01262     }
01263 
01264     /** Call the attached function
01265      */
01266     R call(A0 a0, A1 a1) const {
01267         MBED_ASSERT(_thunk);
01268         return _thunk(_obj, &_func, a0, a1);
01269     }
01270 
01271     /** Call the attached function
01272      */
01273     R operator()(A0 a0, A1 a1) const {
01274         return call(a0, a1);
01275     }
01276 
01277     /** Test if function has been attached
01278      */
01279     operator bool() const {
01280         return _thunk;
01281     }
01282 
01283     /** Test for equality
01284      */
01285     friend bool operator==(const Callback &l, const Callback &r) {
01286         return memcmp(&l, &r, sizeof(Callback)) == 0;
01287     }
01288 
01289     /** Test for inequality
01290      */
01291     friend bool operator!=(const Callback &l, const Callback &r) {
01292         return !(l == r);
01293     }
01294 
01295     /** Static thunk for passing as C-style function
01296      *  @param func Callback to call passed as void pointer
01297      */
01298     static R thunk(void *func, A0 a0, A1 a1) {
01299         return static_cast<Callback<R(A0, A1)>*>(func)->call(
01300                 a0, a1);
01301     }
01302 
01303 private:
01304     // Stored as pointer to function and pointer to optional object
01305     // Function pointer is stored as union of possible function types
01306     // to garuntee proper size and alignment
01307     struct _class;
01308     union {
01309         void (*_staticfunc)();
01310         void (*_boundfunc)(_class *);
01311         void (_class::*_methodfunc)();
01312     } _func;
01313 
01314     void *_obj;
01315 
01316     // Thunk registered on attach to dispatch calls
01317     R (*_thunk)(void*, const void*, A0, A1);
01318 };
01319 
01320 /** Callback class based on template specialization
01321  *
01322  * @Note Synchronization level: Not protected
01323  */
01324 template <typename R, typename A0, typename A1, typename A2>
01325 class Callback<R(A0, A1, A2)> {
01326 public:
01327     /** Create a Callback with a static function
01328      *  @param func Static function to attach
01329      */
01330     Callback(R (*func)(A0, A1, A2) = 0) {
01331         attach(func);
01332     }
01333 
01334     /** Create a Callback with a static function and bound pointer
01335      *  @param obj  Pointer to object to bind to function
01336      *  @param func Static function to attach
01337      */
01338     Callback(void *obj, R (*func)(void*, A0, A1, A2)) {
01339         attach(obj, func);
01340     }
01341 
01342     /** Create a Callback with a static function and bound pointer
01343      *  @param obj  Pointer to object to bind to function
01344      *  @param func Static function to attach
01345      */
01346     Callback(const void *obj, R (*func)(const void*, A0, A1, A2)) {
01347         attach(obj, func);
01348     }
01349 
01350     /** Create a Callback with a static function and bound pointer
01351      *  @param obj  Pointer to object to bind to function
01352      *  @param func Static function to attach
01353      */
01354     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) {
01355         attach(obj, func);
01356     }
01357 
01358     /** Create a Callback with a static function and bound pointer
01359      *  @param obj  Pointer to object to bind to function
01360      *  @param func Static function to attach
01361      */
01362     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) {
01363         attach(obj, func);
01364     }
01365 
01366     /** Create a Callback with a static function and bound pointer
01367      *  @param obj  Pointer to object to bind to function
01368      *  @param func Static function to attach
01369      */
01370     template<typename T>
01371     Callback(T *obj, R (*func)(T*, A0, A1, A2)) {
01372         attach(obj, func);
01373     }
01374 
01375     /** Create a Callback with a static function and bound pointer
01376      *  @param obj  Pointer to object to bind to function
01377      *  @param func Static function to attach
01378      */
01379     template<typename T>
01380     Callback(const T *obj, R (*func)(const T*, A0, A1, A2)) {
01381         attach(obj, func);
01382     }
01383 
01384     /** Create a Callback with a static function and bound pointer
01385      *  @param obj  Pointer to object to bind to function
01386      *  @param func Static function to attach
01387      */
01388     template<typename T>
01389     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) {
01390         attach(obj, func);
01391     }
01392 
01393     /** Create a Callback with a static function and bound pointer
01394      *  @param obj  Pointer to object to bind to function
01395      *  @param func Static function to attach
01396      */
01397     template<typename T>
01398     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) {
01399         attach(obj, func);
01400     }
01401 
01402     /** Create a Callback with a member function
01403      *  @param obj  Pointer to object to invoke member function on
01404      *  @param func Member function to attach
01405      */
01406     template<typename T>
01407     Callback(T *obj, R (T::*func)(A0, A1, A2)) {
01408         attach(obj, func);
01409     }
01410 
01411     /** Create a Callback with a member function
01412      *  @param obj  Pointer to object to invoke member function on
01413      *  @param func Member function to attach
01414      */
01415     template<typename T>
01416     Callback(const T *obj, R (T::*func)(A0, A1, A2) const) {
01417         attach(obj, func);
01418     }
01419 
01420     /** Create a Callback with a member function
01421      *  @param obj  Pointer to object to invoke member function on
01422      *  @param func Member function to attach
01423      */
01424     template<typename T>
01425     Callback(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) {
01426         attach(obj, func);
01427     }
01428 
01429     /** Create a Callback with a member function
01430      *  @param obj  Pointer to object to invoke member function on
01431      *  @param func Member function to attach
01432      */
01433     template<typename T>
01434     Callback(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) {
01435         attach(obj, func);
01436     }
01437 
01438     /** Attach a static function
01439      *  @param func Static function to attach
01440      */
01441     void attach(R (*func)(A0, A1, A2)) {
01442         struct local {
01443             static R _thunk(void*, const void *func, A0 a0, A1 a1, A2 a2) {
01444                 return (*static_cast<R (*const *)(A0, A1, A2)>(func))(
01445                         a0, a1, a2);
01446             }
01447         };
01448 
01449         memset(&_func, 0, sizeof _func);
01450         memcpy(&_func, &func, sizeof func);
01451         _obj = 0;
01452         _thunk = func ? &local::_thunk : 0;
01453     }
01454 
01455     /** Attach a Callback
01456      *  @param func The Callback to attach
01457      */
01458     void attach(const Callback<R(A0, A1, A2)> &func) {
01459         memset(&_func, 0, sizeof _func);
01460         memcpy(&_func, &func._func, sizeof func);
01461         _obj = func._obj;
01462         _thunk = func._thunk;
01463     }
01464 
01465     /** Attach a static function with a bound pointer
01466      *  @param obj  Pointer to object to bind to function
01467      *  @param func Static function to attach
01468      */
01469     void attach(void *obj, R (*func)(void*, A0, A1, A2)) {
01470         struct local {
01471             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01472                 return (*static_cast<R (*const *)(void*, A0, A1, A2)>(func))(
01473                         (void*)obj, a0, a1, a2);
01474             }
01475         };
01476 
01477         memset(&_func, 0, sizeof _func);
01478         memcpy(&_func, &func, sizeof func);
01479         _obj = (void*)obj;
01480         _thunk = &local::_thunk;
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      */
01487     void attach(const void *obj, R (*func)(const void*, A0, A1, A2)) {
01488         struct local {
01489             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01490                 return (*static_cast<R (*const *)(const void*, A0, A1, A2)>(func))(
01491                         (const void*)obj, a0, a1, a2);
01492             }
01493         };
01494 
01495         memset(&_func, 0, sizeof _func);
01496         memcpy(&_func, &func, sizeof func);
01497         _obj = (void*)obj;
01498         _thunk = &local::_thunk;
01499     }
01500 
01501     /** Attach a static function with a bound pointer
01502      *  @param obj  Pointer to object to bind to function
01503      *  @param func Static function to attach
01504      */
01505     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) {
01506         struct local {
01507             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01508                 return (*static_cast<R (*const *)(volatile void*, A0, A1, A2)>(func))(
01509                         (volatile void*)obj, a0, a1, a2);
01510             }
01511         };
01512 
01513         memset(&_func, 0, sizeof _func);
01514         memcpy(&_func, &func, sizeof func);
01515         _obj = (void*)obj;
01516         _thunk = &local::_thunk;
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      */
01523     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) {
01524         struct local {
01525             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01526                 return (*static_cast<R (*const *)(const volatile void*, A0, A1, A2)>(func))(
01527                         (const volatile void*)obj, a0, a1, a2);
01528             }
01529         };
01530 
01531         memset(&_func, 0, sizeof _func);
01532         memcpy(&_func, &func, sizeof func);
01533         _obj = (void*)obj;
01534         _thunk = &local::_thunk;
01535     }
01536 
01537     /** Attach a static function with a bound pointer
01538      *  @param obj  Pointer to object to bind to function
01539      *  @param func Static function to attach
01540      */
01541     template <typename T>
01542     void attach(T *obj, R (*func)(T*, A0, A1, A2)) {
01543         struct local {
01544             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01545                 return (*static_cast<R (*const *)(T*, A0, A1, A2)>(func))(
01546                         (T*)obj, a0, a1, a2);
01547             }
01548         };
01549 
01550         memset(&_func, 0, sizeof _func);
01551         memcpy(&_func, &func, sizeof func);
01552         _obj = (void*)obj;
01553         _thunk = &local::_thunk;
01554     }
01555 
01556     /** Attach a static function with a bound pointer
01557      *  @param obj  Pointer to object to bind to function
01558      *  @param func Static function to attach
01559      */
01560     template <typename T>
01561     void attach(const T *obj, R (*func)(const T*, A0, A1, A2)) {
01562         struct local {
01563             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01564                 return (*static_cast<R (*const *)(const T*, A0, A1, A2)>(func))(
01565                         (const T*)obj, a0, a1, a2);
01566             }
01567         };
01568 
01569         memset(&_func, 0, sizeof _func);
01570         memcpy(&_func, &func, sizeof func);
01571         _obj = (void*)obj;
01572         _thunk = &local::_thunk;
01573     }
01574 
01575     /** Attach a static function with a bound pointer
01576      *  @param obj  Pointer to object to bind to function
01577      *  @param func Static function to attach
01578      */
01579     template <typename T>
01580     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) {
01581         struct local {
01582             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01583                 return (*static_cast<R (*const *)(volatile T*, A0, A1, A2)>(func))(
01584                         (volatile T*)obj, a0, a1, a2);
01585             }
01586         };
01587 
01588         memset(&_func, 0, sizeof _func);
01589         memcpy(&_func, &func, sizeof func);
01590         _obj = (void*)obj;
01591         _thunk = &local::_thunk;
01592     }
01593 
01594     /** Attach a static function with a bound pointer
01595      *  @param obj  Pointer to object to bind to function
01596      *  @param func Static function to attach
01597      */
01598     template <typename T>
01599     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) {
01600         struct local {
01601             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01602                 return (*static_cast<R (*const *)(const volatile T*, A0, A1, A2)>(func))(
01603                         (const volatile T*)obj, a0, a1, a2);
01604             }
01605         };
01606 
01607         memset(&_func, 0, sizeof _func);
01608         memcpy(&_func, &func, sizeof func);
01609         _obj = (void*)obj;
01610         _thunk = &local::_thunk;
01611     }
01612 
01613     /** Attach a member function
01614      *  @param obj  Pointer to object to invoke member function on
01615      *  @param func Member function to attach
01616      */
01617     template<typename T>
01618     void attach(T *obj, R (T::*func)(A0, A1, A2)) {
01619         struct local {
01620             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01621                 return (((T*)obj)->*
01622                         (*static_cast<R (T::*const *)(A0, A1, A2)>(func)))(
01623                         a0, a1, a2);
01624             }
01625         };
01626 
01627         memset(&_func, 0, sizeof _func);
01628         memcpy(&_func, &func, sizeof func);
01629         _obj = (void*)obj;
01630         _thunk = &local::_thunk;
01631     }
01632 
01633     /** Attach a member function
01634      *  @param obj  Pointer to object to invoke member function on
01635      *  @param func Member function to attach
01636      */
01637     template<typename T>
01638     void attach(const T *obj, R (T::*func)(A0, A1, A2) const) {
01639         struct local {
01640             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01641                 return (((const T*)obj)->*
01642                         (*static_cast<R (T::*const *)(A0, A1, A2) const>(func)))(
01643                         a0, a1, a2);
01644             }
01645         };
01646 
01647         memset(&_func, 0, sizeof _func);
01648         memcpy(&_func, &func, sizeof func);
01649         _obj = (void*)obj;
01650         _thunk = &local::_thunk;
01651     }
01652 
01653     /** Attach a member function
01654      *  @param obj  Pointer to object to invoke member function on
01655      *  @param func Member function to attach
01656      */
01657     template<typename T>
01658     void attach(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) {
01659         struct local {
01660             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01661                 return (((volatile T*)obj)->*
01662                         (*static_cast<R (T::*const *)(A0, A1, A2) volatile>(func)))(
01663                         a0, a1, a2);
01664             }
01665         };
01666 
01667         memset(&_func, 0, sizeof _func);
01668         memcpy(&_func, &func, sizeof func);
01669         _obj = (void*)obj;
01670         _thunk = &local::_thunk;
01671     }
01672 
01673     /** Attach a member function
01674      *  @param obj  Pointer to object to invoke member function on
01675      *  @param func Member function to attach
01676      */
01677     template<typename T>
01678     void attach(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) {
01679         struct local {
01680             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) {
01681                 return (((const volatile T*)obj)->*
01682                         (*static_cast<R (T::*const *)(A0, A1, A2) const volatile>(func)))(
01683                         a0, a1, a2);
01684             }
01685         };
01686 
01687         memset(&_func, 0, sizeof _func);
01688         memcpy(&_func, &func, sizeof func);
01689         _obj = (void*)obj;
01690         _thunk = &local::_thunk;
01691     }
01692 
01693     /** Call the attached function
01694      */
01695     R call(A0 a0, A1 a1, A2 a2) const {
01696         MBED_ASSERT(_thunk);
01697         return _thunk(_obj, &_func, a0, a1, a2);
01698     }
01699 
01700     /** Call the attached function
01701      */
01702     R operator()(A0 a0, A1 a1, A2 a2) const {
01703         return call(a0, a1, a2);
01704     }
01705 
01706     /** Test if function has been attached
01707      */
01708     operator bool() const {
01709         return _thunk;
01710     }
01711 
01712     /** Test for equality
01713      */
01714     friend bool operator==(const Callback &l, const Callback &r) {
01715         return memcmp(&l, &r, sizeof(Callback)) == 0;
01716     }
01717 
01718     /** Test for inequality
01719      */
01720     friend bool operator!=(const Callback &l, const Callback &r) {
01721         return !(l == r);
01722     }
01723 
01724     /** Static thunk for passing as C-style function
01725      *  @param func Callback to call passed as void pointer
01726      */
01727     static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
01728         return static_cast<Callback<R(A0, A1, A2)>*>(func)->call(
01729                 a0, a1, a2);
01730     }
01731 
01732 private:
01733     // Stored as pointer to function and pointer to optional object
01734     // Function pointer is stored as union of possible function types
01735     // to garuntee proper size and alignment
01736     struct _class;
01737     union {
01738         void (*_staticfunc)();
01739         void (*_boundfunc)(_class *);
01740         void (_class::*_methodfunc)();
01741     } _func;
01742 
01743     void *_obj;
01744 
01745     // Thunk registered on attach to dispatch calls
01746     R (*_thunk)(void*, const void*, A0, A1, A2);
01747 };
01748 
01749 /** Callback class based on template specialization
01750  *
01751  * @Note Synchronization level: Not protected
01752  */
01753 template <typename R, typename A0, typename A1, typename A2, typename A3>
01754 class Callback<R(A0, A1, A2, A3)> {
01755 public:
01756     /** Create a Callback with a static function
01757      *  @param func Static function to attach
01758      */
01759     Callback(R (*func)(A0, A1, A2, A3) = 0) {
01760         attach(func);
01761     }
01762 
01763     /** Create a Callback with a static function and bound pointer
01764      *  @param obj  Pointer to object to bind to function
01765      *  @param func Static function to attach
01766      */
01767     Callback(void *obj, R (*func)(void*, A0, A1, A2, A3)) {
01768         attach(obj, func);
01769     }
01770 
01771     /** Create a Callback with a static function and bound pointer
01772      *  @param obj  Pointer to object to bind to function
01773      *  @param func Static function to attach
01774      */
01775     Callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) {
01776         attach(obj, func);
01777     }
01778 
01779     /** Create a Callback with a static function and bound pointer
01780      *  @param obj  Pointer to object to bind to function
01781      *  @param func Static function to attach
01782      */
01783     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) {
01784         attach(obj, func);
01785     }
01786 
01787     /** Create a Callback with a static function and bound pointer
01788      *  @param obj  Pointer to object to bind to function
01789      *  @param func Static function to attach
01790      */
01791     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) {
01792         attach(obj, func);
01793     }
01794 
01795     /** Create a Callback with a static function and bound pointer
01796      *  @param obj  Pointer to object to bind to function
01797      *  @param func Static function to attach
01798      */
01799     template<typename T>
01800     Callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
01801         attach(obj, func);
01802     }
01803 
01804     /** Create a Callback with a static function and bound pointer
01805      *  @param obj  Pointer to object to bind to function
01806      *  @param func Static function to attach
01807      */
01808     template<typename T>
01809     Callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) {
01810         attach(obj, func);
01811     }
01812 
01813     /** Create a Callback with a static function and bound pointer
01814      *  @param obj  Pointer to object to bind to function
01815      *  @param func Static function to attach
01816      */
01817     template<typename T>
01818     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
01819         attach(obj, func);
01820     }
01821 
01822     /** Create a Callback with a static function and bound pointer
01823      *  @param obj  Pointer to object to bind to function
01824      *  @param func Static function to attach
01825      */
01826     template<typename T>
01827     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
01828         attach(obj, func);
01829     }
01830 
01831     /** Create a Callback with a member function
01832      *  @param obj  Pointer to object to invoke member function on
01833      *  @param func Member function to attach
01834      */
01835     template<typename T>
01836     Callback(T *obj, R (T::*func)(A0, A1, A2, A3)) {
01837         attach(obj, func);
01838     }
01839 
01840     /** Create a Callback with a member function
01841      *  @param obj  Pointer to object to invoke member function on
01842      *  @param func Member function to attach
01843      */
01844     template<typename T>
01845     Callback(const T *obj, R (T::*func)(A0, A1, A2, A3) const) {
01846         attach(obj, func);
01847     }
01848 
01849     /** Create a Callback with a member function
01850      *  @param obj  Pointer to object to invoke member function on
01851      *  @param func Member function to attach
01852      */
01853     template<typename T>
01854     Callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) {
01855         attach(obj, func);
01856     }
01857 
01858     /** Create a Callback with a member function
01859      *  @param obj  Pointer to object to invoke member function on
01860      *  @param func Member function to attach
01861      */
01862     template<typename T>
01863     Callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) {
01864         attach(obj, func);
01865     }
01866 
01867     /** Attach a static function
01868      *  @param func Static function to attach
01869      */
01870     void attach(R (*func)(A0, A1, A2, A3)) {
01871         struct local {
01872             static R _thunk(void*, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01873                 return (*static_cast<R (*const *)(A0, A1, A2, A3)>(func))(
01874                         a0, a1, a2, a3);
01875             }
01876         };
01877 
01878         memset(&_func, 0, sizeof _func);
01879         memcpy(&_func, &func, sizeof func);
01880         _obj = 0;
01881         _thunk = func ? &local::_thunk : 0;
01882     }
01883 
01884     /** Attach a Callback
01885      *  @param func The Callback to attach
01886      */
01887     void attach(const Callback<R(A0, A1, A2, A3)> &func) {
01888         memset(&_func, 0, sizeof _func);
01889         memcpy(&_func, &func._func, sizeof func);
01890         _obj = func._obj;
01891         _thunk = func._thunk;
01892     }
01893 
01894     /** Attach a static function with a bound pointer
01895      *  @param obj  Pointer to object to bind to function
01896      *  @param func Static function to attach
01897      */
01898     void attach(void *obj, R (*func)(void*, A0, A1, A2, A3)) {
01899         struct local {
01900             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01901                 return (*static_cast<R (*const *)(void*, A0, A1, A2, A3)>(func))(
01902                         (void*)obj, a0, a1, a2, a3);
01903             }
01904         };
01905 
01906         memset(&_func, 0, sizeof _func);
01907         memcpy(&_func, &func, sizeof func);
01908         _obj = (void*)obj;
01909         _thunk = &local::_thunk;
01910     }
01911 
01912     /** Attach a static function with a bound pointer
01913      *  @param obj  Pointer to object to bind to function
01914      *  @param func Static function to attach
01915      */
01916     void attach(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) {
01917         struct local {
01918             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01919                 return (*static_cast<R (*const *)(const void*, A0, A1, A2, A3)>(func))(
01920                         (const void*)obj, a0, a1, a2, a3);
01921             }
01922         };
01923 
01924         memset(&_func, 0, sizeof _func);
01925         memcpy(&_func, &func, sizeof func);
01926         _obj = (void*)obj;
01927         _thunk = &local::_thunk;
01928     }
01929 
01930     /** Attach a static function with a bound pointer
01931      *  @param obj  Pointer to object to bind to function
01932      *  @param func Static function to attach
01933      */
01934     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) {
01935         struct local {
01936             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01937                 return (*static_cast<R (*const *)(volatile void*, A0, A1, A2, A3)>(func))(
01938                         (volatile void*)obj, a0, a1, a2, a3);
01939             }
01940         };
01941 
01942         memset(&_func, 0, sizeof _func);
01943         memcpy(&_func, &func, sizeof func);
01944         _obj = (void*)obj;
01945         _thunk = &local::_thunk;
01946     }
01947 
01948     /** Attach a static function with a bound pointer
01949      *  @param obj  Pointer to object to bind to function
01950      *  @param func Static function to attach
01951      */
01952     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) {
01953         struct local {
01954             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01955                 return (*static_cast<R (*const *)(const volatile void*, A0, A1, A2, A3)>(func))(
01956                         (const volatile void*)obj, a0, a1, a2, a3);
01957             }
01958         };
01959 
01960         memset(&_func, 0, sizeof _func);
01961         memcpy(&_func, &func, sizeof func);
01962         _obj = (void*)obj;
01963         _thunk = &local::_thunk;
01964     }
01965 
01966     /** Attach a static function with a bound pointer
01967      *  @param obj  Pointer to object to bind to function
01968      *  @param func Static function to attach
01969      */
01970     template <typename T>
01971     void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
01972         struct local {
01973             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01974                 return (*static_cast<R (*const *)(T*, A0, A1, A2, A3)>(func))(
01975                         (T*)obj, a0, a1, a2, a3);
01976             }
01977         };
01978 
01979         memset(&_func, 0, sizeof _func);
01980         memcpy(&_func, &func, sizeof func);
01981         _obj = (void*)obj;
01982         _thunk = &local::_thunk;
01983     }
01984 
01985     /** Attach a static function with a bound pointer
01986      *  @param obj  Pointer to object to bind to function
01987      *  @param func Static function to attach
01988      */
01989     template <typename T>
01990     void attach(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) {
01991         struct local {
01992             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
01993                 return (*static_cast<R (*const *)(const T*, A0, A1, A2, A3)>(func))(
01994                         (const T*)obj, a0, a1, a2, a3);
01995             }
01996         };
01997 
01998         memset(&_func, 0, sizeof _func);
01999         memcpy(&_func, &func, sizeof func);
02000         _obj = (void*)obj;
02001         _thunk = &local::_thunk;
02002     }
02003 
02004     /** Attach a static function with a bound pointer
02005      *  @param obj  Pointer to object to bind to function
02006      *  @param func Static function to attach
02007      */
02008     template <typename T>
02009     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
02010         struct local {
02011             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02012                 return (*static_cast<R (*const *)(volatile T*, A0, A1, A2, A3)>(func))(
02013                         (volatile T*)obj, a0, a1, a2, a3);
02014             }
02015         };
02016 
02017         memset(&_func, 0, sizeof _func);
02018         memcpy(&_func, &func, sizeof func);
02019         _obj = (void*)obj;
02020         _thunk = &local::_thunk;
02021     }
02022 
02023     /** Attach a static function with a bound pointer
02024      *  @param obj  Pointer to object to bind to function
02025      *  @param func Static function to attach
02026      */
02027     template <typename T>
02028     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
02029         struct local {
02030             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02031                 return (*static_cast<R (*const *)(const volatile T*, A0, A1, A2, A3)>(func))(
02032                         (const volatile T*)obj, a0, a1, a2, a3);
02033             }
02034         };
02035 
02036         memset(&_func, 0, sizeof _func);
02037         memcpy(&_func, &func, sizeof func);
02038         _obj = (void*)obj;
02039         _thunk = &local::_thunk;
02040     }
02041 
02042     /** Attach a member function
02043      *  @param obj  Pointer to object to invoke member function on
02044      *  @param func Member function to attach
02045      */
02046     template<typename T>
02047     void attach(T *obj, R (T::*func)(A0, A1, A2, A3)) {
02048         struct local {
02049             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02050                 return (((T*)obj)->*
02051                         (*static_cast<R (T::*const *)(A0, A1, A2, A3)>(func)))(
02052                         a0, a1, a2, a3);
02053             }
02054         };
02055 
02056         memset(&_func, 0, sizeof _func);
02057         memcpy(&_func, &func, sizeof func);
02058         _obj = (void*)obj;
02059         _thunk = &local::_thunk;
02060     }
02061 
02062     /** Attach a member function
02063      *  @param obj  Pointer to object to invoke member function on
02064      *  @param func Member function to attach
02065      */
02066     template<typename T>
02067     void attach(const T *obj, R (T::*func)(A0, A1, A2, A3) const) {
02068         struct local {
02069             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02070                 return (((const T*)obj)->*
02071                         (*static_cast<R (T::*const *)(A0, A1, A2, A3) const>(func)))(
02072                         a0, a1, a2, a3);
02073             }
02074         };
02075 
02076         memset(&_func, 0, sizeof _func);
02077         memcpy(&_func, &func, sizeof func);
02078         _obj = (void*)obj;
02079         _thunk = &local::_thunk;
02080     }
02081 
02082     /** Attach a member function
02083      *  @param obj  Pointer to object to invoke member function on
02084      *  @param func Member function to attach
02085      */
02086     template<typename T>
02087     void attach(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) {
02088         struct local {
02089             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02090                 return (((volatile T*)obj)->*
02091                         (*static_cast<R (T::*const *)(A0, A1, A2, A3) volatile>(func)))(
02092                         a0, a1, a2, a3);
02093             }
02094         };
02095 
02096         memset(&_func, 0, sizeof _func);
02097         memcpy(&_func, &func, sizeof func);
02098         _obj = (void*)obj;
02099         _thunk = &local::_thunk;
02100     }
02101 
02102     /** Attach a member function
02103      *  @param obj  Pointer to object to invoke member function on
02104      *  @param func Member function to attach
02105      */
02106     template<typename T>
02107     void attach(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) {
02108         struct local {
02109             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02110                 return (((const volatile T*)obj)->*
02111                         (*static_cast<R (T::*const *)(A0, A1, A2, A3) const volatile>(func)))(
02112                         a0, a1, a2, a3);
02113             }
02114         };
02115 
02116         memset(&_func, 0, sizeof _func);
02117         memcpy(&_func, &func, sizeof func);
02118         _obj = (void*)obj;
02119         _thunk = &local::_thunk;
02120     }
02121 
02122     /** Call the attached function
02123      */
02124     R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
02125         MBED_ASSERT(_thunk);
02126         return _thunk(_obj, &_func, a0, a1, a2, a3);
02127     }
02128 
02129     /** Call the attached function
02130      */
02131     R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
02132         return call(a0, a1, a2, a3);
02133     }
02134 
02135     /** Test if function has been attached
02136      */
02137     operator bool() const {
02138         return _thunk;
02139     }
02140 
02141     /** Test for equality
02142      */
02143     friend bool operator==(const Callback &l, const Callback &r) {
02144         return memcmp(&l, &r, sizeof(Callback)) == 0;
02145     }
02146 
02147     /** Test for inequality
02148      */
02149     friend bool operator!=(const Callback &l, const Callback &r) {
02150         return !(l == r);
02151     }
02152 
02153     /** Static thunk for passing as C-style function
02154      *  @param func Callback to call passed as void pointer
02155      */
02156     static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
02157         return static_cast<Callback<R(A0, A1, A2, A3)>*>(func)->call(
02158                 a0, a1, a2, a3);
02159     }
02160 
02161 private:
02162     // Stored as pointer to function and pointer to optional object
02163     // Function pointer is stored as union of possible function types
02164     // to garuntee proper size and alignment
02165     struct _class;
02166     union {
02167         void (*_staticfunc)();
02168         void (*_boundfunc)(_class *);
02169         void (_class::*_methodfunc)();
02170     } _func;
02171 
02172     void *_obj;
02173 
02174     // Thunk registered on attach to dispatch calls
02175     R (*_thunk)(void*, const void*, A0, A1, A2, A3);
02176 };
02177 
02178 /** Callback class based on template specialization
02179  *
02180  * @Note Synchronization level: Not protected
02181  */
02182 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
02183 class Callback<R(A0, A1, A2, A3, A4)> {
02184 public:
02185     /** Create a Callback with a static function
02186      *  @param func Static function to attach
02187      */
02188     Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
02189         attach(func);
02190     }
02191 
02192     /** Create a Callback with a static function and bound pointer
02193      *  @param obj  Pointer to object to bind to function
02194      *  @param func Static function to attach
02195      */
02196     Callback(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) {
02197         attach(obj, func);
02198     }
02199 
02200     /** Create a Callback with a static function and bound pointer
02201      *  @param obj  Pointer to object to bind to function
02202      *  @param func Static function to attach
02203      */
02204     Callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) {
02205         attach(obj, func);
02206     }
02207 
02208     /** Create a Callback with a static function and bound pointer
02209      *  @param obj  Pointer to object to bind to function
02210      *  @param func Static function to attach
02211      */
02212     Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) {
02213         attach(obj, func);
02214     }
02215 
02216     /** Create a Callback with a static function and bound pointer
02217      *  @param obj  Pointer to object to bind to function
02218      *  @param func Static function to attach
02219      */
02220     Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) {
02221         attach(obj, func);
02222     }
02223 
02224     /** Create a Callback with a static function and bound pointer
02225      *  @param obj  Pointer to object to bind to function
02226      *  @param func Static function to attach
02227      */
02228     template<typename T>
02229     Callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
02230         attach(obj, func);
02231     }
02232 
02233     /** Create a Callback with a static function and bound pointer
02234      *  @param obj  Pointer to object to bind to function
02235      *  @param func Static function to attach
02236      */
02237     template<typename T>
02238     Callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
02239         attach(obj, func);
02240     }
02241 
02242     /** Create a Callback with a static function and bound pointer
02243      *  @param obj  Pointer to object to bind to function
02244      *  @param func Static function to attach
02245      */
02246     template<typename T>
02247     Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
02248         attach(obj, func);
02249     }
02250 
02251     /** Create a Callback with a static function and bound pointer
02252      *  @param obj  Pointer to object to bind to function
02253      *  @param func Static function to attach
02254      */
02255     template<typename T>
02256     Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
02257         attach(obj, func);
02258     }
02259 
02260     /** Create a Callback with a member function
02261      *  @param obj  Pointer to object to invoke member function on
02262      *  @param func Member function to attach
02263      */
02264     template<typename T>
02265     Callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
02266         attach(obj, func);
02267     }
02268 
02269     /** Create a Callback with a member function
02270      *  @param obj  Pointer to object to invoke member function on
02271      *  @param func Member function to attach
02272      */
02273     template<typename T>
02274     Callback(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) {
02275         attach(obj, func);
02276     }
02277 
02278     /** Create a Callback with a member function
02279      *  @param obj  Pointer to object to invoke member function on
02280      *  @param func Member function to attach
02281      */
02282     template<typename T>
02283     Callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) {
02284         attach(obj, func);
02285     }
02286 
02287     /** Create a Callback with a member function
02288      *  @param obj  Pointer to object to invoke member function on
02289      *  @param func Member function to attach
02290      */
02291     template<typename T>
02292     Callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) {
02293         attach(obj, func);
02294     }
02295 
02296     /** Attach a static function
02297      *  @param func Static function to attach
02298      */
02299     void attach(R (*func)(A0, A1, A2, A3, A4)) {
02300         struct local {
02301             static R _thunk(void*, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02302                 return (*static_cast<R (*const *)(A0, A1, A2, A3, A4)>(func))(
02303                         a0, a1, a2, a3, a4);
02304             }
02305         };
02306 
02307         memset(&_func, 0, sizeof _func);
02308         memcpy(&_func, &func, sizeof func);
02309         _obj = 0;
02310         _thunk = func ? &local::_thunk : 0;
02311     }
02312 
02313     /** Attach a Callback
02314      *  @param func The Callback to attach
02315      */
02316     void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
02317         memset(&_func, 0, sizeof _func);
02318         memcpy(&_func, &func._func, sizeof func);
02319         _obj = func._obj;
02320         _thunk = func._thunk;
02321     }
02322 
02323     /** Attach a static function with a bound pointer
02324      *  @param obj  Pointer to object to bind to function
02325      *  @param func Static function to attach
02326      */
02327     void attach(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) {
02328         struct local {
02329             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02330                 return (*static_cast<R (*const *)(void*, A0, A1, A2, A3, A4)>(func))(
02331                         (void*)obj, a0, a1, a2, a3, a4);
02332             }
02333         };
02334 
02335         memset(&_func, 0, sizeof _func);
02336         memcpy(&_func, &func, sizeof func);
02337         _obj = (void*)obj;
02338         _thunk = &local::_thunk;
02339     }
02340 
02341     /** Attach a static function with a bound pointer
02342      *  @param obj  Pointer to object to bind to function
02343      *  @param func Static function to attach
02344      */
02345     void attach(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) {
02346         struct local {
02347             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02348                 return (*static_cast<R (*const *)(const void*, A0, A1, A2, A3, A4)>(func))(
02349                         (const void*)obj, a0, a1, a2, a3, a4);
02350             }
02351         };
02352 
02353         memset(&_func, 0, sizeof _func);
02354         memcpy(&_func, &func, sizeof func);
02355         _obj = (void*)obj;
02356         _thunk = &local::_thunk;
02357     }
02358 
02359     /** Attach a static function with a bound pointer
02360      *  @param obj  Pointer to object to bind to function
02361      *  @param func Static function to attach
02362      */
02363     void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) {
02364         struct local {
02365             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02366                 return (*static_cast<R (*const *)(volatile void*, A0, A1, A2, A3, A4)>(func))(
02367                         (volatile void*)obj, a0, a1, a2, a3, a4);
02368             }
02369         };
02370 
02371         memset(&_func, 0, sizeof _func);
02372         memcpy(&_func, &func, sizeof func);
02373         _obj = (void*)obj;
02374         _thunk = &local::_thunk;
02375     }
02376 
02377     /** Attach a static function with a bound pointer
02378      *  @param obj  Pointer to object to bind to function
02379      *  @param func Static function to attach
02380      */
02381     void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) {
02382         struct local {
02383             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02384                 return (*static_cast<R (*const *)(const volatile void*, A0, A1, A2, A3, A4)>(func))(
02385                         (const volatile void*)obj, a0, a1, a2, a3, a4);
02386             }
02387         };
02388 
02389         memset(&_func, 0, sizeof _func);
02390         memcpy(&_func, &func, sizeof func);
02391         _obj = (void*)obj;
02392         _thunk = &local::_thunk;
02393     }
02394 
02395     /** Attach a static function with a bound pointer
02396      *  @param obj  Pointer to object to bind to function
02397      *  @param func Static function to attach
02398      */
02399     template <typename T>
02400     void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
02401         struct local {
02402             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02403                 return (*static_cast<R (*const *)(T*, A0, A1, A2, A3, A4)>(func))(
02404                         (T*)obj, a0, a1, a2, a3, a4);
02405             }
02406         };
02407 
02408         memset(&_func, 0, sizeof _func);
02409         memcpy(&_func, &func, sizeof func);
02410         _obj = (void*)obj;
02411         _thunk = &local::_thunk;
02412     }
02413 
02414     /** Attach a static function with a bound pointer
02415      *  @param obj  Pointer to object to bind to function
02416      *  @param func Static function to attach
02417      */
02418     template <typename T>
02419     void attach(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
02420         struct local {
02421             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02422                 return (*static_cast<R (*const *)(const T*, A0, A1, A2, A3, A4)>(func))(
02423                         (const T*)obj, a0, a1, a2, a3, a4);
02424             }
02425         };
02426 
02427         memset(&_func, 0, sizeof _func);
02428         memcpy(&_func, &func, sizeof func);
02429         _obj = (void*)obj;
02430         _thunk = &local::_thunk;
02431     }
02432 
02433     /** Attach a static function with a bound pointer
02434      *  @param obj  Pointer to object to bind to function
02435      *  @param func Static function to attach
02436      */
02437     template <typename T>
02438     void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
02439         struct local {
02440             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02441                 return (*static_cast<R (*const *)(volatile T*, A0, A1, A2, A3, A4)>(func))(
02442                         (volatile T*)obj, a0, a1, a2, a3, a4);
02443             }
02444         };
02445 
02446         memset(&_func, 0, sizeof _func);
02447         memcpy(&_func, &func, sizeof func);
02448         _obj = (void*)obj;
02449         _thunk = &local::_thunk;
02450     }
02451 
02452     /** Attach a static function with a bound pointer
02453      *  @param obj  Pointer to object to bind to function
02454      *  @param func Static function to attach
02455      */
02456     template <typename T>
02457     void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
02458         struct local {
02459             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02460                 return (*static_cast<R (*const *)(const volatile T*, A0, A1, A2, A3, A4)>(func))(
02461                         (const volatile T*)obj, a0, a1, a2, a3, a4);
02462             }
02463         };
02464 
02465         memset(&_func, 0, sizeof _func);
02466         memcpy(&_func, &func, sizeof func);
02467         _obj = (void*)obj;
02468         _thunk = &local::_thunk;
02469     }
02470 
02471     /** Attach a member function
02472      *  @param obj  Pointer to object to invoke member function on
02473      *  @param func Member function to attach
02474      */
02475     template<typename T>
02476     void attach(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
02477         struct local {
02478             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02479                 return (((T*)obj)->*
02480                         (*static_cast<R (T::*const *)(A0, A1, A2, A3, A4)>(func)))(
02481                         a0, a1, a2, a3, a4);
02482             }
02483         };
02484 
02485         memset(&_func, 0, sizeof _func);
02486         memcpy(&_func, &func, sizeof func);
02487         _obj = (void*)obj;
02488         _thunk = &local::_thunk;
02489     }
02490 
02491     /** Attach a member function
02492      *  @param obj  Pointer to object to invoke member function on
02493      *  @param func Member function to attach
02494      */
02495     template<typename T>
02496     void attach(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) {
02497         struct local {
02498             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02499                 return (((const T*)obj)->*
02500                         (*static_cast<R (T::*const *)(A0, A1, A2, A3, A4) const>(func)))(
02501                         a0, a1, a2, a3, a4);
02502             }
02503         };
02504 
02505         memset(&_func, 0, sizeof _func);
02506         memcpy(&_func, &func, sizeof func);
02507         _obj = (void*)obj;
02508         _thunk = &local::_thunk;
02509     }
02510 
02511     /** Attach a member function
02512      *  @param obj  Pointer to object to invoke member function on
02513      *  @param func Member function to attach
02514      */
02515     template<typename T>
02516     void attach(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) {
02517         struct local {
02518             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02519                 return (((volatile T*)obj)->*
02520                         (*static_cast<R (T::*const *)(A0, A1, A2, A3, A4) volatile>(func)))(
02521                         a0, a1, a2, a3, a4);
02522             }
02523         };
02524 
02525         memset(&_func, 0, sizeof _func);
02526         memcpy(&_func, &func, sizeof func);
02527         _obj = (void*)obj;
02528         _thunk = &local::_thunk;
02529     }
02530 
02531     /** Attach a member function
02532      *  @param obj  Pointer to object to invoke member function on
02533      *  @param func Member function to attach
02534      */
02535     template<typename T>
02536     void attach(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) {
02537         struct local {
02538             static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02539                 return (((const volatile T*)obj)->*
02540                         (*static_cast<R (T::*const *)(A0, A1, A2, A3, A4) const volatile>(func)))(
02541                         a0, a1, a2, a3, a4);
02542             }
02543         };
02544 
02545         memset(&_func, 0, sizeof _func);
02546         memcpy(&_func, &func, sizeof func);
02547         _obj = (void*)obj;
02548         _thunk = &local::_thunk;
02549     }
02550 
02551     /** Call the attached function
02552      */
02553     R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
02554         MBED_ASSERT(_thunk);
02555         return _thunk(_obj, &_func, a0, a1, a2, a3, a4);
02556     }
02557 
02558     /** Call the attached function
02559      */
02560     R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
02561         return call(a0, a1, a2, a3, a4);
02562     }
02563 
02564     /** Test if function has been attached
02565      */
02566     operator bool() const {
02567         return _thunk;
02568     }
02569 
02570     /** Test for equality
02571      */
02572     friend bool operator==(const Callback &l, const Callback &r) {
02573         return memcmp(&l, &r, sizeof(Callback)) == 0;
02574     }
02575 
02576     /** Test for inequality
02577      */
02578     friend bool operator!=(const Callback &l, const Callback &r) {
02579         return !(l == r);
02580     }
02581 
02582     /** Static thunk for passing as C-style function
02583      *  @param func Callback to call passed as void pointer
02584      */
02585     static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
02586         return static_cast<Callback<R(A0, A1, A2, A3, A4)>*>(func)->call(
02587                 a0, a1, a2, a3, a4);
02588     }
02589 
02590 private:
02591     // Stored as pointer to function and pointer to optional object
02592     // Function pointer is stored as union of possible function types
02593     // to garuntee proper size and alignment
02594     struct _class;
02595     union {
02596         void (*_staticfunc)();
02597         void (*_boundfunc)(_class *);
02598         void (_class::*_methodfunc)();
02599     } _func;
02600 
02601     void *_obj;
02602 
02603     // Thunk registered on attach to dispatch calls
02604     R (*_thunk)(void*, const void*, A0, A1, A2, A3, A4);
02605 };
02606 
02607 // Internally used event type
02608 typedef Callback<void(int)> event_callback_t;
02609 
02610 
02611 /** Create a callback class with type infered from the arguments
02612  *
02613  *  @param func Static function to attach
02614  *  @return     Callback with infered type
02615  */
02616 template <typename R>
02617 Callback<R()> callback(R (*func)() = 0) {
02618     return Callback<R()>(func);
02619 }
02620 
02621 /** Create a callback class with type infered from the arguments
02622  *
02623  *  @param func Static function to attach
02624  *  @return     Callback with infered type
02625  */
02626 template <typename R>
02627 Callback<R()> callback(const Callback<R()> &func) {
02628     return Callback<R()>(func);
02629 }
02630 
02631 /** Create a callback class with type infered from the arguments
02632  *
02633  *  @param obj  Optional pointer to object to bind to function
02634  *  @param func Static function to attach
02635  *  @return     Callback with infered type
02636  */
02637 template <typename R>
02638 Callback<R()> callback(void *obj, R (*func)(void*)) {
02639     return Callback<R()>(obj, func);
02640 }
02641 
02642 /** Create a callback class with type infered from the arguments
02643  *
02644  *  @param obj  Optional pointer to object to bind to function
02645  *  @param func Static function to attach
02646  *  @return     Callback with infered type
02647  */
02648 template <typename R>
02649 Callback<R()> callback(const void *obj, R (*func)(const void*)) {
02650     return Callback<R()>(obj, func);
02651 }
02652 
02653 /** Create a callback class with type infered from the arguments
02654  *
02655  *  @param obj  Optional pointer to object to bind to function
02656  *  @param func Static function to attach
02657  *  @return     Callback with infered type
02658  */
02659 template <typename R>
02660 Callback<R()> callback(volatile void *obj, R (*func)(volatile void*)) {
02661     return Callback<R()>(obj, func);
02662 }
02663 
02664 /** Create a callback class with type infered from the arguments
02665  *
02666  *  @param obj  Optional pointer to object to bind to function
02667  *  @param func Static function to attach
02668  *  @return     Callback with infered type
02669  */
02670 template <typename R>
02671 Callback<R()> callback(const volatile void *obj, R (*func)(const volatile void*)) {
02672     return Callback<R()>(obj, func);
02673 }
02674 
02675 /** Create a callback class with type infered from the arguments
02676  *
02677  *  @param obj  Optional pointer to object to bind to function
02678  *  @param func Static function to attach
02679  *  @return     Callback with infered type
02680  */
02681 template <typename T, typename R>
02682 Callback<R()> callback(T *obj, R (*func)(T*)) {
02683     return Callback<R()>(obj, func);
02684 }
02685 
02686 /** Create a callback class with type infered from the arguments
02687  *
02688  *  @param obj  Optional pointer to object to bind to function
02689  *  @param func Static function to attach
02690  *  @return     Callback with infered type
02691  */
02692 template <typename T, typename R>
02693 Callback<R()> callback(const T *obj, R (*func)(const T*)) {
02694     return Callback<R()>(obj, func);
02695 }
02696 
02697 /** Create a callback class with type infered from the arguments
02698  *
02699  *  @param obj  Optional pointer to object to bind to function
02700  *  @param func Static function to attach
02701  *  @return     Callback with infered type
02702  */
02703 template <typename T, typename R>
02704 Callback<R()> callback(volatile T *obj, R (*func)(volatile T*)) {
02705     return Callback<R()>(obj, func);
02706 }
02707 
02708 /** Create a callback class with type infered from the arguments
02709  *
02710  *  @param obj  Optional pointer to object to bind to function
02711  *  @param func Static function to attach
02712  *  @return     Callback with infered type
02713  */
02714 template <typename T, typename R>
02715 Callback<R()> callback(const volatile T *obj, R (*func)(const volatile T*)) {
02716     return Callback<R()>(obj, func);
02717 }
02718 
02719 /** Create a callback class with type infered from the arguments
02720  *
02721  *  @param obj  Optional pointer to object to bind to function
02722  *  @param func Static function to attach
02723  *  @return     Callback with infered type
02724  */
02725 template<typename T, typename R>
02726 Callback<R()> callback(T *obj, R (T::*func)()) {
02727     return Callback<R()>(obj, func);
02728 }
02729 
02730 /** Create a callback class with type infered from the arguments
02731  *
02732  *  @param obj  Optional pointer to object to bind to function
02733  *  @param func Static function to attach
02734  *  @return     Callback with infered type
02735  */
02736 template<typename T, typename R>
02737 Callback<R()> callback(const T *obj, R (T::*func)() const) {
02738     return Callback<R()>(obj, func);
02739 }
02740 
02741 /** Create a callback class with type infered from the arguments
02742  *
02743  *  @param obj  Optional pointer to object to bind to function
02744  *  @param func Static function to attach
02745  *  @return     Callback with infered type
02746  */
02747 template<typename T, typename R>
02748 Callback<R()> callback(volatile T *obj, R (T::*func)() volatile) {
02749     return Callback<R()>(obj, func);
02750 }
02751 
02752 /** Create a callback class with type infered from the arguments
02753  *
02754  *  @param obj  Optional pointer to object to bind to function
02755  *  @param func Static function to attach
02756  *  @return     Callback with infered type
02757  */
02758 template<typename T, typename R>
02759 Callback<R()> callback(const volatile T *obj, R (T::*func)() const volatile) {
02760     return Callback<R()>(obj, func);
02761 }
02762 
02763 
02764 /** Create a callback class with type infered from the arguments
02765  *
02766  *  @param func Static function to attach
02767  *  @return     Callback with infered type
02768  */
02769 template <typename R, typename A0>
02770 Callback<R(A0)> callback(R (*func)(A0) = 0) {
02771     return Callback<R(A0)>(func);
02772 }
02773 
02774 /** Create a callback class with type infered from the arguments
02775  *
02776  *  @param func Static function to attach
02777  *  @return     Callback with infered type
02778  */
02779 template <typename R, typename A0>
02780 Callback<R(A0)> callback(const Callback<R(A0)> &func) {
02781     return Callback<R(A0)>(func);
02782 }
02783 
02784 /** Create a callback class with type infered from the arguments
02785  *
02786  *  @param obj  Optional pointer to object to bind to function
02787  *  @param func Static function to attach
02788  *  @return     Callback with infered type
02789  */
02790 template <typename R, typename A0>
02791 Callback<R(A0)> callback(void *obj, R (*func)(void*, A0)) {
02792     return Callback<R(A0)>(obj, func);
02793 }
02794 
02795 /** Create a callback class with type infered from the arguments
02796  *
02797  *  @param obj  Optional pointer to object to bind to function
02798  *  @param func Static function to attach
02799  *  @return     Callback with infered type
02800  */
02801 template <typename R, typename A0>
02802 Callback<R(A0)> callback(const void *obj, R (*func)(const void*, A0)) {
02803     return Callback<R(A0)>(obj, func);
02804 }
02805 
02806 /** Create a callback class with type infered from the arguments
02807  *
02808  *  @param obj  Optional pointer to object to bind to function
02809  *  @param func Static function to attach
02810  *  @return     Callback with infered type
02811  */
02812 template <typename R, typename A0>
02813 Callback<R(A0)> callback(volatile void *obj, R (*func)(volatile void*, A0)) {
02814     return Callback<R(A0)>(obj, func);
02815 }
02816 
02817 /** Create a callback class with type infered from the arguments
02818  *
02819  *  @param obj  Optional pointer to object to bind to function
02820  *  @param func Static function to attach
02821  *  @return     Callback with infered type
02822  */
02823 template <typename R, typename A0>
02824 Callback<R(A0)> callback(const volatile void *obj, R (*func)(const volatile void*, A0)) {
02825     return Callback<R(A0)>(obj, func);
02826 }
02827 
02828 /** Create a callback class with type infered from the arguments
02829  *
02830  *  @param obj  Optional pointer to object to bind to function
02831  *  @param func Static function to attach
02832  *  @return     Callback with infered type
02833  */
02834 template <typename T, typename R, typename A0>
02835 Callback<R(A0)> callback(T *obj, R (*func)(T*, A0)) {
02836     return Callback<R(A0)>(obj, func);
02837 }
02838 
02839 /** Create a callback class with type infered from the arguments
02840  *
02841  *  @param obj  Optional pointer to object to bind to function
02842  *  @param func Static function to attach
02843  *  @return     Callback with infered type
02844  */
02845 template <typename T, typename R, typename A0>
02846 Callback<R(A0)> callback(const T *obj, R (*func)(const T*, A0)) {
02847     return Callback<R(A0)>(obj, func);
02848 }
02849 
02850 /** Create a callback class with type infered from the arguments
02851  *
02852  *  @param obj  Optional pointer to object to bind to function
02853  *  @param func Static function to attach
02854  *  @return     Callback with infered type
02855  */
02856 template <typename T, typename R, typename A0>
02857 Callback<R(A0)> callback(volatile T *obj, R (*func)(volatile T*, A0)) {
02858     return Callback<R(A0)>(obj, func);
02859 }
02860 
02861 /** Create a callback class with type infered from the arguments
02862  *
02863  *  @param obj  Optional pointer to object to bind to function
02864  *  @param func Static function to attach
02865  *  @return     Callback with infered type
02866  */
02867 template <typename T, typename R, typename A0>
02868 Callback<R(A0)> callback(const volatile T *obj, R (*func)(const volatile T*, A0)) {
02869     return Callback<R(A0)>(obj, func);
02870 }
02871 
02872 /** Create a callback class with type infered from the arguments
02873  *
02874  *  @param obj  Optional pointer to object to bind to function
02875  *  @param func Static function to attach
02876  *  @return     Callback with infered type
02877  */
02878 template<typename T, typename R, typename A0>
02879 Callback<R(A0)> callback(T *obj, R (T::*func)(A0)) {
02880     return Callback<R(A0)>(obj, func);
02881 }
02882 
02883 /** Create a callback class with type infered from the arguments
02884  *
02885  *  @param obj  Optional pointer to object to bind to function
02886  *  @param func Static function to attach
02887  *  @return     Callback with infered type
02888  */
02889 template<typename T, typename R, typename A0>
02890 Callback<R(A0)> callback(const T *obj, R (T::*func)(A0) const) {
02891     return Callback<R(A0)>(obj, func);
02892 }
02893 
02894 /** Create a callback class with type infered from the arguments
02895  *
02896  *  @param obj  Optional pointer to object to bind to function
02897  *  @param func Static function to attach
02898  *  @return     Callback with infered type
02899  */
02900 template<typename T, typename R, typename A0>
02901 Callback<R(A0)> callback(volatile T *obj, R (T::*func)(A0) volatile) {
02902     return Callback<R(A0)>(obj, func);
02903 }
02904 
02905 /** Create a callback class with type infered from the arguments
02906  *
02907  *  @param obj  Optional pointer to object to bind to function
02908  *  @param func Static function to attach
02909  *  @return     Callback with infered type
02910  */
02911 template<typename T, typename R, typename A0>
02912 Callback<R(A0)> callback(const volatile T *obj, R (T::*func)(A0) const volatile) {
02913     return Callback<R(A0)>(obj, func);
02914 }
02915 
02916 
02917 /** Create a callback class with type infered from the arguments
02918  *
02919  *  @param func Static function to attach
02920  *  @return     Callback with infered type
02921  */
02922 template <typename R, typename A0, typename A1>
02923 Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
02924     return Callback<R(A0, A1)>(func);
02925 }
02926 
02927 /** Create a callback class with type infered from the arguments
02928  *
02929  *  @param func Static function to attach
02930  *  @return     Callback with infered type
02931  */
02932 template <typename R, typename A0, typename A1>
02933 Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
02934     return Callback<R(A0, A1)>(func);
02935 }
02936 
02937 /** Create a callback class with type infered from the arguments
02938  *
02939  *  @param obj  Optional pointer to object to bind to function
02940  *  @param func Static function to attach
02941  *  @return     Callback with infered type
02942  */
02943 template <typename R, typename A0, typename A1>
02944 Callback<R(A0, A1)> callback(void *obj, R (*func)(void*, A0, A1)) {
02945     return Callback<R(A0, A1)>(obj, func);
02946 }
02947 
02948 /** Create a callback class with type infered from the arguments
02949  *
02950  *  @param obj  Optional pointer to object to bind to function
02951  *  @param func Static function to attach
02952  *  @return     Callback with infered type
02953  */
02954 template <typename R, typename A0, typename A1>
02955 Callback<R(A0, A1)> callback(const void *obj, R (*func)(const void*, A0, A1)) {
02956     return Callback<R(A0, A1)>(obj, func);
02957 }
02958 
02959 /** Create a callback class with type infered from the arguments
02960  *
02961  *  @param obj  Optional pointer to object to bind to function
02962  *  @param func Static function to attach
02963  *  @return     Callback with infered type
02964  */
02965 template <typename R, typename A0, typename A1>
02966 Callback<R(A0, A1)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1)) {
02967     return Callback<R(A0, A1)>(obj, func);
02968 }
02969 
02970 /** Create a callback class with type infered from the arguments
02971  *
02972  *  @param obj  Optional pointer to object to bind to function
02973  *  @param func Static function to attach
02974  *  @return     Callback with infered type
02975  */
02976 template <typename R, typename A0, typename A1>
02977 Callback<R(A0, A1)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) {
02978     return Callback<R(A0, A1)>(obj, func);
02979 }
02980 
02981 /** Create a callback class with type infered from the arguments
02982  *
02983  *  @param obj  Optional pointer to object to bind to function
02984  *  @param func Static function to attach
02985  *  @return     Callback with infered type
02986  */
02987 template <typename T, typename R, typename A0, typename A1>
02988 Callback<R(A0, A1)> callback(T *obj, R (*func)(T*, A0, A1)) {
02989     return Callback<R(A0, A1)>(obj, func);
02990 }
02991 
02992 /** Create a callback class with type infered from the arguments
02993  *
02994  *  @param obj  Optional pointer to object to bind to function
02995  *  @param func Static function to attach
02996  *  @return     Callback with infered type
02997  */
02998 template <typename T, typename R, typename A0, typename A1>
02999 Callback<R(A0, A1)> callback(const T *obj, R (*func)(const T*, A0, A1)) {
03000     return Callback<R(A0, A1)>(obj, func);
03001 }
03002 
03003 /** Create a callback class with type infered from the arguments
03004  *
03005  *  @param obj  Optional pointer to object to bind to function
03006  *  @param func Static function to attach
03007  *  @return     Callback with infered type
03008  */
03009 template <typename T, typename R, typename A0, typename A1>
03010 Callback<R(A0, A1)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1)) {
03011     return Callback<R(A0, A1)>(obj, func);
03012 }
03013 
03014 /** Create a callback class with type infered from the arguments
03015  *
03016  *  @param obj  Optional pointer to object to bind to function
03017  *  @param func Static function to attach
03018  *  @return     Callback with infered type
03019  */
03020 template <typename T, typename R, typename A0, typename A1>
03021 Callback<R(A0, A1)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) {
03022     return Callback<R(A0, A1)>(obj, func);
03023 }
03024 
03025 /** Create a callback class with type infered from the arguments
03026  *
03027  *  @param obj  Optional pointer to object to bind to function
03028  *  @param func Static function to attach
03029  *  @return     Callback with infered type
03030  */
03031 template<typename T, typename R, typename A0, typename A1>
03032 Callback<R(A0, A1)> callback(T *obj, R (T::*func)(A0, A1)) {
03033     return Callback<R(A0, A1)>(obj, func);
03034 }
03035 
03036 /** Create a callback class with type infered from the arguments
03037  *
03038  *  @param obj  Optional pointer to object to bind to function
03039  *  @param func Static function to attach
03040  *  @return     Callback with infered type
03041  */
03042 template<typename T, typename R, typename A0, typename A1>
03043 Callback<R(A0, A1)> callback(const T *obj, R (T::*func)(A0, A1) const) {
03044     return Callback<R(A0, A1)>(obj, func);
03045 }
03046 
03047 /** Create a callback class with type infered from the arguments
03048  *
03049  *  @param obj  Optional pointer to object to bind to function
03050  *  @param func Static function to attach
03051  *  @return     Callback with infered type
03052  */
03053 template<typename T, typename R, typename A0, typename A1>
03054 Callback<R(A0, A1)> callback(volatile T *obj, R (T::*func)(A0, A1) volatile) {
03055     return Callback<R(A0, A1)>(obj, func);
03056 }
03057 
03058 /** Create a callback class with type infered from the arguments
03059  *
03060  *  @param obj  Optional pointer to object to bind to function
03061  *  @param func Static function to attach
03062  *  @return     Callback with infered type
03063  */
03064 template<typename T, typename R, typename A0, typename A1>
03065 Callback<R(A0, A1)> callback(const volatile T *obj, R (T::*func)(A0, A1) const volatile) {
03066     return Callback<R(A0, A1)>(obj, func);
03067 }
03068 
03069 
03070 /** Create a callback class with type infered from the arguments
03071  *
03072  *  @param func Static function to attach
03073  *  @return     Callback with infered type
03074  */
03075 template <typename R, typename A0, typename A1, typename A2>
03076 Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
03077     return Callback<R(A0, A1, A2)>(func);
03078 }
03079 
03080 /** Create a callback class with type infered from the arguments
03081  *
03082  *  @param func Static function to attach
03083  *  @return     Callback with infered type
03084  */
03085 template <typename R, typename A0, typename A1, typename A2>
03086 Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
03087     return Callback<R(A0, A1, A2)>(func);
03088 }
03089 
03090 /** Create a callback class with type infered from the arguments
03091  *
03092  *  @param obj  Optional pointer to object to bind to function
03093  *  @param func Static function to attach
03094  *  @return     Callback with infered type
03095  */
03096 template <typename R, typename A0, typename A1, typename A2>
03097 Callback<R(A0, A1, A2)> callback(void *obj, R (*func)(void*, A0, A1, A2)) {
03098     return Callback<R(A0, A1, A2)>(obj, func);
03099 }
03100 
03101 /** Create a callback class with type infered from the arguments
03102  *
03103  *  @param obj  Optional pointer to object to bind to function
03104  *  @param func Static function to attach
03105  *  @return     Callback with infered type
03106  */
03107 template <typename R, typename A0, typename A1, typename A2>
03108 Callback<R(A0, A1, A2)> callback(const void *obj, R (*func)(const void*, A0, A1, A2)) {
03109     return Callback<R(A0, A1, A2)>(obj, func);
03110 }
03111 
03112 /** Create a callback class with type infered from the arguments
03113  *
03114  *  @param obj  Optional pointer to object to bind to function
03115  *  @param func Static function to attach
03116  *  @return     Callback with infered type
03117  */
03118 template <typename R, typename A0, typename A1, typename A2>
03119 Callback<R(A0, A1, A2)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) {
03120     return Callback<R(A0, A1, A2)>(obj, func);
03121 }
03122 
03123 /** Create a callback class with type infered from the arguments
03124  *
03125  *  @param obj  Optional pointer to object to bind to function
03126  *  @param func Static function to attach
03127  *  @return     Callback with infered type
03128  */
03129 template <typename R, typename A0, typename A1, typename A2>
03130 Callback<R(A0, A1, A2)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) {
03131     return Callback<R(A0, A1, A2)>(obj, func);
03132 }
03133 
03134 /** Create a callback class with type infered from the arguments
03135  *
03136  *  @param obj  Optional pointer to object to bind to function
03137  *  @param func Static function to attach
03138  *  @return     Callback with infered type
03139  */
03140 template <typename T, typename R, typename A0, typename A1, typename A2>
03141 Callback<R(A0, A1, A2)> callback(T *obj, R (*func)(T*, A0, A1, A2)) {
03142     return Callback<R(A0, A1, A2)>(obj, func);
03143 }
03144 
03145 /** Create a callback class with type infered from the arguments
03146  *
03147  *  @param obj  Optional pointer to object to bind to function
03148  *  @param func Static function to attach
03149  *  @return     Callback with infered type
03150  */
03151 template <typename T, typename R, typename A0, typename A1, typename A2>
03152 Callback<R(A0, A1, A2)> callback(const T *obj, R (*func)(const T*, A0, A1, A2)) {
03153     return Callback<R(A0, A1, A2)>(obj, func);
03154 }
03155 
03156 /** Create a callback class with type infered from the arguments
03157  *
03158  *  @param obj  Optional pointer to object to bind to function
03159  *  @param func Static function to attach
03160  *  @return     Callback with infered type
03161  */
03162 template <typename T, typename R, typename A0, typename A1, typename A2>
03163 Callback<R(A0, A1, A2)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) {
03164     return Callback<R(A0, A1, A2)>(obj, func);
03165 }
03166 
03167 /** Create a callback class with type infered from the arguments
03168  *
03169  *  @param obj  Optional pointer to object to bind to function
03170  *  @param func Static function to attach
03171  *  @return     Callback with infered type
03172  */
03173 template <typename T, typename R, typename A0, typename A1, typename A2>
03174 Callback<R(A0, A1, A2)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) {
03175     return Callback<R(A0, A1, A2)>(obj, func);
03176 }
03177 
03178 /** Create a callback class with type infered from the arguments
03179  *
03180  *  @param obj  Optional pointer to object to bind to function
03181  *  @param func Static function to attach
03182  *  @return     Callback with infered type
03183  */
03184 template<typename T, typename R, typename A0, typename A1, typename A2>
03185 Callback<R(A0, A1, A2)> callback(T *obj, R (T::*func)(A0, A1, A2)) {
03186     return Callback<R(A0, A1, A2)>(obj, func);
03187 }
03188 
03189 /** Create a callback class with type infered from the arguments
03190  *
03191  *  @param obj  Optional pointer to object to bind to function
03192  *  @param func Static function to attach
03193  *  @return     Callback with infered type
03194  */
03195 template<typename T, typename R, typename A0, typename A1, typename A2>
03196 Callback<R(A0, A1, A2)> callback(const T *obj, R (T::*func)(A0, A1, A2) const) {
03197     return Callback<R(A0, A1, A2)>(obj, func);
03198 }
03199 
03200 /** Create a callback class with type infered from the arguments
03201  *
03202  *  @param obj  Optional pointer to object to bind to function
03203  *  @param func Static function to attach
03204  *  @return     Callback with infered type
03205  */
03206 template<typename T, typename R, typename A0, typename A1, typename A2>
03207 Callback<R(A0, A1, A2)> callback(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) {
03208     return Callback<R(A0, A1, A2)>(obj, func);
03209 }
03210 
03211 /** Create a callback class with type infered from the arguments
03212  *
03213  *  @param obj  Optional pointer to object to bind to function
03214  *  @param func Static function to attach
03215  *  @return     Callback with infered type
03216  */
03217 template<typename T, typename R, typename A0, typename A1, typename A2>
03218 Callback<R(A0, A1, A2)> callback(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) {
03219     return Callback<R(A0, A1, A2)>(obj, func);
03220 }
03221 
03222 
03223 /** Create a callback class with type infered from the arguments
03224  *
03225  *  @param func Static function to attach
03226  *  @return     Callback with infered type
03227  */
03228 template <typename R, typename A0, typename A1, typename A2, typename A3>
03229 Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
03230     return Callback<R(A0, A1, A2, A3)>(func);
03231 }
03232 
03233 /** Create a callback class with type infered from the arguments
03234  *
03235  *  @param func Static function to attach
03236  *  @return     Callback with infered type
03237  */
03238 template <typename R, typename A0, typename A1, typename A2, typename A3>
03239 Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
03240     return Callback<R(A0, A1, A2, A3)>(func);
03241 }
03242 
03243 /** Create a callback class with type infered from the arguments
03244  *
03245  *  @param obj  Optional pointer to object to bind to function
03246  *  @param func Static function to attach
03247  *  @return     Callback with infered type
03248  */
03249 template <typename R, typename A0, typename A1, typename A2, typename A3>
03250 Callback<R(A0, A1, A2, A3)> callback(void *obj, R (*func)(void*, A0, A1, A2, A3)) {
03251     return Callback<R(A0, A1, A2, A3)>(obj, func);
03252 }
03253 
03254 /** Create a callback class with type infered from the arguments
03255  *
03256  *  @param obj  Optional pointer to object to bind to function
03257  *  @param func Static function to attach
03258  *  @return     Callback with infered type
03259  */
03260 template <typename R, typename A0, typename A1, typename A2, typename A3>
03261 Callback<R(A0, A1, A2, A3)> callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) {
03262     return Callback<R(A0, A1, A2, A3)>(obj, func);
03263 }
03264 
03265 /** Create a callback class with type infered from the arguments
03266  *
03267  *  @param obj  Optional pointer to object to bind to function
03268  *  @param func Static function to attach
03269  *  @return     Callback with infered type
03270  */
03271 template <typename R, typename A0, typename A1, typename A2, typename A3>
03272 Callback<R(A0, A1, A2, A3)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) {
03273     return Callback<R(A0, A1, A2, A3)>(obj, func);
03274 }
03275 
03276 /** Create a callback class with type infered from the arguments
03277  *
03278  *  @param obj  Optional pointer to object to bind to function
03279  *  @param func Static function to attach
03280  *  @return     Callback with infered type
03281  */
03282 template <typename R, typename A0, typename A1, typename A2, typename A3>
03283 Callback<R(A0, A1, A2, A3)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) {
03284     return Callback<R(A0, A1, A2, A3)>(obj, func);
03285 }
03286 
03287 /** Create a callback class with type infered from the arguments
03288  *
03289  *  @param obj  Optional pointer to object to bind to function
03290  *  @param func Static function to attach
03291  *  @return     Callback with infered type
03292  */
03293 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03294 Callback<R(A0, A1, A2, A3)> callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) {
03295     return Callback<R(A0, A1, A2, A3)>(obj, func);
03296 }
03297 
03298 /** Create a callback class with type infered from the arguments
03299  *
03300  *  @param obj  Optional pointer to object to bind to function
03301  *  @param func Static function to attach
03302  *  @return     Callback with infered type
03303  */
03304 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03305 Callback<R(A0, A1, A2, A3)> callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) {
03306     return Callback<R(A0, A1, A2, A3)>(obj, func);
03307 }
03308 
03309 /** Create a callback class with type infered from the arguments
03310  *
03311  *  @param obj  Optional pointer to object to bind to function
03312  *  @param func Static function to attach
03313  *  @return     Callback with infered type
03314  */
03315 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03316 Callback<R(A0, A1, A2, A3)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
03317     return Callback<R(A0, A1, A2, A3)>(obj, func);
03318 }
03319 
03320 /** Create a callback class with type infered from the arguments
03321  *
03322  *  @param obj  Optional pointer to object to bind to function
03323  *  @param func Static function to attach
03324  *  @return     Callback with infered type
03325  */
03326 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03327 Callback<R(A0, A1, A2, A3)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
03328     return Callback<R(A0, A1, A2, A3)>(obj, func);
03329 }
03330 
03331 /** Create a callback class with type infered from the arguments
03332  *
03333  *  @param obj  Optional pointer to object to bind to function
03334  *  @param func Static function to attach
03335  *  @return     Callback with infered type
03336  */
03337 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03338 Callback<R(A0, A1, A2, A3)> callback(T *obj, R (T::*func)(A0, A1, A2, A3)) {
03339     return Callback<R(A0, A1, A2, A3)>(obj, func);
03340 }
03341 
03342 /** Create a callback class with type infered from the arguments
03343  *
03344  *  @param obj  Optional pointer to object to bind to function
03345  *  @param func Static function to attach
03346  *  @return     Callback with infered type
03347  */
03348 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03349 Callback<R(A0, A1, A2, A3)> callback(const T *obj, R (T::*func)(A0, A1, A2, A3) const) {
03350     return Callback<R(A0, A1, A2, A3)>(obj, func);
03351 }
03352 
03353 /** Create a callback class with type infered from the arguments
03354  *
03355  *  @param obj  Optional pointer to object to bind to function
03356  *  @param func Static function to attach
03357  *  @return     Callback with infered type
03358  */
03359 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03360 Callback<R(A0, A1, A2, A3)> callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) {
03361     return Callback<R(A0, A1, A2, A3)>(obj, func);
03362 }
03363 
03364 /** Create a callback class with type infered from the arguments
03365  *
03366  *  @param obj  Optional pointer to object to bind to function
03367  *  @param func Static function to attach
03368  *  @return     Callback with infered type
03369  */
03370 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3>
03371 Callback<R(A0, A1, A2, A3)> callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) {
03372     return Callback<R(A0, A1, A2, A3)>(obj, func);
03373 }
03374 
03375 
03376 /** Create a callback class with type infered from the arguments
03377  *
03378  *  @param func Static function to attach
03379  *  @return     Callback with infered type
03380  */
03381 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03382 Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
03383     return Callback<R(A0, A1, A2, A3, A4)>(func);
03384 }
03385 
03386 /** Create a callback class with type infered from the arguments
03387  *
03388  *  @param func Static function to attach
03389  *  @return     Callback with infered type
03390  */
03391 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03392 Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
03393     return Callback<R(A0, A1, A2, A3, A4)>(func);
03394 }
03395 
03396 /** Create a callback class with type infered from the arguments
03397  *
03398  *  @param obj  Optional pointer to object to bind to function
03399  *  @param func Static function to attach
03400  *  @return     Callback with infered type
03401  */
03402 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03403 Callback<R(A0, A1, A2, A3, A4)> callback(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) {
03404     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03405 }
03406 
03407 /** Create a callback class with type infered from the arguments
03408  *
03409  *  @param obj  Optional pointer to object to bind to function
03410  *  @param func Static function to attach
03411  *  @return     Callback with infered type
03412  */
03413 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03414 Callback<R(A0, A1, A2, A3, A4)> callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) {
03415     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03416 }
03417 
03418 /** Create a callback class with type infered from the arguments
03419  *
03420  *  @param obj  Optional pointer to object to bind to function
03421  *  @param func Static function to attach
03422  *  @return     Callback with infered type
03423  */
03424 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03425 Callback<R(A0, A1, A2, A3, A4)> callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) {
03426     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03427 }
03428 
03429 /** Create a callback class with type infered from the arguments
03430  *
03431  *  @param obj  Optional pointer to object to bind to function
03432  *  @param func Static function to attach
03433  *  @return     Callback with infered type
03434  */
03435 template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03436 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) {
03437     return Callback<R(A0, A1, A2, A3, A4)>(obj, 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 func Static function to attach
03444  *  @return     Callback with infered type
03445  */
03446 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03447 Callback<R(A0, A1, A2, A3, A4)> callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
03448     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
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 func Static function to attach
03455  *  @return     Callback with infered type
03456  */
03457 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03458 Callback<R(A0, A1, A2, A3, A4)> callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
03459     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
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 func Static function to attach
03466  *  @return     Callback with infered type
03467  */
03468 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03469 Callback<R(A0, A1, A2, A3, A4)> callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
03470     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
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 func Static function to attach
03477  *  @return     Callback with infered type
03478  */
03479 template <typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03480 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
03481     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03482 }
03483 
03484 /** Create a callback class with type infered from the arguments
03485  *
03486  *  @param obj  Optional pointer to object to bind to function
03487  *  @param func Static function to attach
03488  *  @return     Callback with infered type
03489  */
03490 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03491 Callback<R(A0, A1, A2, A3, A4)> callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) {
03492     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03493 }
03494 
03495 /** Create a callback class with type infered from the arguments
03496  *
03497  *  @param obj  Optional pointer to object to bind to function
03498  *  @param func Static function to attach
03499  *  @return     Callback with infered type
03500  */
03501 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03502 Callback<R(A0, A1, A2, A3, A4)> callback(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) {
03503     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03504 }
03505 
03506 /** Create a callback class with type infered from the arguments
03507  *
03508  *  @param obj  Optional pointer to object to bind to function
03509  *  @param func Static function to attach
03510  *  @return     Callback with infered type
03511  */
03512 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03513 Callback<R(A0, A1, A2, A3, A4)> callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) {
03514     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03515 }
03516 
03517 /** Create a callback class with type infered from the arguments
03518  *
03519  *  @param obj  Optional pointer to object to bind to function
03520  *  @param func Static function to attach
03521  *  @return     Callback with infered type
03522  */
03523 template<typename T, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
03524 Callback<R(A0, A1, A2, A3, A4)> callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) {
03525     return Callback<R(A0, A1, A2, A3, A4)>(obj, func);
03526 }
03527 
03528 
03529 } // namespace mbed
03530 
03531 #endif