Skip to content

Commit bf498de

Browse files
committed
Add backward compatiblity for FunctionPointer class using Callback
effectively: typedef Callback<R(A)> FunctionPointerArg1<R,A> typedef Callback<R()> FunctionPointerArg1<R,void> typedef Callback<R()> FunctionPointer typedef Callback<R()> event_callback_t
1 parent 8b330ae commit bf498de

File tree

3 files changed

+38
-156
lines changed

3 files changed

+38
-156
lines changed

hal/TESTS/api/callback/main.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,22 @@ void test_dispatch0() {
211211
Verifier<T>::verify0((void*)&callback, &Callback<T()>::thunk);
212212
}
213213

214+
template <typename T>
215+
void test_fparg1() {
216+
Thing<T> thing;
217+
FunctionPointerArg1<T,T> fp(static_func1<T>);
218+
Verifier<T>::verify1(fp);
219+
Verifier<T>::verify1(fp.get_function());
220+
}
221+
222+
template <typename T>
223+
void test_fparg0() {
224+
Thing<T> thing;
225+
FunctionPointerArg1<T,void> fp(static_func0<T>);
226+
Verifier<T>::verify0(fp);
227+
Verifier<T>::verify0(fp.get_function());
228+
}
229+
214230

215231
// Test setup
216232
status_t test_setup(const size_t number_of_cases) {
@@ -239,6 +255,9 @@ Case cases[] = {
239255
Case("Testing callbacks with 2 uint64s", test_dispatch2<uint64_t>),
240256
Case("Testing callbacks with 1 uint64s", test_dispatch1<uint64_t>),
241257
Case("Testing callbacks with 0 uint64s", test_dispatch0<uint64_t>),
258+
259+
Case("Testing FunctionPointerArg1 compatibility", test_fparg1<int>),
260+
Case("Testing FunctionPointer compatibility", test_fparg0<int>),
242261
};
243262

244263
Specification specification(test_setup, cases);

hal/api/FunctionPointer.h

Lines changed: 18 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -16,187 +16,49 @@
1616
#ifndef MBED_FUNCTIONPOINTER_H
1717
#define MBED_FUNCTIONPOINTER_H
1818

19+
#include "Callback.h"
1920
#include <string.h>
2021
#include <stdint.h>
2122

2223
namespace mbed {
2324

24-
/* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
2525

26-
/** A class for storing and calling a pointer to a static or member function
27-
*/
26+
// Declarations for backwards compatibility
27+
// To be foward compatible, code should adopt the Callback class
2828
template <typename R, typename A1>
29-
class FunctionPointerArg1{
29+
class FunctionPointerArg1 : public Callback<R(A1)> {
3030
public:
31-
/** Create a FunctionPointer, attaching a static function
32-
*
33-
* @param function The static function to attach (default is none)
34-
*/
35-
FunctionPointerArg1(R (*function)(A1) = 0) {
36-
attach(function);
37-
}
31+
FunctionPointerArg1(R (*function)(A1) = 0)
32+
: Callback<R(A1)>(function) {}
3833

39-
/** Create a FunctionPointer, attaching a member function
40-
*
41-
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
42-
* @param function The address of the member function to attach
43-
*/
4434
template<typename T>
45-
FunctionPointerArg1(T *object, R (T::*member)(A1)) {
46-
attach(object, member);
47-
}
48-
49-
/** Attach a static function
50-
*
51-
* @param function The static function to attach (default is none)
52-
*/
53-
void attach(R (*function)(A1)) {
54-
_p.function = function;
55-
_membercaller = 0;
56-
}
57-
58-
/** Attach a member function
59-
*
60-
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
61-
* @param function The address of the member function to attach
62-
*/
63-
template<typename T>
64-
void attach(T *object, R (T::*member)(A1)) {
65-
_p.object = static_cast<void*>(object);
66-
*reinterpret_cast<R (T::**)(A1)>(_member) = member;
67-
_membercaller = &FunctionPointerArg1::membercaller<T>;
68-
}
69-
70-
/** Call the attached static or member function
71-
*/
72-
R call(A1 a) {
73-
if (_membercaller == 0 && _p.function) {
74-
return _p.function(a);
75-
} else if (_membercaller && _p.object) {
76-
return _membercaller(_p.object, _member, a);
77-
}
78-
return (R)0;
79-
}
80-
81-
/** Get registered static function
82-
*/
83-
R(*get_function(A1))() {
84-
return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function;
85-
}
35+
FunctionPointerArg1(T *object, R (T::*member)(A1))
36+
: Callback<R(A1)>(object, member) {}
8637

87-
#ifdef MBED_OPERATORS
88-
R operator ()(A1 a) {
89-
return call(a);
38+
R (*get_function())(A1) {
39+
return *reinterpret_cast<R (**)(A1)>(this);
9040
}
91-
operator bool(void) const {
92-
return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
93-
}
94-
#endif
95-
private:
96-
template<typename T>
97-
static R membercaller(void *object, uintptr_t *member, A1 a) {
98-
T* o = static_cast<T*>(object);
99-
R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
100-
return (o->**m)(a);
101-
}
102-
103-
union {
104-
R (*function)(A1); // static function pointer
105-
void *object; // object this pointer
106-
} _p;
107-
uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
108-
R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object
10941
};
11042

111-
/** A class for storing and calling a pointer to a static or member function (R ()(void))
112-
*/
11343
template <typename R>
114-
class FunctionPointerArg1<R, void>{
44+
class FunctionPointerArg1<R, void> : public Callback<R()> {
11545
public:
116-
/** Create a FunctionPointer, attaching a static function
117-
*
118-
* @param function The static function to attach (default is none)
119-
*/
120-
FunctionPointerArg1(R (*function)(void) = 0) {
121-
attach(function);
122-
}
46+
FunctionPointerArg1(R (*function)() = 0)
47+
: Callback<R()>(function) {}
12348

124-
/** Create a FunctionPointer, attaching a member function
125-
*
126-
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
127-
* @param function The address of the void member function to attach
128-
*/
12949
template<typename T>
130-
FunctionPointerArg1(T *object, R (T::*member)(void)) {
131-
attach(object, member);
132-
}
133-
134-
/** Attach a static function
135-
*
136-
* @param function The void static function to attach (default is none)
137-
*/
138-
void attach(R (*function)(void)) {
139-
_p.function = function;
140-
_membercaller = 0;
141-
}
142-
143-
/** Attach a member function
144-
*
145-
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
146-
* @param function The address of the void member function to attach
147-
*/
148-
template<typename T>
149-
void attach(T *object, R (T::*member)(void)) {
150-
_p.object = static_cast<void*>(object);
151-
*reinterpret_cast<R (T::**)(void)>(_member) = member;
152-
_membercaller = &FunctionPointerArg1::membercaller<T>;
153-
}
154-
155-
/** Call the attached static or member function
156-
*/
157-
R call(){
158-
if (_membercaller == 0 && _p.function) {
159-
return _p.function();
160-
} else if (_membercaller && _p.object) {
161-
return _membercaller(_p.object, _member);
162-
}
163-
return (R)0;
164-
}
50+
FunctionPointerArg1(T *object, R (T::*member)())
51+
: Callback<R()>(object, member) {}
16552

166-
/** Get registered static function
167-
*/
168-
R(*get_function())() {
169-
return _membercaller ? (R(*)())0 : (R(*)())_p.function;
53+
R (*get_function())() {
54+
return *reinterpret_cast<R (**)()>(this);
17055
}
171-
172-
#ifdef MBED_OPERATORS
173-
R operator ()(void) {
174-
return call();
175-
}
176-
operator bool(void) const {
177-
return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
178-
}
179-
#endif
180-
181-
private:
182-
template<typename T>
183-
static R membercaller(void *object, uintptr_t *member) {
184-
T* o = static_cast<T*>(object);
185-
R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
186-
return (o->**m)();
187-
}
188-
189-
union {
190-
R (*function)(void); // static function pointer
191-
void *object; // object this pointer
192-
} _p;
193-
uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
194-
R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object
19556
};
19657

19758
typedef FunctionPointerArg1<void, void> FunctionPointer;
19859
typedef FunctionPointerArg1<void, int> event_callback_t;
19960

61+
20062
} // namespace mbed
20163

20264
#endif

hal/api/mbed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
// mbed Non-hardware components
6868
#include "Callback.h"
69+
#include "FunctionPointer.h"
6970

7071
using namespace mbed;
7172
using namespace std;

0 commit comments

Comments
 (0)