Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_PingPong DISCO-L072CZ-LRWAN1_LoRa_USB_Rx ... more
Fork of SX1276Lib by
Revision 71:7067e67902a8, committed 2017-07-23
- Comitter:
- Helmut Tschemernjak
- Date:
- Sun Jul 23 16:09:55 2017 +0200
- Parent:
- 70:1d496aae2819
- Child:
- 72:2a6c776b5e92
- Commit message:
- Renamed Arduino files to Arduino-mbed-APIs
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Arduino-mbed-APIs/Callback-A.h Sun Jul 23 16:09:55 2017 +0200
@@ -0,0 +1,4228 @@
+/* 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.
+ */
+#ifdef ARDUINO
+
+#ifndef MBED_CALLBACK_H
+#define MBED_CALLBACK_H
+
+
+#include <string.h>
+#include <stdint.h>
+#include <new>
+//#include "platform/mbed_assert.h"
+//#include "platform/mbed_toolchain.h"
+#ifdef ARDUINO
+#undef F
+#endif
+
+// namespace mbed {
+/** \addtogroup platform */
+
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename F>
+class Callback;
+
+// Internal sfinae declarations
+//
+// These are used to eliminate overloads based on type attributes
+// 1. Does a function object have a call operator
+// 2. Does a function object fit in the available storage
+//
+// These eliminations are handled cleanly by the compiler and avoid
+// massive and misleading error messages when confronted with an
+// invalid type (or worse, runtime failures)
+namespace detail {
+ struct nil {};
+
+ template <bool B, typename R = nil>
+ struct enable_if { typedef R type; };
+
+ template <typename R>
+ struct enable_if<false, R> {};
+
+ template <typename M, M>
+ struct is_type {
+ static const bool value = true;
+ };
+}
+
+#define MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M) \
+ typename detail::enable_if< \
+ detail::is_type<M, &F::operator()>::value && \
+ sizeof(F) <= sizeof(uintptr_t) \
+ >::type = detail::nil()
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R>
+class Callback<R()> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)() = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R()> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)()) {
+ generate(method_context<T, R (T::*)()>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)() const) {
+ generate(method_context<const T, R (T::*)() const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)() volatile) {
+ generate(method_context<volatile T, R (T::*)() volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)() const volatile) {
+ generate(method_context<const volatile T, R (T::*)() const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*), U *arg) {
+ generate(function_context<R (*)(T*), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*), const U *arg) {
+ generate(function_context<R (*)(const T*), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
+ generate(f);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)()) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R()> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)()) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)() const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)() volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)() const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call() const {
+ return _ops->call(this);
+ }
+
+ /** Call the attached function
+ */
+ R operator()() const {
+ return call();
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** 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
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func) {
+ return static_cast<Callback*>(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;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+ //MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ // "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p) {
+ return (*(F*)p)();
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()() const {
+ return (obj->*method)();
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()() const {
+ return func(arg);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+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) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0)) {
+ generate(method_context<T, R (T::*)(A0)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0) const) {
+ generate(method_context<const T, R (T::*)(A0) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0), U *arg) {
+ generate(function_context<R (*)(T*, A0), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0), const U *arg) {
+ generate(function_context<R (*)(const T*, A0), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
+ generate(f);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0) const {
+ return call(a0);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** 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
+ * @param a0 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0) {
+ return static_cast<Callback*>(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)(A0);
+ void (*_boundfunc)(_class*, A0);
+ void (_class::*_methodfunc)(A0);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0) {
+ return (*(F*)p)(a0);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0) const {
+ return (obj->*method)(a0);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0) const {
+ return func(arg, a0);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+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) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1)) {
+ generate(method_context<T, R (T::*)(A0, A1)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1) const) {
+ generate(method_context<const T, R (T::*)(A0, A1) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
+ generate(f);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, 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 _ops;
+ }
+
+ /** 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
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1) {
+ return static_cast<Callback*>(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)(A0, A1);
+ void (*_boundfunc)(_class*, A0, A1);
+ void (_class::*_methodfunc)(A0, A1);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1) {
+ return (*(F*)p)(a0, a1);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1) const {
+ return (obj->*method)(a0, a1);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1) const {
+ return func(arg, a0, a1);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+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) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
+ generate(f);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1, A2)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1, A2), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, 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 _ops;
+ }
+
+ /** 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
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @param a2 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
+ return static_cast<Callback*>(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)(A0, A1, A2);
+ void (*_boundfunc)(_class*, A0, A1, A2);
+ void (_class::*_methodfunc)(A0, A1, A2);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
+ return (*(F*)p)(a0, a1, a2);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return (obj->*method)(a0, a1, a2);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return func(arg, a0, a1, a2);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+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) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2, A3)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2, A3)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2, A3) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2, A3), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2, A3), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2, A3), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
+ generate(f);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1, A2, A3)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, 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 _ops;
+ }
+
+ /** 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
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @param a2 An argument to be called with function func
+ * @param a3 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return static_cast<Callback*>(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)(A0, A1, A2, A3);
+ void (*_boundfunc)(_class*, A0, A1, A2, A3);
+ void (_class::*_methodfunc)(A0, A1, A2, A3);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2, A3);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return (*(F*)p)(a0, a1, a2, a3);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return (obj->*method)(a0, a1, a2, a3);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return func(arg, a0, a1, a2, a3);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+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) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2, A3, A4)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2, A3, A4) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2, A3, A4), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2, A3, A4), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2, A3, A4), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3, A4), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
+ generate(f);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** 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
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, 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 _ops;
+ }
+
+ /** 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
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @param a2 An argument to be called with function func
+ * @param a3 An argument to be called with function func
+ * @param a4 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return static_cast<Callback*>(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)(A0, A1, A2, A3, A4);
+ void (*_boundfunc)(_class*, A0, A1, A2, A3, A4);
+ void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2, A3, A4);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return (*(F*)p)(a0, a1, a2, a3, a4);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return (obj->*method)(a0, a1, a2, a3, a4);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return func(arg, a0, a1, a2, a3, a4);
+ }
+ };
+};
+
+// Internally used event type
+typedef Callback<void(int)> 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 <typename R>
+Callback<R()> callback(R (*func)() = 0) {
+ return Callback<R()>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R>
+Callback<R()> callback(const Callback<R()> &func) {
+ return Callback<R()>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(U *obj, R (T::*method)()) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(const U *obj, R (T::*method)() const) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(volatile U *obj, R (T::*method)() volatile) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(const volatile U *obj, R (T::*method)() const volatile) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(T*), U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(const T*), const U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(volatile T*), volatile U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(const volatile T*), const volatile U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(U *obj, R (*func)(T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(const U *obj, R (*func)(const T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(volatile U *obj, R (*func)(volatile T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(const volatile U *obj, R (*func)(const volatile T*)) {
+ return Callback<R()>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(A0) = 0) {
+ return Callback<R(A0)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0>
+Callback<R(A0)> callback(const Callback<R(A0)> &func) {
+ return Callback<R(A0)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(U *obj, R (T::*method)(A0)) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const U *obj, R (T::*method)(A0) const) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(volatile U *obj, R (T::*method)(A0) volatile) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(T*, A0), U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(const T*, A0), const U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(volatile T*, A0), volatile U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(U *obj, R (*func)(T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const U *obj, R (*func)(const T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(volatile U *obj, R (*func)(volatile T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
+ return Callback<R(A0, A1)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
+ return Callback<R(A0, A1)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(U *obj, R (T::*method)(A0, A1)) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const U *obj, R (T::*method)(A0, A1) const) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(T*, A0, A1), U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(const T*, A0, A1), const U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(U *obj, R (*func)(T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const U *obj, R (*func)(const T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
+ return Callback<R(A0, A1, A2)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
+ return Callback<R(A0, A1, A2)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(U *obj, R (T::*method)(A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(T*, A0, A1, A2), U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(U *obj, R (*func)(T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
+ return Callback<R(A0, A1, A2, A3)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
+ return Callback<R(A0, A1, A2, A3)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** 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
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+
+// } // namespace mbed
+
+#endif
+#endif // Arduino
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Arduino-mbed-APIs/arduino-mbed.cpp Sun Jul 23 16:09:55 2017 +0200
@@ -0,0 +1,667 @@
+/*
+ * The file is Licensed under the Apache License, Version 2.0
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+#ifdef ARDUINO
+
+using namespace std;
+
+#include "arduino-mbed.h"
+
+
+static void pinInt00(void);
+static void pinInt01(void);
+static void pinInt02(void);
+static void pinInt03(void);
+static void pinInt04(void);
+static void pinInt05(void);
+static void pinInt06(void);
+static void pinInt07(void);
+static void pinInt08(void);
+static void pinInt09(void);
+static void pinInt10(void);
+static void pinInt11(void);
+static void pinInt12(void);
+static void pinInt13(void);
+static void pinInt14(void);
+static void pinInt15(void);
+static void pinInt16(void);
+static void pinInt17(void);
+static void pinInt18(void);
+static void pinInt19(void);
+static void pinInt20(void);
+static void pinInt21(void);
+static void pinInt22(void);
+static void pinInt23(void);
+static void pinInt24(void);
+static void pinInt25(void);
+static void pinInt26(void);
+static void pinInt27(void);
+static void pinInt28(void);
+static void pinInt29(void);
+static void pinInt30(void);
+static void pinInt31(void);
+static void pinInt32(void);
+static void pinInt33(void);
+static void pinInt34(void);
+static void pinInt35(void);
+static void pinInt36(void);
+static void pinInt37(void);
+static void pinInt38(void);
+static void pinInt39(void);
+static void pinInt40(void);
+static void pinInt41(void);
+static void pinInt42(void);
+static void pinInt43(void);
+static void pinInt44(void);
+static void pinInt45(void);
+static void pinInt46(void);
+static void pinInt47(void);
+
+
+
+#define MAX_MCU_PINS 48
+class InterruptIn;
+struct intPtrTable {
+ void (*func)(void);
+ InterruptIn *context;
+} intPtrTable[MAX_MCU_PINS] = {
+ { pinInt00, NULL },
+ { pinInt01, NULL },
+ { pinInt02, NULL },
+ { pinInt03, NULL },
+ { pinInt04, NULL },
+ { pinInt05, NULL },
+ { pinInt06, NULL },
+ { pinInt07, NULL },
+ { pinInt08, NULL },
+ { pinInt09, NULL },
+ { pinInt10, NULL },
+ { pinInt11, NULL },
+ { pinInt12, NULL },
+ { pinInt13, NULL },
+ { pinInt14, NULL },
+ { pinInt15, NULL },
+ { pinInt16, NULL },
+ { pinInt17, NULL },
+ { pinInt18, NULL },
+ { pinInt19, NULL },
+ { pinInt20, NULL },
+ { pinInt21, NULL },
+ { pinInt22, NULL },
+ { pinInt23, NULL },
+ { pinInt24, NULL },
+ { pinInt25, NULL },
+ { pinInt26, NULL },
+ { pinInt27, NULL },
+ { pinInt28, NULL },
+ { pinInt29, NULL },
+ { pinInt30, NULL },
+ { pinInt31, NULL },
+ { pinInt32, NULL },
+ { pinInt33, NULL },
+ { pinInt34, NULL },
+ { pinInt35, NULL },
+ { pinInt36, NULL },
+ { pinInt37, NULL },
+ { pinInt38, NULL },
+ { pinInt39, NULL },
+ { pinInt40, NULL },
+ { pinInt41, NULL },
+ { pinInt42, NULL },
+ { pinInt43, NULL },
+ { pinInt44, NULL },
+ { pinInt45, NULL },
+ { pinInt46, NULL },
+ { pinInt47, NULL }
+}; // our max MCUs pins
+
+
+
+static void pinInt00(void) { InterruptIn::_irq_handler(intPtrTable[0].context); }
+static void pinInt01(void) { InterruptIn::_irq_handler(intPtrTable[1].context); }
+static void pinInt02(void) { InterruptIn::_irq_handler(intPtrTable[2].context); }
+static void pinInt03(void) { InterruptIn::_irq_handler(intPtrTable[3].context); }
+static void pinInt04(void) { InterruptIn::_irq_handler(intPtrTable[4].context); }
+static void pinInt05(void) { InterruptIn::_irq_handler(intPtrTable[5].context); }
+static void pinInt06(void) { InterruptIn::_irq_handler(intPtrTable[6].context); }
+static void pinInt07(void) { InterruptIn::_irq_handler(intPtrTable[7].context); }
+static void pinInt08(void) { InterruptIn::_irq_handler(intPtrTable[8].context); }
+static void pinInt09(void) { InterruptIn::_irq_handler(intPtrTable[9].context); }
+static void pinInt10(void) { InterruptIn::_irq_handler(intPtrTable[10].context); }
+static void pinInt11(void) { InterruptIn::_irq_handler(intPtrTable[11].context); }
+static void pinInt12(void) { InterruptIn::_irq_handler(intPtrTable[12].context); }
+static void pinInt13(void) { InterruptIn::_irq_handler(intPtrTable[13].context); }
+static void pinInt14(void) { InterruptIn::_irq_handler(intPtrTable[14].context); }
+static void pinInt15(void) { InterruptIn::_irq_handler(intPtrTable[15].context); }
+static void pinInt16(void) { InterruptIn::_irq_handler(intPtrTable[16].context); }
+static void pinInt17(void) { InterruptIn::_irq_handler(intPtrTable[17].context); }
+static void pinInt18(void) { InterruptIn::_irq_handler(intPtrTable[18].context); }
+static void pinInt19(void) { InterruptIn::_irq_handler(intPtrTable[19].context); }
+static void pinInt20(void) { InterruptIn::_irq_handler(intPtrTable[20].context); }
+static void pinInt21(void) { InterruptIn::_irq_handler(intPtrTable[21].context); }
+static void pinInt22(void) { InterruptIn::_irq_handler(intPtrTable[22].context); }
+static void pinInt23(void) { InterruptIn::_irq_handler(intPtrTable[23].context); }
+static void pinInt24(void) { InterruptIn::_irq_handler(intPtrTable[24].context); }
+static void pinInt25(void) { InterruptIn::_irq_handler(intPtrTable[25].context); }
+static void pinInt26(void) { InterruptIn::_irq_handler(intPtrTable[26].context); }
+static void pinInt27(void) { InterruptIn::_irq_handler(intPtrTable[27].context); }
+static void pinInt28(void) { InterruptIn::_irq_handler(intPtrTable[28].context); }
+static void pinInt29(void) { InterruptIn::_irq_handler(intPtrTable[29].context); }
+static void pinInt30(void) { InterruptIn::_irq_handler(intPtrTable[30].context); }
+static void pinInt31(void) { InterruptIn::_irq_handler(intPtrTable[31].context); }
+static void pinInt32(void) { InterruptIn::_irq_handler(intPtrTable[32].context); }
+static void pinInt33(void) { InterruptIn::_irq_handler(intPtrTable[33].context); }
+static void pinInt34(void) { InterruptIn::_irq_handler(intPtrTable[34].context); }
+static void pinInt35(void) { InterruptIn::_irq_handler(intPtrTable[35].context); }
+static void pinInt36(void) { InterruptIn::_irq_handler(intPtrTable[36].context); }
+static void pinInt37(void) { InterruptIn::_irq_handler(intPtrTable[37].context); }
+static void pinInt38(void) { InterruptIn::_irq_handler(intPtrTable[38].context); }
+static void pinInt39(void) { InterruptIn::_irq_handler(intPtrTable[39].context); }
+static void pinInt40(void) { InterruptIn::_irq_handler(intPtrTable[40].context); }
+static void pinInt41(void) { InterruptIn::_irq_handler(intPtrTable[41].context); }
+static void pinInt42(void) { InterruptIn::_irq_handler(intPtrTable[42].context); }
+static void pinInt43(void) { InterruptIn::_irq_handler(intPtrTable[43].context); }
+static void pinInt44(void) { InterruptIn::_irq_handler(intPtrTable[44].context); }
+static void pinInt45(void) { InterruptIn::_irq_handler(intPtrTable[45].context); }
+static void pinInt46(void) { InterruptIn::_irq_handler(intPtrTable[46].context); }
+static void pinInt47(void) { InterruptIn::_irq_handler(intPtrTable[47].context); }
+
+
+
+
+void
+InterruptIn::rise(Callback<void()> func) {
+ if (_gpioPin >= MAX_MCU_PINS-1)
+ return;
+ if (func) {
+ _func = func;
+ intPtrTable[_gpioPin].context = this;
+ attachInterrupt(MYdigitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, RISING);
+ } else {
+ _func = InterruptIn::donothing;
+ intPtrTable[_gpioPin].context = NULL;
+ detachInterrupt(_gpioPin);
+ }
+};
+
+void
+InterruptIn::fall(Callback<void()> func) {
+ if (func) {
+ _func = func;
+ intPtrTable[_gpioPin].context = this;
+ attachInterrupt(MYdigitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, FALLING);
+ } else {
+ _func = InterruptIn::donothing;
+ intPtrTable[_gpioPin].context = NULL;
+ detachInterrupt(_gpioPin);
+ }
+}
+
+
+#define MAX_TIMEOUTS 10
+class Timeout;
+struct TimeoutVector {
+ Timeout *timer;
+} TimeOuts[MAX_TIMEOUTS];
+
+
+#if defined(__SAMD21G18A__) || defined(__SAMD21J18A__)
+/*
+ * __SAMD21J18A__ is the SamD21 Explained Board
+ * __SAMD21G18A__ is Genuino Zero-Board (compatible with the LoRa board)
+ */
+
+/*
+ * see tcc.h is automatically included from:
+ * Arduino15/packages/arduino/tools/CMSIS-Atmel/1.1.0/CMSIS/
+ * Device/ATMEL/samd21/include/component/tcc.h
+ * See also tcc.c (ASF/mbed, e.g. Tcc_get_count_value)
+ */
+static void initTimer(Tcc *t);
+static uint32_t getTimerCount(Tcc *t);
+
+/*
+ * The Atmel D21 has three TCC timer, other models have more.
+ */
+static const struct TCC_config {
+ Tcc *tcc_ptr;
+ IRQn_Type tcc_irq;
+ uint8_t nbits;
+} TCC_data[] {
+ { TCC0, TCC0_IRQn, 24 },
+ { TCC1, TCC1_IRQn, 24 },
+ { TCC2, TCC2_IRQn, 16 },
+ { NULL, (IRQn_Type)NULL, 0 }
+};
+
+/*
+ * We preferably use the TCC timers because it supports 24-bit counters
+ * versus TC Timer which supports only 8 or 16 bit counters
+ * TCC0/1/2 timer work on the D21 using Arduino.
+ */
+#define USE_TCC_TIMEOUT 0 // 0=TCC0, 1=TTC1, 2=TTC2 (see TCC_data)
+#define USE_TCC_TICKER 1
+
+
+/*
+ * every 21333 ns equals one tick (1/(48000000/1024)) // prescaler 1024, 48 MHz
+ * every 61035 ns equals one tick (1/(32768/2)) // prescaler 2, 32 kHz
+ * COUNT*DIVIDER*SECS until interrupt
+ * CPU 48 MHz = (65536*1024)/1.398636s
+ * RTC 32 kHz = (65536*2)/4.0s
+ */
+#define NS_PER_CLOCK_CPU 21333 // ns secs per clock
+#define NS_PER_CLOCK_RTC 61035 // ns secs per clock
+
+#define NS_PER_CLOCK NS_PER_CLOCK_RTC
+
+/* ----------------- TICKER TIMER CODE ----------------------*/
+
+/*
+ * The global ns_counter contains the time in ns from the last time
+ * the counter has been wrapped. It cannot be used directly because the
+ * current counter has to be added fore using it. Use instead
+ * ns_getTicker(), us_ ns_getTicker(), ms_getTicker()
+ */
+
+uint64_t ticker_ns;
+static bool initTickerDone = false;
+
+uint32_t s_getTicker(void)
+{
+ long long ns = ns_getTicker();
+ ns /= (long long)1000000000; // to secs
+
+ int secs = ns;
+ return secs;
+}
+
+
+uint32_t ms_getTicker(void)
+{
+ uint32_t us = us_getTicker();
+
+ us /= 1000; // to ms
+ return us;
+}
+
+uint32_t us_getTicker(void)
+{
+ long long ns = ns_getTicker();
+
+ ns /= (long long)1000; // to us
+ uint32_t us = ns & 0xffffffff;
+
+ return us;
+}
+
+
+uint64_t ns_getTicker(void)
+{
+ Tcc *t = TCC_data[USE_TCC_TICKER].tcc_ptr;
+ if (!initTickerDone) {
+ initTimer(t);
+ initTickerDone = true;
+
+ // set counter top to max 16 bit for testing
+ // t->PER.bit.PER = 0xffff;
+ // while (t->SYNCBUSY.bit.PER == 1); // wait for sync
+
+ t->CTRLA.reg |= TCC_CTRLA_ENABLE ; // Enable TC
+ while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+ }
+
+ /*
+ * if we are called from the interrupt level, the counter contains
+ * somehow wrong data, therfore we needs to read it twice.
+ * Another option was to add a little wait (loop 500x)
+ * in the TCC_TIMEOUT interrupt handler.
+ */
+ if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) // check if we are in the interrupt
+ getTimerCount(t);
+
+ uint64_t counter_us = (uint64_t)NS_PER_CLOCK * (uint64_t)getTimerCount(t);
+ uint64_t ns = ticker_ns + counter_us;
+
+ return ns;
+}
+
+#if USE_TCC_TICKER == 0
+void TCC0_Handler()
+#elif USE_TCC_TICKER == 1
+void TCC1_Handler()
+#elif USE_TCC_TICKER == 2
+void TCC2_Handler()
+#endif
+{
+ Tcc *t = TCC_data[USE_TCC_TICKER].tcc_ptr;
+ /*
+ * Overflow means the timer top exeeded
+ */
+ if (t->INTFLAG.bit.OVF == 1) { // A overflow caused the interrupt
+ t->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag
+ // Serial.println("T_OVF");
+
+ /*
+ * reading the count once is needed, otherwise
+ * it will not wrap correct.
+ */
+ getTimerCount(t);
+
+ int bits = TCC_data[USE_TCC_TICKER].nbits;
+ int maxCounts = (uint32_t)(1<<bits);
+
+ ticker_ns += (uint64_t)NS_PER_CLOCK * (uint64_t)maxCounts;
+ }
+ if (t->INTFLAG.bit.MC0 == 1) { // A compare to cc0 caused the interrupt
+ t->INTFLAG.bit.MC0 = 1; // writing a one clears the MCO (match capture) flag
+ // Serial.println("T_MC0");
+ }
+}
+
+/* ----------------- SUPPORT CODE FOR TCC TIMERS----------------------*/
+
+static bool initTimerDone = false;
+
+static void initTimer(Tcc *t)
+{
+
+ /*
+ * enable clock for TCC, see gclk.h
+ * GCLK_CLKCTRL_GEN_GCLK0 for 48 Mhz CPU
+ * GCLK_CLKCTRL_GEN_GCLK1 for 32k extern crystal XOSC32K (ifdef CRYSTALLESS)
+ * GCLK_CLKCTRL_GEN_GCLK1 for 32k internal OSC32K
+ * see Arduino: arduino/hardware/samd/1.6.15/cores/arduino/startup.c
+ * Use TCC_CTRLA_PRESCALER_DIV1024 for for 48 Mhz clock
+ * Use TCC_CTRLA_PRESCALER_DIV2 for 32k clock
+ */
+ if (t == TCC0 || t == TCC1) {
+ REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TCC0_TCC1);
+ } else if (t == TCC2) {
+ REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TCC2_TC3_Val);
+ }
+ while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync
+
+ t->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TCC
+ while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+
+ t->CTRLA.reg |= (TCC_CTRLA_PRESCALER_DIV2 | TCC_CTRLA_RUNSTDBY); // Set perscaler
+
+ t->WAVE.reg |= TCC_WAVE_WAVEGEN_NFRQ; // Set wave form configuration
+ while (t->SYNCBUSY.bit.WAVE == 1); // wait for sync
+
+ t->PER.bit.PER = 0xffffff; // set counter top to max 24 bit
+ while (t->SYNCBUSY.bit.PER == 1); // wait for sync
+
+ // the compare counter TC->CC[0].reg will be set in the startTimer
+ // after the timeout calculation is known.
+
+ // Interrupts
+ t->INTENSET.reg = 0; // disable all interrupts
+ t->INTENSET.bit.OVF = 1; // enable overfollow
+ t->INTENSET.bit.MC0 = 1; // enable compare match to CC0
+
+ const struct TCC_config *cp = &TCC_data[0];
+ while (cp->tcc_ptr) {
+ if (cp->tcc_ptr == t) {
+ NVIC_EnableIRQ(cp->tcc_irq); // Enable InterruptVector
+ break;
+ }
+ cp++;
+ }
+}
+
+#if 0
+// Atmel ASF Code
+static uint32_t getTimerCount(Tcc *t)
+{
+ uint32_t last_cmd;
+ /* Wait last command done */
+ do {
+ while (t->SYNCBUSY.bit.CTRLB); /* Wait for sync */
+
+ last_cmd = t->CTRLBSET.reg & TCC_CTRLBSET_CMD_Msk;
+ if (TCC_CTRLBSET_CMD_NONE == last_cmd) {
+ /* Issue read command and break */
+ t->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val;
+ break;
+ } else if (TCC_CTRLBSET_CMD_READSYNC == last_cmd) {
+ /* Command have been issued */
+ break;
+ }
+ } while (1);
+
+ while (t->SYNCBUSY.bit.COUNT); /* Wait for sync */
+
+ return t->COUNT.reg;
+}
+#endif
+
+
+static uint32_t getTimerCount(Tcc *t)
+{
+
+ noInterrupts();
+
+ while (t->SYNCBUSY.bit.CTRLB); /* Wait for sync */
+
+ t->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val; /* Issue read command and break */
+
+ while (t->SYNCBUSY.bit.COUNT); /* Wait for sync */
+
+ uint32_t count = t->COUNT.reg;
+
+ interrupts();
+
+ return count;
+}
+
+
+static void stopTimer(Tcc *t)
+{
+ t->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
+ while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+}
+
+
+/* ----------------- TIMEOUT TIMER CODE ----------------------*/
+
+static void startTimer(Tcc *t, uint64_t delay_ns)
+{
+ if (!initTimerDone) {
+ initTimer(t); // initial setup with stopped timer
+ initTimerDone = true;
+ }
+
+ stopTimer(t); // avoid timer interrupts while calculating
+
+ /*
+ * every 21333 ns equals one tick (1/(48000000/1024))
+ * COUNT*DIVIDER*SECS until interrupt
+ * 48 Mhz = (65536*1024)/1.398636s
+ */
+ uint64_t nclocks = (uint64_t)delay_ns;
+ nclocks /= (uint64_t)NS_PER_CLOCK;
+ int nCounts = nclocks;
+
+ int bits = TCC_data[USE_TCC_TIMEOUT].nbits;
+ int maxCounts = (uint32_t)(1<<bits)-1;
+
+ if (nCounts > maxCounts) // if count exceeds timer capacity
+ nCounts = maxCounts; // set the largest posible count.
+ if (nCounts <= 0)
+ nCounts = 1;
+ t->CC[0].bit.CC = nCounts;
+ while (t->SYNCBUSY.bit.CC0 == 1); // wait for sync
+
+ t->CTRLA.reg |= TCC_CTRLA_ENABLE ; // Enable TC
+ while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+#if 0
+ Serial.print(ms_getTicker(), DEC);
+ Serial.print(" startTimer: nCounts=");
+ Serial.println(nCounts, DEC);
+#endif
+}
+
+
+#if USE_TCC_TIMEOUT == 0
+void TCC0_Handler()
+#elif USE_TCC_TIMEOUT == 1
+void TCC1_Handler()
+#elif USE_TCC_TIMEOUT == 2
+void TCC2_Handler()
+#endif
+{
+ Tcc *t = TCC_data[USE_TCC_TIMEOUT].tcc_ptr;
+ uint64_t nsecs = ns_getTicker();
+
+ /*
+ * Overflow means the max timer exeeded, we need restart the timer
+ * Interrupts and
+ */
+ if (t->INTFLAG.bit.OVF == 1) { // A overflow caused the interrupt
+ t->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag
+ }
+
+ if (t->INTFLAG.bit.MC0 == 1) { // A compare to cc0 caused the interrupt
+ //Serial.print("MC0\r\n");
+ t->INTFLAG.bit.MC0 = 1; // writing a one clears the MCO (match capture) flag
+ }
+
+ t->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
+ while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer && nsecs >= tvp->timer->_timeout) {
+ Timeout *saveTimer = tvp->timer;
+ tvp->timer = NULL;
+ Timeout::_irq_handler(saveTimer);
+ }
+ }
+ /*
+ * we need to restart the timer for remaining interrupts
+ * Another reason is that we stopped this counter, in case there are
+ * remaining counts, we need to re-schedule the counter.
+ */
+ Timeout::restart();
+}
+
+
+#endif // D21 TCC Timer
+
+void
+Timeout::insert(void)
+{
+ noInterrupts();
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer == NULL) {
+ tvp->timer = this;
+ break;
+ }
+ }
+ interrupts();
+}
+
+void
+Timeout::remove(void)
+{
+ noInterrupts();
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer == this) {
+ tvp->timer = NULL;
+ break;
+ }
+ }
+ interrupts();
+}
+
+
+void
+Timeout::restart()
+{
+ Tcc *t = TCC_data[USE_TCC_TIMEOUT].tcc_ptr;
+ uint64_t timeout = ~0;
+
+ /*
+ * find the lowest timeout value which is our the next timeout
+ * zero means stop the timer.
+ */
+ noInterrupts();
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer) {
+ if (tvp->timer->_timeout < timeout) {
+ timeout = tvp->timer->_timeout;
+ }
+ }
+ }
+ interrupts();
+
+ if (timeout == (uint64_t)~0) {
+ stopTimer(t);
+ return;
+ }
+
+ uint64_t nsecs = ns_getTicker();
+
+ if (timeout > nsecs) {
+ startTimer(t, (uint64_t)timeout - (uint64_t)nsecs);
+ return;
+ } else {
+ startTimer(t, (uint64_t)1); // just one nsec to trigger interrrupt
+ }
+}
+
+/* ----------------- D21 sleep() and deepsleep() code ----------------------*/
+
+void sleep(void)
+{
+#if 1 // (SAMD20 || SAMD21)
+ /* Errata: Make sure that the Flash does not power all the way down
+ * when in sleep mode. */
+ NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val;
+#endif
+ uint32_t saved_ms = ms_getTicker();
+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // disbale SysTick
+
+ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; // clear deep sleep
+ PM->SLEEP.reg = 2; // SYSTEM_SLEEPMODE_IDLE_2 IDLE 2 sleep mode.
+
+ __DSB(); // ensures the completion of memory accesses
+ __WFI(); // wait for interrupt
+
+ int count = ms_getTicker() - saved_ms;
+ if (count > 0) { // update the Arduino Systicks
+ for (int i = 0; i < count; i++) {
+ SysTick_Handler();
+ }
+ }
+ SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // enable SysTick
+}
+
+void deepsleep(void)
+{
+#if 1 // (SAMD20 || SAMD21)
+ /* Errata: Make sure that the Flash does not power all the way down
+ * when in sleep mode. */
+ NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val;
+#endif
+
+ SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // disbale SysTick
+
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // standby mode
+
+ __DSB(); // ensures the completion of memory accesses
+ __WFI(); // wait for interrupt
+
+ SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // enable SysTick
+}
+
+
+#endif // ARDUINO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Arduino-mbed-APIs/arduino-mbed.h Sun Jul 23 16:09:55 2017 +0200
@@ -0,0 +1,305 @@
+/*
+ * The file is Licensed under the Apache License, Version 2.0
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+
+
+#ifdef ARDUINO
+#ifndef __ARDUINO_MBED_H__
+#define __ARDUINO_MBED_H__
+
+#include <arduino.h>
+#include "Callback-A.h"
+#include <SPI.h>
+#undef min
+#undef max
+#undef map
+
+typedef int PinName;
+#define NC -1
+#define wait_ms delay
+/* we need to redefine out dprintf because stdio.h uses the same name */
+#define dprint dxprintf
+
+#if ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606
+ #define MYdigitalPinToInterrupt(x) digitalPinToInterrupt(x)
+#else
+ #define MYdigitalPinToInterrupt(x) (x)
+#endif
+
+
+enum PinMode {
+ PullUp = 1,
+ PullDown = 2,
+};
+
+class DigitalInOut {
+public:
+ DigitalInOut(PinName pin) {
+ _gpioPin = pin;
+ }
+ void write(int value) {
+ digitalWrite(_gpioPin, value == 0 ? LOW : HIGH);
+ };
+
+ void output() {
+ pinMode(_gpioPin, OUTPUT);
+ };
+
+ void input() {
+ pinMode(_gpioPin, INPUT);
+ };
+
+ void mode(PinMode pull) {
+ switch(pull) {
+ case PullUp:
+ pinMode(_gpioPin, INPUT_PULLUP);
+ break;
+ case PullDown:
+ pinMode(_gpioPin, INPUT_PULLDOWN);
+ break;
+ }
+ }
+
+ int read() {
+ if (digitalRead(_gpioPin) == HIGH)
+ return 1;
+ else
+ return 0;
+ };
+ operator int() {
+ return read();
+ };
+
+ DigitalInOut& operator= (int value) {
+ // Underlying write is thread safe
+ write(value);
+ return *this;
+ }
+
+ DigitalInOut& operator= (DigitalInOut& rhs) {
+ write(rhs.read());
+ return *this;
+ }
+
+private:
+ int _gpioPin;
+};
+
+class DigitalOut : public DigitalInOut {
+public:
+
+ DigitalOut(PinName pin) : DigitalInOut(pin) {
+ output();
+ }
+
+ DigitalOut& operator= (int value) {
+ write(value);
+ return *this;
+ }
+
+};
+
+class DigitalIn : public DigitalInOut {
+public:
+
+ DigitalIn(PinName pin) : DigitalInOut(pin) {
+ input();
+ }
+};
+
+class XSPI {
+public:
+ XSPI(PinName mosi, PinName miso, PinName sclk) {
+ _mosi = mosi;
+ _miso = miso;
+ _sclk = sclk;
+ if (mosi == PIN_SPI_MOSI && miso == PIN_SPI_MISO && sclk == PIN_SPI_SCK)
+ _spi = &SPI;
+#if SPI_INTERFACES_COUNT > 1
+ else if (mosi == PIN_SPI1_MOSI && miso == PIN_SPI1_MISO && sclk == PIN_SPI1_SCK)
+ _spi = &SPI1;
+#endif
+#if SPI_INTERFACES_COUNT > 2
+ else if (mosi == PIN_SPI2_MOSI && miso == PIN_SPI2_MISO && sclk == PIN_SPI2_SCK)
+ _spi = &SPI2;
+#endif
+ else {
+ _spi = NULL;
+ return;
+ }
+ _hz = 1000000;
+ _mode = SPI_MODE0;
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ }
+ ~XSPI() {
+ _spi->endTransaction();
+ };
+
+ void format(int bits, int mode = 0) {
+ if (mode == 0)
+ _mode = SPI_MODE0;
+ else if (mode == 1)
+ _mode = SPI_MODE1;
+ else if (mode == 2)
+ _mode = SPI_MODE2;
+ else if (mode == 3)
+ _mode = SPI_MODE3;
+ else
+ _mode = SPI_MODE0;
+ _bits = bits;
+ _spi->endTransaction();
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ }
+ void frequency(int hz) {
+ _hz = hz;
+ _spi->endTransaction();
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ }
+
+ int write(int value) {
+ int ret = _spi->transfer(value);
+ return ret;
+ }
+
+private:
+ SPIClass *_spi;
+ int _hz;
+ int _mode;
+ int _bits;
+ int _mosi, _miso, _sclk;
+};
+
+class InterruptIn {
+public:
+ static void donothing(void) {
+ }
+
+ InterruptIn(PinName pin) : _func() {
+ _gpioPin = pin;
+ _func = InterruptIn::donothing;
+ pinMode(_gpioPin, INPUT);
+ }
+
+ ~InterruptIn() {
+ detachInterrupt(MYdigitalPinToInterrupt(_gpioPin));
+ };
+
+ static void _irq_handler(InterruptIn *id) {
+ if (id)
+ id->_func();
+ }
+
+ void rise(Callback<void()> func);
+
+ void fall(Callback<void()> func);
+
+ void mode(PinMode pull) {
+ switch(pull) {
+ case PullUp:
+ pinMode(_gpioPin, INPUT_PULLUP);
+ break;
+ case PullDown:
+ pinMode(_gpioPin, INPUT_PULLDOWN);
+ break;
+ }
+ }
+private:
+ int _gpioPin;
+ Callback<void()> _func;
+};
+
+extern uint32_t s_getTicker(void);
+extern uint32_t ms_getTicker(void);
+extern uint32_t us_getTicker(void);
+extern uint64_t ns_getTicker(void);
+extern void sleep(void);
+extern void deepsleep(void);
+
+
+class Timer {
+public:
+ void start(void) {
+ _time = ns_getTicker();
+ }
+ uint32_t read_sec(void) {
+ int64_t n = ns_getTicker() - (uint64_t)_time;
+ n /= (uint64_t)1000000000;
+ return n;
+ }
+ uint32_t read_ms(void) {
+ int64_t n = ns_getTicker() - (uint64_t)_time;
+ n /= (uint64_t)1000000;
+ return n;
+ }
+ uint32_t read_us(void) {
+ int64_t n = ns_getTicker() - (uint64_t)_time;
+ n /= (uint64_t)1000;
+ return n;
+ }
+private:
+ uint64_t _time;
+};
+
+
+class Timeout {
+public:
+ Timeout() : _func() {
+ }
+ ~Timeout() {
+ detach();
+ }
+
+ void attach_sec(Callback<void()> func, uint32_t secs) {
+ if (secs == 0)
+ return detach();
+ _func = func;
+ _timeout = ns_getTicker() + (uint64_t)secs * (uint64_t)1000000000;
+ insert();
+ restart();
+ }
+
+ void attach(Callback<void()> func, uint32_t msecs) {
+ if (msecs == 0)
+ return detach();
+ _func = func;
+ _timeout = ns_getTicker() + (uint64_t)msecs * (uint64_t)1000000;
+ insert();
+ restart();
+ }
+
+ void attach_us(Callback<void()> func, long usecs) {
+ if (usecs == 0)
+ return detach();
+ _func = func;
+ _timeout = ns_getTicker() + (uint64_t)usecs * (uint64_t)1000;
+ insert();
+ restart();
+ }
+
+ void detach(void) {
+ _func = NULL;
+ remove();
+ restart();
+ }
+
+ static void _irq_handler(Timeout *tp) {
+ if (tp) {
+ tp->_func();
+ }
+ }
+
+ static void restart(void);
+ uint64_t _timeout; // in ns this lasts for 539 years.
+protected:
+ void insert(void);
+ void remove(void);
+private:
+ Callback<void()> _func;
+};
+
+#endif // __ARDUINO_MBED_H__
+
+#endif // ARDUINO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Arduino-mbed-APIs/library.properties Sun Jul 23 16:09:55 2017 +0200 @@ -0,0 +1,9 @@ +name=Arduino-mbed-APIs +version=1.0 +author=Helmut Tschemernjak <helmut2009@me.com> +maintainer=Helmut Tschemernjak <helmut2009@me.com> +sentence=Arduino-mbed-APIs to support mbed like APIs including Timer, Timeout, SPI, InterruptIn, DigialIn, DigitalOut, DigitalInOut, sleep, deepsleep, it also includes a SAMD TCC based Timer implementation for correct timestamps and timeouts. +paragraph= +category=Kernel +url=http://https://TODO +architectures=samd
--- a/LoRa_TODO.txt Sun Jul 23 15:44:57 2017 +0200 +++ b/LoRa_TODO.txt Sun Jul 23 16:09:55 2017 +0200 @@ -2,7 +2,6 @@ Move finished tasks to Done section: TODOs: -- add support for Arduino - add sx1276-Arduino-hal.h/cpp - add support for Linux - add sx1276-Linux-hal.h/cpp - Add support to provide the send/receive packet buffer, no need to allocate packet data in the sx1276 driver. Can be provided @@ -44,4 +43,4 @@ - Add support for Cad detection before sending a packet, already done in higher level protocols - Added initial Arduino support, needs more testing/completion. - +- Support for Arduino completed, initial version works.
--- a/sx1276/Callback-A.h Sun Jul 23 15:44:57 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,4228 +0,0 @@
-/* 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.
- */
-#ifdef ARDUINO
-
-#ifndef MBED_CALLBACK_H
-#define MBED_CALLBACK_H
-
-
-#include <string.h>
-#include <stdint.h>
-#include <new>
-//#include "platform/mbed_assert.h"
-//#include "platform/mbed_toolchain.h"
-#ifdef ARDUINO
-#undef F
-#endif
-
-// namespace mbed {
-/** \addtogroup platform */
-
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-template <typename F>
-class Callback;
-
-// Internal sfinae declarations
-//
-// These are used to eliminate overloads based on type attributes
-// 1. Does a function object have a call operator
-// 2. Does a function object fit in the available storage
-//
-// These eliminations are handled cleanly by the compiler and avoid
-// massive and misleading error messages when confronted with an
-// invalid type (or worse, runtime failures)
-namespace detail {
- struct nil {};
-
- template <bool B, typename R = nil>
- struct enable_if { typedef R type; };
-
- template <typename R>
- struct enable_if<false, R> {};
-
- template <typename M, M>
- struct is_type {
- static const bool value = true;
- };
-}
-
-#define MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M) \
- typename detail::enable_if< \
- detail::is_type<M, &F::operator()>::value && \
- sizeof(F) <= sizeof(uintptr_t) \
- >::type = detail::nil()
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-template <typename R>
-class Callback<R()> {
-public:
- /** Create a Callback with a static function
- * @param func Static function to attach
- */
- Callback(R (*func)() = 0) {
- if (!func) {
- _ops = 0;
- } else {
- generate(func);
- }
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- */
- Callback(const Callback<R()> &func) {
- if (func._ops) {
- func._ops->move(this, &func);
- }
- _ops = func._ops;
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(U *obj, R (T::*method)()) {
- generate(method_context<T, R (T::*)()>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const U *obj, R (T::*method)() const) {
- generate(method_context<const T, R (T::*)() const>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (T::*method)() volatile) {
- generate(method_context<volatile T, R (T::*)() volatile>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (T::*method)() const volatile) {
- generate(method_context<const volatile T, R (T::*)() const volatile>(obj, method));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(T*), U *arg) {
- generate(function_context<R (*)(T*), T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const T*), const U *arg) {
- generate(function_context<R (*)(const T*), const T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(volatile T*), volatile U *arg) {
- generate(function_context<R (*)(volatile T*), volatile T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const volatile T*), const volatile U *arg) {
- generate(function_context<R (*)(const volatile T*), const volatile T>(func, arg));
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
- generate(f);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(U *obj, R (*func)(T*)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const U *obj, R (*func)(const T*)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (*func)(volatile T*)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (*func)(const volatile T*)) {
- new (this) Callback(func, obj);
- }
-
- /** Destroy a callback
- */
- ~Callback() {
- if (_ops) {
- _ops->dtor(this);
- }
- }
-
- /** Attach a static function
- * @param func Static function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(R (*func)()) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(const Callback<R()> &func) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(U *obj, R (T::*method)()) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const U *obj, R (T::*method)() const) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(volatile U *obj, R (T::*method)() volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const volatile U *obj, R (T::*method)() const volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(T*), U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const T*), const U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(volatile T*), volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const volatile T*), const volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(U *obj, R (*func)(T*)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const U *obj, R (*func)(const T*)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(volatile U *obj, R (*func)(volatile T*)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const volatile U *obj, R (*func)(const volatile T*)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Assign a callback
- */
- Callback &operator=(const Callback &that) {
- if (this != &that) {
- this->~Callback();
- new (this) Callback(that);
- }
-
- return *this;
- }
-
- /** Call the attached function
- */
- R call() const {
- return _ops->call(this);
- }
-
- /** Call the attached function
- */
- R operator()() const {
- return call();
- }
-
- /** Test if function has been attached
- */
- operator bool() const {
- return _ops;
- }
-
- /** 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
- * @return the value as determined by func which is of
- * type and determined by the signiture of func
- */
- static R thunk(void *func) {
- return static_cast<Callback*>(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;
-
- // Dynamically dispatched operations
- const struct ops {
- R (*call)(const void*);
- void (*move)(void*, const void*);
- void (*dtor)(void*);
- } *_ops;
-
-
- // Generate operations for function object
- template <typename F>
- void generate(const F &f) {
- static const ops ops = {
- &Callback::function_call<F>,
- &Callback::function_move<F>,
- &Callback::function_dtor<F>,
- };
- //MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
- // "Type F must not exceed the size of the Callback class");
- new (this) F(f);
- _ops = &ops;
- }
-
- // Function attributes
- template <typename F>
- static R function_call(const void *p) {
- return (*(F*)p)();
- }
-
- template <typename F>
- static void function_move(void *d, const void *p) {
- new (d) F(*(F*)p);
- }
-
- template <typename F>
- static void function_dtor(void *p) {
- ((F*)p)->~F();
- }
-
- // Wrappers for functions with context
- template <typename O, typename M>
- struct method_context {
- M method;
- O *obj;
-
- method_context(O *obj, M method)
- : method(method), obj(obj) {}
-
- R operator()() const {
- return (obj->*method)();
- }
- };
-
- template <typename F, typename A>
- struct function_context {
- F func;
- A *arg;
-
- function_context(F func, A *arg)
- : func(func), arg(arg) {}
-
- R operator()() const {
- return func(arg);
- }
- };
-};
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-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) {
- if (!func) {
- _ops = 0;
- } else {
- generate(func);
- }
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- */
- Callback(const Callback<R(A0)> &func) {
- if (func._ops) {
- func._ops->move(this, &func);
- }
- _ops = func._ops;
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(U *obj, R (T::*method)(A0)) {
- generate(method_context<T, R (T::*)(A0)>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const U *obj, R (T::*method)(A0) const) {
- generate(method_context<const T, R (T::*)(A0) const>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (T::*method)(A0) volatile) {
- generate(method_context<volatile T, R (T::*)(A0) volatile>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
- generate(method_context<const volatile T, R (T::*)(A0) const volatile>(obj, method));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(T*, A0), U *arg) {
- generate(function_context<R (*)(T*, A0), T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const T*, A0), const U *arg) {
- generate(function_context<R (*)(const T*, A0), const T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(volatile T*, A0), volatile U *arg) {
- generate(function_context<R (*)(volatile T*, A0), volatile T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
- generate(function_context<R (*)(const volatile T*, A0), const volatile T>(func, arg));
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
- generate(f);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(U *obj, R (*func)(T*, A0)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const U *obj, R (*func)(const T*, A0)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (*func)(volatile T*, A0)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
- new (this) Callback(func, obj);
- }
-
- /** Destroy a callback
- */
- ~Callback() {
- if (_ops) {
- _ops->dtor(this);
- }
- }
-
- /** Attach a static function
- * @param func Static function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(R (*func)(A0)) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(const Callback<R(A0)> &func) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(U *obj, R (T::*method)(A0)) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const U *obj, R (T::*method)(A0) const) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(volatile U *obj, R (T::*method)(A0) volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const volatile U *obj, R (T::*method)(A0) const volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(T*, A0), U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const T*, A0), const U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(volatile T*, A0), volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const volatile T*, A0), const volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(U *obj, R (*func)(T*, A0)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const U *obj, R (*func)(const T*, A0)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(volatile U *obj, R (*func)(volatile T*, A0)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const volatile U *obj, R (*func)(const volatile T*, A0)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Assign a callback
- */
- Callback &operator=(const Callback &that) {
- if (this != &that) {
- this->~Callback();
- new (this) Callback(that);
- }
-
- return *this;
- }
-
- /** Call the attached function
- */
- R call(A0 a0) const {
- MBED_ASSERT(_ops);
- return _ops->call(this, a0);
- }
-
- /** Call the attached function
- */
- R operator()(A0 a0) const {
- return call(a0);
- }
-
- /** Test if function has been attached
- */
- operator bool() const {
- return _ops;
- }
-
- /** 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
- * @param a0 An argument to be called with function func
- * @return the value as determined by func which is of
- * type and determined by the signiture of func
- */
- static R thunk(void *func, A0 a0) {
- return static_cast<Callback*>(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)(A0);
- void (*_boundfunc)(_class*, A0);
- void (_class::*_methodfunc)(A0);
- } _func;
- void *_obj;
-
- // Dynamically dispatched operations
- const struct ops {
- R (*call)(const void*, A0);
- void (*move)(void*, const void*);
- void (*dtor)(void*);
- } *_ops;
-
- // Generate operations for function object
- template <typename F>
- void generate(const F &f) {
- static const ops ops = {
- &Callback::function_call<F>,
- &Callback::function_move<F>,
- &Callback::function_dtor<F>,
- };
- new (this) F(f);
- _ops = &ops;
- }
-
- // Function attributes
- template <typename F>
- static R function_call(const void *p, A0 a0) {
- return (*(F*)p)(a0);
- }
-
- template <typename F>
- static void function_move(void *d, const void *p) {
- new (d) F(*(F*)p);
- }
-
- template <typename F>
- static void function_dtor(void *p) {
- ((F*)p)->~F();
- }
-
- // Wrappers for functions with context
- template <typename O, typename M>
- struct method_context {
- M method;
- O *obj;
-
- method_context(O *obj, M method)
- : method(method), obj(obj) {}
-
- R operator()(A0 a0) const {
- return (obj->*method)(a0);
- }
- };
-
- template <typename F, typename A>
- struct function_context {
- F func;
- A *arg;
-
- function_context(F func, A *arg)
- : func(func), arg(arg) {}
-
- R operator()(A0 a0) const {
- return func(arg, a0);
- }
- };
-};
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-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) {
- if (!func) {
- _ops = 0;
- } else {
- generate(func);
- }
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- */
- Callback(const Callback<R(A0, A1)> &func) {
- if (func._ops) {
- func._ops->move(this, &func);
- }
- _ops = func._ops;
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(U *obj, R (T::*method)(A0, A1)) {
- generate(method_context<T, R (T::*)(A0, A1)>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const U *obj, R (T::*method)(A0, A1) const) {
- generate(method_context<const T, R (T::*)(A0, A1) const>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
- generate(method_context<volatile T, R (T::*)(A0, A1) volatile>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
- generate(method_context<const volatile T, R (T::*)(A0, A1) const volatile>(obj, method));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(T*, A0, A1), U *arg) {
- generate(function_context<R (*)(T*, A0, A1), T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const T*, A0, A1), const U *arg) {
- generate(function_context<R (*)(const T*, A0, A1), const T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
- generate(function_context<R (*)(volatile T*, A0, A1), volatile T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
- generate(function_context<R (*)(const volatile T*, A0, A1), const volatile T>(func, arg));
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
- generate(f);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(U *obj, R (*func)(T*, A0, A1)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const U *obj, R (*func)(const T*, A0, A1)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
- new (this) Callback(func, obj);
- }
-
- /** Destroy a callback
- */
- ~Callback() {
- if (_ops) {
- _ops->dtor(this);
- }
- }
-
- /** Attach a static function
- * @param func Static function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(R (*func)(A0, A1)) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(const Callback<R(A0, A1)> &func) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(U *obj, R (T::*method)(A0, A1)) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const U *obj, R (T::*method)(A0, A1) const) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(volatile U *obj, R (T::*method)(A0, A1) volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(T*, A0, A1), U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const T*, A0, A1), const U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(volatile T*, A0, A1), volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(U *obj, R (*func)(T*, A0, A1)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const U *obj, R (*func)(const T*, A0, A1)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Assign a callback
- */
- Callback &operator=(const Callback &that) {
- if (this != &that) {
- this->~Callback();
- new (this) Callback(that);
- }
-
- return *this;
- }
-
- /** Call the attached function
- */
- R call(A0 a0, A1 a1) const {
- MBED_ASSERT(_ops);
- return _ops->call(this, 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 _ops;
- }
-
- /** 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
- * @param a0 An argument to be called with function func
- * @param a1 An argument to be called with function func
- * @return the value as determined by func which is of
- * type and determined by the signiture of func
- */
- static R thunk(void *func, A0 a0, A1 a1) {
- return static_cast<Callback*>(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)(A0, A1);
- void (*_boundfunc)(_class*, A0, A1);
- void (_class::*_methodfunc)(A0, A1);
- } _func;
- void *_obj;
-
- // Dynamically dispatched operations
- const struct ops {
- R (*call)(const void*, A0, A1);
- void (*move)(void*, const void*);
- void (*dtor)(void*);
- } *_ops;
-
- // Generate operations for function object
- template <typename F>
- void generate(const F &f) {
- static const ops ops = {
- &Callback::function_call<F>,
- &Callback::function_move<F>,
- &Callback::function_dtor<F>,
- };
- new (this) F(f);
- _ops = &ops;
- }
-
- // Function attributes
- template <typename F>
- static R function_call(const void *p, A0 a0, A1 a1) {
- return (*(F*)p)(a0, a1);
- }
-
- template <typename F>
- static void function_move(void *d, const void *p) {
- new (d) F(*(F*)p);
- }
-
- template <typename F>
- static void function_dtor(void *p) {
- ((F*)p)->~F();
- }
-
- // Wrappers for functions with context
- template <typename O, typename M>
- struct method_context {
- M method;
- O *obj;
-
- method_context(O *obj, M method)
- : method(method), obj(obj) {}
-
- R operator()(A0 a0, A1 a1) const {
- return (obj->*method)(a0, a1);
- }
- };
-
- template <typename F, typename A>
- struct function_context {
- F func;
- A *arg;
-
- function_context(F func, A *arg)
- : func(func), arg(arg) {}
-
- R operator()(A0 a0, A1 a1) const {
- return func(arg, a0, a1);
- }
- };
-};
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-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) {
- if (!func) {
- _ops = 0;
- } else {
- generate(func);
- }
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- */
- Callback(const Callback<R(A0, A1, A2)> &func) {
- if (func._ops) {
- func._ops->move(this, &func);
- }
- _ops = func._ops;
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(U *obj, R (T::*method)(A0, A1, A2)) {
- generate(method_context<T, R (T::*)(A0, A1, A2)>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
- generate(method_context<const T, R (T::*)(A0, A1, A2) const>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
- generate(method_context<volatile T, R (T::*)(A0, A1, A2) volatile>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
- generate(method_context<const volatile T, R (T::*)(A0, A1, A2) const volatile>(obj, method));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(T*, A0, A1, A2), U *arg) {
- generate(function_context<R (*)(T*, A0, A1, A2), T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
- generate(function_context<R (*)(const T*, A0, A1, A2), const T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
- generate(function_context<R (*)(volatile T*, A0, A1, A2), volatile T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
- generate(function_context<R (*)(const volatile T*, A0, A1, A2), const volatile T>(func, arg));
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
- generate(f);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(U *obj, R (*func)(T*, A0, A1, A2)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
- new (this) Callback(func, obj);
- }
-
- /** Destroy a callback
- */
- ~Callback() {
- if (_ops) {
- _ops->dtor(this);
- }
- }
-
- /** Attach a static function
- * @param func Static function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(R (*func)(A0, A1, A2)) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(const Callback<R(A0, A1, A2)> &func) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(U *obj, R (T::*method)(A0, A1, A2)) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const U *obj, R (T::*method)(A0, A1, A2) const) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(T*, A0, A1, A2), U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const T*, A0, A1, A2), const U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(U *obj, R (*func)(T*, A0, A1, A2)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const U *obj, R (*func)(const T*, A0, A1, A2)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Assign a callback
- */
- Callback &operator=(const Callback &that) {
- if (this != &that) {
- this->~Callback();
- new (this) Callback(that);
- }
-
- return *this;
- }
-
- /** Call the attached function
- */
- R call(A0 a0, A1 a1, A2 a2) const {
- MBED_ASSERT(_ops);
- return _ops->call(this, 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 _ops;
- }
-
- /** 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
- * @param a0 An argument to be called with function func
- * @param a1 An argument to be called with function func
- * @param a2 An argument to be called with function func
- * @return the value as determined by func which is of
- * type and determined by the signiture of func
- */
- static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
- return static_cast<Callback*>(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)(A0, A1, A2);
- void (*_boundfunc)(_class*, A0, A1, A2);
- void (_class::*_methodfunc)(A0, A1, A2);
- } _func;
- void *_obj;
-
- // Dynamically dispatched operations
- const struct ops {
- R (*call)(const void*, A0, A1, A2);
- void (*move)(void*, const void*);
- void (*dtor)(void*);
- } *_ops;
-
- // Generate operations for function object
- template <typename F>
- void generate(const F &f) {
- static const ops ops = {
- &Callback::function_call<F>,
- &Callback::function_move<F>,
- &Callback::function_dtor<F>,
- };
-
- new (this) F(f);
- _ops = &ops;
- }
-
- // Function attributes
- template <typename F>
- static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
- return (*(F*)p)(a0, a1, a2);
- }
-
- template <typename F>
- static void function_move(void *d, const void *p) {
- new (d) F(*(F*)p);
- }
-
- template <typename F>
- static void function_dtor(void *p) {
- ((F*)p)->~F();
- }
-
- // Wrappers for functions with context
- template <typename O, typename M>
- struct method_context {
- M method;
- O *obj;
-
- method_context(O *obj, M method)
- : method(method), obj(obj) {}
-
- R operator()(A0 a0, A1 a1, A2 a2) const {
- return (obj->*method)(a0, a1, a2);
- }
- };
-
- template <typename F, typename A>
- struct function_context {
- F func;
- A *arg;
-
- function_context(F func, A *arg)
- : func(func), arg(arg) {}
-
- R operator()(A0 a0, A1 a1, A2 a2) const {
- return func(arg, a0, a1, a2);
- }
- };
-};
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-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) {
- if (!func) {
- _ops = 0;
- } else {
- generate(func);
- }
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- */
- Callback(const Callback<R(A0, A1, A2, A3)> &func) {
- if (func._ops) {
- func._ops->move(this, &func);
- }
- _ops = func._ops;
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
- generate(method_context<T, R (T::*)(A0, A1, A2, A3)>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
- generate(method_context<const T, R (T::*)(A0, A1, A2, A3) const>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
- generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3) volatile>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
- generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3) const volatile>(obj, method));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
- generate(function_context<R (*)(T*, A0, A1, A2, A3), T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
- generate(function_context<R (*)(const T*, A0, A1, A2, A3), const T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
- generate(function_context<R (*)(volatile T*, A0, A1, A2, A3), volatile T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
- generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3), const volatile T>(func, arg));
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
- generate(f);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
- new (this) Callback(func, obj);
- }
-
- /** Destroy a callback
- */
- ~Callback() {
- if (_ops) {
- _ops->dtor(this);
- }
- }
-
- /** Attach a static function
- * @param func Static function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(R (*func)(A0, A1, A2, A3)) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(const Callback<R(A0, A1, A2, A3)> &func) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(U *obj, R (T::*method)(A0, A1, A2, A3)) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(T*, A0, A1, A2, A3), U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Assign a callback
- */
- Callback &operator=(const Callback &that) {
- if (this != &that) {
- this->~Callback();
- new (this) Callback(that);
- }
-
- return *this;
- }
-
- /** Call the attached function
- */
- R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
- MBED_ASSERT(_ops);
- return _ops->call(this, 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 _ops;
- }
-
- /** 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
- * @param a0 An argument to be called with function func
- * @param a1 An argument to be called with function func
- * @param a2 An argument to be called with function func
- * @param a3 An argument to be called with function func
- * @return the value as determined by func which is of
- * type and determined by the signiture of func
- */
- static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
- return static_cast<Callback*>(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)(A0, A1, A2, A3);
- void (*_boundfunc)(_class*, A0, A1, A2, A3);
- void (_class::*_methodfunc)(A0, A1, A2, A3);
- } _func;
- void *_obj;
-
- // Dynamically dispatched operations
- const struct ops {
- R (*call)(const void*, A0, A1, A2, A3);
- void (*move)(void*, const void*);
- void (*dtor)(void*);
- } *_ops;
-
- // Generate operations for function object
- template <typename F>
- void generate(const F &f) {
- static const ops ops = {
- &Callback::function_call<F>,
- &Callback::function_move<F>,
- &Callback::function_dtor<F>,
- };
-
- new (this) F(f);
- _ops = &ops;
- }
-
- // Function attributes
- template <typename F>
- static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
- return (*(F*)p)(a0, a1, a2, a3);
- }
-
- template <typename F>
- static void function_move(void *d, const void *p) {
- new (d) F(*(F*)p);
- }
-
- template <typename F>
- static void function_dtor(void *p) {
- ((F*)p)->~F();
- }
-
- // Wrappers for functions with context
- template <typename O, typename M>
- struct method_context {
- M method;
- O *obj;
-
- method_context(O *obj, M method)
- : method(method), obj(obj) {}
-
- R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
- return (obj->*method)(a0, a1, a2, a3);
- }
- };
-
- template <typename F, typename A>
- struct function_context {
- F func;
- A *arg;
-
- function_context(F func, A *arg)
- : func(func), arg(arg) {}
-
- R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
- return func(arg, a0, a1, a2, a3);
- }
- };
-};
-
-/** Callback class based on template specialization
- *
- * @note Synchronization level: Not protected
- * @ingroup platform
- */
-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) {
- if (!func) {
- _ops = 0;
- } else {
- generate(func);
- }
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- */
- Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
- if (func._ops) {
- func._ops->move(this, &func);
- }
- _ops = func._ops;
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
- generate(method_context<T, R (T::*)(A0, A1, A2, A3, A4)>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
- generate(method_context<const T, R (T::*)(A0, A1, A2, A3, A4) const>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
- generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
- }
-
- /** Create a Callback with a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
- generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
- generate(function_context<R (*)(T*, A0, A1, A2, A3, A4), T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
- generate(function_context<R (*)(const T*, A0, A1, A2, A3, A4), const T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
- generate(function_context<R (*)(volatile T*, A0, A1, A2, A3, A4), volatile T>(func, arg));
- }
-
- /** Create a Callback with a static function and bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- */
- template<typename T, typename U>
- Callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
- generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3, A4), const volatile T>(func, arg));
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
- generate(f);
- }
-
- /** Create a Callback with a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- */
- template <typename F>
- Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
- generate(f);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
- new (this) Callback(func, obj);
- }
-
- /** 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
- * @deprecated
- * Arguments to callback have been reordered to Callback(func, arg)
- */
- template<typename T, typename U>
- Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
- new (this) Callback(func, obj);
- }
-
- /** Destroy a callback
- */
- ~Callback() {
- if (_ops) {
- _ops->dtor(this);
- }
- }
-
- /** Attach a static function
- * @param func Static function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(R (*func)(A0, A1, A2, A3, A4)) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a Callback
- * @param func The Callback to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
- this->~Callback();
- new (this) Callback(func);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a member function
- * @param obj Pointer to object to invoke member function on
- * @param method Member function to attach
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template<typename T, typename U>
- void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
- this->~Callback();
- new (this) Callback(obj, method);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a static function with a bound pointer
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename T, typename U>
- void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
- this->~Callback();
- new (this) Callback(func, arg);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a function object
- * @param f Function object to attach
- * @note The function object is limited to a single word of storage
- * @deprecated
- * Replaced by simple assignment 'Callback cb = func'
- */
- template <typename F>
- void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
- this->~Callback();
- new (this) Callback(f);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Attach a static function with a bound pointer
- * @param obj Pointer to object to bind to function
- * @param func Static function to attach
- * @deprecated
- * Arguments to callback have been reordered to attach(func, arg)
- */
- template <typename T, typename U>
- void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
- this->~Callback();
- new (this) Callback(func, obj);
- }
-
- /** Assign a callback
- */
- Callback &operator=(const Callback &that) {
- if (this != &that) {
- this->~Callback();
- new (this) Callback(that);
- }
-
- return *this;
- }
-
- /** Call the attached function
- */
- R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
- MBED_ASSERT(_ops);
- return _ops->call(this, 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 _ops;
- }
-
- /** 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
- * @param a0 An argument to be called with function func
- * @param a1 An argument to be called with function func
- * @param a2 An argument to be called with function func
- * @param a3 An argument to be called with function func
- * @param a4 An argument to be called with function func
- * @return the value as determined by func which is of
- * type and determined by the signiture of func
- */
- static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
- return static_cast<Callback*>(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)(A0, A1, A2, A3, A4);
- void (*_boundfunc)(_class*, A0, A1, A2, A3, A4);
- void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
- } _func;
- void *_obj;
-
- // Dynamically dispatched operations
- const struct ops {
- R (*call)(const void*, A0, A1, A2, A3, A4);
- void (*move)(void*, const void*);
- void (*dtor)(void*);
- } *_ops;
-
- // Generate operations for function object
- template <typename F>
- void generate(const F &f) {
- static const ops ops = {
- &Callback::function_call<F>,
- &Callback::function_move<F>,
- &Callback::function_dtor<F>,
- };
-
- new (this) F(f);
- _ops = &ops;
- }
-
- // Function attributes
- template <typename F>
- static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
- return (*(F*)p)(a0, a1, a2, a3, a4);
- }
-
- template <typename F>
- static void function_move(void *d, const void *p) {
- new (d) F(*(F*)p);
- }
-
- template <typename F>
- static void function_dtor(void *p) {
- ((F*)p)->~F();
- }
-
- // Wrappers for functions with context
- template <typename O, typename M>
- struct method_context {
- M method;
- O *obj;
-
- method_context(O *obj, M method)
- : method(method), obj(obj) {}
-
- R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
- return (obj->*method)(a0, a1, a2, a3, a4);
- }
- };
-
- template <typename F, typename A>
- struct function_context {
- F func;
- A *arg;
-
- function_context(F func, A *arg)
- : func(func), arg(arg) {}
-
- R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
- return func(arg, a0, a1, a2, a3, a4);
- }
- };
-};
-
-// Internally used event type
-typedef Callback<void(int)> 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 <typename R>
-Callback<R()> callback(R (*func)() = 0) {
- return Callback<R()>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R>
-Callback<R()> callback(const Callback<R()> &func) {
- return Callback<R()>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R>
-Callback<R()> callback(U *obj, R (T::*method)()) {
- return Callback<R()>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R>
-Callback<R()> callback(const U *obj, R (T::*method)() const) {
- return Callback<R()>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R>
-Callback<R()> callback(volatile U *obj, R (T::*method)() volatile) {
- return Callback<R()>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R>
-Callback<R()> callback(const volatile U *obj, R (T::*method)() const volatile) {
- return Callback<R()>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(R (*func)(T*), U *arg) {
- return Callback<R()>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(R (*func)(const T*), const U *arg) {
- return Callback<R()>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(R (*func)(volatile T*), volatile U *arg) {
- return Callback<R()>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(R (*func)(const volatile T*), const volatile U *arg) {
- return Callback<R()>(func, arg);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(U *obj, R (*func)(T*)) {
- return Callback<R()>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(const U *obj, R (*func)(const T*)) {
- return Callback<R()>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(volatile U *obj, R (*func)(volatile T*)) {
- return Callback<R()>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R>
-Callback<R()> callback(const volatile U *obj, R (*func)(const volatile T*)) {
- return Callback<R()>(func, obj);
-}
-
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0>
-Callback<R(A0)> callback(R (*func)(A0) = 0) {
- return Callback<R(A0)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0>
-Callback<R(A0)> callback(const Callback<R(A0)> &func) {
- return Callback<R(A0)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(U *obj, R (T::*method)(A0)) {
- return Callback<R(A0)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(const U *obj, R (T::*method)(A0) const) {
- return Callback<R(A0)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(volatile U *obj, R (T::*method)(A0) volatile) {
- return Callback<R(A0)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
- return Callback<R(A0)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(R (*func)(T*, A0), U *arg) {
- return Callback<R(A0)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(R (*func)(const T*, A0), const U *arg) {
- return Callback<R(A0)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(R (*func)(volatile T*, A0), volatile U *arg) {
- return Callback<R(A0)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
- return Callback<R(A0)>(func, arg);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(U *obj, R (*func)(T*, A0)) {
- return Callback<R(A0)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(const U *obj, R (*func)(const T*, A0)) {
- return Callback<R(A0)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(volatile U *obj, R (*func)(volatile T*, A0)) {
- return Callback<R(A0)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0>
-Callback<R(A0)> callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
- return Callback<R(A0)>(func, obj);
-}
-
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
- return Callback<R(A0, A1)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
- return Callback<R(A0, A1)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(U *obj, R (T::*method)(A0, A1)) {
- return Callback<R(A0, A1)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(const U *obj, R (T::*method)(A0, A1) const) {
- return Callback<R(A0, A1)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
- return Callback<R(A0, A1)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
- return Callback<R(A0, A1)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(R (*func)(T*, A0, A1), U *arg) {
- return Callback<R(A0, A1)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(R (*func)(const T*, A0, A1), const U *arg) {
- return Callback<R(A0, A1)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
- return Callback<R(A0, A1)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
- return Callback<R(A0, A1)>(func, arg);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(U *obj, R (*func)(T*, A0, A1)) {
- return Callback<R(A0, A1)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(const U *obj, R (*func)(const T*, A0, A1)) {
- return Callback<R(A0, A1)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
- return Callback<R(A0, A1)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1>
-Callback<R(A0, A1)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
- return Callback<R(A0, A1)>(func, obj);
-}
-
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
- return Callback<R(A0, A1, A2)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
- return Callback<R(A0, A1, A2)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(U *obj, R (T::*method)(A0, A1, A2)) {
- return Callback<R(A0, A1, A2)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
- return Callback<R(A0, A1, A2)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
- return Callback<R(A0, A1, A2)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
- return Callback<R(A0, A1, A2)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(R (*func)(T*, A0, A1, A2), U *arg) {
- return Callback<R(A0, A1, A2)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
- return Callback<R(A0, A1, A2)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
- return Callback<R(A0, A1, A2)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
- return Callback<R(A0, A1, A2)>(func, arg);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(U *obj, R (*func)(T*, A0, A1, A2)) {
- return Callback<R(A0, A1, A2)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
- return Callback<R(A0, A1, A2)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
- return Callback<R(A0, A1, A2)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
-Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
- return Callback<R(A0, A1, A2)>(func, obj);
-}
-
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
- return Callback<R(A0, A1, A2, A3)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
- return Callback<R(A0, A1, A2, A3)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
- return Callback<R(A0, A1, A2, A3)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
- return Callback<R(A0, A1, A2, A3)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
- return Callback<R(A0, A1, A2, A3)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
- return Callback<R(A0, A1, A2, A3)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
- return Callback<R(A0, A1, A2, A3)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
- return Callback<R(A0, A1, A2, A3)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
- return Callback<R(A0, A1, A2, A3)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
- return Callback<R(A0, A1, A2, A3)>(func, arg);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
- return Callback<R(A0, A1, A2, A3)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
- return Callback<R(A0, A1, A2, A3)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
- return Callback<R(A0, A1, A2, A3)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
-Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
- return Callback<R(A0, A1, A2, A3)>(func, obj);
-}
-
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
- return Callback<R(A0, A1, A2, A3, A4)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @return Callback with infered type
- */
-template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
- return Callback<R(A0, A1, A2, A3, A4)>(func);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
- return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
- return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
- return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param obj Optional pointer to object to bind to function
- * @param method Member function to attach
- * @return Callback with infered type
- */
-template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
- return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
-}
-
-/** Create a callback class with type infered from the arguments
- *
- * @param func Static function to attach
- * @param arg Pointer argument to function
- * @return Callback with infered type
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
-}
-
-/** 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
- * @deprecated
- * Arguments to callback have been reordered to callback(func, arg)
- */
-template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
-Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
- return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
-}
-
-
-// } // namespace mbed
-
-#endif
-#endif // Arduino
--- a/sx1276/arduino-mbed.cpp Sun Jul 23 15:44:57 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,667 +0,0 @@
-/*
- * The file is Licensed under the Apache License, Version 2.0
- * (c) 2017 Helmut Tschemernjak
- * 30826 Garbsen (Hannover) Germany
- */
-
-#ifdef ARDUINO
-
-using namespace std;
-
-#include "arduino-mbed.h"
-
-
-static void pinInt00(void);
-static void pinInt01(void);
-static void pinInt02(void);
-static void pinInt03(void);
-static void pinInt04(void);
-static void pinInt05(void);
-static void pinInt06(void);
-static void pinInt07(void);
-static void pinInt08(void);
-static void pinInt09(void);
-static void pinInt10(void);
-static void pinInt11(void);
-static void pinInt12(void);
-static void pinInt13(void);
-static void pinInt14(void);
-static void pinInt15(void);
-static void pinInt16(void);
-static void pinInt17(void);
-static void pinInt18(void);
-static void pinInt19(void);
-static void pinInt20(void);
-static void pinInt21(void);
-static void pinInt22(void);
-static void pinInt23(void);
-static void pinInt24(void);
-static void pinInt25(void);
-static void pinInt26(void);
-static void pinInt27(void);
-static void pinInt28(void);
-static void pinInt29(void);
-static void pinInt30(void);
-static void pinInt31(void);
-static void pinInt32(void);
-static void pinInt33(void);
-static void pinInt34(void);
-static void pinInt35(void);
-static void pinInt36(void);
-static void pinInt37(void);
-static void pinInt38(void);
-static void pinInt39(void);
-static void pinInt40(void);
-static void pinInt41(void);
-static void pinInt42(void);
-static void pinInt43(void);
-static void pinInt44(void);
-static void pinInt45(void);
-static void pinInt46(void);
-static void pinInt47(void);
-
-
-
-#define MAX_MCU_PINS 48
-class InterruptIn;
-struct intPtrTable {
- void (*func)(void);
- InterruptIn *context;
-} intPtrTable[MAX_MCU_PINS] = {
- { pinInt00, NULL },
- { pinInt01, NULL },
- { pinInt02, NULL },
- { pinInt03, NULL },
- { pinInt04, NULL },
- { pinInt05, NULL },
- { pinInt06, NULL },
- { pinInt07, NULL },
- { pinInt08, NULL },
- { pinInt09, NULL },
- { pinInt10, NULL },
- { pinInt11, NULL },
- { pinInt12, NULL },
- { pinInt13, NULL },
- { pinInt14, NULL },
- { pinInt15, NULL },
- { pinInt16, NULL },
- { pinInt17, NULL },
- { pinInt18, NULL },
- { pinInt19, NULL },
- { pinInt20, NULL },
- { pinInt21, NULL },
- { pinInt22, NULL },
- { pinInt23, NULL },
- { pinInt24, NULL },
- { pinInt25, NULL },
- { pinInt26, NULL },
- { pinInt27, NULL },
- { pinInt28, NULL },
- { pinInt29, NULL },
- { pinInt30, NULL },
- { pinInt31, NULL },
- { pinInt32, NULL },
- { pinInt33, NULL },
- { pinInt34, NULL },
- { pinInt35, NULL },
- { pinInt36, NULL },
- { pinInt37, NULL },
- { pinInt38, NULL },
- { pinInt39, NULL },
- { pinInt40, NULL },
- { pinInt41, NULL },
- { pinInt42, NULL },
- { pinInt43, NULL },
- { pinInt44, NULL },
- { pinInt45, NULL },
- { pinInt46, NULL },
- { pinInt47, NULL }
-}; // our max MCUs pins
-
-
-
-static void pinInt00(void) { InterruptIn::_irq_handler(intPtrTable[0].context); }
-static void pinInt01(void) { InterruptIn::_irq_handler(intPtrTable[1].context); }
-static void pinInt02(void) { InterruptIn::_irq_handler(intPtrTable[2].context); }
-static void pinInt03(void) { InterruptIn::_irq_handler(intPtrTable[3].context); }
-static void pinInt04(void) { InterruptIn::_irq_handler(intPtrTable[4].context); }
-static void pinInt05(void) { InterruptIn::_irq_handler(intPtrTable[5].context); }
-static void pinInt06(void) { InterruptIn::_irq_handler(intPtrTable[6].context); }
-static void pinInt07(void) { InterruptIn::_irq_handler(intPtrTable[7].context); }
-static void pinInt08(void) { InterruptIn::_irq_handler(intPtrTable[8].context); }
-static void pinInt09(void) { InterruptIn::_irq_handler(intPtrTable[9].context); }
-static void pinInt10(void) { InterruptIn::_irq_handler(intPtrTable[10].context); }
-static void pinInt11(void) { InterruptIn::_irq_handler(intPtrTable[11].context); }
-static void pinInt12(void) { InterruptIn::_irq_handler(intPtrTable[12].context); }
-static void pinInt13(void) { InterruptIn::_irq_handler(intPtrTable[13].context); }
-static void pinInt14(void) { InterruptIn::_irq_handler(intPtrTable[14].context); }
-static void pinInt15(void) { InterruptIn::_irq_handler(intPtrTable[15].context); }
-static void pinInt16(void) { InterruptIn::_irq_handler(intPtrTable[16].context); }
-static void pinInt17(void) { InterruptIn::_irq_handler(intPtrTable[17].context); }
-static void pinInt18(void) { InterruptIn::_irq_handler(intPtrTable[18].context); }
-static void pinInt19(void) { InterruptIn::_irq_handler(intPtrTable[19].context); }
-static void pinInt20(void) { InterruptIn::_irq_handler(intPtrTable[20].context); }
-static void pinInt21(void) { InterruptIn::_irq_handler(intPtrTable[21].context); }
-static void pinInt22(void) { InterruptIn::_irq_handler(intPtrTable[22].context); }
-static void pinInt23(void) { InterruptIn::_irq_handler(intPtrTable[23].context); }
-static void pinInt24(void) { InterruptIn::_irq_handler(intPtrTable[24].context); }
-static void pinInt25(void) { InterruptIn::_irq_handler(intPtrTable[25].context); }
-static void pinInt26(void) { InterruptIn::_irq_handler(intPtrTable[26].context); }
-static void pinInt27(void) { InterruptIn::_irq_handler(intPtrTable[27].context); }
-static void pinInt28(void) { InterruptIn::_irq_handler(intPtrTable[28].context); }
-static void pinInt29(void) { InterruptIn::_irq_handler(intPtrTable[29].context); }
-static void pinInt30(void) { InterruptIn::_irq_handler(intPtrTable[30].context); }
-static void pinInt31(void) { InterruptIn::_irq_handler(intPtrTable[31].context); }
-static void pinInt32(void) { InterruptIn::_irq_handler(intPtrTable[32].context); }
-static void pinInt33(void) { InterruptIn::_irq_handler(intPtrTable[33].context); }
-static void pinInt34(void) { InterruptIn::_irq_handler(intPtrTable[34].context); }
-static void pinInt35(void) { InterruptIn::_irq_handler(intPtrTable[35].context); }
-static void pinInt36(void) { InterruptIn::_irq_handler(intPtrTable[36].context); }
-static void pinInt37(void) { InterruptIn::_irq_handler(intPtrTable[37].context); }
-static void pinInt38(void) { InterruptIn::_irq_handler(intPtrTable[38].context); }
-static void pinInt39(void) { InterruptIn::_irq_handler(intPtrTable[39].context); }
-static void pinInt40(void) { InterruptIn::_irq_handler(intPtrTable[40].context); }
-static void pinInt41(void) { InterruptIn::_irq_handler(intPtrTable[41].context); }
-static void pinInt42(void) { InterruptIn::_irq_handler(intPtrTable[42].context); }
-static void pinInt43(void) { InterruptIn::_irq_handler(intPtrTable[43].context); }
-static void pinInt44(void) { InterruptIn::_irq_handler(intPtrTable[44].context); }
-static void pinInt45(void) { InterruptIn::_irq_handler(intPtrTable[45].context); }
-static void pinInt46(void) { InterruptIn::_irq_handler(intPtrTable[46].context); }
-static void pinInt47(void) { InterruptIn::_irq_handler(intPtrTable[47].context); }
-
-
-
-
-void
-InterruptIn::rise(Callback<void()> func) {
- if (_gpioPin >= MAX_MCU_PINS-1)
- return;
- if (func) {
- _func = func;
- intPtrTable[_gpioPin].context = this;
- attachInterrupt(MYdigitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, RISING);
- } else {
- _func = InterruptIn::donothing;
- intPtrTable[_gpioPin].context = NULL;
- detachInterrupt(_gpioPin);
- }
-};
-
-void
-InterruptIn::fall(Callback<void()> func) {
- if (func) {
- _func = func;
- intPtrTable[_gpioPin].context = this;
- attachInterrupt(MYdigitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, FALLING);
- } else {
- _func = InterruptIn::donothing;
- intPtrTable[_gpioPin].context = NULL;
- detachInterrupt(_gpioPin);
- }
-}
-
-
-#define MAX_TIMEOUTS 10
-class Timeout;
-struct TimeoutVector {
- Timeout *timer;
-} TimeOuts[MAX_TIMEOUTS];
-
-
-#if defined(__SAMD21G18A__) || defined(__SAMD21J18A__)
-/*
- * __SAMD21J18A__ is the SamD21 Explained Board
- * __SAMD21G18A__ is Genuino Zero-Board (compatible with the LoRa board)
- */
-
-/*
- * see tcc.h is automatically included from:
- * Arduino15/packages/arduino/tools/CMSIS-Atmel/1.1.0/CMSIS/
- * Device/ATMEL/samd21/include/component/tcc.h
- * See also tcc.c (ASF/mbed, e.g. Tcc_get_count_value)
- */
-static void initTimer(Tcc *t);
-static uint32_t getTimerCount(Tcc *t);
-
-/*
- * The Atmel D21 has three TCC timer, other models have more.
- */
-static const struct TCC_config {
- Tcc *tcc_ptr;
- IRQn_Type tcc_irq;
- uint8_t nbits;
-} TCC_data[] {
- { TCC0, TCC0_IRQn, 24 },
- { TCC1, TCC1_IRQn, 24 },
- { TCC2, TCC2_IRQn, 16 },
- { NULL, (IRQn_Type)NULL, 0 }
-};
-
-/*
- * We preferably use the TCC timers because it supports 24-bit counters
- * versus TC Timer which supports only 8 or 16 bit counters
- * TCC0/1/2 timer work on the D21 using Arduino.
- */
-#define USE_TCC_TIMEOUT 0 // 0=TCC0, 1=TTC1, 2=TTC2 (see TCC_data)
-#define USE_TCC_TICKER 1
-
-
-/*
- * every 21333 ns equals one tick (1/(48000000/1024)) // prescaler 1024, 48 MHz
- * every 61035 ns equals one tick (1/(32768/2)) // prescaler 2, 32 kHz
- * COUNT*DIVIDER*SECS until interrupt
- * CPU 48 MHz = (65536*1024)/1.398636s
- * RTC 32 kHz = (65536*2)/4.0s
- */
-#define NS_PER_CLOCK_CPU 21333 // ns secs per clock
-#define NS_PER_CLOCK_RTC 61035 // ns secs per clock
-
-#define NS_PER_CLOCK NS_PER_CLOCK_RTC
-
-/* ----------------- TICKER TIMER CODE ----------------------*/
-
-/*
- * The global ns_counter contains the time in ns from the last time
- * the counter has been wrapped. It cannot be used directly because the
- * current counter has to be added fore using it. Use instead
- * ns_getTicker(), us_ ns_getTicker(), ms_getTicker()
- */
-
-uint64_t ticker_ns;
-static bool initTickerDone = false;
-
-uint32_t s_getTicker(void)
-{
- long long ns = ns_getTicker();
- ns /= (long long)1000000000; // to secs
-
- int secs = ns;
- return secs;
-}
-
-
-uint32_t ms_getTicker(void)
-{
- uint32_t us = us_getTicker();
-
- us /= 1000; // to ms
- return us;
-}
-
-uint32_t us_getTicker(void)
-{
- long long ns = ns_getTicker();
-
- ns /= (long long)1000; // to us
- uint32_t us = ns & 0xffffffff;
-
- return us;
-}
-
-
-uint64_t ns_getTicker(void)
-{
- Tcc *t = TCC_data[USE_TCC_TICKER].tcc_ptr;
- if (!initTickerDone) {
- initTimer(t);
- initTickerDone = true;
-
- // set counter top to max 16 bit for testing
- // t->PER.bit.PER = 0xffff;
- // while (t->SYNCBUSY.bit.PER == 1); // wait for sync
-
- t->CTRLA.reg |= TCC_CTRLA_ENABLE ; // Enable TC
- while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
- }
-
- /*
- * if we are called from the interrupt level, the counter contains
- * somehow wrong data, therfore we needs to read it twice.
- * Another option was to add a little wait (loop 500x)
- * in the TCC_TIMEOUT interrupt handler.
- */
- if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) // check if we are in the interrupt
- getTimerCount(t);
-
- uint64_t counter_us = (uint64_t)NS_PER_CLOCK * (uint64_t)getTimerCount(t);
- uint64_t ns = ticker_ns + counter_us;
-
- return ns;
-}
-
-#if USE_TCC_TICKER == 0
-void TCC0_Handler()
-#elif USE_TCC_TICKER == 1
-void TCC1_Handler()
-#elif USE_TCC_TICKER == 2
-void TCC2_Handler()
-#endif
-{
- Tcc *t = TCC_data[USE_TCC_TICKER].tcc_ptr;
- /*
- * Overflow means the timer top exeeded
- */
- if (t->INTFLAG.bit.OVF == 1) { // A overflow caused the interrupt
- t->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag
- // Serial.println("T_OVF");
-
- /*
- * reading the count once is needed, otherwise
- * it will not wrap correct.
- */
- getTimerCount(t);
-
- int bits = TCC_data[USE_TCC_TICKER].nbits;
- int maxCounts = (uint32_t)(1<<bits);
-
- ticker_ns += (uint64_t)NS_PER_CLOCK * (uint64_t)maxCounts;
- }
- if (t->INTFLAG.bit.MC0 == 1) { // A compare to cc0 caused the interrupt
- t->INTFLAG.bit.MC0 = 1; // writing a one clears the MCO (match capture) flag
- // Serial.println("T_MC0");
- }
-}
-
-/* ----------------- SUPPORT CODE FOR TCC TIMERS----------------------*/
-
-static bool initTimerDone = false;
-
-static void initTimer(Tcc *t)
-{
-
- /*
- * enable clock for TCC, see gclk.h
- * GCLK_CLKCTRL_GEN_GCLK0 for 48 Mhz CPU
- * GCLK_CLKCTRL_GEN_GCLK1 for 32k extern crystal XOSC32K (ifdef CRYSTALLESS)
- * GCLK_CLKCTRL_GEN_GCLK1 for 32k internal OSC32K
- * see Arduino: arduino/hardware/samd/1.6.15/cores/arduino/startup.c
- * Use TCC_CTRLA_PRESCALER_DIV1024 for for 48 Mhz clock
- * Use TCC_CTRLA_PRESCALER_DIV2 for 32k clock
- */
- if (t == TCC0 || t == TCC1) {
- REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TCC0_TCC1);
- } else if (t == TCC2) {
- REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK1 | GCLK_CLKCTRL_ID_TCC2_TC3_Val);
- }
- while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync
-
- t->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TCC
- while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
-
- t->CTRLA.reg |= (TCC_CTRLA_PRESCALER_DIV2 | TCC_CTRLA_RUNSTDBY); // Set perscaler
-
- t->WAVE.reg |= TCC_WAVE_WAVEGEN_NFRQ; // Set wave form configuration
- while (t->SYNCBUSY.bit.WAVE == 1); // wait for sync
-
- t->PER.bit.PER = 0xffffff; // set counter top to max 24 bit
- while (t->SYNCBUSY.bit.PER == 1); // wait for sync
-
- // the compare counter TC->CC[0].reg will be set in the startTimer
- // after the timeout calculation is known.
-
- // Interrupts
- t->INTENSET.reg = 0; // disable all interrupts
- t->INTENSET.bit.OVF = 1; // enable overfollow
- t->INTENSET.bit.MC0 = 1; // enable compare match to CC0
-
- const struct TCC_config *cp = &TCC_data[0];
- while (cp->tcc_ptr) {
- if (cp->tcc_ptr == t) {
- NVIC_EnableIRQ(cp->tcc_irq); // Enable InterruptVector
- break;
- }
- cp++;
- }
-}
-
-#if 0
-// Atmel ASF Code
-static uint32_t getTimerCount(Tcc *t)
-{
- uint32_t last_cmd;
- /* Wait last command done */
- do {
- while (t->SYNCBUSY.bit.CTRLB); /* Wait for sync */
-
- last_cmd = t->CTRLBSET.reg & TCC_CTRLBSET_CMD_Msk;
- if (TCC_CTRLBSET_CMD_NONE == last_cmd) {
- /* Issue read command and break */
- t->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val;
- break;
- } else if (TCC_CTRLBSET_CMD_READSYNC == last_cmd) {
- /* Command have been issued */
- break;
- }
- } while (1);
-
- while (t->SYNCBUSY.bit.COUNT); /* Wait for sync */
-
- return t->COUNT.reg;
-}
-#endif
-
-
-static uint32_t getTimerCount(Tcc *t)
-{
-
- noInterrupts();
-
- while (t->SYNCBUSY.bit.CTRLB); /* Wait for sync */
-
- t->CTRLBSET.bit.CMD = TCC_CTRLBSET_CMD_READSYNC_Val; /* Issue read command and break */
-
- while (t->SYNCBUSY.bit.COUNT); /* Wait for sync */
-
- uint32_t count = t->COUNT.reg;
-
- interrupts();
-
- return count;
-}
-
-
-static void stopTimer(Tcc *t)
-{
- t->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
- while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
-}
-
-
-/* ----------------- TIMEOUT TIMER CODE ----------------------*/
-
-static void startTimer(Tcc *t, uint64_t delay_ns)
-{
- if (!initTimerDone) {
- initTimer(t); // initial setup with stopped timer
- initTimerDone = true;
- }
-
- stopTimer(t); // avoid timer interrupts while calculating
-
- /*
- * every 21333 ns equals one tick (1/(48000000/1024))
- * COUNT*DIVIDER*SECS until interrupt
- * 48 Mhz = (65536*1024)/1.398636s
- */
- uint64_t nclocks = (uint64_t)delay_ns;
- nclocks /= (uint64_t)NS_PER_CLOCK;
- int nCounts = nclocks;
-
- int bits = TCC_data[USE_TCC_TIMEOUT].nbits;
- int maxCounts = (uint32_t)(1<<bits)-1;
-
- if (nCounts > maxCounts) // if count exceeds timer capacity
- nCounts = maxCounts; // set the largest posible count.
- if (nCounts <= 0)
- nCounts = 1;
- t->CC[0].bit.CC = nCounts;
- while (t->SYNCBUSY.bit.CC0 == 1); // wait for sync
-
- t->CTRLA.reg |= TCC_CTRLA_ENABLE ; // Enable TC
- while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
-#if 0
- Serial.print(ms_getTicker(), DEC);
- Serial.print(" startTimer: nCounts=");
- Serial.println(nCounts, DEC);
-#endif
-}
-
-
-#if USE_TCC_TIMEOUT == 0
-void TCC0_Handler()
-#elif USE_TCC_TIMEOUT == 1
-void TCC1_Handler()
-#elif USE_TCC_TIMEOUT == 2
-void TCC2_Handler()
-#endif
-{
- Tcc *t = TCC_data[USE_TCC_TIMEOUT].tcc_ptr;
- uint64_t nsecs = ns_getTicker();
-
- /*
- * Overflow means the max timer exeeded, we need restart the timer
- * Interrupts and
- */
- if (t->INTFLAG.bit.OVF == 1) { // A overflow caused the interrupt
- t->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag
- }
-
- if (t->INTFLAG.bit.MC0 == 1) { // A compare to cc0 caused the interrupt
- //Serial.print("MC0\r\n");
- t->INTFLAG.bit.MC0 = 1; // writing a one clears the MCO (match capture) flag
- }
-
- t->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
- while (t->SYNCBUSY.bit.ENABLE == 1); // wait for sync
-
- for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
- struct TimeoutVector *tvp = &TimeOuts[i];
- if (tvp->timer && nsecs >= tvp->timer->_timeout) {
- Timeout *saveTimer = tvp->timer;
- tvp->timer = NULL;
- Timeout::_irq_handler(saveTimer);
- }
- }
- /*
- * we need to restart the timer for remaining interrupts
- * Another reason is that we stopped this counter, in case there are
- * remaining counts, we need to re-schedule the counter.
- */
- Timeout::restart();
-}
-
-
-#endif // D21 TCC Timer
-
-void
-Timeout::insert(void)
-{
- noInterrupts();
- for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
- struct TimeoutVector *tvp = &TimeOuts[i];
- if (tvp->timer == NULL) {
- tvp->timer = this;
- break;
- }
- }
- interrupts();
-}
-
-void
-Timeout::remove(void)
-{
- noInterrupts();
- for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
- struct TimeoutVector *tvp = &TimeOuts[i];
- if (tvp->timer == this) {
- tvp->timer = NULL;
- break;
- }
- }
- interrupts();
-}
-
-
-void
-Timeout::restart()
-{
- Tcc *t = TCC_data[USE_TCC_TIMEOUT].tcc_ptr;
- uint64_t timeout = ~0;
-
- /*
- * find the lowest timeout value which is our the next timeout
- * zero means stop the timer.
- */
- noInterrupts();
- for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
- struct TimeoutVector *tvp = &TimeOuts[i];
- if (tvp->timer) {
- if (tvp->timer->_timeout < timeout) {
- timeout = tvp->timer->_timeout;
- }
- }
- }
- interrupts();
-
- if (timeout == (uint64_t)~0) {
- stopTimer(t);
- return;
- }
-
- uint64_t nsecs = ns_getTicker();
-
- if (timeout > nsecs) {
- startTimer(t, (uint64_t)timeout - (uint64_t)nsecs);
- return;
- } else {
- startTimer(t, (uint64_t)1); // just one nsec to trigger interrrupt
- }
-}
-
-/* ----------------- D21 sleep() and deepsleep() code ----------------------*/
-
-void sleep(void)
-{
-#if 1 // (SAMD20 || SAMD21)
- /* Errata: Make sure that the Flash does not power all the way down
- * when in sleep mode. */
- NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val;
-#endif
- uint32_t saved_ms = ms_getTicker();
- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // disbale SysTick
-
- SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; // clear deep sleep
- PM->SLEEP.reg = 2; // SYSTEM_SLEEPMODE_IDLE_2 IDLE 2 sleep mode.
-
- __DSB(); // ensures the completion of memory accesses
- __WFI(); // wait for interrupt
-
- int count = ms_getTicker() - saved_ms;
- if (count > 0) { // update the Arduino Systicks
- for (int i = 0; i < count; i++) {
- SysTick_Handler();
- }
- }
- SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // enable SysTick
-}
-
-void deepsleep(void)
-{
-#if 1 // (SAMD20 || SAMD21)
- /* Errata: Make sure that the Flash does not power all the way down
- * when in sleep mode. */
- NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val;
-#endif
-
- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; // disbale SysTick
-
- SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; // standby mode
-
- __DSB(); // ensures the completion of memory accesses
- __WFI(); // wait for interrupt
-
- SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // enable SysTick
-}
-
-
-#endif // ARDUINO
--- a/sx1276/arduino-mbed.h Sun Jul 23 15:44:57 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,305 +0,0 @@
-/*
- * The file is Licensed under the Apache License, Version 2.0
- * (c) 2017 Helmut Tschemernjak
- * 30826 Garbsen (Hannover) Germany
- */
-
-
-
-#ifdef ARDUINO
-#ifndef __ARDUINO_MBED_H__
-#define __ARDUINO_MBED_H__
-
-#include <arduino.h>
-#include "Callback-A.h"
-#include <SPI.h>
-#undef min
-#undef max
-#undef map
-
-typedef int PinName;
-#define NC -1
-#define wait_ms delay
-/* we need to redefine out dprintf because stdio.h uses the same name */
-#define dprint dxprintf
-
-#if ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10606
- #define MYdigitalPinToInterrupt(x) digitalPinToInterrupt(x)
-#else
- #define MYdigitalPinToInterrupt(x) (x)
-#endif
-
-
-enum PinMode {
- PullUp = 1,
- PullDown = 2,
-};
-
-class DigitalInOut {
-public:
- DigitalInOut(PinName pin) {
- _gpioPin = pin;
- }
- void write(int value) {
- digitalWrite(_gpioPin, value == 0 ? LOW : HIGH);
- };
-
- void output() {
- pinMode(_gpioPin, OUTPUT);
- };
-
- void input() {
- pinMode(_gpioPin, INPUT);
- };
-
- void mode(PinMode pull) {
- switch(pull) {
- case PullUp:
- pinMode(_gpioPin, INPUT_PULLUP);
- break;
- case PullDown:
- pinMode(_gpioPin, INPUT_PULLDOWN);
- break;
- }
- }
-
- int read() {
- if (digitalRead(_gpioPin) == HIGH)
- return 1;
- else
- return 0;
- };
- operator int() {
- return read();
- };
-
- DigitalInOut& operator= (int value) {
- // Underlying write is thread safe
- write(value);
- return *this;
- }
-
- DigitalInOut& operator= (DigitalInOut& rhs) {
- write(rhs.read());
- return *this;
- }
-
-private:
- int _gpioPin;
-};
-
-class DigitalOut : public DigitalInOut {
-public:
-
- DigitalOut(PinName pin) : DigitalInOut(pin) {
- output();
- }
-
- DigitalOut& operator= (int value) {
- write(value);
- return *this;
- }
-
-};
-
-class DigitalIn : public DigitalInOut {
-public:
-
- DigitalIn(PinName pin) : DigitalInOut(pin) {
- input();
- }
-};
-
-class XSPI {
-public:
- XSPI(PinName mosi, PinName miso, PinName sclk) {
- _mosi = mosi;
- _miso = miso;
- _sclk = sclk;
- if (mosi == PIN_SPI_MOSI && miso == PIN_SPI_MISO && sclk == PIN_SPI_SCK)
- _spi = &SPI;
-#if SPI_INTERFACES_COUNT > 1
- else if (mosi == PIN_SPI1_MOSI && miso == PIN_SPI1_MISO && sclk == PIN_SPI1_SCK)
- _spi = &SPI1;
-#endif
-#if SPI_INTERFACES_COUNT > 2
- else if (mosi == PIN_SPI2_MOSI && miso == PIN_SPI2_MISO && sclk == PIN_SPI2_SCK)
- _spi = &SPI2;
-#endif
- else {
- _spi = NULL;
- return;
- }
- _hz = 1000000;
- _mode = SPI_MODE0;
- _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
- }
- ~XSPI() {
- _spi->endTransaction();
- };
-
- void format(int bits, int mode = 0) {
- if (mode == 0)
- _mode = SPI_MODE0;
- else if (mode == 1)
- _mode = SPI_MODE1;
- else if (mode == 2)
- _mode = SPI_MODE2;
- else if (mode == 3)
- _mode = SPI_MODE3;
- else
- _mode = SPI_MODE0;
- _bits = bits;
- _spi->endTransaction();
- _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
- }
- void frequency(int hz) {
- _hz = hz;
- _spi->endTransaction();
- _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
- }
-
- int write(int value) {
- int ret = _spi->transfer(value);
- return ret;
- }
-
-private:
- SPIClass *_spi;
- int _hz;
- int _mode;
- int _bits;
- int _mosi, _miso, _sclk;
-};
-
-class InterruptIn {
-public:
- static void donothing(void) {
- }
-
- InterruptIn(PinName pin) : _func() {
- _gpioPin = pin;
- _func = InterruptIn::donothing;
- pinMode(_gpioPin, INPUT);
- }
-
- ~InterruptIn() {
- detachInterrupt(MYdigitalPinToInterrupt(_gpioPin));
- };
-
- static void _irq_handler(InterruptIn *id) {
- if (id)
- id->_func();
- }
-
- void rise(Callback<void()> func);
-
- void fall(Callback<void()> func);
-
- void mode(PinMode pull) {
- switch(pull) {
- case PullUp:
- pinMode(_gpioPin, INPUT_PULLUP);
- break;
- case PullDown:
- pinMode(_gpioPin, INPUT_PULLDOWN);
- break;
- }
- }
-private:
- int _gpioPin;
- Callback<void()> _func;
-};
-
-extern uint32_t s_getTicker(void);
-extern uint32_t ms_getTicker(void);
-extern uint32_t us_getTicker(void);
-extern uint64_t ns_getTicker(void);
-extern void sleep(void);
-extern void deepsleep(void);
-
-
-class Timer {
-public:
- void start(void) {
- _time = ns_getTicker();
- }
- uint32_t read_sec(void) {
- int64_t n = ns_getTicker() - (uint64_t)_time;
- n /= (uint64_t)1000000000;
- return n;
- }
- uint32_t read_ms(void) {
- int64_t n = ns_getTicker() - (uint64_t)_time;
- n /= (uint64_t)1000000;
- return n;
- }
- uint32_t read_us(void) {
- int64_t n = ns_getTicker() - (uint64_t)_time;
- n /= (uint64_t)1000;
- return n;
- }
-private:
- uint64_t _time;
-};
-
-
-class Timeout {
-public:
- Timeout() : _func() {
- }
- ~Timeout() {
- detach();
- }
-
- void attach_sec(Callback<void()> func, uint32_t secs) {
- if (secs == 0)
- return detach();
- _func = func;
- _timeout = ns_getTicker() + (uint64_t)secs * (uint64_t)1000000000;
- insert();
- restart();
- }
-
- void attach(Callback<void()> func, uint32_t msecs) {
- if (msecs == 0)
- return detach();
- _func = func;
- _timeout = ns_getTicker() + (uint64_t)msecs * (uint64_t)1000000;
- insert();
- restart();
- }
-
- void attach_us(Callback<void()> func, long usecs) {
- if (usecs == 0)
- return detach();
- _func = func;
- _timeout = ns_getTicker() + (uint64_t)usecs * (uint64_t)1000;
- insert();
- restart();
- }
-
- void detach(void) {
- _func = NULL;
- remove();
- restart();
- }
-
- static void _irq_handler(Timeout *tp) {
- if (tp) {
- tp->_func();
- }
- }
-
- static void restart(void);
- uint64_t _timeout; // in ns this lasts for 539 years.
-protected:
- void insert(void);
- void remove(void);
-private:
- Callback<void()> _func;
-};
-
-#endif // __ARDUINO_MBED_H__
-
-#endif // ARDUINO

