mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

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