Merge pull request #14 from geky/funcptr-undo

Reverted merge of FuncPtr (#10)
Bogdan Marinescu 2016-04-07 11:11:30 +01:00
commit 6093cb0300
9 changed files with 93 additions and 741 deletions

View File

@ -21,566 +21,38 @@
namespace mbed { namespace mbed {
// Reusable FuncPtr class based on template specialization /* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */
template <typename F>
class FuncPtr;
/** A class for storing and calling a pointer to a static or member function
*/
template <typename R, typename A1, typename A2, typename A3, typename A4>
class FuncPtr<R(A1, A2, A3, A4)> {
public:
/** Create a FuncPtr, attaching a static function
*
* @param function The static function to attach (default is none)
*/
FuncPtr(R (*function)(A1, A2, A3, A4) = 0) {
attach(function);
}
/** Create a FuncPtr, attaching a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template<typename T>
FuncPtr(T *object, R (*function)(T*, A1, A2, A3, A4)) {
attach(object, function);
}
/** Create a FuncPtr, attaching a member function
*
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach
*/
template<typename T>
FuncPtr(T *object, R (T::*member)(A1, A2, A3, A4)) {
attach(object, member);
}
/** Create a FuncPtr, attaching a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
FuncPtr(T *object) {
attach(object, &T::operator());
}
/** Create a FuncPtr from another FuncPtr
*
* @param func The func to attach
*/
FuncPtr(const FuncPtr<R(A1, A2, A3, A4)> &func) {
attach(func);
}
/** Attach a static function
*
* @param function The static function to attach (default is none)
*/
void attach(R (*function)(A1, A2, A3, A4)) {
_object = 0;
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::staticthunk;
}
/** Attach a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template <typename T>
void attach(T *object, R (*function)(T*, A1, A2, A3, A4)) {
_object = static_cast<void*>(object);
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::boundthunk<T>;
}
/** Attach a member function
*
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach
*/
template<typename T>
void attach(T *object, R (T::*method)(A1, A2, A3, A4)) {
_object = static_cast<void*>(object);
memcpy(&_function, &method, sizeof method);
_thunk = &FuncPtr::methodthunk<T>;
}
/** Attach a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
void attach(T *object) {
attach(object, &T::operator());
}
/** Attach a FuncPtr
*
* @param func The func to attach
*/
void attach(const FuncPtr<R(A1, A2, A3, A4)> &func) {
_object = func._object;
memcpy(&_function, &func._function, sizeof _function);
_thunk = func._thunk;
}
/** Call the attached static or member function
*/
R call(A1 a1, A2 a2, A3 a3, A4 a4) {
return _thunk(_object, _function, a1, a2, a3, a4);
}
/** Get registered static function
*/
R (*get_function(A1, A2, A3, A4))() {
return reinterpret_cast<R (*)(A1, A2, A3, A4)>(_object ? 0 : _function);
}
#ifdef MBED_OPERATORS
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) {
return call(a1, a2, a3, a4);
}
operator bool(void) const {
return static_cast<bool>(_function);
}
#endif
private:
// Static thunks for various function types
static R staticthunk(void*, void *func, A1 a1, A2 a2, A3 a3, A4 a4) {
R (*f)(A1, A2, A3, A4) = *reinterpret_cast<R (**)(A1, A2, A3, A4)>(func);
return f(a1, a2, a3, a4);
}
template<typename T>
static R boundthunk(void *object, void *func, A1 a1, A2 a2, A3 a3, A4 a4) {
T *o = static_cast<T*>(object);
R (*f)(T*, A1, A2, A3, A4) = *reinterpret_cast<R (**)(T*, A1, A2, A3, A4)>(func);
return f(o, a1);
}
template<typename T>
static R methodthunk(void *object, void *member, A1 a1, A2 a2, A3 a3, A4 a4) {
T* o = static_cast<T*>(object);
R (T::*m)(A1, A2, A3, A4) = *reinterpret_cast<R (T::**)(A1, A2, A3, A4)>(member);
return (o->*m)(a1, a2, a3, a4);
}
// Forward declaration of an unknown class
// this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
// As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
// and biggest alignment possible for member function.
// This type can be used inside unions, it will help to provide the storage
// with the proper size and alignment guarantees
class UnknownClass;
// object this pointer
void *_object;
// aligned raw member function pointer storage - converted back by registered thunk
char _function[sizeof(void (UnknownClass::*)())];
// registered function to convert back and call _m.member on _object
R (*_thunk)(void*, void*, A1, A2, A3, A4);
};
/** A class for storing and calling a pointer to a static or member function
*/
template <typename R, typename A1, typename A2, typename A3>
class FuncPtr<R(A1, A2, A3)> {
public:
/** Create a FuncPtr, attaching a static function
*
* @param function The static function to attach (default is none)
*/
FuncPtr(R (*function)(A1, A2, A3) = 0) {
attach(function);
}
/** Create a FuncPtr, attaching a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template<typename T>
FuncPtr(T *object, R (*function)(T*, A1, A2, A3)) {
attach(object, function);
}
/** Create a FuncPtr, attaching a member function
*
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach
*/
template<typename T>
FuncPtr(T *object, R (T::*member)(A1, A2, A3)) {
attach(object, member);
}
/** Create a FuncPtr, attaching a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
FuncPtr(T *object) {
attach(object, &T::operator());
}
/** Create a FuncPtr from another FuncPtr
*
* @param func The func to attach
*/
FuncPtr(const FuncPtr<R(A1, A2, A3)> &func) {
attach(func);
}
/** Attach a static function
*
* @param function The static function to attach (default is none)
*/
void attach(R (*function)(A1, A2, A3)) {
_object = 0;
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::staticthunk;
}
/** Attach a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template <typename T>
void attach(T *object, R (*function)(T*, A1, A2, A3)) {
_object = static_cast<void*>(object);
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::boundthunk<T>;
}
/** Attach a member function
*
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach
*/
template<typename T>
void attach(T *object, R (T::*method)(A1, A2, A3)) {
_object = static_cast<void*>(object);
memcpy(&_function, &method, sizeof method);
_thunk = &FuncPtr::methodthunk<T>;
}
/** Attach a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
void attach(T *object) {
attach(object, &T::operator());
}
/** Attach a FuncPtr
*
* @param func The func to attach
*/
void attach(const FuncPtr<R(A1, A2, A3)> &func) {
_object = func._object;
memcpy(&_function, &func._function, sizeof _function);
_thunk = func._thunk;
}
/** Call the attached static or member function
*/
R call(A1 a1, A2 a2, A3 a3) {
return _thunk(_object, _function, a1, a2, a3);
}
/** Get registered static function
*/
R (*get_function(A1, A2, A3))() {
return reinterpret_cast<R (*)(A1, A2, A3)>(_object ? 0 : _function);
}
#ifdef MBED_OPERATORS
R operator ()(A1 a1, A2 a2, A3 a3) {
return call(a1, a2, a3);
}
operator bool(void) const {
return static_cast<bool>(_function);
}
#endif
private:
// Static thunks for various function types
static R staticthunk(void*, void *func, A1 a1, A2 a2, A3 a3) {
R (*f)(A1, A2, A3) = *reinterpret_cast<R (**)(A1, A2, A3)>(func);
return f(a1, a2, a3);
}
template<typename T>
static R boundthunk(void *object, void *func, A1 a1, A2 a2, A3 a3) {
T *o = static_cast<T*>(object);
R (*f)(T*, A1, A2, A3) = *reinterpret_cast<R (**)(T*, A1, A2, A3)>(func);
return f(o, a1);
}
template<typename T>
static R methodthunk(void *object, void *member, A1 a1, A2 a2, A3 a3) {
T* o = static_cast<T*>(object);
R (T::*m)(A1, A2, A3) = *reinterpret_cast<R (T::**)(A1, A2, A3)>(member);
return (o->*m)(a1, a2, a3);
}
// Forward declaration of an unknown class
// this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
// As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
// and biggest alignment possible for member function.
// This type can be used inside unions, it will help to provide the storage
// with the proper size and alignment guarantees
class UnknownClass;
// object this pointer
void *_object;
// aligned raw member function pointer storage - converted back by registered thunk
char _function[sizeof(void (UnknownClass::*)())];
// registered function to convert back and call _m.member on _object
R (*_thunk)(void*, void*, A1, A2, A3);
};
/** A class for storing and calling a pointer to a static or member function
*/
template <typename R, typename A1, typename A2>
class FuncPtr<R(A1, A2)> {
public:
/** Create a FuncPtr, attaching a static function
*
* @param function The static function to attach (default is none)
*/
FuncPtr(R (*function)(A1, A2) = 0) {
attach(function);
}
/** Create a FuncPtr, attaching a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template<typename T>
FuncPtr(T *object, R (*function)(T*, A1, A2)) {
attach(object, function);
}
/** Create a FuncPtr, attaching a member function
*
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach
*/
template<typename T>
FuncPtr(T *object, R (T::*member)(A1, A2)) {
attach(object, member);
}
/** Create a FuncPtr, attaching a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
FuncPtr(T *object) {
attach(object, &T::operator());
}
/** Create a FuncPtr from another FuncPtr
*
* @param func The func to attach
*/
FuncPtr(const FuncPtr<R(A1, A2)> &func) {
attach(func);
}
/** Attach a static function
*
* @param function The static function to attach (default is none)
*/
void attach(R (*function)(A1, A2)) {
_object = 0;
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::staticthunk;
}
/** Attach a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template <typename T>
void attach(T *object, R (*function)(T*, A1, A2)) {
_object = static_cast<void*>(object);
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::boundthunk<T>;
}
/** Attach a member function
*
* @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach
*/
template<typename T>
void attach(T *object, R (T::*method)(A1, A2)) {
_object = static_cast<void*>(object);
memcpy(&_function, &method, sizeof method);
_thunk = &FuncPtr::methodthunk<T>;
}
/** Attach a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
void attach(T *object) {
attach(object, &T::operator());
}
/** Attach a FuncPtr
*
* @param func The func to attach
*/
void attach(const FuncPtr<R(A1, A2)> &func) {
_object = func._object;
memcpy(&_function, &func._function, sizeof _function);
_thunk = func._thunk;
}
/** Call the attached static or member function
*/
R call(A1 a1, A2 a2) {
return _thunk(_object, _function, a1, a2);
}
/** Get registered static function
*/
R (*get_function(A1, A2))() {
return reinterpret_cast<R (*)(A1, A2)>(_object ? 0 : _function);
}
#ifdef MBED_OPERATORS
R operator ()(A1 a1, A2 a2) {
return call(a1, a2);
}
operator bool(void) const {
return static_cast<bool>(_function);
}
#endif
private:
// Static thunks for various function types
static R staticthunk(void*, void *func, A1 a1, A2 a2) {
R (*f)(A1, A2) = *reinterpret_cast<R (**)(A1, A2)>(func);
return f(a1, a2);
}
template<typename T>
static R boundthunk(void *object, void *func, A1 a1, A2 a2) {
T *o = static_cast<T*>(object);
R (*f)(T*, A1, A2) = *reinterpret_cast<R (**)(T*, A1, A2)>(func);
return f(o, a1);
}
template<typename T>
static R methodthunk(void *object, void *member, A1 a1, A2 a2) {
T* o = static_cast<T*>(object);
R (T::*m)(A1, A2) = *reinterpret_cast<R (T::**)(A1, A2)>(member);
return (o->*m)(a1, a2);
}
// Forward declaration of an unknown class
// this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
// As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
// and biggest alignment possible for member function.
// This type can be used inside unions, it will help to provide the storage
// with the proper size and alignment guarantees
class UnknownClass;
// object this pointer
void *_object;
// aligned raw member function pointer storage - converted back by registered thunk
char _function[sizeof(void (UnknownClass::*)())];
// registered function to convert back and call _m.member on _object
R (*_thunk)(void*, void*, A1, A2);
};
/** A class for storing and calling a pointer to a static or member function /** A class for storing and calling a pointer to a static or member function
*/ */
template <typename R, typename A1> template <typename R, typename A1>
class FuncPtr<R(A1)> { class FunctionPointerArg1{
public: public:
/** Create a FuncPtr, attaching a static function /** Create a FunctionPointer, attaching a static function
* *
* @param function The static function to attach (default is none) * @param function The static function to attach (default is none)
*/ */
FuncPtr(R (*function)(A1) = 0) { FunctionPointerArg1(R (*function)(A1) = 0) {
attach(function); attach(function);
} }
/** Create a FuncPtr, attaching a static function with bound pointer /** Create a FunctionPointer, attaching a member function
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template<typename T>
FuncPtr(T *object, R (*function)(T*, A1)) {
attach(object, function);
}
/** Create a FuncPtr, attaching a member function
* *
* @param object The object pointer to invoke the member function on (i.e. the this pointer) * @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach * @param function The address of the member function to attach
*/ */
template<typename T> template<typename T>
FuncPtr(T *object, R (T::*member)(A1)) { FunctionPointerArg1(T *object, R (T::*member)(A1)) {
attach(object, member); attach(object, member);
} }
/** Create a FuncPtr, attaching a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
FuncPtr(T *object) {
attach(object, &T::operator());
}
/** Create a FuncPtr from another FuncPtr
*
* @param func The func to attach
*/
FuncPtr(const FuncPtr<R(A1)> &func) {
attach(func);
}
/** Attach a static function /** Attach a static function
* *
* @param function The static function to attach (default is none) * @param function The static function to attach (default is none)
*/ */
void attach(R (*function)(A1)) { void attach(R (*function)(A1)) {
_object = 0; _p.function = function;
memcpy(&_function, &function, sizeof function); _membercaller = 0;
_thunk = &FuncPtr::staticthunk;
}
/** Attach a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template <typename T>
void attach(T *object, R (*function)(T*, A1)) {
_object = static_cast<void*>(object);
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::boundthunk<T>;
} }
/** Attach a member function /** Attach a member function
@ -589,258 +61,141 @@ public:
* @param function The address of the member function to attach * @param function The address of the member function to attach
*/ */
template<typename T> template<typename T>
void attach(T *object, R (T::*method)(A1)) { void attach(T *object, R (T::*member)(A1)) {
_object = static_cast<void*>(object); _p.object = static_cast<void*>(object);
memcpy(&_function, &method, sizeof method); *reinterpret_cast<R (T::**)(A1)>(_member) = member;
_thunk = &FuncPtr::methodthunk<T>; _membercaller = &FunctionPointerArg1::membercaller<T>;
}
/** Attach a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
void attach(T *object) {
attach(object, &T::operator());
}
/** Attach a FuncPtr
*
* @param func The func to attach
*/
void attach(const FuncPtr<R(A1)> &func) {
_object = func._object;
memcpy(&_function, &func._function, sizeof _function);
_thunk = func._thunk;
} }
/** Call the attached static or member function /** Call the attached static or member function
*/ */
R call(A1 a1) { R call(A1 a) {
return _thunk(_object, _function, a1); if (_membercaller == 0 && _p.function) {
return _p.function(a);
} else if (_membercaller && _p.object) {
return _membercaller(_p.object, _member, a);
}
return (R)0;
} }
/** Get registered static function /** Get registered static function
*/ */
R (*get_function(A1))() { R(*get_function(A1))() {
return reinterpret_cast<R (*)(A1)>(_object ? 0 : _function); return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function;
} }
#ifdef MBED_OPERATORS #ifdef MBED_OPERATORS
R operator ()(A1 a1) { R operator ()(A1 a) {
return call(a1); return call(a);
} }
operator bool(void) const { operator bool(void) const {
return static_cast<bool>(_function); return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
} }
#endif #endif
private: private:
// Static thunks for various function types
static R staticthunk(void*, void *func, A1 a1) {
R (*f)(A1) = *reinterpret_cast<R (**)(A1)>(func);
return f(a1);
}
template<typename T> template<typename T>
static R boundthunk(void *object, void *func, A1 a1) { static R membercaller(void *object, uintptr_t *member, A1 a) {
T *o = static_cast<T*>(object);
R (*f)(T*, A1) = *reinterpret_cast<R (**)(T*, A1)>(func);
return f(o, a1);
}
template<typename T>
static R methodthunk(void *object, void *member, A1 a1) {
T* o = static_cast<T*>(object); T* o = static_cast<T*>(object);
R (T::*m)(A1) = *reinterpret_cast<R (T::**)(A1)>(member); R (T::**m)(A1) = reinterpret_cast<R (T::**)(A1)>(member);
return (o->*m)(a1); return (o->**m)(a);
} }
// Forward declaration of an unknown class union {
// this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard). R (*function)(A1); // static function pointer
// As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size void *object; // object this pointer
// and biggest alignment possible for member function. } _p;
// This type can be used inside unions, it will help to provide the storage uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
// with the proper size and alignment guarantees R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object
class UnknownClass;
// object this pointer
void *_object;
// aligned raw member function pointer storage - converted back by registered thunk
char _function[sizeof(void (UnknownClass::*)())];
// registered function to convert back and call _m.member on _object
R (*_thunk)(void*, void*, A1);
}; };
/** A class for storing and calling a pointer to a static or member function /** A class for storing and calling a pointer to a static or member function (R ()(void))
*/ */
template <typename R> template <typename R>
class FuncPtr<R()> { class FunctionPointerArg1<R, void>{
public: public:
/** Create a FuncPtr, attaching a static function /** Create a FunctionPointer, attaching a static function
* *
* @param function The static function to attach (default is none) * @param function The static function to attach (default is none)
*/ */
FuncPtr(R (*function)() = 0) { FunctionPointerArg1(R (*function)(void) = 0) {
attach(function); attach(function);
} }
/** Create a FuncPtr, attaching a static function with bound pointer /** Create a FunctionPointer, attaching a member function
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template<typename T>
FuncPtr(T *object, R (*function)(T*)) {
attach(object, function);
}
/** Create a FuncPtr, attaching a member function
* *
* @param object The object pointer to invoke the member function on (i.e. the this pointer) * @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach * @param function The address of the void member function to attach
*/ */
template<typename T> template<typename T>
FuncPtr(T *object, R (T::*member)()) { FunctionPointerArg1(T *object, R (T::*member)(void)) {
attach(object, member); attach(object, member);
} }
/** Create a FuncPtr, attaching a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
FuncPtr(T *object) {
attach(object, &T::operator());
}
/** Create a FuncPtr from another FuncPtr
*
* @param func The func to attach
*/
FuncPtr(const FuncPtr<R()> &func) {
attach(func);
}
/** Attach a static function /** Attach a static function
* *
* @param function The static function to attach (default is none) * @param function The void static function to attach (default is none)
*/ */
void attach(R (*function)()) { void attach(R (*function)(void)) {
_object = 0; _p.function = function;
memcpy(&_function, &function, sizeof function); _membercaller = 0;
_thunk = &FuncPtr::staticthunk;
}
/** Attach a static function with bound pointer
*
* @param object Pointer to object to bind to function
* @param function The static function to attach
*/
template <typename T>
void attach(T *object, R (*function)(T*)) {
_object = static_cast<void*>(object);
memcpy(&_function, &function, sizeof function);
_thunk = &FuncPtr::boundthunk<T>;
} }
/** Attach a member function /** Attach a member function
* *
* @param object The object pointer to invoke the member function on (i.e. the this pointer) * @param object The object pointer to invoke the member function on (i.e. the this pointer)
* @param function The address of the member function to attach * @param function The address of the void member function to attach
*/ */
template<typename T> template<typename T>
void attach(T *object, R (T::*method)()) { void attach(T *object, R (T::*member)(void)) {
_object = static_cast<void*>(object); _p.object = static_cast<void*>(object);
memcpy(&_function, &method, sizeof method); *reinterpret_cast<R (T::**)(void)>(_member) = member;
_thunk = &FuncPtr::methodthunk<T>; _membercaller = &FunctionPointerArg1::membercaller<T>;
}
/** Attach a function object
*
* @param object Pointer to a function object to attach
*/
template<typename T>
void attach(T *object) {
attach(object, &T::operator());
}
/** Attach a FuncPtr
*
* @param func The func to attach
*/
void attach(const FuncPtr<R()> &func) {
_object = func._object;
memcpy(&_function, &func._function, sizeof _function);
_thunk = func._thunk;
} }
/** Call the attached static or member function /** Call the attached static or member function
*/ */
R call() { R call(){
return _thunk(_object, _function); if (_membercaller == 0 && _p.function) {
return _p.function();
} else if (_membercaller && _p.object) {
return _membercaller(_p.object, _member);
}
return (R)0;
} }
/** Get registered static function /** Get registered static function
*/ */
R (*get_function())() { R(*get_function())() {
return reinterpret_cast<R (*)()>(_object ? 0 : _function); return _membercaller ? (R(*)())0 : (R(*)())_p.function;
} }
#ifdef MBED_OPERATORS #ifdef MBED_OPERATORS
R operator ()() { R operator ()(void) {
return call(); return call();
} }
operator bool(void) const { operator bool(void) const {
return static_cast<bool>(_function); return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL;
} }
#endif #endif
private: private:
// Static thunks for various function types
static R staticthunk(void*, void *func) {
R (*f)() = *reinterpret_cast<R (**)()>(func);
return f();
}
template<typename T> template<typename T>
static R boundthunk(void *object, void *func) { static R membercaller(void *object, uintptr_t *member) {
T *o = static_cast<T*>(object);
R (*f)(T*) = *reinterpret_cast<R (**)(T*)>(func);
return f(o);
}
template<typename T>
static R methodthunk(void *object, void *member) {
T* o = static_cast<T*>(object); T* o = static_cast<T*>(object);
R (T::*m)() = *reinterpret_cast<R (T::**)()>(member); R (T::**m)(void) = reinterpret_cast<R (T::**)(void)>(member);
return (o->*m)(); return (o->**m)();
} }
// Forward declaration of an unknown class
// this kind of declaration is authorized by the standard (see 8.3.3/2 of C++ 03 standard).
// As a result, the compiler will allocate for UnknownFunctionMember_t the biggest size
// and biggest alignment possible for member function.
// This type can be used inside unions, it will help to provide the storage
// with the proper size and alignment guarantees
class UnknownClass;
// object this pointer
void *_object;
// aligned raw member function pointer storage - converted back by registered thunk
union { union {
char _function[sizeof(void (UnknownClass::*)())]; R (*function)(void); // static function pointer
void (UnknownClass::*_unknownMethod)(); void *object; // object this pointer
}; } _p;
uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller
// registered function to convert back and call _m.member on _object R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object
R (*_thunk)(void*, void*);
}; };
// Overloads for backwards compatibility typedef FunctionPointerArg1<void, void> FunctionPointer;
typedef FuncPtr<void()> FunctionPointer; typedef FunctionPointerArg1<void, int> event_callback_t;
typedef FuncPtr<void(int)> event_callback_t;
} // namespace mbed } // namespace mbed

View File

@ -17,10 +17,7 @@
#ifndef NETWORK_INTERFACE_H #ifndef NETWORK_INTERFACE_H
#define NETWORK_INTERFACE_H #define NETWORK_INTERFACE_H
#ifndef MBED_OPERATORS #include "mbed.h"
#define MBED_OPERATORS
#endif
#include "FunctionPointer.h"
#include "SocketAddress.h" #include "SocketAddress.h"
/** /**

View File

@ -77,6 +77,6 @@ int Socket::close(bool shutdown)
void Socket::thunk(void *p) void Socket::thunk(void *p)
{ {
mbed::FuncPtr<void()> *fptr = (mbed::FuncPtr<void()> *)p; FunctionPointer *fptr = (FunctionPointer *)p;
(*fptr)(); (*fptr)();
} }

View File

@ -68,7 +68,7 @@ int TCPServer::accept(TCPSocket *connection)
} }
void TCPServer::attach_accept(mbed::FuncPtr<void()> callback) void TCPServer::attach_accept(FunctionPointer callback)
{ {
_accept_cb = callback; _accept_cb = callback;

View File

@ -53,15 +53,15 @@ public:
\param callback Function to call when accept will succeed, may be called in \param callback Function to call when accept will succeed, may be called in
interrupt context. interrupt context.
*/ */
void attach_accept(mbed::FuncPtr<void()> callback); void attach_accept(FunctionPointer callback);
template <typename T, typename M> template <typename T, typename M>
void attach_accept(T *tptr, M mptr) { void attach_accept(T *tptr, M mptr) {
attach_accept(mbed::FuncPtr<void()>(tptr, mptr)); attach_accept(FunctionPointer(tptr, mptr));
} }
private: private:
mbed::FuncPtr<void()> _accept_cb; FunctionPointer _accept_cb;
}; };
#endif #endif

