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((const volatile Thing<T>*)&thing, &const_volatile_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);
 | 
			
		||||
    Verifier<T>::verify0(callback);
 | 
			
		||||
    callback.attach(&thing, &bound_func0<T>);
 | 
			
		||||
    Verifier<T>::verify0(&callback, &Callback<T()>::call);
 | 
			
		||||
    Verifier<T>::verify0((void*)&callback, &Callback<T()>::thunk);
 | 
			
		||||
    Callback<T()> cb(static_func0);
 | 
			
		||||
    Verifier<T>::verify0(cb);
 | 
			
		||||
    cb = static_func0;
 | 
			
		||||
    Verifier<T>::verify0(cb);
 | 
			
		||||
    cb.attach(&thing, &bound_func0<T>);
 | 
			
		||||
    Verifier<T>::verify0(&cb, &Callback<T()>::call);
 | 
			
		||||
    Verifier<T>::verify0((void*)&cb, &Callback<T()>::thunk);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
| 
						 | 
				
			
			@ -232,20 +226,14 @@ void test_dispatch1() {
 | 
			
		|||
    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(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);
 | 
			
		||||
    Verifier<T>::verify1(callback);
 | 
			
		||||
    callback.attach(&thing, &bound_func1<T>);
 | 
			
		||||
    Verifier<T>::verify1(&callback, &Callback<T(T)>::call);
 | 
			
		||||
    Verifier<T>::verify1((void*)&callback, &Callback<T(T)>::thunk);
 | 
			
		||||
    Callback<T(T)> cb(static_func1);
 | 
			
		||||
    Verifier<T>::verify1(cb);
 | 
			
		||||
    cb = static_func1;
 | 
			
		||||
    Verifier<T>::verify1(cb);
 | 
			
		||||
    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>
 | 
			
		||||
| 
						 | 
				
			
			@ -261,20 +249,14 @@ void test_dispatch2() {
 | 
			
		|||
    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(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);
 | 
			
		||||
    Verifier<T>::verify2(callback);
 | 
			
		||||
    callback.attach(&thing, &bound_func2<T>);
 | 
			
		||||
    Verifier<T>::verify2(&callback, &Callback<T(T, T)>::call);
 | 
			
		||||
    Verifier<T>::verify2((void*)&callback, &Callback<T(T, T)>::thunk);
 | 
			
		||||
    Callback<T(T, T)> cb(static_func2);
 | 
			
		||||
    Verifier<T>::verify2(cb);
 | 
			
		||||
    cb = static_func2;
 | 
			
		||||
    Verifier<T>::verify2(cb);
 | 
			
		||||
    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>
 | 
			
		||||
| 
						 | 
				
			
			@ -290,20 +272,14 @@ void test_dispatch3() {
 | 
			
		|||
    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(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);
 | 
			
		||||
    Verifier<T>::verify3(callback);
 | 
			
		||||
    callback.attach(&thing, &bound_func3<T>);
 | 
			
		||||
    Verifier<T>::verify3(&callback, &Callback<T(T, T, T)>::call);
 | 
			
		||||
    Verifier<T>::verify3((void*)&callback, &Callback<T(T, T, T)>::thunk);
 | 
			
		||||
    Callback<T(T, T, T)> cb(static_func3);
 | 
			
		||||
    Verifier<T>::verify3(cb);
 | 
			
		||||
    cb = static_func3;
 | 
			
		||||
    Verifier<T>::verify3(cb);
 | 
			
		||||
    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>
 | 
			
		||||
| 
						 | 
				
			
			@ -319,20 +295,14 @@ void test_dispatch4() {
 | 
			
		|||
    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(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);
 | 
			
		||||
    Verifier<T>::verify4(callback);
 | 
			
		||||
    callback.attach(&thing, &bound_func4<T>);
 | 
			
		||||
    Verifier<T>::verify4(&callback, &Callback<T(T, T, T, T)>::call);
 | 
			
		||||
    Verifier<T>::verify4((void*)&callback, &Callback<T(T, T, T, T)>::thunk);
 | 
			
		||||
    Callback<T(T, T, T, T)> cb(static_func4);
 | 
			
		||||
    Verifier<T>::verify4(cb);
 | 
			
		||||
    cb = static_func4;
 | 
			
		||||
    Verifier<T>::verify4(cb);
 | 
			
		||||
    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>
 | 
			
		||||
| 
						 | 
				
			
			@ -348,20 +318,14 @@ void test_dispatch5() {
 | 
			
		|||
    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(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);
 | 
			
		||||
    Verifier<T>::verify5(callback);
 | 
			
		||||
    callback.attach(&thing, &bound_func5<T>);
 | 
			
		||||
    Verifier<T>::verify5(&callback, &Callback<T(T, T, T, T, T)>::call);
 | 
			
		||||
    Verifier<T>::verify5((void*)&callback, &Callback<T(T, T, T, T, T)>::thunk);
 | 
			
		||||
    Callback<T(T, T, T, T, T)> cb(static_func5);
 | 
			
		||||
    Verifier<T>::verify5(cb);
 | 
			
		||||
    cb = static_func5;
 | 
			
		||||
    Verifier<T>::verify5(cb);
 | 
			
		||||
    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>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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) {
 | 
			
		||||
        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>
 | 
			
		||||
| 
						 | 
				
			
			@ -62,6 +74,18 @@ public:
 | 
			
		|||
    R (*get_function())() {
 | 
			
		||||
        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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,8 +21,15 @@
 | 
			
		|||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
static void donothing() {}
 | 
			
		||||
 | 
			
		||||
CAN::CAN(PinName rd, PinName td) : _can(), _irq() {
 | 
			
		||||
    // 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_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);
 | 
			
		||||
        can_irq_set(&_can, (CanIrqType)type, 1);
 | 
			
		||||
    } else {
 | 
			
		||||
        _irq[(CanIrqType)type].attach(donothing);
 | 
			
		||||
        can_irq_set(&_can, (CanIrqType)type, 0);
 | 
			
		||||
    }
 | 
			
		||||
    unlock();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,11 +19,17 @@
 | 
			
		|||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
static void donothing() {}
 | 
			
		||||
 | 
			
		||||
InterruptIn::InterruptIn(PinName pin) : gpio(),
 | 
			
		||||
                                        gpio_irq(),
 | 
			
		||||
                                        _rise(),
 | 
			
		||||
                                        _fall() {
 | 
			
		||||
    // 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_init_in(&gpio, pin);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +56,7 @@ void InterruptIn::rise(Callback<void()> func) {
 | 
			
		|||
        _rise.attach(func);
 | 
			
		||||
        gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
 | 
			
		||||
    } else {
 | 
			
		||||
        _rise.attach(NULL);
 | 
			
		||||
        _rise.attach(donothing);
 | 
			
		||||
        gpio_irq_set(&gpio_irq, IRQ_RISE, 0);
 | 
			
		||||
    }
 | 
			
		||||
    core_util_critical_section_exit();
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +68,7 @@ void InterruptIn::fall(Callback<void()> func) {
 | 
			
		|||
        _fall.attach(func);
 | 
			
		||||
        gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
 | 
			
		||||
    } else {
 | 
			
		||||
        _fall.attach(NULL);
 | 
			
		||||
        _fall.attach(donothing);
 | 
			
		||||
        gpio_irq_set(&gpio_irq, IRQ_FALL, 0);
 | 
			
		||||
    }
 | 
			
		||||
    core_util_critical_section_exit();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,8 @@
 | 
			
		|||
 | 
			
		||||
namespace mbed {
 | 
			
		||||
 | 
			
		||||
static void donothing() {};
 | 
			
		||||
 | 
			
		||||
SerialBase::SerialBase(PinName tx, PinName rx) :
 | 
			
		||||
#if DEVICE_SERIAL_ASYNCH
 | 
			
		||||
                                                 _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
 | 
			
		||||
| 
						 | 
				
			
			@ -29,6 +31,10 @@ SerialBase::SerialBase(PinName tx, PinName rx) :
 | 
			
		|||
                                                _serial(), _baud(9600) {
 | 
			
		||||
    // 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_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);
 | 
			
		||||
        serial_irq_set(&_serial, (SerialIrq)type, 1);
 | 
			
		||||
    } else {
 | 
			
		||||
        _irq[type].attach(donothing);
 | 
			
		||||
        serial_irq_set(&_serial, (SerialIrq)type, 0);
 | 
			
		||||
    }
 | 
			
		||||
    core_util_critical_section_exit();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue