takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

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