View File

@ -83,7 +83,7 @@ int TCPSocket::recv(void *data, unsigned size)
} }
void TCPSocket::attach_send(mbed::FuncPtr<void()> callback) void TCPSocket::attach_send(FunctionPointer callback)
{ {
_send_cb = callback; _send_cb = callback;
@ -94,7 +94,7 @@ void TCPSocket::attach_send(mbed::FuncPtr<void()> callback)
} }
} }
void TCPSocket::attach_recv(mbed::FuncPtr<void()> callback) void TCPSocket::attach_recv(FunctionPointer callback)
{ {
_recv_cb = callback; _recv_cb = callback;

View File

@ -67,29 +67,29 @@ public:
\param callback Function to call when send will succeed, may be called in \param callback Function to call when send will succeed, may be called in
interrupt context. interrupt context.
*/ */
void attach_send(mbed::FuncPtr<void()> callback); void attach_send(FunctionPointer callback);
template <typename T, typename M> template <typename T, typename M>
void attach_send(T *tptr, M mptr) { void attach_send(T *tptr, M mptr) {
attach_send(mbed::FuncPtr<void()>(tptr, mptr)); attach_send(FunctionPointer(tptr, mptr));
} }
/** Register a callback on when recv is ready /** Register a callback on when recv is ready
\param callback Function to call when recv will succeed, may be called in \param callback Function to call when recv will succeed, may be called in
interrupt context. interrupt context.
*/ */
void attach_recv(mbed::FuncPtr<void()> callback); void attach_recv(FunctionPointer callback);
template <typename T, typename M> template <typename T, typename M>
void attach_recv(T *tptr, M mptr) { void attach_recv(T *tptr, M mptr) {
attach_recv(mbed::FuncPtr<void()>(tptr, mptr)); attach_recv(FunctionPointer(tptr, mptr));
} }
private: private:
friend class TCPServer; friend class TCPServer;
mbed::FuncPtr<void()> _send_cb; FunctionPointer _send_cb;
mbed::FuncPtr<void()> _recv_cb; FunctionPointer _recv_cb;
}; };
#endif #endif

