added prescaler for 16 bit pwm in LPC1347 target
Fork of mbed-dev by
Diff: api/Callback.h
- Revision:
- 144:ef7eb2e8f9f7
diff -r 423e1876dc07 -r ef7eb2e8f9f7 api/Callback.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/api/Callback.h Fri Sep 02 15:07:44 2016 +0100 @@ -0,0 +1,883 @@ +/* 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 <string.h> +#include <stdint.h> + +namespace mbed { + + +/** Callback class based on template specialization + * + * @Note Synchronization level: Not protected + */ +template <typename F> +class Callback; + +/** Templated function class + */ +template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4> +class Callback<R(A0, A1, A2, A3, A4)> { +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 + */ + template<typename T> + Callback(T *obj, R (*func)(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<typename T> + Callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { + attach(obj, func); + } + + /** Create a Callback with another Callback + * @param func Callback to attach + */ + Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) { + attach(func); + } + + /** Attach a static function + * @param func Static function to attach + */ + void attach(R (*func)(A0, A1, A2, A3, A4)) { + memcpy(&_func, &func, sizeof func); + _thunk = func ? &Callback::_staticthunk : 0; + } + + /** Attach a static function with a bound pointer + * @param obj Pointer to object to bind to function + * @param func Static function to attach + */ + template <typename T> + void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) { + _obj = (void*)obj; + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_boundthunk<T>; + } + + /** Attach a member function + * @param obj Pointer to object to invoke member function on + * @param func Member function to attach + */ + template<typename T> + void attach(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { + _obj = static_cast<void*>(obj); + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_methodthunk<T>; + } + + /** Attach a Callback + * @param func The Callback to attach + */ + void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) { + _obj = func._obj; + memcpy(&_func, &func._func, sizeof _func); + _thunk = func._thunk; + } + + /** Call the attached function + */ + R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + if (!_thunk) { + return (R)0; + } + 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) { + return call(a0, a1, a2, a3, a4); + } + + /** Test if function has been attached + */ + operator bool() const { + return _thunk; + } + + /** 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<Callback<R(A0, A1, A2, A3, A4)>*>(func) + ->call(a0, a1, a2, a3, a4); + } + +private: + // Internal thunks for various function types + static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return (*reinterpret_cast<R (**)(A0, A1, A2, A3, A4)>(func)) + (a0, a1, a2, a3, a4); + } + + template<typename T> + static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3, A4)>(func)) + (static_cast<T*>(obj), a0, a1, a2, a3, a4); + } + + template<typename T> + static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return (static_cast<T*>(obj)->* + (*reinterpret_cast<R (T::**)(A0, A1, A2, A3, A4)>(func))) + (a0, a1, a2, a3, a4); + } + + // 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*, void*, A0, A1, A2, A3, A4); +}; + +/** Templated function class + */ +template <typename R, typename A0, typename A1, typename A2, typename A3> +class Callback<R(A0, A1, A2, A3)> { +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 + */ + template<typename T> + Callback(T *obj, R (*func)(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<typename T> + Callback(T *obj, R (T::*func)(A0, A1, A2, A3)) { + attach(obj, func); + } + + /** Create a Callback with another Callback + * @param func Callback to attach + */ + Callback(const Callback<R(A0, A1, A2, A3)> &func) { + attach(func); + } + + /** Attach a static function + * @param func Static function to attach + */ + void attach(R (*func)(A0, A1, A2, A3)) { + memcpy(&_func, &func, sizeof func); + _thunk = func ? &Callback::_staticthunk : 0; + } + + /** Attach a static function with a bound pointer + * @param obj Pointer to object to bind to function + * @param func Static function to attach + */ + template <typename T> + void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) { + _obj = (void*)obj; + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_boundthunk<T>; + } + + /** Attach a member function + * @param obj Pointer to object to invoke member function on + * @param func Member function to attach + */ + template<typename T> + void attach(T *obj, R (T::*func)(A0, A1, A2, A3)) { + _obj = static_cast<void*>(obj); + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_methodthunk<T>; + } + + /** Attach a Callback + * @param func The Callback to attach + */ + void attach(const Callback<R(A0, A1, A2, A3)> &func) { + _obj = func._obj; + memcpy(&_func, &func._func, sizeof _func); + _thunk = func._thunk; + } + + /** Call the attached function + */ + R call(A0 a0, A1 a1, A2 a2, A3 a3) { + if (!_thunk) { + return (R)0; + } + return _thunk(_obj, &_func, a0, a1, a2, a3); + } + + /** Call the attached function + */ + R operator()(A0 a0, A1 a1, A2 a2, A3 a3) { + return call(a0, a1, a2, a3); + } + + /** Test if function has been attached + */ + operator bool() const { + return _thunk; + } + + /** 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<Callback<R(A0, A1, A2, A3)>*>(func) + ->call(a0, a1, a2, a3); + } + +private: + // Internal thunks for various function types + static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3) { + return (*reinterpret_cast<R (**)(A0, A1, A2, A3)>(func)) + (a0, a1, a2, a3); + } + + template<typename T> + static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) { + return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3)>(func)) + (static_cast<T*>(obj), a0, a1, a2, a3); + } + + template<typename T> + static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) { + return (static_cast<T*>(obj)->* + (*reinterpret_cast<R (T::**)(A0, A1, A2, A3)>(func))) + (a0, a1, a2, a3); + } + + // 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*, void*, A0, A1, A2, A3); +}; + +/** Templated function class + */ +template <typename R, typename A0, typename A1, typename A2> +class Callback<R(A0, A1, A2)> { +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 + */ + template<typename T> + Callback(T *obj, R (*func)(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<typename T> + Callback(T *obj, R (T::*func)(A0, A1, A2)) { + attach(obj, func); + } + + /** Create a Callback with another Callback + * @param func Callback to attach + */ + Callback(const Callback<R(A0, A1, A2)> &func) { + attach(func); + } + + /** Attach a static function + * @param func Static function to attach + */ + void attach(R (*func)(A0, A1, A2)) { + memcpy(&_func, &func, sizeof func); + _thunk = func ? &Callback::_staticthunk : 0; + } + + /** Attach a static function with a bound pointer + * @param obj Pointer to object to bind to function + * @param func Static function to attach + */ + template <typename T> + void attach(T *obj, R (*func)(T*, A0, A1, A2)) { + _obj = (void*)obj; + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_boundthunk<T>; + } + + /** Attach a member function + * @param obj Pointer to object to invoke member function on + * @param func Member function to attach + */ + template<typename T> + void attach(T *obj, R (T::*func)(A0, A1, A2)) { + _obj = static_cast<void*>(obj); + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_methodthunk<T>; + } + + /** Attach a Callback + * @param func The Callback to attach + */ + void attach(const Callback<R(A0, A1, A2)> &func) { + _obj = func._obj; + memcpy(&_func, &func._func, sizeof _func); + _thunk = func._thunk; + } + + /** Call the attached function + */ + R call(A0 a0, A1 a1, A2 a2) { + if (!_thunk) { + return (R)0; + } + return _thunk(_obj, &_func, a0, a1, a2); + } + + /** Call the attached function + */ + R operator()(A0 a0, A1 a1, A2 a2) { + return call(a0, a1, a2); + } + + /** Test if function has been attached + */ + operator bool() const { + return _thunk; + } + + /** 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<Callback<R(A0, A1, A2)>*>(func) + ->call(a0, a1, a2); + } + +private: + // Internal thunks for various function types + static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2) { + return (*reinterpret_cast<R (**)(A0, A1, A2)>(func)) + (a0, a1, a2); + } + + template<typename T> + static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) { + return (*reinterpret_cast<R (**)(T*, A0, A1, A2)>(func)) + (static_cast<T*>(obj), a0, a1, a2); + } + + template<typename T> + static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) { + return (static_cast<T*>(obj)->* + (*reinterpret_cast<R (T::**)(A0, A1, A2)>(func))) + (a0, a1, a2); + } + + // 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*, void*, A0, A1, A2); +}; + +/** Templated function class + */ +template <typename R, typename A0, typename A1> +class Callback<R(A0, A1)> { +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 + */ + template<typename T> + Callback(T *obj, R (*func)(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<typename T> + Callback(T *obj, R (T::*func)(A0, A1)) { + attach(obj, func); + } + + /** Create a Callback with another Callback + * @param func Callback to attach + */ + Callback(const Callback<R(A0, A1)> &func) { + attach(func); + } + + /** Attach a static function + * @param func Static function to attach + */ + void attach(R (*func)(A0, A1)) { + memcpy(&_func, &func, sizeof func); + _thunk = func ? &Callback::_staticthunk : 0; + } + + /** Attach a static function with a bound pointer + * @param obj Pointer to object to bind to function + * @param func Static function to attach + */ + template <typename T> + void attach(T *obj, R (*func)(T*, A0, A1)) { + _obj = (void*)obj; + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_boundthunk<T>; + } + + /** Attach a member function + * @param obj Pointer to object to invoke member function on + * @param func Member function to attach + */ + template<typename T> + void attach(T *obj, R (T::*func)(A0, A1)) { + _obj = static_cast<void*>(obj); + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_methodthunk<T>; + } + + /** Attach a Callback + * @param func The Callback to attach + */ + void attach(const Callback<R(A0, A1)> &func) { + _obj = func._obj; + memcpy(&_func, &func._func, sizeof _func); + _thunk = func._thunk; + } + + /** Call the attached function + */ + R call(A0 a0, A1 a1) { + if (!_thunk) { + return (R)0; + } + return _thunk(_obj, &_func, a0, a1); + } + + /** Call the attached function + */ + R operator()(A0 a0, A1 a1) { + return call(a0, a1); + } + + /** Test if function has been attached + */ + operator bool() const { + return _thunk; + } + + /** 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<Callback<R(A0, A1)>*>(func) + ->call(a0, a1); + } + +private: + // Internal thunks for various function types + static R _staticthunk(void*, void *func, A0 a0, A1 a1) { + return (*reinterpret_cast<R (**)(A0, A1)>(func)) + (a0, a1); + } + + template<typename T> + static R _boundthunk(void *obj, void *func, A0 a0, A1 a1) { + return (*reinterpret_cast<R (**)(T*, A0, A1)>(func)) + (static_cast<T*>(obj), a0, a1); + } + + template<typename T> + static R _methodthunk(void *obj, void *func, A0 a0, A1 a1) { + return (static_cast<T*>(obj)->* + (*reinterpret_cast<R (T::**)(A0, A1)>(func))) + (a0, a1); + } + + // 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*, void*, A0, A1); +}; + +/** Templated function class + */ +template <typename R, typename A0> +class Callback<R(A0)> { +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 + */ + template<typename T> + Callback(T *obj, R (*func)(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<typename T> + Callback(T *obj, R (T::*func)(A0)) { + attach(obj, func); + } + + /** Create a Callback with another Callback + * @param func Callback to attach + */ + Callback(const Callback<R(A0)> &func) { + attach(func); + } + + /** Attach a static function + * @param func Static function to attach + */ + void attach(R (*func)(A0)) { + memcpy(&_func, &func, sizeof func); + _thunk = func ? &Callback::_staticthunk : 0; + } + + /** Attach a static function with a bound pointer + * @param obj Pointer to object to bind to function + * @param func Static function to attach + */ + template <typename T> + void attach(T *obj, R (*func)(T*, A0)) { + _obj = (void*)obj; + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_boundthunk<T>; + } + + /** Attach a member function + * @param obj Pointer to object to invoke member function on + * @param func Member function to attach + */ + template<typename T> + void attach(T *obj, R (T::*func)(A0)) { + _obj = static_cast<void*>(obj); + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_methodthunk<T>; + } + + /** Attach a Callback + * @param func The Callback to attach + */ + void attach(const Callback<R(A0)> &func) { + _obj = func._obj; + memcpy(&_func, &func._func, sizeof _func); + _thunk = func._thunk; + } + + /** Call the attached function + */ + R call(A0 a0) { + if (!_thunk) { + return (R)0; + } + return _thunk(_obj, &_func, a0); + } + + /** Call the attached function + */ + R operator()(A0 a0) { + return call(a0); + } + + /** Test if function has been attached + */ + operator bool() const { + return _thunk; + } + + /** 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<Callback<R(A0)>*>(func) + ->call(a0); + } + +private: + // Internal thunks for various function types + static R _staticthunk(void*, void *func, A0 a0) { + return (*reinterpret_cast<R (**)(A0)>(func)) + (a0); + } + + template<typename T> + static R _boundthunk(void *obj, void *func, A0 a0) { + return (*reinterpret_cast<R (**)(T*, A0)>(func)) + (static_cast<T*>(obj), a0); + } + + template<typename T> + static R _methodthunk(void *obj, void *func, A0 a0) { + return (static_cast<T*>(obj)->* + (*reinterpret_cast<R (T::**)(A0)>(func))) + (a0); + } + + // 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*, void*, A0); +}; + +/** Templated function class + */ +template <typename R> +class Callback<R()> { +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 + */ + template<typename T> + Callback(T *obj, R (*func)(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<typename T> + Callback(T *obj, R (T::*func)()) { + attach(obj, func); + } + + /** Create a Callback with another Callback + * @param func Callback to attach + */ + Callback(const Callback<R()> &func) { + attach(func); + } + + /** Attach a static function + * @param func Static function to attach + */ + void attach(R (*func)()) { + memcpy(&_func, &func, sizeof func); + _thunk = func ? &Callback::_staticthunk : 0; + } + + /** Attach a static function with a bound pointer + * @param obj Pointer to object to bind to function + * @param func Static function to attach + */ + template <typename T> + void attach(T *obj, R (*func)(T*)) { + _obj = (void*)obj; + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_boundthunk<T>; + } + + /** Attach a member function + * @param obj Pointer to object to invoke member function on + * @param func Member function to attach + */ + template<typename T> + void attach(T *obj, R (T::*func)()) { + _obj = static_cast<void*>(obj); + memcpy(&_func, &func, sizeof func); + _thunk = &Callback::_methodthunk<T>; + } + + /** Attach a Callback + * @param func The Callback to attach + */ + void attach(const Callback<R()> &func) { + _obj = func._obj; + memcpy(&_func, &func._func, sizeof _func); + _thunk = func._thunk; + } + + /** Call the attached function + */ + R call() { + if (!_thunk) { + return (R)0; + } + return _thunk(_obj, &_func); + } + + /** Call the attached function + */ + R operator()() { + return call(); + } + + /** Test if function has been attached + */ + operator bool() const { + return _thunk; + } + + /** 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<Callback<R()>*>(func) + ->call(); + } + +private: + // Internal thunks for various function types + static R _staticthunk(void*, void *func) { + return (*reinterpret_cast<R (**)()>(func)) + (); + } + + template<typename T> + static R _boundthunk(void *obj, void *func) { + return (*reinterpret_cast<R (**)(T*)>(func)) + (static_cast<T*>(obj)); + } + + template<typename T> + static R _methodthunk(void *obj, void *func) { + return (static_cast<T*>(obj)->* + (*reinterpret_cast<R (T::**)()>(func))) + (); + } + + // 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*, void*); +}; + + typedef Callback<void(int)> event_callback_t; + + +} // namespace mbed + +#endif