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: BLE_PowerBank_HeyFaradey
Fork of BLE_API by
Diff: ble/FunctionPointerWithContext.h
- Revision:
- 969:61f13bc8edbf
- Parent:
- 966:9451b90bbb66
- Child:
- 970:b3e45745026d
diff -r 9b6005880241 -r 61f13bc8edbf ble/FunctionPointerWithContext.h
--- a/ble/FunctionPointerWithContext.h Thu Nov 26 12:52:35 2015 +0000
+++ b/ble/FunctionPointerWithContext.h Thu Nov 26 12:52:35 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