View File

@ -68,7 +68,7 @@ int UDPSocket::recvfrom(SocketAddress *address, void *buffer, unsigned size)
} }
void UDPSocket::attach_send(mbed::FuncPtr<void()> callback) void UDPSocket::attach_send(FunctionPointer callback)
{ {
_send_cb = callback; _send_cb = callback;
if (_socket && _send_cb) { if (_socket && _send_cb) {
@ -78,7 +78,7 @@ void UDPSocket::attach_send(mbed::FuncPtr<void()> callback)
} }
} }
void UDPSocket::attach_recv(mbed::FuncPtr<void()> callback) void UDPSocket::attach_recv(FunctionPointer callback)
{ {
_recv_cb = callback; _recv_cb = callback;
if (_socket && _recv_cb) { if (_socket && _recv_cb) {

View File

@ -58,27 +58,27 @@ public:
\param callback Function to call when send will succeed, may be called in \param callback Function to call when send will succeed, may be called in
interrupt context. interrupt context.
*/ */
void attach_send(mbed::FuncPtr<void()> callback); void attach_send(FunctionPointer callback);
template <typename T, typename M> template <typename T, typename M>
void attach_send(T *tptr, M mptr) { void attach_send(T *tptr, M mptr) {
attach_send(mbed::FuncPtr<void()>(tptr, mptr)); attach_send(FunctionPointer(tptr, mptr));
} }
/** Register a callback on when recv is ready /** Register a callback on when recv is ready
\param callback Function to call when recv will succeed, may be called in \param callback Function to call when recv will succeed, may be called in
interrupt context. interrupt context.
*/ */
void attach_recv(mbed::FuncPtr<void()> callback); void attach_recv(FunctionPointer callback);
template <typename T, typename M> template <typename T, typename M>
void attach_recv(T *tptr, M mptr) { void attach_recv(T *tptr, M mptr) {
attach_recv(mbed::FuncPtr<void()>(tptr, mptr)); attach_recv(FunctionPointer(tptr, mptr));
} }
private: private:
mbed::FuncPtr<void()> _send_cb; FunctionPointer _send_cb;
mbed::FuncPtr<void()> _recv_cb; FunctionPointer _recv_cb;
}; };
#endif #endif