Skip to content

Commit 5babe7e

Browse files
committed
Constrain context argument types
Previous commit just replaced instances of "class B0, class B1, class C0, class C1" with "class... BoundArgs, class... ContextArgs". This loses the requirement that the numbers must match. Now, the original code was also inconsistent as to whether it used separate types for the target function and the call input parameters. Some forms just used B0, B1 as parameters rather than separate C0, C1. I believe the separate parameters would have been primarily to avoid template deduction confusion - eg if int was supplied to a B0 parameter but the function took char as B0, there would be an ambiguity. But the fix didn't seem to be fully applied. Rewritten all templates parameterising on function pointer type and input arguments so that they use `type_identity_t<BoundArgTs>...` as input parameters to match the target function. This has the subtle effect that any conversion happens at invocation, before storing to the context, rather than when the context calls the target.
1 parent 4d9148a commit 5babe7e

File tree

2 files changed

+45
-34
lines changed

2 files changed

+45
-34
lines changed

events/Event.h

+16-16
Original file line numberDiff line numberDiff line change
@@ -252,28 +252,28 @@ class Event<void(ArgTs...)> {
252252
* @see Event::Event
253253
*/
254254
template <typename T, typename R, typename... BoundArgTs>
255-
Event(EventQueue *q, T *obj, R(T::*method)(BoundArgTs..., ArgTs...), BoundArgTs... context_args) :
255+
Event(EventQueue *q, T *obj, R(T::*method)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args) :
256256
Event(q, mbed::callback(obj, method), context_args...) { }
257257

258258
/** Create an event
259259
* @see Event::Event
260260
*/
261261
template <typename T, typename R, typename... BoundArgTs>
262-
Event(EventQueue *q, const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, BoundArgTs... context_args) :
262+
Event(EventQueue *q, const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, impl::type_identity_t<BoundArgTs>... context_args) :
263263
Event(q, mbed::callback(obj, method), context_args...) { }
264264

265265
/** Create an event
266266
* @see Event::Event
267267
*/
268268
template <typename T, typename R, typename... BoundArgTs>
269-
Event(EventQueue *q, volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, BoundArgTs... context_args) :
269+
Event(EventQueue *q, volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, impl::type_identity_t<BoundArgTs>... context_args) :
270270
Event(q, mbed::callback(obj, method), context_args...) { }
271271

272272
/** Create an event
273273
* @see Event::Event
274274
*/
275275
template <typename T, typename R, typename... BoundArgTs>
276-
Event(EventQueue *q, const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, BoundArgTs... context_args) :
276+
Event(EventQueue *q, const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, impl::type_identity_t<BoundArgTs>... context_args) :
277277
Event(q, mbed::callback(obj, method), context_args...) { }
278278
};
279279

@@ -283,38 +283,38 @@ class Event<void(ArgTs...)> {
283283

284284
// Convenience functions declared here to avoid cyclic
285285
// dependency between Event and EventQueue
286-
template <typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
287-
Event<void(ArgTs...)> EventQueue::event(R(*func)(BoundArgTs..., ArgTs...), ContextArgTs... context_args)
286+
template <typename R, typename... BoundArgTs, typename... ArgTs>
287+
Event<void(ArgTs...)> EventQueue::event(R(*func)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args)
288288
{
289289
return Event<void(ArgTs...)>(this, func, context_args...);
290290
}
291291

292-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
293-
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(BoundArgTs..., ArgTs...), ContextArgTs... context_args)
292+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
293+
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args)
294294
{
295295
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
296296
}
297297

298-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
299-
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, ContextArgTs... context_args)
298+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
299+
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, impl::type_identity_t<BoundArgTs>... context_args)
300300
{
301301
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
302302
}
303303

304-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
305-
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, ContextArgTs... context_args)
304+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
305+
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, impl::type_identity_t<BoundArgTs>... context_args)
306306
{
307307
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
308308
}
309309

310-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
311-
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, ContextArgTs... context_args)
310+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
311+
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, impl::type_identity_t<BoundArgTs>... context_args)
312312
{
313313
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
314314
}
315315

316-
template <typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
317-
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(BoundArgTs..., ArgTs...)> cb, ContextArgTs... context_args)
316+
template <typename R, typename... BoundArgTs, typename... ArgTs>
317+
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(BoundArgTs..., ArgTs...)> cb, impl::type_identity_t<BoundArgTs>... context_args)
318318
{
319319
return Event<void(ArgTs...)>(this, cb, context_args...);
320320
}

events/EventQueue.h

