mirror of https://github.com/ARMmbed/mbed-os.git
Updated minor functionality of the Callback class
- Marked `call` and `operator()` functions as const - Moved to static_cast for internal function pointer to avoid losing compiler checked const-safety - Added test for `operator=` with non-callback types - Moved from zero-cast to value-initializer when callback is null - Added `operator==` and `operator!=` - Removed special handling of null callback - Replicated doxygen to all overloads - Added correct nops where uninitialized callbacks are called - Added assertion for null callback - Removed copy-constructor from callback constructorpull/2496/head
parent
45d25ed493
commit
c71e67f2dc
|
|
@ -203,20 +203,14 @@ void test_dispatch0() {
|
||||||
Verifier<T>::verify0((volatile Thing<T>*)&thing, &volatile_func0<T>);
|
Verifier<T>::verify0((volatile Thing<T>*)&thing, &volatile_func0<T>);
|
||||||
Verifier<T>::verify0((const volatile Thing<T>*)&thing, &const_volatile_func0<T>);
|
Verifier<T>::verify0((const volatile Thing<T>*)&thing, &const_volatile_func0<T>);
|
||||||
Verifier<T>::verify0(callback(static_func0<T>));
|
Verifier<T>::verify0(callback(static_func0<T>));
|
||||||
Verifier<T>::verify0(callback(&thing, &Thing<T>::member_func0));
|
|
||||||
Verifier<T>::verify0(callback((const Thing<T>*)&thing, &Thing<T>::const_member_func0));
|
|
||||||
Verifier<T>::verify0(callback((volatile Thing<T>*)&thing, &Thing<T>::volatile_member_func0));
|
|
||||||
Verifier<T>::verify0(callback((const volatile Thing<T>*)&thing, &Thing<T>::const_volatile_member_func0));
|
|
||||||
Verifier<T>::verify0(callback(&thing, &bound_func0<T>));
|
|
||||||
Verifier<T>::verify0(callback((const Thing<T>*)&thing, &const_func0<T>));
|
|
||||||
Verifier<T>::verify0(callback((volatile Thing<T>*)&thing, &volatile_func0<T>));
|
|
||||||
Verifier<T>::verify0(callback((const volatile Thing<T>*)&thing, &const_volatile_func0<T>));
|
|
||||||
|
|
||||||
Callback<T()> callback(static_func0);
|
Callback<T()> cb(static_func0);
|
||||||
Verifier<T>::verify0(callback);
|
Verifier<T>::verify0(cb);
|
||||||
callback.attach(&thing, &bound_func0<T>);
|
cb = static_func0;
|
||||||
Verifier<T>::verify0(&callback, &Callback<T()>::call);
|
Verifier<T>::verify0(cb);
|
||||||
Verifier<T>::verify0((void*)&callback, &Callback<T()>::thunk);
|
cb.attach(&thing, &bound_func0<T>);
|
||||||
|
Verifier<T>::verify0(&cb, &Callback<T()>::call);
|
||||||
|
Verifier<T>::verify0((void*)&cb, &Callback<T()>::thunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -232,20 +226,14 @@ void test_dispatch1() {
|
||||||
Verifier<T>::verify1((volatile Thing<T>*)&thing, &volatile_func1<T>);
|
Verifier<T>::verify1((volatile Thing<T>*)&thing, &volatile_func1<T>);
|
||||||
Verifier<T>::verify1((const volatile Thing<T>*)&thing, &const_volatile_func1<T>);
|
Verifier<T>::verify1((const volatile Thing<T>*)&thing, &const_volatile_func1<T>);
|
||||||
Verifier<T>::verify1(callback(static_func1<T>));
|
Verifier<T>::verify1(callback(static_func1<T>));
|
||||||
Verifier<T>::verify1(callback(&thing, &Thing<T>::member_func1));
|
|
||||||
Verifier<T>::verify1(callback((const Thing<T>*)&thing, &Thing<T>::const_member_func1));
|
|
||||||
Verifier<T>::verify1(callback((volatile Thing<T>*)&thing, &Thing<T>::volatile_member_func1));
|
|
||||||
Verifier<T>::verify1(callback((const volatile Thing<T>*)&thing, &Thing<T>::const_volatile_member_func1));
|
|
||||||
Verifier<T>::verify1(callback(&thing, &bound_func1<T>));
|
|
||||||
Verifier<T>::verify1(callback((const Thing<T>*)&thing, &const_func1<T>));
|
|
||||||
Verifier<T>::verify1(callback((volatile Thing<T>*)&thing, &volatile_func1<T>));
|
|
||||||
Verifier<T>::verify1(callback((const volatile Thing<T>*)&thing, &const_volatile_func1<T>));
|
|
||||||
|
|
||||||
Callback<T(T)> callback(static_func1);
|
Callback<T(T)> cb(static_func1);
|
||||||
Verifier<T>::verify1(callback);
|
Verifier<T>::verify1(cb);
|
||||||
callback.attach(&thing, &bound_func1<T>);
|
cb = static_func1;
|
||||||
Verifier<T>::verify1(&callback, &Callback<T(T)>::call);
|
Verifier<T>::verify1(cb);
|
||||||
Verifier<T>::verify1((void*)&callback, &Callback<T(T)>::thunk);
|
cb.attach(&thing, &bound_func1<T>);
|
||||||
|
Verifier<T>::verify1(&cb, &Callback<T(T)>::call);
|
||||||
|
Verifier<T>::verify1((void*)&cb, &Callback<T(T)>::thunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -261,20 +249,14 @@ void test_dispatch2() {
|
||||||
Verifier<T>::verify2((volatile Thing<T>*)&thing, &volatile_func2<T>);
|
Verifier<T>::verify2((volatile Thing<T>*)&thing, &volatile_func2<T>);
|
||||||
Verifier<T>::verify2((const volatile Thing<T>*)&thing, &const_volatile_func2<T>);
|
Verifier<T>::verify2((const volatile Thing<T>*)&thing, &const_volatile_func2<T>);
|
||||||
Verifier<T>::verify2(callback(static_func2<T>));
|
Verifier<T>::verify2(callback(static_func2<T>));
|
||||||
Verifier<T>::verify2(callback(&thing, &Thing<T>::member_func2));
|
|
||||||
Verifier<T>::verify2(callback((const Thing<T>*)&thing, &Thing<T>::const_member_func2));
|
|
||||||
Verifier<T>::verify2(callback((volatile Thing<T>*)&thing, &Thing<T>::volatile_member_func2));
|
|
||||||
Verifier<T>::verify2(callback((const volatile Thing<T>*)&thing, &Thing<T>::const_volatile_member_func2));
|
|
||||||
Verifier<T>::verify2(callback(&thing, &bound_func2<T>));
|
|
||||||
Verifier<T>::verify2(callback((const Thing<T>*)&thing, &const_func2<T>));
|
|
||||||
Verifier<T>::verify2(callback((volatile Thing<T>*)&thing, &volatile_func2<T>));
|
|
||||||
Verifier<T>::verify2(callback((const volatile Thing<T>*)&thing, &const_volatile_func2<T>));
|
|
||||||
|
|
||||||
Callback<T(T, T)> callback(static_func2);
|
Callback<T(T, T)> cb(static_func2);
|
||||||
Verifier<T>::verify2(callback);
|
Verifier<T>::verify2(cb);
|
||||||
callback.attach(&thing, &bound_func2<T>);
|
cb = static_func2;
|
||||||
Verifier<T>::verify2(&callback, &Callback<T(T, T)>::call);
|
Verifier<T>::verify2(cb);
|
||||||
Verifier<T>::verify2((void*)&callback, &Callback<T(T, T)>::thunk);
|
cb.attach(&thing, &bound_func2<T>);
|
||||||
|
Verifier<T>::verify2(&cb, &Callback<T(T, T)>::call);
|
||||||
|
Verifier<T>::verify2((void*)&cb, &Callback<T(T, T)>::thunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -290,20 +272,14 @@ void test_dispatch3() {
|
||||||
Verifier<T>::verify3((volatile Thing<T>*)&thing, &volatile_func3<T>);
|
Verifier<T>::verify3((volatile Thing<T>*)&thing, &volatile_func3<T>);
|
||||||
Verifier<T>::verify3((const volatile Thing<T>*)&thing, &const_volatile_func3<T>);
|
Verifier<T>::verify3((const volatile Thing<T>*)&thing, &const_volatile_func3<T>);
|
||||||
Verifier<T>::verify3(callback(static_func3<T>));
|
Verifier<T>::verify3(callback(static_func3<T>));
|
||||||
Verifier<T>::verify3(callback(&thing, &Thing<T>::member_func3));
|
|
||||||
Verifier<T>::verify3(callback((const Thing<T>*)&thing, &Thing<T>::const_member_func3));
|
|
||||||
Verifier<T>::verify3(callback((volatile Thing<T>*)&thing, &Thing<T>::volatile_member_func3));
|
|
||||||
Verifier<T>::verify3(callback((const volatile Thing<T>*)&thing, &Thing<T>::const_volatile_member_func3));
|
|
||||||
Verifier<T>::verify3(callback(&thing, &bound_func3<T>));
|
|
||||||
Verifier<T>::verify3(callback((const Thing<T>*)&thing, &const_func3<T>));
|
|
||||||
Verifier<T>::verify3(callback((volatile Thing<T>*)&thing, &volatile_func3<T>));
|
|
||||||
Verifier<T>::verify3(callback((const volatile Thing<T>*)&thing, &const_volatile_func3<T>));
|
|
||||||
|
|
||||||
Callback<T(T, T, T)> callback(static_func3);
|
Callback<T(T, T, T)> cb(static_func3);
|
||||||
Verifier<T>::verify3(callback);
|
Verifier<T>::verify3(cb);
|
||||||
callback.attach(&thing, &bound_func3<T>);
|
cb = static_func3;
|
||||||
Verifier<T>::verify3(&callback, &Callback<T(T, T, T)>::call);
|
Verifier<T>::verify3(cb);
|
||||||
Verifier<T>::verify3((void*)&callback, &Callback<T(T, T, T)>::thunk);
|
cb.attach(&thing, &bound_func3<T>);
|
||||||
|
Verifier<T>::verify3(&cb, &Callback<T(T, T, T)>::call);
|
||||||
|
Verifier<T>::verify3((void*)&cb, &Callback<T(T, T, T)>::thunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -319,20 +295,14 @@ void test_dispatch4() {
|
||||||
Verifier<T>::verify4((volatile Thing<T>*)&thing, &volatile_func4<T>);
|
Verifier<T>::verify4((volatile Thing<T>*)&thing, &volatile_func4<T>);
|
||||||
Verifier<T>::verify4((const volatile Thing<T>*)&thing, &const_volatile_func4<T>);
|
Verifier<T>::verify4((const volatile Thing<T>*)&thing, &const_volatile_func4<T>);
|
||||||
Verifier<T>::verify4(callback(static_func4<T>));
|
Verifier<T>::verify4(callback(static_func4<T>));
|
||||||
Verifier<T>::verify4(callback(&thing, &Thing<T>::member_func4));
|
|
||||||
Verifier<T>::verify4(callback((const Thing<T>*)&thing, &Thing<T>::const_member_func4));
|
|
||||||
Verifier<T>::verify4(callback((volatile Thing<T>*)&thing, &Thing<T>::volatile_member_func4));
|
|
||||||
Verifier<T>::verify4(callback((const volatile Thing<T>*)&thing, &Thing<T>::const_volatile_member_func4));
|
|
||||||
Verifier<T>::verify4(callback(&thing, &bound_func4<T>));
|
|
||||||
Verifier<T>::verify4(callback((const Thing<T>*)&thing, &const_func4<T>));
|
|
||||||
Verifier<T>::verify4(callback((volatile Thing<T>*)&thing, &volatile_func4<T>));
|
|
||||||
Verifier<T>::verify4(callback((const volatile Thing<T>*)&thing, &const_volatile_func4<T>));
|
|
||||||
|
|
||||||
Callback<T(T, T, T, T)> callback(static_func4);
|
Callback<T(T, T, T, T)> cb(static_func4);
|
||||||
Verifier<T>::verify4(callback);
|
Verifier<T>::verify4(cb);
|
||||||
callback.attach(&thing, &bound_func4<T>);
|
cb = static_func4;
|
||||||
Verifier<T>::verify4(&callback, &Callback<T(T, T, T, T)>::call);
|
Verifier<T>::verify4(cb);
|
||||||
Verifier<T>::verify4((void*)&callback, &Callback<T(T, T, T, T)>::thunk);
|
cb.attach(&thing, &bound_func4<T>);
|
||||||
|
Verifier<T>::verify4(&cb, &Callback<T(T, T, T, T)>::call);
|
||||||
|
Verifier<T>::verify4((void*)&cb, &Callback<T(T, T, T, T)>::thunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -348,20 +318,14 @@ void test_dispatch5() {
|
||||||
Verifier<T>::verify5((volatile Thing<T>*)&thing, &volatile_func5<T>);
|
Verifier<T>::verify5((volatile Thing<T>*)&thing, &volatile_func5<T>);
|
||||||
Verifier<T>::verify5((const volatile Thing<T>*)&thing, &const_volatile_func5<T>);
|
Verifier<T>::verify5((const volatile Thing<T>*)&thing, &const_volatile_func5<T>);
|
||||||
Verifier<T>::verify5(callback(static_func5<T>));
|
Verifier<T>::verify5(callback(static_func5<T>));
|
||||||
Verifier<T>::verify5(callback(&thing, &Thing<T>::member_func5));
|
|
||||||
Verifier<T>::verify5(callback((const Thing<T>*)&thing, &Thing<T>::const_member_func5));
|
|
||||||
Verifier<T>::verify5(callback((volatile Thing<T>*)&thing, &Thing<T>::volatile_member_func5));
|
|
||||||
Verifier<T>::verify5(callback((const volatile Thing<T>*)&thing, &Thing<T>::const_volatile_member_func5));
|
|
||||||
Verifier<T>::verify5(callback(&thing, &bound_func5<T>));
|
|
||||||
Verifier<T>::verify5(callback((const Thing<T>*)&thing, &const_func5<T>));
|
|
||||||
Verifier<T>::verify5(callback((volatile Thing<T>*)&thing, &volatile_func5<T>));
|
|
||||||
Verifier<T>::verify5(callback((const volatile Thing<T>*)&thing, &const_volatile_func5<T>));
|
|
||||||
|
|
||||||
Callback<T(T, T, T, T, T)> callback(static_func5);
|
Callback<T(T, T, T, T, T)> cb(static_func5);
|
||||||
Verifier<T>::verify5(callback);
|
Verifier<T>::verify5(cb);
|
||||||
callback.attach(&thing, &bound_func5<T>);
|
cb = static_func5;
|
||||||
Verifier<T>::verify5(&callback, &Callback<T(T, T, T, T, T)>::call);
|
Verifier<T>::verify5(cb);
|
||||||
Verifier<T>::verify5((void*)&callback, &Callback<T(T, T, T, T, T)>::thunk);
|
cb.attach(&thing, &bound_func5<T>);
|
||||||
|
Verifier<T>::verify5(&cb, &Callback<T(T, T, T, T, T)>::call);
|
||||||
|
Verifier<T>::verify5((void*)&cb, &Callback<T(T, T, T, T, T)>::thunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
||||||
1259
hal/api/Callback.h
1259
hal/api/Callback.h
File diff suppressed because it is too large
Load Diff
|
|
@ -43,6 +43,18 @@ public:
|
||||||
R (*get_function())(A1) {
|
R (*get_function())(A1) {
|
||||||
return *reinterpret_cast<R (**)(A1)>(this);
|
return *reinterpret_cast<R (**)(A1)>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R call(A1 a1) const {
|
||||||
|
if (!Callback<R(A1)>::operator bool()) {
|
||||||
|
return (R)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Callback<R(A1)>::call(a1);
|
||||||
|
}
|
||||||
|
|
||||||
|
R operator()(A1 a1) const {
|
||||||
|
return Callback<R(A1)>::call(a1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename R>
|
template <typename R>
|
||||||
|
|
@ -62,6 +74,18 @@ public:
|
||||||
R (*get_function())() {
|
R (*get_function())() {
|
||||||
return *reinterpret_cast<R (**)()>(this);
|
return *reinterpret_cast<R (**)()>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
R call() const {
|
||||||
|
if (!Callback<R()>::operator bool()) {
|
||||||
|
return (R)0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Callback<R()>::call();
|
||||||
|
}
|
||||||
|
|
||||||
|
R operator()() const {
|
||||||
|
return Callback<R()>::call();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef FunctionPointerArg1<void, void> FunctionPointer;
|
typedef FunctionPointerArg1<void, void> FunctionPointer;
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,15 @@
|
||||||
|
|
||||||
namespace mbed {
|
namespace mbed {
|
||||||
|
|
||||||
|
static void donothing() {}
|
||||||
|
|
||||||
CAN::CAN(PinName rd, PinName td) : _can(), _irq() {
|
CAN::CAN(PinName rd, PinName td) : _can(), _irq() {
|
||||||
// No lock needed in constructor
|
// No lock needed in constructor
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
|
||||||
|
_irq[i].attach(donothing);
|
||||||
|
}
|
||||||
|
|
||||||
can_init(&_can, rd, td);
|
can_init(&_can, rd, td);
|
||||||
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
|
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
|
||||||
}
|
}
|
||||||
|
|
@ -100,6 +107,7 @@ void CAN::attach(Callback<void()> func, IrqType type) {
|
||||||
_irq[(CanIrqType)type].attach(func);
|
_irq[(CanIrqType)type].attach(func);
|
||||||
can_irq_set(&_can, (CanIrqType)type, 1);
|
can_irq_set(&_can, (CanIrqType)type, 1);
|
||||||
} else {
|
} else {
|
||||||
|
_irq[(CanIrqType)type].attach(donothing);
|
||||||
can_irq_set(&_can, (CanIrqType)type, 0);
|
can_irq_set(&_can, (CanIrqType)type, 0);
|
||||||
}
|
}
|
||||||
unlock();
|
unlock();
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,17 @@
|
||||||
|
|
||||||
namespace mbed {
|
namespace mbed {
|
||||||
|
|
||||||
|
static void donothing() {}
|
||||||
|
|
||||||
InterruptIn::InterruptIn(PinName pin) : gpio(),
|
InterruptIn::InterruptIn(PinName pin) : gpio(),
|
||||||
gpio_irq(),
|
gpio_irq(),
|
||||||
_rise(),
|
_rise(),
|
||||||
_fall() {
|
_fall() {
|
||||||
// No lock needed in the constructor
|
// No lock needed in the constructor
|
||||||
|
|
||||||
|
_rise.attach(donothing);
|
||||||
|
_fall.attach(donothing);
|
||||||
|
|
||||||
gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), (uint32_t)this);
|
gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), (uint32_t)this);
|
||||||
gpio_init_in(&gpio, pin);
|
gpio_init_in(&gpio, pin);
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +56,7 @@ void InterruptIn::rise(Callback<void()> func) {
|
||||||
_rise.attach(func);
|
_rise.attach(func);
|
||||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
|
gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
|
||||||
} else {
|
} else {
|
||||||
_rise.attach(NULL);
|
_rise.attach(donothing);
|
||||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 0);
|
gpio_irq_set(&gpio_irq, IRQ_RISE, 0);
|
||||||
}
|
}
|
||||||
core_util_critical_section_exit();
|
core_util_critical_section_exit();
|
||||||
|
|
@ -62,7 +68,7 @@ void InterruptIn::fall(Callback<void()> func) {
|
||||||
_fall.attach(func);
|
_fall.attach(func);
|
||||||
gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
|
gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
|
||||||
} else {
|
} else {
|
||||||
_fall.attach(NULL);
|
_fall.attach(donothing);
|
||||||
gpio_irq_set(&gpio_irq, IRQ_FALL, 0);
|
gpio_irq_set(&gpio_irq, IRQ_FALL, 0);
|
||||||
}
|
}
|
||||||
core_util_critical_section_exit();
|
core_util_critical_section_exit();
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
namespace mbed {
|
namespace mbed {
|
||||||
|
|
||||||
|
static void donothing() {};
|
||||||
|
|
||||||
SerialBase::SerialBase(PinName tx, PinName rx) :
|
SerialBase::SerialBase(PinName tx, PinName rx) :
|
||||||
#if DEVICE_SERIAL_ASYNCH
|
#if DEVICE_SERIAL_ASYNCH
|
||||||
_thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
|
_thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
|
||||||
|
|
@ -29,6 +31,10 @@ SerialBase::SerialBase(PinName tx, PinName rx) :
|
||||||
_serial(), _baud(9600) {
|
_serial(), _baud(9600) {
|
||||||
// No lock needed in the constructor
|
// No lock needed in the constructor
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
|
||||||
|
_irq[i].attach(donothing);
|
||||||
|
}
|
||||||
|
|
||||||
serial_init(&_serial, tx, rx);
|
serial_init(&_serial, tx, rx);
|
||||||
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
|
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
|
||||||
}
|
}
|
||||||
|
|
@ -69,6 +75,7 @@ void SerialBase::attach(Callback<void()> func, IrqType type) {
|
||||||
_irq[type].attach(func);
|
_irq[type].attach(func);
|
||||||
serial_irq_set(&_serial, (SerialIrq)type, 1);
|
serial_irq_set(&_serial, (SerialIrq)type, 1);
|
||||||
} else {
|
} else {
|
||||||
|
_irq[type].attach(donothing);
|
||||||
serial_irq_set(&_serial, (SerialIrq)type, 0);
|
serial_irq_set(&_serial, (SerialIrq)type, 0);
|
||||||
}
|
}
|
||||||
core_util_critical_section_exit();
|
core_util_critical_section_exit();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue