Rtos API example

Committer:
marcozecchini
Date:
Sat Feb 23 12:13:36 2019 +0000
Revision:
0:9fca2b23d0ba
final commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcozecchini 0:9fca2b23d0ba 1 /* mbed Microcontroller Library
marcozecchini 0:9fca2b23d0ba 2 * Copyright (c) 2006-2013 ARM Limited
marcozecchini 0:9fca2b23d0ba 3 *
marcozecchini 0:9fca2b23d0ba 4 * Licensed under the Apache License, Version 2.0 (the "License");
marcozecchini 0:9fca2b23d0ba 5 * you may not use this file except in compliance with the License.
marcozecchini 0:9fca2b23d0ba 6 * You may obtain a copy of the License at
marcozecchini 0:9fca2b23d0ba 7 *
marcozecchini 0:9fca2b23d0ba 8 * http://www.apache.org/licenses/LICENSE-2.0
marcozecchini 0:9fca2b23d0ba 9 *
marcozecchini 0:9fca2b23d0ba 10 * Unless required by applicable law or agreed to in writing, software
marcozecchini 0:9fca2b23d0ba 11 * distributed under the License is distributed on an "AS IS" BASIS,
marcozecchini 0:9fca2b23d0ba 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcozecchini 0:9fca2b23d0ba 13 * See the License for the specific language governing permissions and
marcozecchini 0:9fca2b23d0ba 14 * limitations under the License.
marcozecchini 0:9fca2b23d0ba 15 */
marcozecchini 0:9fca2b23d0ba 16
marcozecchini 0:9fca2b23d0ba 17 #ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
marcozecchini 0:9fca2b23d0ba 18 #define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
marcozecchini 0:9fca2b23d0ba 19
marcozecchini 0:9fca2b23d0ba 20 #include <string.h>
marcozecchini 0:9fca2b23d0ba 21 #include "SafeBool.h"
marcozecchini 0:9fca2b23d0ba 22
marcozecchini 0:9fca2b23d0ba 23 /**
marcozecchini 0:9fca2b23d0ba 24 * @file
marcozecchini 0:9fca2b23d0ba 25 * @addtogroup ble
marcozecchini 0:9fca2b23d0ba 26 * @{
marcozecchini 0:9fca2b23d0ba 27 * @addtogroup common
marcozecchini 0:9fca2b23d0ba 28 * @{
marcozecchini 0:9fca2b23d0ba 29 */
marcozecchini 0:9fca2b23d0ba 30
marcozecchini 0:9fca2b23d0ba 31 /**
marcozecchini 0:9fca2b23d0ba 32 * Function like object adapter over freestanding and member functions.
marcozecchini 0:9fca2b23d0ba 33 *
marcozecchini 0:9fca2b23d0ba 34 * Freestanding and member functions are two distinct types in C++. One is
marcozecchini 0:9fca2b23d0ba 35 * not convertible into the other, and the call syntax between the two is
marcozecchini 0:9fca2b23d0ba 36 * different even if conceptually they are similar: Both primitives can be
marcozecchini 0:9fca2b23d0ba 37 * copied, called and produce a result.
marcozecchini 0:9fca2b23d0ba 38 *
marcozecchini 0:9fca2b23d0ba 39 * To solve incompatibilities, this class adapts freestanding and member functions
marcozecchini 0:9fca2b23d0ba 40 * to a common interface. The interface chosen is similar to the freestanding
marcozecchini 0:9fca2b23d0ba 41 * function pointers interface:
marcozecchini 0:9fca2b23d0ba 42 * - Copyable.
marcozecchini 0:9fca2b23d0ba 43 * - Nullable.
marcozecchini 0:9fca2b23d0ba 44 * - Callable.
marcozecchini 0:9fca2b23d0ba 45 *
marcozecchini 0:9fca2b23d0ba 46 * This class also offers a mechanism to chain other instances to it. When an
marcozecchini 0:9fca2b23d0ba 47 * instance is called, all the instances being part of the chain are called.
marcozecchini 0:9fca2b23d0ba 48 *
marcozecchini 0:9fca2b23d0ba 49 * @important freestanding or member function adapted must accept a single
marcozecchini 0:9fca2b23d0ba 50 * argument, and this argument is a pointer to ContextType. Adapted
marcozecchini 0:9fca2b23d0ba 51 * primitives do not return anything.
marcozecchini 0:9fca2b23d0ba 52 *
marcozecchini 0:9fca2b23d0ba 53 * @tparam ContextType Type of the argument pointee.
marcozecchini 0:9fca2b23d0ba 54 */
marcozecchini 0:9fca2b23d0ba 55 template <typename ContextType>
marcozecchini 0:9fca2b23d0ba 56 class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<ContextType> > {
marcozecchini 0:9fca2b23d0ba 57 public:
marcozecchini 0:9fca2b23d0ba 58 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
marcozecchini 0:9fca2b23d0ba 59 typedef const FunctionPointerWithContext<ContextType> *cpFunctionPointerWithContext_t;
marcozecchini 0:9fca2b23d0ba 60 typedef void (*pvoidfcontext_t)(ContextType context);
marcozecchini 0:9fca2b23d0ba 61
marcozecchini 0:9fca2b23d0ba 62 /**
marcozecchini 0:9fca2b23d0ba 63 * Create a FunctionPointerWithContext from a pointer to a freestanding
marcozecchini 0:9fca2b23d0ba 64 * function.
marcozecchini 0:9fca2b23d0ba 65 *
marcozecchini 0:9fca2b23d0ba 66 * @param[in] function The freestanding function to attach.
marcozecchini 0:9fca2b23d0ba 67 */
marcozecchini 0:9fca2b23d0ba 68 FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
marcozecchini 0:9fca2b23d0ba 69 _memberFunctionAndPointer(), _caller(NULL), _next(NULL)
marcozecchini 0:9fca2b23d0ba 70 {
marcozecchini 0:9fca2b23d0ba 71 attach(function);
marcozecchini 0:9fca2b23d0ba 72 }
marcozecchini 0:9fca2b23d0ba 73
marcozecchini 0:9fca2b23d0ba 74 /**
marcozecchini 0:9fca2b23d0ba 75 * Create a FunctionPointerWithContext from a pointer to a member function
marcozecchini 0:9fca2b23d0ba 76 * and the instance which is used to call it.
marcozecchini 0:9fca2b23d0ba 77 *
marcozecchini 0:9fca2b23d0ba 78 * @param[in] object Pointer to the instance which is used to invoke @p
marcozecchini 0:9fca2b23d0ba 79 * member.
marcozecchini 0:9fca2b23d0ba 80 * @param[in] Pointer to the member function to adapt.
marcozecchini 0:9fca2b23d0ba 81 */
marcozecchini 0:9fca2b23d0ba 82 template<typename T>
marcozecchini 0:9fca2b23d0ba 83 FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
marcozecchini 0:9fca2b23d0ba 84 _memberFunctionAndPointer(), _caller(NULL), _next(NULL)
marcozecchini 0:9fca2b23d0ba 85 {
marcozecchini 0:9fca2b23d0ba 86 attach(object, member);
marcozecchini 0:9fca2b23d0ba 87 }
marcozecchini 0:9fca2b23d0ba 88
marcozecchini 0:9fca2b23d0ba 89 /**
marcozecchini 0:9fca2b23d0ba 90 * Copy construction.
marcozecchini 0:9fca2b23d0ba 91 *
marcozecchini 0:9fca2b23d0ba 92 * @param[in] that The FunctionPointerWithContext instance used to create
marcozecchini 0:9fca2b23d0ba 93 * this.
marcozecchini 0:9fca2b23d0ba 94 */
marcozecchini 0:9fca2b23d0ba 95 FunctionPointerWithContext(const FunctionPointerWithContext &that) :
marcozecchini 0:9fca2b23d0ba 96 _memberFunctionAndPointer(that._memberFunctionAndPointer),
marcozecchini 0:9fca2b23d0ba 97 _caller(that._caller), _next(NULL) {
marcozecchini 0:9fca2b23d0ba 98 }
marcozecchini 0:9fca2b23d0ba 99
marcozecchini 0:9fca2b23d0ba 100 /**
marcozecchini 0:9fca2b23d0ba 101 * Copy assignment.
marcozecchini 0:9fca2b23d0ba 102 *
marcozecchini 0:9fca2b23d0ba 103 * @param[in] that The FunctionPointerWithContext instance copied into this.
marcozecchini 0:9fca2b23d0ba 104 */
marcozecchini 0:9fca2b23d0ba 105 FunctionPointerWithContext &operator=(const FunctionPointerWithContext &that)
marcozecchini 0:9fca2b23d0ba 106 {
marcozecchini 0:9fca2b23d0ba 107 _memberFunctionAndPointer = that._memberFunctionAndPointer;
marcozecchini 0:9fca2b23d0ba 108 _caller = that._caller;
marcozecchini 0:9fca2b23d0ba 109 _next = NULL;
marcozecchini 0:9fca2b23d0ba 110 return *this;
marcozecchini 0:9fca2b23d0ba 111 }
marcozecchini 0:9fca2b23d0ba 112
marcozecchini 0:9fca2b23d0ba 113 /**
marcozecchini 0:9fca2b23d0ba 114 * Adapt a freestanding function.
marcozecchini 0:9fca2b23d0ba 115 *
marcozecchini 0:9fca2b23d0ba 116 * Previous content adapted is discarded while @p function replaces it.
marcozecchini 0:9fca2b23d0ba 117 *
marcozecchini 0:9fca2b23d0ba 118 * @note This function is equivalent to a call to the copy assignment
marcozecchini 0:9fca2b23d0ba 119 * operator.
marcozecchini 0:9fca2b23d0ba 120 *
marcozecchini 0:9fca2b23d0ba 121 * @param[in] function The freestanding function to attach.
marcozecchini 0:9fca2b23d0ba 122 */
marcozecchini 0:9fca2b23d0ba 123 void attach(void (*function)(ContextType context) = NULL)
marcozecchini 0:9fca2b23d0ba 124 {
marcozecchini 0:9fca2b23d0ba 125 _function = function;
marcozecchini 0:9fca2b23d0ba 126 _caller = functioncaller;
marcozecchini 0:9fca2b23d0ba 127 }
marcozecchini 0:9fca2b23d0ba 128
marcozecchini 0:9fca2b23d0ba 129 /**
marcozecchini 0:9fca2b23d0ba 130 * Adapt a pointer to member function and the instance to use to call it.
marcozecchini 0:9fca2b23d0ba 131 *
marcozecchini 0:9fca2b23d0ba 132 * Previous content adapted is discarded while the adaptation
marcozecchini 0:9fca2b23d0ba 133 * of the pair @p object and @p member replaces it.
marcozecchini 0:9fca2b23d0ba 134 *
marcozecchini 0:9fca2b23d0ba 135 * @note This function is equivalent to a call to the copy assignment
marcozecchini 0:9fca2b23d0ba 136 * operator.
marcozecchini 0:9fca2b23d0ba 137 *
marcozecchini 0:9fca2b23d0ba 138 * @param[in] object Pointer to the instance is used to invoke @p member.
marcozecchini 0:9fca2b23d0ba 139 * @param[in] function Pointer to the member function to adapt.
marcozecchini 0:9fca2b23d0ba 140 */
marcozecchini 0:9fca2b23d0ba 141 template<typename T>
marcozecchini 0:9fca2b23d0ba 142 void attach(T *object, void (T::*member)(ContextType context))
marcozecchini 0:9fca2b23d0ba 143 {
marcozecchini 0:9fca2b23d0ba 144 _memberFunctionAndPointer._object = static_cast<void *>(object);
marcozecchini 0:9fca2b23d0ba 145 memcpy(
marcozecchini 0:9fca2b23d0ba 146 _memberFunctionAndPointer._memberFunction,
marcozecchini 0:9fca2b23d0ba 147 (char*) &member,
marcozecchini 0:9fca2b23d0ba 148 sizeof(member)
marcozecchini 0:9fca2b23d0ba 149 );
marcozecchini 0:9fca2b23d0ba 150 _caller = &FunctionPointerWithContext::membercaller<T>;
marcozecchini 0:9fca2b23d0ba 151 }
marcozecchini 0:9fca2b23d0ba 152
marcozecchini 0:9fca2b23d0ba 153 /**
marcozecchini 0:9fca2b23d0ba 154 * Call the adapted function and functions chained to the instance.
marcozecchini 0:9fca2b23d0ba 155 *
marcozecchini 0:9fca2b23d0ba 156 * @param[in] context parameter to pass to chain of adapted functions.
marcozecchini 0:9fca2b23d0ba 157 */
marcozecchini 0:9fca2b23d0ba 158 void call(ContextType context) const
marcozecchini 0:9fca2b23d0ba 159 {
marcozecchini 0:9fca2b23d0ba 160 _caller(this, context);
marcozecchini 0:9fca2b23d0ba 161 }
marcozecchini 0:9fca2b23d0ba 162
marcozecchini 0:9fca2b23d0ba 163 /**
marcozecchini 0:9fca2b23d0ba 164 * Call the adapted function and functions chained to the instance.
marcozecchini 0:9fca2b23d0ba 165 *
marcozecchini 0:9fca2b23d0ba 166 * @param[in] context parameter to pass to chain of adapted functions.
marcozecchini 0:9fca2b23d0ba 167 */
marcozecchini 0:9fca2b23d0ba 168 void call(ContextType context)
marcozecchini 0:9fca2b23d0ba 169 {
marcozecchini 0:9fca2b23d0ba 170 ((const FunctionPointerWithContext*) this)->call(context);
marcozecchini 0:9fca2b23d0ba 171 }
marcozecchini 0:9fca2b23d0ba 172
marcozecchini 0:9fca2b23d0ba 173 /**
marcozecchini 0:9fca2b23d0ba 174 * Call the adapted function and functions chained to the instance.
marcozecchini 0:9fca2b23d0ba 175 *
marcozecchini 0:9fca2b23d0ba 176 * @param[in] context parameter to pass to chain of adapted functions.
marcozecchini 0:9fca2b23d0ba 177 */
marcozecchini 0:9fca2b23d0ba 178 void operator()(ContextType context) const
marcozecchini 0:9fca2b23d0ba 179 {
marcozecchini 0:9fca2b23d0ba 180 call(context);
marcozecchini 0:9fca2b23d0ba 181 }
marcozecchini 0:9fca2b23d0ba 182
marcozecchini 0:9fca2b23d0ba 183 typedef void (FunctionPointerWithContext::*bool_type)() const;
marcozecchini 0:9fca2b23d0ba 184
marcozecchini 0:9fca2b23d0ba 185 /**
marcozecchini 0:9fca2b23d0ba 186 * Indicate if a callable object is being adapted.
marcozecchini 0:9fca2b23d0ba 187 *
marcozecchini 0:9fca2b23d0ba 188 * @note implementation of safe bool operator.
marcozecchini 0:9fca2b23d0ba 189 *
marcozecchini 0:9fca2b23d0ba 190 * @return true if the content of the instance can be invoked and false
marcozecchini 0:9fca2b23d0ba 191 * otherwise.
marcozecchini 0:9fca2b23d0ba 192 */
marcozecchini 0:9fca2b23d0ba 193 bool toBool() const
marcozecchini 0:9fca2b23d0ba 194 {
marcozecchini 0:9fca2b23d0ba 195 return (_function || _memberFunctionAndPointer._object);
marcozecchini 0:9fca2b23d0ba 196 }
marcozecchini 0:9fca2b23d0ba 197
marcozecchini 0:9fca2b23d0ba 198 /**
marcozecchini 0:9fca2b23d0ba 199 * Set a FunctionPointer instance as the next element in the chain of
marcozecchini 0:9fca2b23d0ba 200 * callable objects.
marcozecchini 0:9fca2b23d0ba 201 *
marcozecchini 0:9fca2b23d0ba 202 * @note Invoking call() on the head FunctionPointer invokes all
marcozecchini 0:9fca2b23d0ba 203 * chained callbacks.
marcozecchini 0:9fca2b23d0ba 204 *
marcozecchini 0:9fca2b23d0ba 205 * @note Refer to CallChainOfFunctionPointerWithContext as an alternative.
marcozecchini 0:9fca2b23d0ba 206 *
marcozecchini 0:9fca2b23d0ba 207 * @param next The instance to set as the next element in the chain of
marcozecchini 0:9fca2b23d0ba 208 * callable objects.
marcozecchini 0:9fca2b23d0ba 209 */
marcozecchini 0:9fca2b23d0ba 210 void chainAsNext(pFunctionPointerWithContext_t next)
marcozecchini 0:9fca2b23d0ba 211 {
marcozecchini 0:9fca2b23d0ba 212 _next = next;
marcozecchini 0:9fca2b23d0ba 213 }
marcozecchini 0:9fca2b23d0ba 214
marcozecchini 0:9fca2b23d0ba 215 /**
marcozecchini 0:9fca2b23d0ba 216 * Access the next element in the call chain.
marcozecchini 0:9fca2b23d0ba 217 *
marcozecchini 0:9fca2b23d0ba 218 * If there is no next element in the chain, this function returns NULL.
marcozecchini 0:9fca2b23d0ba 219 *
marcozecchini 0:9fca2b23d0ba 220 * @return A pointer to the next FunctionPointerWithContext instance in the
marcozecchini 0:9fca2b23d0ba 221 * chain.
marcozecchini 0:9fca2b23d0ba 222 */
marcozecchini 0:9fca2b23d0ba 223 pFunctionPointerWithContext_t getNext(void) const
marcozecchini 0:9fca2b23d0ba 224 {
marcozecchini 0:9fca2b23d0ba 225 return _next;
marcozecchini 0:9fca2b23d0ba 226 }
marcozecchini 0:9fca2b23d0ba 227
marcozecchini 0:9fca2b23d0ba 228 /**
marcozecchini 0:9fca2b23d0ba 229 * Access the next element in the call chain.
marcozecchini 0:9fca2b23d0ba 230 *
marcozecchini 0:9fca2b23d0ba 231 * If there is no next element in the chain, this function returns NULL.
marcozecchini 0:9fca2b23d0ba 232 *
marcozecchini 0:9fca2b23d0ba 233 * @return A pointer to the next FunctionPointerWithContext instance in the
marcozecchini 0:9fca2b23d0ba 234 * chain.
marcozecchini 0:9fca2b23d0ba 235 */
marcozecchini 0:9fca2b23d0ba 236 pvoidfcontext_t get_function() const
marcozecchini 0:9fca2b23d0ba 237 {
marcozecchini 0:9fca2b23d0ba 238 return (pvoidfcontext_t)_function;
marcozecchini 0:9fca2b23d0ba 239 }
marcozecchini 0:9fca2b23d0ba 240
marcozecchini 0:9fca2b23d0ba 241 /**
marcozecchini 0:9fca2b23d0ba 242 * Equal to operator between two FunctionPointerWithContext instances.
marcozecchini 0:9fca2b23d0ba 243 *
marcozecchini 0:9fca2b23d0ba 244 * @param[in] lhs Left hand side of the expression.
marcozecchini 0:9fca2b23d0ba 245 * @param[in] rhs Right hand side of the expression.
marcozecchini 0:9fca2b23d0ba 246 *
marcozecchini 0:9fca2b23d0ba 247 * @return true if lhs and rhs adapt the same object and false otherwise.
marcozecchini 0:9fca2b23d0ba 248 */
marcozecchini 0:9fca2b23d0ba 249 friend bool operator==(
marcozecchini 0:9fca2b23d0ba 250 const FunctionPointerWithContext &lhs,
marcozecchini 0:9fca2b23d0ba 251 const FunctionPointerWithContext &rhs
marcozecchini 0:9fca2b23d0ba 252 ) {
marcozecchini 0:9fca2b23d0ba 253 return rhs._caller == lhs._caller &&
marcozecchini 0:9fca2b23d0ba 254 memcmp(
marcozecchini 0:9fca2b23d0ba 255 &rhs._memberFunctionAndPointer,
marcozecchini 0:9fca2b23d0ba 256 &lhs._memberFunctionAndPointer,
marcozecchini 0:9fca2b23d0ba 257 sizeof(rhs._memberFunctionAndPointer)
marcozecchini 0:9fca2b23d0ba 258 ) == 0;
marcozecchini 0:9fca2b23d0ba 259 }
marcozecchini 0:9fca2b23d0ba 260
marcozecchini 0:9fca2b23d0ba 261 private:
marcozecchini 0:9fca2b23d0ba 262 template<typename T>
marcozecchini 0:9fca2b23d0ba 263 static void membercaller(cpFunctionPointerWithContext_t self, ContextType context) {
marcozecchini 0:9fca2b23d0ba 264 if (self->_memberFunctionAndPointer._object) {
marcozecchini 0:9fca2b23d0ba 265 T *o = static_cast<T *>(self->_memberFunctionAndPointer._object);
marcozecchini 0:9fca2b23d0ba 266 void (T::*m)(ContextType);
marcozecchini 0:9fca2b23d0ba 267 memcpy((char*) &m, self->_memberFunctionAndPointer._memberFunction, sizeof(m));
marcozecchini 0:9fca2b23d0ba 268 (o->*m)(context);
marcozecchini 0:9fca2b23d0ba 269 }
marcozecchini 0:9fca2b23d0ba 270 }
marcozecchini 0:9fca2b23d0ba 271
marcozecchini 0:9fca2b23d0ba 272 static void functioncaller(cpFunctionPointerWithContext_t self, ContextType context) {
marcozecchini 0:9fca2b23d0ba 273 if (self->_function) {
marcozecchini 0:9fca2b23d0ba 274 self->_function(context);
marcozecchini 0:9fca2b23d0ba 275 }
marcozecchini 0:9fca2b23d0ba 276 }
marcozecchini 0:9fca2b23d0ba 277
marcozecchini 0:9fca2b23d0ba 278 struct MemberFunctionAndPtr {
marcozecchini 0:9fca2b23d0ba 279 /*
marcozecchini 0:9fca2b23d0ba 280 * Forward declaration of a class and a member function to this class.
marcozecchini 0:9fca2b23d0ba 281 * Because the compiler doesn't know anything about the forwarded member
marcozecchini 0:9fca2b23d0ba 282 * function, it always uses the biggest size and the biggest alignment
marcozecchini 0:9fca2b23d0ba 283 * that a member function can take for objects of type UndefinedMemberFunction.
marcozecchini 0:9fca2b23d0ba 284 */
marcozecchini 0:9fca2b23d0ba 285 class UndefinedClass;
marcozecchini 0:9fca2b23d0ba 286 typedef void (UndefinedClass::*UndefinedMemberFunction)(ContextType);
marcozecchini 0:9fca2b23d0ba 287
marcozecchini 0:9fca2b23d0ba 288 void* _object;
marcozecchini 0:9fca2b23d0ba 289 union {
marcozecchini 0:9fca2b23d0ba 290 char _memberFunction[sizeof(UndefinedMemberFunction)];
marcozecchini 0:9fca2b23d0ba 291 UndefinedMemberFunction _alignment;
marcozecchini 0:9fca2b23d0ba 292 };
marcozecchini 0:9fca2b23d0ba 293 };
marcozecchini 0:9fca2b23d0ba 294
marcozecchini 0:9fca2b23d0ba 295 union {
marcozecchini 0:9fca2b23d0ba 296 pvoidfcontext_t _function; /**< Static function pointer - NULL if none attached */
marcozecchini 0:9fca2b23d0ba 297 /**
marcozecchini 0:9fca2b23d0ba 298 * object this pointer and pointer to member -
marcozecchini 0:9fca2b23d0ba 299 * _memberFunctionAndPointer._object will be NULL if none attached
marcozecchini 0:9fca2b23d0ba 300 */
marcozecchini 0:9fca2b23d0ba 301 mutable MemberFunctionAndPtr _memberFunctionAndPointer;
marcozecchini 0:9fca2b23d0ba 302 };
marcozecchini 0:9fca2b23d0ba 303
marcozecchini 0:9fca2b23d0ba 304 void (*_caller)(const FunctionPointerWithContext*, ContextType);
marcozecchini 0:9fca2b23d0ba 305
marcozecchini 0:9fca2b23d0ba 306 pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers. This
marcozecchini 0:9fca2b23d0ba 307 * allows chaining function pointers without requiring
marcozecchini 0:9fca2b23d0ba 308 * external memory to manage the chain. Refer to
marcozecchini 0:9fca2b23d0ba 309 * 'CallChain' as an alternative. */
marcozecchini 0:9fca2b23d0ba 310 };
marcozecchini 0:9fca2b23d0ba 311
marcozecchini 0:9fca2b23d0ba 312 /**
marcozecchini 0:9fca2b23d0ba 313 * Factory of adapted member function pointers.
marcozecchini 0:9fca2b23d0ba 314 *
marcozecchini 0:9fca2b23d0ba 315 * This factory eliminates the need to invoke the qualified constructor of
marcozecchini 0:9fca2b23d0ba 316 * FunctionPointerWithContext by using automatic type deduction of function
marcozecchini 0:9fca2b23d0ba 317 * templates.
marcozecchini 0:9fca2b23d0ba 318 *
marcozecchini 0:9fca2b23d0ba 319 * @code
marcozecchini 0:9fca2b23d0ba 320 *
marcozecchini 0:9fca2b23d0ba 321 * struct ReadHandler {
marcozecchini 0:9fca2b23d0ba 322 * void on_data_read(const GattReadCallbackParams*);
marcozecchini 0:9fca2b23d0ba 323 * };
marcozecchini 0:9fca2b23d0ba 324 *
marcozecchini 0:9fca2b23d0ba 325 * ReadHandler read_handler;
marcozecchini 0:9fca2b23d0ba 326 *
marcozecchini 0:9fca2b23d0ba 327 * GattClient& client;
marcozecchini 0:9fca2b23d0ba 328 *
marcozecchini 0:9fca2b23d0ba 329 * client.onDataRead(
marcozecchini 0:9fca2b23d0ba 330 * makeFunctionPointer(&read_handler, &ReadHandler::on_data_read)
marcozecchini 0:9fca2b23d0ba 331 * );
marcozecchini 0:9fca2b23d0ba 332 *
marcozecchini 0:9fca2b23d0ba 333 * // instead of
marcozecchini 0:9fca2b23d0ba 334 *
marcozecchini 0:9fca2b23d0ba 335 * client.onDataRead(
marcozecchini 0:9fca2b23d0ba 336 * FunctionPointerWithContext<const GattReadCallbackParams*>(
marcozecchini 0:9fca2b23d0ba 337 * &read_handler,
marcozecchini 0:9fca2b23d0ba 338 * &ReadHandler::on_data_read
marcozecchini 0:9fca2b23d0ba 339 * )
marcozecchini 0:9fca2b23d0ba 340 * );
marcozecchini 0:9fca2b23d0ba 341 * @endcode
marcozecchini 0:9fca2b23d0ba 342 *
marcozecchini 0:9fca2b23d0ba 343 *
marcozecchini 0:9fca2b23d0ba 344 * @param[in] object Instance to bound with @p member.
marcozecchini 0:9fca2b23d0ba 345 * @param member The member being adapted.
marcozecchini 0:9fca2b23d0ba 346 *
marcozecchini 0:9fca2b23d0ba 347 * @return Adaptation of the parameters in a FunctionPointerWithContext instance.
marcozecchini 0:9fca2b23d0ba 348 */
marcozecchini 0:9fca2b23d0ba 349 template<typename T, typename ContextType>
marcozecchini 0:9fca2b23d0ba 350 FunctionPointerWithContext<ContextType> makeFunctionPointer(
marcozecchini 0:9fca2b23d0ba 351 T *object,
marcozecchini 0:9fca2b23d0ba 352 void (T::*member)(ContextType context)
marcozecchini 0:9fca2b23d0ba 353 ) {
marcozecchini 0:9fca2b23d0ba 354 return FunctionPointerWithContext<ContextType>(object, member);
marcozecchini 0:9fca2b23d0ba 355 }
marcozecchini 0:9fca2b23d0ba 356
marcozecchini 0:9fca2b23d0ba 357 /**
marcozecchini 0:9fca2b23d0ba 358 * @}
marcozecchini 0:9fca2b23d0ba 359 * @}
marcozecchini 0:9fca2b23d0ba 360 */
marcozecchini 0:9fca2b23d0ba 361
marcozecchini 0:9fca2b23d0ba 362 #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H