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.
Fork of BLE_API by
Diff: ble/FunctionPointerWithContext.h
- Revision:
- 976:043b3bd94ee0
- Parent:
- 970:b3e45745026d
- Child:
- 986:5292837107a3
--- a/ble/FunctionPointerWithContext.h Thu Nov 26 12:52:36 2015 +0000 +++ b/ble/FunctionPointerWithContext.h Thu Nov 26 12:52:36 2015 +0000 @@ -18,14 +18,16 @@ #define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H #include <string.h> +#include "SafeBool.h" /** A class for storing and calling a pointer to a static or member void function * that takes a context. */ template <typename ContextType> -class FunctionPointerWithContext { +class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<ContextType> > { public: typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; + typedef const FunctionPointerWithContext<ContextType> *cpFunctionPointerWithContext_t; typedef void (*pvoidfcontext_t)(ContextType context); /** Create a FunctionPointerWithContext, attaching a static function. @@ -33,7 +35,7 @@ * @param function The void static function to attach (default is none). */ FunctionPointerWithContext(void (*function)(ContextType context) = NULL) : - _function(NULL), _caller(NULL), _next(NULL) { + _memberFunctionAndPointer(), _caller(NULL), _next(NULL) { attach(function); } @@ -48,6 +50,17 @@ attach(object, member); } + FunctionPointerWithContext(const FunctionPointerWithContext& that) : + _memberFunctionAndPointer(that._memberFunctionAndPointer), _caller(that._caller), _next(NULL) { + } + + FunctionPointerWithContext& operator=(const FunctionPointerWithContext& that) { + _memberFunctionAndPointer = that._memberFunctionAndPointer; + _caller = that._caller; + _next = NULL; + return *this; + } + /** Attach a static function. * * @param function The void static function to attach (default is none). @@ -73,13 +86,29 @@ * FunctionPointers their callbacks are invoked as well. * @Note: All chained callbacks stack up, so hopefully there won't be too * many FunctionPointers in a chain. */ - void call(ContextType context) { + void call(ContextType context) const { _caller(this, context); + } + + /** + * @brief Same as above + */ + void operator()(ContextType context) const { + call(context); + } - /* Propagate the call to next in the chain. */ - if (_next) { - _next->call(context); - } + /** Same as above, workaround for mbed os FunctionPointer implementation. */ + void call(ContextType context) { + ((const FunctionPointerWithContext*) this)->call(context); + } + + typedef void (FunctionPointerWithContext::*bool_type)() const; + + /** + * implementation of safe bool operator + */ + bool toBool() const { + return (_function || _memberFunctionAndPointer._object); } /** @@ -101,9 +130,18 @@ return (pvoidfcontext_t)_function; } + friend bool operator==(const FunctionPointerWithContext& lhs, const FunctionPointerWithContext& rhs) { + return rhs._caller == lhs._caller && + memcmp( + &rhs._memberFunctionAndPointer, + &lhs._memberFunctionAndPointer, + sizeof(rhs._memberFunctionAndPointer) + ) == 0; + } + private: template<typename T> - static void membercaller(pFunctionPointerWithContext_t self, ContextType context) { + static void membercaller(cpFunctionPointerWithContext_t self, ContextType context) { if (self->_memberFunctionAndPointer._object) { T *o = static_cast<T *>(self->_memberFunctionAndPointer._object); void (T::*m)(ContextType); @@ -112,7 +150,7 @@ } } - static void functioncaller(pFunctionPointerWithContext_t self, ContextType context) { + static void functioncaller(cpFunctionPointerWithContext_t self, ContextType context) { if (self->_function) { self->_function(context); } @@ -141,10 +179,10 @@ * object this pointer and pointer to member - * _memberFunctionAndPointer._object will be NULL if none attached */ - MemberFunctionAndPtr _memberFunctionAndPointer; + mutable MemberFunctionAndPtr _memberFunctionAndPointer; }; - void (*_caller)(FunctionPointerWithContext*, ContextType); + void (*_caller)(const FunctionPointerWithContext*, ContextType); pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers. This * allows chaining function pointers without requiring @@ -152,4 +190,23 @@ * 'CallChain' as an alternative. */ }; +/** + * @brief Create a new FunctionPointerWithContext which bind an instance and a + * a member function together. + * @details This little helper is a just here to eliminate the need to write the + * FunctionPointerWithContext type each time you want to create one by kicking + * automatic type deduction of function templates. With this function, it is easy + * to write only one entry point for functions which expect a FunctionPointer + * in parameters. + * + * @param object to bound with member function + * @param member The member function called + * @return a new FunctionPointerWithContext + */ +template<typename T, typename ContextType> +FunctionPointerWithContext<ContextType> makeFunctionPointer(T *object, void (T::*member)(ContextType context)) +{ + return FunctionPointerWithContext<ContextType>(object, member); +} + #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H \ No newline at end of file