+29-18
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ namespace events {
3939
*/
4040
#define EVENTS_QUEUE_SIZE (32*EVENTS_EVENT_SIZE)
4141

42+
namespace impl {
43+
/* C++20 type identity */
44+
template<typename T>
45+
struct type_identity {
46+
using type = T;
47+
};
48+
49+
template <typename T>
50+
using type_identity_t = typename type_identity<T>::type;
51+
}
52+
4253
// Predeclared classes
4354
template <typename F>
4455
class Event;
@@ -498,8 +509,8 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
498509
*/
499510
// AStyle ignore, not handling correctly below
500511
// *INDENT-OFF*
501-
template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
502-
Event<void(Args...)> event(R (*func)(BoundArgs..., Args...), ContextArgs ...context_args);
512+
template <typename R, typename ...BoundArgs, typename ...Args>
513+
Event<void(Args...)> event(R (*func)(BoundArgs..., Args...), BoundArgs ...context_args);
503514
// *INDENT-ON*
504515

505516
/** Creates an event bound to the event queue
@@ -546,8 +557,8 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
546557
*/
547558
// AStyle ignore, not handling correctly below
548559
// *INDENT-OFF*
549-
template <typename T, typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
550-
Event<void(Args...)> event(T *obj, R (T::*method)(BoundArgs..., Args...), ContextArgs ...context_args);
560+
template <typename T, typename R, typename ...BoundArgs, typename ...Args>
561+
Event<void(Args...)> event(T *obj, R (T::*method)(BoundArgs..., Args...), BoundArgs ...context_args);
551562
// *INDENT-ON*
552563

553564
/** Creates an event bound to the event queue
@@ -585,8 +596,8 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
585596
* }
586597
* @endcode
587598
*/
588-
template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
589-
Event<void(Args...)> event(mbed::Callback<R(BoundArgs..., Args...)> cb, ContextArgs ...context_args);
599+
template <typename R, typename ...BoundArgs, typename ...Args>
600+
Event<void(Args...)> event(mbed::Callback<R(BoundArgs..., Args...)> cb, BoundArgs ...context_args);
590601

591602
#else
592603

@@ -847,38 +858,38 @@ class EventQueue : private mbed::NonCopyable<EventQueue> {
847858
* @param func Function to execute when the event is dispatched
848859
* @return Event that will dispatch on the specific queue
849860
*/
850-
template <typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
851-
Event<void(ArgTs...)> event(R(*func)(BoundArgTs..., ArgTs...), ContextArgTs... context_args);
861+
template <typename R, typename... BoundArgTs, typename... ArgTs>
862+
Event<void(ArgTs...)> event(R(*func)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args);
852863

853864
/** Creates an event bound to the event queue
854865
* @see EventQueue::event
855866
*/
856-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
857-
Event<void(ArgTs...)> event(T *obj, R(T::*method)(BoundArgTs..., ArgTs...), ContextArgTs... context_args);
867+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
868+
Event<void(ArgTs...)> event(T *obj, R(T::*method)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args);
858869

859870
/** Creates an event bound to the event queue
860871
* @see EventQueue::event
861872
*/
862-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
863-
Event<void(ArgTs...)> event(const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, ContextArgTs... context_args);
873+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
874+
Event<void(ArgTs...)> event(const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, impl::type_identity_t<BoundArgTs>... context_args);
864875

865876
/** Creates an event bound to the event queue
866877
* @see EventQueue::event
867878
*/
868-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
869-
Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, ContextArgTs... context_args);
879+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
880+
Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, impl::type_identity_t<BoundArgTs>... context_args);
870881

871882
/** Creates an event bound to the event queue
872883
* @see EventQueue::event
873884
*/
874-
template <typename T, typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
875-
Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, ContextArgTs... context_args);
885+
template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
886+
Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, impl::type_identity_t<BoundArgTs>... context_args);
876887

877888
/** Creates an event bound to the event queue
878889
* @see EventQueue::event
879890
*/
880-
template <typename R, typename... BoundArgTs, typename... ContextArgTs, typename... ArgTs>
881-
Event<void(ArgTs...)> event(mbed::Callback<R(BoundArgTs..., ArgTs...)> cb, ContextArgTs... context_args);
891+
template <typename R, typename... BoundArgTs, typename... ArgTs>
892+
Event<void(ArgTs...)> event(mbed::Callback<R(BoundArgTs..., ArgTs...)> cb, impl::type_identity_t<BoundArgTs>... context_args);
882893
#endif
883894

884895
protected:

0 commit comments

Comments
 (0)