Skip to content

Commit 95950ad

Browse files
committed
BLE: Improve FunctionPointerWithContext.h documentation.
1 parent d7936e1 commit 95950ad

File tree

1 file changed

+207
-57
lines changed

1 file changed

+207
-57
lines changed

features/FEATURE_BLE/ble/FunctionPointerWithContext.h

Lines changed: 207 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,37 @@
2020
#include <string.h>
2121
#include "SafeBool.h"
2222

23-
/** A class for storing and calling a pointer to a static or member void function
24-
* that takes a context.
23+
/**
24+
* @file
25+
* @addtogroup ble
26+
* @{
27+
* @addtogroup common
28+
* @{
29+
*/
30+
31+
/**
32+
* Function like object adapter over freestanding and member functions.
33+
*
34+
* Freestanding and member functions are two very distinct types in C++, one is
35+
* not convertible into the other and the call syntax between those two is very
36+
* different even if conceptually they are very similar: Both primitives can be
37+
* copied, called and produce a result.
38+
*
39+
* To solve incompatibilities this class addapt freestanding and member function
40+
* to a common interface. The interface chosen is similar to the freestanding
41+
* function pointers interface:
42+
* - Copyable
43+
* - Nullable
44+
* - Callable .
45+
*
46+
* This class also offers a mechanism to chain other instances to it. When an
47+
* instance is called, all the instances being part of the chain are called.
48+
*
49+
* @important freestanding or member function adapted must accept a single
50+
* argument and this argument shall be a pointer to ContextType. Adapted
51+
* primitives shall not return anything.
52+
*
53+
* @tparam ContextType Type of the argument pointee.
2554
*/
2655
template <typename ContextType>
2756
class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<ContextType> > {
@@ -30,111 +59,201 @@ class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<Co
3059
typedef const FunctionPointerWithContext<ContextType> *cpFunctionPointerWithContext_t;
3160
typedef void (*pvoidfcontext_t)(ContextType context);
3261

33-
/** Create a FunctionPointerWithContext, attaching a static function.
62+
/**
63+
* Create a FunctionPointerWithContext from a pointer to a freestanding
64+
* function.
3465
*
35-
* @param function The void static function to attach (default is none).
66+
* @param[in] function The freestanding function to attach.
3667
*/
3768
FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
38-
_memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
69+
_memberFunctionAndPointer(), _caller(NULL), _next(NULL)
70+
{
3971
attach(function);
4072
}
4173

42-
/** Create a FunctionPointerWithContext, attaching a member function.
74+
/**
75+
* Create a FunctionPointerWithContext from a pointer to member function
76+
* and the instance which shall be used to call it.
4377
*
44-
* @param object The object pointer to invoke the member function on (the "this" pointer).
45-
* @param function The address of the void member function to attach.
78+
* @param[in] object Pointer to the instance which will be used to invoke @p
79+
* member.
80+
* @param[in] Pointer to the member function to adapt.
4681
*/
4782
template<typename T>
4883
FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
49-
_memberFunctionAndPointer(), _caller(NULL), _next(NULL) {
84+
_memberFunctionAndPointer(), _caller(NULL), _next(NULL)
85+
{
5086
attach(object, member);
5187
}
5288

53-
FunctionPointerWithContext(const FunctionPointerWithContext& that) :
54-
_memberFunctionAndPointer(that._memberFunctionAndPointer), _caller(that._caller), _next(NULL) {
89+
/**
90+
* Copy construction.
91+
*
92+
* @param[in] that The FunctionPointerWithContext instance used to create
93+
* this.
94+
*/
95+
FunctionPointerWithContext(const FunctionPointerWithContext &that) :
96+
_memberFunctionAndPointer(that._memberFunctionAndPointer),
97+
_caller(that._caller), _next(NULL) {
5598
}
5699

57-
FunctionPointerWithContext& operator=(const FunctionPointerWithContext& that) {
100+
/**
101+
* Copy assignment.
102+
*
103+
* @param[in] that The FunctionPointerWithContext instance copied into this.
104+
*/
105+
FunctionPointerWithContext &operator=(const FunctionPointerWithContext &that)
106+
{
58107
_memberFunctionAndPointer = that._memberFunctionAndPointer;
59-
_caller = that._caller;
108+
_caller = that._caller;
60109
_next = NULL;
61110
return *this;
62111
}
63112

64-
/** Attach a static function.
113+
/**
114+
* Adapt a freestanding function.
115+
*
116+
* Previous content adapted is discarded while it is replace by @p function.
65117
*
66-
* @param function The void static function to attach (default is none).
118+
* @note This function is equivalent to a call to the copy assignment
119+
* operator.
120+
*
121+
* @param[in] function The freestanding function to attach.
67122
*/
68-
void attach(void (*function)(ContextType context) = NULL) {
123+
void attach(void (*function)(ContextType context) = NULL)
124+
{
69125
_function = function;
70126
_caller = functioncaller;
71127
}
72128

73-
/** Attach a member function.
129+
/**
130+
* Adapt a pointer to member function and the instance to use to call it.
74131
*
75-
* @param object The object pointer to invoke the member function on (the "this" pointer).
76-
* @param function The address of the void member function to attach.
132+
* Previous content adapted is discarded while it is replace by the
133+
* adaptation of the pair @p object and @p member.
134+
*
135+
* @note This function is equivalent to a call to the copy assignment
136+
* operator.
137+
*
138+
* @param[in] object Pointer to the instance used to invoke @p member.
139+
* @param[in] function Pointer to the member function to adapt.
77140
*/
78141
template<typename T>
79-
void attach(T *object, void (T::*member)(ContextType context)) {
142+
void attach(T *object, void (T::*member)(ContextType context))
143+
{
80144
_memberFunctionAndPointer._object = static_cast<void *>(object);
81-
memcpy(_memberFunctionAndPointer._memberFunction, (char*) &member, sizeof(member));
145+
memcpy(
146+
_memberFunctionAndPointer._memberFunction,
147+
(char*) &member,
148+
sizeof(member)
149+
);
82150
_caller = &FunctionPointerWithContext::membercaller<T>;
83151
}
84152

85-
/** Call the attached static or member function; if there are chained
86-
* FunctionPointers their callbacks are invoked as well.
87-
* @Note: All chained callbacks stack up, so hopefully there won't be too
88-
* many FunctionPointers in a chain. */
89-
void call(ContextType context) const {
153+
/**
154+
* Call the adapted function and functions chained to the instance.
155+
*
156+
* @param[in] context parameter to pass to chain of adapted functions.
157+
*/
158+
void call(ContextType context) const
159+
{
90160
_caller(this, context);
91161
}
92162

93163
/**
94-
* @brief Same as above
164+
* Call the adapted function and functions chained to the instance.
165+
*
166+
* @param[in] context parameter to pass to chain of adapted functions.
95167
*/
96-
void operator()(ContextType context) const {
97-
call(context);
168+
void call(ContextType context)
169+
{
170+
((const FunctionPointerWithContext*) this)->call(context);
98171
}
99172

100-
/** Same as above, workaround for mbed os FunctionPointer implementation. */
101-
void call(ContextType context) {
102-
((const FunctionPointerWithContext*) this)->call(context);
173+
/**
174+
* Call the adapted function and functions chained to the instance.
175+
*
176+
* @param[in] context parameter to pass to chain of adapted functions.
177+
*/
178+
void operator()(ContextType context) const
179+
{
180+
call(context);
103181
}
104182

105183
typedef void (FunctionPointerWithContext::*bool_type)() const;
106184

107-
/**
108-
* implementation of safe bool operator
185+
/**
186+
* Indicate if a callable object is being adapted.
187+
*
188+
* @note implementation of safe bool operator
189+
*
190+
* @return true if the content of the instance can be invoked and false
191+
* otherwise.
109192
*/
110-
bool toBool() const {
193+
bool toBool() const
194+
{
111195
return (_function || _memberFunctionAndPointer._object);
112196
}
113197

114198
/**
115-
* Set up an external FunctionPointer as a next in the chain of related
116-
* callbacks. Invoking call() on the head FunctionPointer will invoke all
199+
* Set a FunctionPointer instance as the next element in the chain of
200+
* callable objects.
201+
*
202+
* @note Invoking call() on the head FunctionPointer will invoke all
117203
* chained callbacks.
118204
*
119-
* Refer to 'CallChain' as an alternative.
205+
* @note Refer to CallChainOfFunctionPointerWithContext as an alternative.
206+
*
207+
* @param next The instance to set as the next element in the chain of
208+
* callable objects.
120209
*/
121-
void chainAsNext(pFunctionPointerWithContext_t next) {
210+
void chainAsNext(pFunctionPointerWithContext_t next)
211+
{
122212
_next = next;
123213
}
124214

125-
pFunctionPointerWithContext_t getNext(void) const {
215+
/**
216+
* Access the next element in the call chain.
217+
*
218+
* If there is no next element in the chain, this function returns NULL.
219+
*
220+
* @return A pointer to the next FunctionPointerWithContext instance in the
221+
* chain.
222+
*/
223+
pFunctionPointerWithContext_t getNext(void) const
224+
{
126225
return _next;
127226
}
128227

129-
pvoidfcontext_t get_function() const {
228+
/**
229+
* Access the next element in the call chain.
230+
*
231+
* If there is no next element in the chain, this function returns NULL.
232+
*
233+
* @return A pointer to the next FunctionPointerWithContext instance in the
234+
* chain.
235+
*/
236+
pvoidfcontext_t get_function() const
237+
{
130238
return (pvoidfcontext_t)_function;
131239
}
132240

133-
friend bool operator==(const FunctionPointerWithContext& lhs, const FunctionPointerWithContext& rhs) {
241+
/**
242+
* Equal to operator between two FunctionPointerWithContext instances.
243+
*
244+
* @param[in] lhs Left hand side of the expression.
245+
* @param[in] rhs Right hand side of the expression.
246+
*
247+
* @return true if lhs and rhs adapt the same object and false otherwise.
248+
*/
249+
friend bool operator==(
250+
const FunctionPointerWithContext &lhs,
251+
const FunctionPointerWithContext &rhs
252+
) {
134253
return rhs._caller == lhs._caller &&
135254
memcmp(
136-
&rhs._memberFunctionAndPointer,
137-
&lhs._memberFunctionAndPointer,
255+
&rhs._memberFunctionAndPointer,
256+
&lhs._memberFunctionAndPointer,
138257
sizeof(rhs._memberFunctionAndPointer)
139258
) == 0;
140259
}
@@ -191,22 +310,53 @@ class FunctionPointerWithContext : public SafeBool<FunctionPointerWithContext<Co
191310
};
192311

193312
/**
194-
* @brief Create a new FunctionPointerWithContext which bind an instance and a
195-
* a member function together.
196-
* @details This little helper is a just here to eliminate the need to write the
197-
* FunctionPointerWithContext type each time you want to create one by kicking
198-
* automatic type deduction of function templates. With this function, it is easy
199-
* to write only one entry point for functions which expect a FunctionPointer
200-
* in parameters.
201-
*
202-
* @param object to bound with member function
203-
* @param member The member function called
204-
* @return a new FunctionPointerWithContext
313+
* Factory of adapted member function pointers.
314+
*
315+
* This factory eliminate the need to invoke the qualified constructor of
316+
* FunctionPointerWithContext by using automatic type deduction of function
317+
* templates
318+
*
319+
* @code
320+
*
321+
* struct ReadHandler {
322+
* void on_data_read(const GattReadCallbackParams*);
323+
* };
324+
*
325+
* ReadHandler read_handler;
326+
*
327+
* GattClient& client;
328+
*
329+
* client.onDataRead(
330+
* makeFunctionPointer(&read_handler, &ReadHandler::on_data_read)
331+
* );
332+
*
333+
* // instead of
334+
*
335+
* client.onDataRead(
336+
* FunctionPointerWithContext<const GattReadCallbackParams*>(
337+
* &read_handler,
338+
* &ReadHandler::on_data_read
339+
* )
340+
* );
341+
* @endcode
342+
*
343+
*
344+
* @param[in] object Instance to bound with @p member.
345+
* @param member The member being adapted.
346+
*
347+
* @return Adaptation of the parameters in a FunctionPointerWithContext instance.
205348
*/
206349
template<typename T, typename ContextType>
207-
FunctionPointerWithContext<ContextType> makeFunctionPointer(T *object, void (T::*member)(ContextType context))
208-
{
350+
FunctionPointerWithContext<ContextType> makeFunctionPointer(
351+
T *object,
352+
void (T::*member)(ContextType context)
353+
) {
209354
return FunctionPointerWithContext<ContextType>(object, member);
210355
}
211356

357+
/**
358+
* @}
359+
* @}
360+
*/
361+
212362
#endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H

0 commit comments

Comments
 (0)