/* mbed Microcontroller Library * Copyright (c) 2006-2015 ARM Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MBED_CALLBACK_H #define MBED_CALLBACK_H #include #include #include "mbed_assert.h" namespace mbed { /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback; /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback { public: /** Create a Callback with a static function * @param func Static function to attach */ Callback(R (*func)() = 0) { attach(func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(void *obj, R (*func)(void*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const void *obj, R (*func)(const void*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(volatile void *obj, R (*func)(volatile void*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const volatile void *obj, R (*func)(const volatile void*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(T *obj, R (*func)(T*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const T *obj, R (*func)(const T*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(volatile T *obj, R (*func)(volatile T*)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const volatile T *obj, R (*func)(const volatile T*)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(T *obj, R (T::*func)()) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const T *obj, R (T::*func)() const) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(volatile T *obj, R (T::*func)() volatile) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const volatile T *obj, R (T::*func)() const volatile) { attach(obj, func); } /** Attach a static function * @param func Static function to attach */ void attach(R (*func)()) { struct local { static R _thunk(void*, const void *func) { return (*static_cast(func))( ); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = 0; _thunk = func ? &local::_thunk : 0; } /** Attach a Callback * @param func The Callback to attach */ void attach(const Callback &func) { memset(&_func, 0, sizeof _func); memcpy(&_func, &func._func, sizeof func); _obj = func._obj; _thunk = func._thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(void *obj, R (*func)(void*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (void*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const void *obj, R (*func)(const void*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (const void*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(volatile void *obj, R (*func)(volatile void*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (volatile void*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const volatile void *obj, R (*func)(const volatile void*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (const volatile void*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(T *obj, R (*func)(T*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (T*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const T *obj, R (*func)(const T*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (const T*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(volatile T *obj, R (*func)(volatile T*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (volatile T*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const volatile T *obj, R (*func)(const volatile T*)) { struct local { static R _thunk(void *obj, const void *func) { return (*static_cast(func))( (const volatile T*)obj); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(T *obj, R (T::*func)()) { struct local { static R _thunk(void *obj, const void *func) { return (((T*)obj)->* (*static_cast(func)))( ); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const T *obj, R (T::*func)() const) { struct local { static R _thunk(void *obj, const void *func) { return (((const T*)obj)->* (*static_cast(func)))( ); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(volatile T *obj, R (T::*func)() volatile) { struct local { static R _thunk(void *obj, const void *func) { return (((volatile T*)obj)->* (*static_cast(func)))( ); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const volatile T *obj, R (T::*func)() const volatile) { struct local { static R _thunk(void *obj, const void *func) { return (((const volatile T*)obj)->* (*static_cast(func)))( ); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Call the attached function */ R call() const { MBED_ASSERT(_thunk); return _thunk(_obj, &_func); } /** Call the attached function */ R operator()() const { return call(); } /** Test if function has been attached */ operator bool() const { return _thunk; } /** Test for equality */ friend bool operator==(const Callback &l, const Callback &r) { return memcmp(&l, &r, sizeof(Callback)) == 0; } /** Test for inequality */ friend bool operator!=(const Callback &l, const Callback &r) { return !(l == r); } /** Static thunk for passing as C-style function * @param func Callback to call passed as void pointer */ static R thunk(void *func) { return static_cast*>(func)->call( ); } private: // Stored as pointer to function and pointer to optional object // Function pointer is stored as union of possible function types // to garuntee proper size and alignment struct _class; union { void (*_staticfunc)(); void (*_boundfunc)(_class *); void (_class::*_methodfunc)(); } _func; void *_obj; // Thunk registered on attach to dispatch calls R (*_thunk)(void*, const void*); }; /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback { public: /** Create a Callback with a static function * @param func Static function to attach */ Callback(R (*func)(A0) = 0) { attach(func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(void *obj, R (*func)(void*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const void *obj, R (*func)(const void*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(volatile void *obj, R (*func)(volatile void*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const volatile void *obj, R (*func)(const volatile void*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(T *obj, R (*func)(T*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const T *obj, R (*func)(const T*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(volatile T *obj, R (*func)(volatile T*, A0)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const volatile T *obj, R (*func)(const volatile T*, A0)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(T *obj, R (T::*func)(A0)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const T *obj, R (T::*func)(A0) const) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(volatile T *obj, R (T::*func)(A0) volatile) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const volatile T *obj, R (T::*func)(A0) const volatile) { attach(obj, func); } /** Attach a static function * @param func Static function to attach */ void attach(R (*func)(A0)) { struct local { static R _thunk(void*, const void *func, A0 a0) { return (*static_cast(func))( a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = 0; _thunk = func ? &local::_thunk : 0; } /** Attach a Callback * @param func The Callback to attach */ void attach(const Callback &func) { memset(&_func, 0, sizeof _func); memcpy(&_func, &func._func, sizeof func); _obj = func._obj; _thunk = func._thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(void *obj, R (*func)(void*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (void*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const void *obj, R (*func)(const void*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (const void*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(volatile void *obj, R (*func)(volatile void*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (volatile void*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const volatile void *obj, R (*func)(const volatile void*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (const volatile void*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(T *obj, R (*func)(T*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (T*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const T *obj, R (*func)(const T*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (const T*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(volatile T *obj, R (*func)(volatile T*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (volatile T*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const volatile T *obj, R (*func)(const volatile T*, A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (*static_cast(func))( (const volatile T*)obj, a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(T *obj, R (T::*func)(A0)) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (((T*)obj)->* (*static_cast(func)))( a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const T *obj, R (T::*func)(A0) const) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (((const T*)obj)->* (*static_cast(func)))( a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(volatile T *obj, R (T::*func)(A0) volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (((volatile T*)obj)->* (*static_cast(func)))( a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const volatile T *obj, R (T::*func)(A0) const volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0) { return (((const volatile T*)obj)->* (*static_cast(func)))( a0); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Call the attached function */ R call(A0 a0) const { MBED_ASSERT(_thunk); return _thunk(_obj, &_func, a0); } /** Call the attached function */ R operator()(A0 a0) const { return call(a0); } /** Test if function has been attached */ operator bool() const { return _thunk; } /** Test for equality */ friend bool operator==(const Callback &l, const Callback &r) { return memcmp(&l, &r, sizeof(Callback)) == 0; } /** Test for inequality */ friend bool operator!=(const Callback &l, const Callback &r) { return !(l == r); } /** Static thunk for passing as C-style function * @param func Callback to call passed as void pointer */ static R thunk(void *func, A0 a0) { return static_cast*>(func)->call( a0); } private: // Stored as pointer to function and pointer to optional object // Function pointer is stored as union of possible function types // to garuntee proper size and alignment struct _class; union { void (*_staticfunc)(); void (*_boundfunc)(_class *); void (_class::*_methodfunc)(); } _func; void *_obj; // Thunk registered on attach to dispatch calls R (*_thunk)(void*, const void*, A0); }; /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback { public: /** Create a Callback with a static function * @param func Static function to attach */ Callback(R (*func)(A0, A1) = 0) { attach(func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(void *obj, R (*func)(void*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const void *obj, R (*func)(const void*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(volatile void *obj, R (*func)(volatile void*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(T *obj, R (*func)(T*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const T *obj, R (*func)(const T*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(volatile T *obj, R (*func)(volatile T*, A0, A1)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(T *obj, R (T::*func)(A0, A1)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const T *obj, R (T::*func)(A0, A1) const) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(volatile T *obj, R (T::*func)(A0, A1) volatile) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const volatile T *obj, R (T::*func)(A0, A1) const volatile) { attach(obj, func); } /** Attach a static function * @param func Static function to attach */ void attach(R (*func)(A0, A1)) { struct local { static R _thunk(void*, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = 0; _thunk = func ? &local::_thunk : 0; } /** Attach a Callback * @param func The Callback to attach */ void attach(const Callback &func) { memset(&_func, 0, sizeof _func); memcpy(&_func, &func._func, sizeof func); _obj = func._obj; _thunk = func._thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(void *obj, R (*func)(void*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (void*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const void *obj, R (*func)(const void*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (const void*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(volatile void *obj, R (*func)(volatile void*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (volatile void*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (const volatile void*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(T *obj, R (*func)(T*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (T*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const T *obj, R (*func)(const T*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (const T*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(volatile T *obj, R (*func)(volatile T*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (volatile T*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (*static_cast(func))( (const volatile T*)obj, a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(T *obj, R (T::*func)(A0, A1)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (((T*)obj)->* (*static_cast(func)))( a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const T *obj, R (T::*func)(A0, A1) const) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (((const T*)obj)->* (*static_cast(func)))( a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(volatile T *obj, R (T::*func)(A0, A1) volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (((volatile T*)obj)->* (*static_cast(func)))( a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const volatile T *obj, R (T::*func)(A0, A1) const volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1) { return (((const volatile T*)obj)->* (*static_cast(func)))( a0, a1); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Call the attached function */ R call(A0 a0, A1 a1) const { MBED_ASSERT(_thunk); return _thunk(_obj, &_func, a0, a1); } /** Call the attached function */ R operator()(A0 a0, A1 a1) const { return call(a0, a1); } /** Test if function has been attached */ operator bool() const { return _thunk; } /** Test for equality */ friend bool operator==(const Callback &l, const Callback &r) { return memcmp(&l, &r, sizeof(Callback)) == 0; } /** Test for inequality */ friend bool operator!=(const Callback &l, const Callback &r) { return !(l == r); } /** Static thunk for passing as C-style function * @param func Callback to call passed as void pointer */ static R thunk(void *func, A0 a0, A1 a1) { return static_cast*>(func)->call( a0, a1); } private: // Stored as pointer to function and pointer to optional object // Function pointer is stored as union of possible function types // to garuntee proper size and alignment struct _class; union { void (*_staticfunc)(); void (*_boundfunc)(_class *); void (_class::*_methodfunc)(); } _func; void *_obj; // Thunk registered on attach to dispatch calls R (*_thunk)(void*, const void*, A0, A1); }; /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback { public: /** Create a Callback with a static function * @param func Static function to attach */ Callback(R (*func)(A0, A1, A2) = 0) { attach(func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(void *obj, R (*func)(void*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const void *obj, R (*func)(const void*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(T *obj, R (*func)(T*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const T *obj, R (*func)(const T*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(T *obj, R (T::*func)(A0, A1, A2)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const T *obj, R (T::*func)(A0, A1, A2) const) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) { attach(obj, func); } /** Attach a static function * @param func Static function to attach */ void attach(R (*func)(A0, A1, A2)) { struct local { static R _thunk(void*, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = 0; _thunk = func ? &local::_thunk : 0; } /** Attach a Callback * @param func The Callback to attach */ void attach(const Callback &func) { memset(&_func, 0, sizeof _func); memcpy(&_func, &func._func, sizeof func); _obj = func._obj; _thunk = func._thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(void *obj, R (*func)(void*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (void*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const void *obj, R (*func)(const void*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (const void*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (volatile void*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (const volatile void*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(T *obj, R (*func)(T*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (T*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const T *obj, R (*func)(const T*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (const T*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (volatile T*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (*static_cast(func))( (const volatile T*)obj, a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(T *obj, R (T::*func)(A0, A1, A2)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (((T*)obj)->* (*static_cast(func)))( a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const T *obj, R (T::*func)(A0, A1, A2) const) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (((const T*)obj)->* (*static_cast(func)))( a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (((volatile T*)obj)->* (*static_cast(func)))( a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2) { return (((const volatile T*)obj)->* (*static_cast(func)))( a0, a1, a2); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Call the attached function */ R call(A0 a0, A1 a1, A2 a2) const { MBED_ASSERT(_thunk); return _thunk(_obj, &_func, a0, a1, a2); } /** Call the attached function */ R operator()(A0 a0, A1 a1, A2 a2) const { return call(a0, a1, a2); } /** Test if function has been attached */ operator bool() const { return _thunk; } /** Test for equality */ friend bool operator==(const Callback &l, const Callback &r) { return memcmp(&l, &r, sizeof(Callback)) == 0; } /** Test for inequality */ friend bool operator!=(const Callback &l, const Callback &r) { return !(l == r); } /** Static thunk for passing as C-style function * @param func Callback to call passed as void pointer */ static R thunk(void *func, A0 a0, A1 a1, A2 a2) { return static_cast*>(func)->call( a0, a1, a2); } private: // Stored as pointer to function and pointer to optional object // Function pointer is stored as union of possible function types // to garuntee proper size and alignment struct _class; union { void (*_staticfunc)(); void (*_boundfunc)(_class *); void (_class::*_methodfunc)(); } _func; void *_obj; // Thunk registered on attach to dispatch calls R (*_thunk)(void*, const void*, A0, A1, A2); }; /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback { public: /** Create a Callback with a static function * @param func Static function to attach */ Callback(R (*func)(A0, A1, A2, A3) = 0) { attach(func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(void *obj, R (*func)(void*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(T *obj, R (T::*func)(A0, A1, A2, A3)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const T *obj, R (T::*func)(A0, A1, A2, A3) const) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) { attach(obj, func); } /** Attach a static function * @param func Static function to attach */ void attach(R (*func)(A0, A1, A2, A3)) { struct local { static R _thunk(void*, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = 0; _thunk = func ? &local::_thunk : 0; } /** Attach a Callback * @param func The Callback to attach */ void attach(const Callback &func) { memset(&_func, 0, sizeof _func); memcpy(&_func, &func._func, sizeof func); _obj = func._obj; _thunk = func._thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(void *obj, R (*func)(void*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (void*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (const void*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (volatile void*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (const volatile void*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (T*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (const T*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (volatile T*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (*static_cast(func))( (const volatile T*)obj, a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(T *obj, R (T::*func)(A0, A1, A2, A3)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (((T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const T *obj, R (T::*func)(A0, A1, A2, A3) const) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (((const T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (((volatile T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return (((const volatile T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Call the attached function */ R call(A0 a0, A1 a1, A2 a2, A3 a3) const { MBED_ASSERT(_thunk); return _thunk(_obj, &_func, a0, a1, a2, a3); } /** Call the attached function */ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const { return call(a0, a1, a2, a3); } /** Test if function has been attached */ operator bool() const { return _thunk; } /** Test for equality */ friend bool operator==(const Callback &l, const Callback &r) { return memcmp(&l, &r, sizeof(Callback)) == 0; } /** Test for inequality */ friend bool operator!=(const Callback &l, const Callback &r) { return !(l == r); } /** Static thunk for passing as C-style function * @param func Callback to call passed as void pointer */ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) { return static_cast*>(func)->call( a0, a1, a2, a3); } private: // Stored as pointer to function and pointer to optional object // Function pointer is stored as union of possible function types // to garuntee proper size and alignment struct _class; union { void (*_staticfunc)(); void (*_boundfunc)(_class *); void (_class::*_methodfunc)(); } _func; void *_obj; // Thunk registered on attach to dispatch calls R (*_thunk)(void*, const void*, A0, A1, A2, A3); }; /** Callback class based on template specialization * * @Note Synchronization level: Not protected */ template class Callback { public: /** Create a Callback with a static function * @param func Static function to attach */ Callback(R (*func)(A0, A1, A2, A3, A4) = 0) { attach(func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ Callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a static function and bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template Callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) { attach(obj, func); } /** Create a Callback with a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template Callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) { attach(obj, func); } /** Attach a static function * @param func Static function to attach */ void attach(R (*func)(A0, A1, A2, A3, A4)) { struct local { static R _thunk(void*, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = 0; _thunk = func ? &local::_thunk : 0; } /** Attach a Callback * @param func The Callback to attach */ void attach(const Callback &func) { memset(&_func, 0, sizeof _func); memcpy(&_func, &func._func, sizeof func); _obj = func._obj; _thunk = func._thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (void*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (const void*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (volatile void*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ void attach(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (const volatile void*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (T*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (const T*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (volatile T*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a static function with a bound pointer * @param obj Pointer to object to bind to function * @param func Static function to attach */ template void attach(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (*static_cast(func))( (const volatile T*)obj, a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (((T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (((const T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (((volatile T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Attach a member function * @param obj Pointer to object to invoke member function on * @param func Member function to attach */ template void attach(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) { struct local { static R _thunk(void *obj, const void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return (((const volatile T*)obj)->* (*static_cast(func)))( a0, a1, a2, a3, a4); } }; memset(&_func, 0, sizeof _func); memcpy(&_func, &func, sizeof func); _obj = (void*)obj; _thunk = &local::_thunk; } /** Call the attached function */ R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { MBED_ASSERT(_thunk); return _thunk(_obj, &_func, a0, a1, a2, a3, a4); } /** Call the attached function */ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const { return call(a0, a1, a2, a3, a4); } /** Test if function has been attached */ operator bool() const { return _thunk; } /** Test for equality */ friend bool operator==(const Callback &l, const Callback &r) { return memcmp(&l, &r, sizeof(Callback)) == 0; } /** Test for inequality */ friend bool operator!=(const Callback &l, const Callback &r) { return !(l == r); } /** Static thunk for passing as C-style function * @param func Callback to call passed as void pointer */ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return static_cast*>(func)->call( a0, a1, a2, a3, a4); } private: // Stored as pointer to function and pointer to optional object // Function pointer is stored as union of possible function types // to garuntee proper size and alignment struct _class; union { void (*_staticfunc)(); void (*_boundfunc)(_class *); void (_class::*_methodfunc)(); } _func; void *_obj; // Thunk registered on attach to dispatch calls R (*_thunk)(void*, const void*, A0, A1, A2, A3, A4); }; // Internally used event type typedef Callback event_callback_t; /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(R (*func)() = 0) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const Callback &func) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(void *obj, R (*func)(void*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const void *obj, R (*func)(const void*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile void *obj, R (*func)(volatile void*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile void *obj, R (*func)(const volatile void*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (*func)(T*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (*func)(const T*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (*func)(volatile T*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (*func)(const volatile T*)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (T::*func)()) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (T::*func)() const) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (T::*func)() volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (T::*func)() const volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(R (*func)(A0) = 0) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const Callback &func) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(void *obj, R (*func)(void*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const void *obj, R (*func)(const void*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile void *obj, R (*func)(volatile void*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile void *obj, R (*func)(const volatile void*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (*func)(T*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (*func)(const T*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (*func)(volatile T*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (*func)(const volatile T*, A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (T::*func)(A0)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (T::*func)(A0) const) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (T::*func)(A0) volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (T::*func)(A0) const volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(R (*func)(A0, A1) = 0) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const Callback &func) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(void *obj, R (*func)(void*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const void *obj, R (*func)(const void*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile void *obj, R (*func)(volatile void*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (*func)(T*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (*func)(const T*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (*func)(volatile T*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (T::*func)(A0, A1)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (T::*func)(A0, A1) const) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (T::*func)(A0, A1) volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (T::*func)(A0, A1) const volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(R (*func)(A0, A1, A2) = 0) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const Callback &func) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(void *obj, R (*func)(void*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const void *obj, R (*func)(const void*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (*func)(T*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (*func)(const T*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (T::*func)(A0, A1, A2)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (T::*func)(A0, A1, A2) const) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (T::*func)(A0, A1, A2) volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (T::*func)(A0, A1, A2) const volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(R (*func)(A0, A1, A2, A3) = 0) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const Callback &func) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(void *obj, R (*func)(void*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (T::*func)(A0, A1, A2, A3)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (T::*func)(A0, A1, A2, A3) const) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3) volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3) const volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(R (*func)(A0, A1, A2, A3, A4) = 0) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const Callback &func) { return Callback(func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(void *obj, R (*func)(void*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const void *obj, R (*func)(const void*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile void *obj, R (*func)(volatile void*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile void *obj, R (*func)(const volatile void*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const T *obj, R (T::*func)(A0, A1, A2, A3, A4) const) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) volatile) { return Callback(obj, func); } /** Create a callback class with type infered from the arguments * * @param obj Optional pointer to object to bind to function * @param func Static function to attach * @return Callback with infered type */ template Callback callback(const volatile T *obj, R (T::*func)(A0, A1, A2, A3, A4) const volatile) { return Callback(obj, func); } } // namespace mbed #endif