Skip to content

Reduce Event.h and EventQueue.h using C++11 #10895

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Revert back to non-variadic binding
Unwind previous commit and restore original behaviour for binding,
pending further investigation.

Some functions like `EventQueue::call` require precisely matching
argument types to get the correct overload, as before.

Others like `EventQueue::event` permit compatible types for binding, and
those handle the 0-5 bound arguments non-variadically in order to
correctly locate the free arguments in deduction.
  • Loading branch information
kjbracey committed Jun 26, 2019
commit 013377a85773a6d00e04514a526b7049c20d1cb3
352 changes: 322 additions & 30 deletions events/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,30 +251,142 @@ class Event<void(ArgTs...)> {
/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename... BoundArgTs>
Event(EventQueue *q, T *obj, R(T::*method)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args) :
Event(q, mbed::callback(obj, method), context_args...) { }
template <typename T, typename R, typename B0>
Event(EventQueue *q, T *obj, R(T::*method)(B0, ArgTs...), B0 b0) :
Event(q, mbed::callback(obj, method), b0) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename... BoundArgTs>
Event(EventQueue *q, const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, impl::type_identity_t<BoundArgTs>... context_args) :
Event(q, mbed::callback(obj, method), context_args...) { }
template <typename T, typename R, typename B0>
Event(EventQueue *q, const T *obj, R(T::*method)(B0, ArgTs...) const, B0 b0) :
Event(q, mbed::callback(obj, method), b0) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename... BoundArgTs>
Event(EventQueue *q, volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, impl::type_identity_t<BoundArgTs>... context_args) :
Event(q, mbed::callback(obj, method), context_args...) { }
template <typename T, typename R, typename B0>
Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, ArgTs...) volatile, B0 b0) :
Event(q, mbed::callback(obj, method), b0) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename... BoundArgTs>
Event(EventQueue *q, const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, impl::type_identity_t<BoundArgTs>... context_args) :
Event(q, mbed::callback(obj, method), context_args...) { }
template <typename T, typename R, typename B0>
Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, ArgTs...) const volatile, B0 b0) :
Event(q, mbed::callback(obj, method), b0) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1>
Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, ArgTs...), B0 b0, B1 b1) :
Event(q, mbed::callback(obj, method), b0, b1) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1>
Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, ArgTs...) const, B0 b0, B1 b1) :
Event(q, mbed::callback(obj, method), b0, b1) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1>
Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, ArgTs...) volatile, B0 b0, B1 b1) :
Event(q, mbed::callback(obj, method), b0, b1) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1>
Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, ArgTs...) const volatile, B0 b0, B1 b1) :
Event(q, mbed::callback(obj, method), b0, b1) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2>
Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, ArgTs...), B0 b0, B1 b1, B2 b2) :
Event(q, mbed::callback(obj, method), b0, b1, b2) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2>
Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const, B0 b0, B1 b1, B2 b2) :
Event(q, mbed::callback(obj, method), b0, b1, b2) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2>
Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) volatile, B0 b0, B1 b1, B2 b2) :
Event(q, mbed::callback(obj, method), b0, b1, b2) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2>
Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const volatile, B0 b0, B1 b1, B2 b2) :
Event(q, mbed::callback(obj, method), b0, b1, b2) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3>
Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...), B0 b0, B1 b1, B2 b2, B3 b3) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3>
Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const, B0 b0, B1 b1, B2 b2, B3 b3) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3>
Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) volatile, B0 b0, B1 b1, B2 b2, B3 b3) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3>
Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const volatile, B0 b0, B1 b1, B2 b2, B3 b3) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4>
Event(EventQueue *q, T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...), B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4>
Event(EventQueue *q, const T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4>
Event(EventQueue *q, volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4) { }

/** Create an event
* @see Event::Event
*/
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4>
Event(EventQueue *q, const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const volatile, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) :
Event(q, mbed::callback(obj, method), b0, b1, b2, b3, b4) { }
};


Expand All @@ -283,40 +395,220 @@ class Event<void(ArgTs...)> {

// Convenience functions declared here to avoid cyclic
// dependency between Event and EventQueue
template <typename R, typename... BoundArgTs, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args)
template <typename R, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(ArgTs...))
{
return Event<void(ArgTs...)>(this, func);
}

template <typename T, typename R, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(ArgTs...))
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method));
}

template <typename T, typename R, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(ArgTs...) const)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method));
}

template <typename T, typename R, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(ArgTs...) volatile)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method));
}

template <typename T, typename R, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(ArgTs...) const volatile)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method));
}

template <typename R, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(ArgTs...)> cb)
{
return Event<void(ArgTs...)>(this, cb);
}

template <typename R, typename B0, typename C0, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(B0, ArgTs...), C0 c0)
{
return Event<void(ArgTs...)>(this, func, c0);
}

template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(B0, ArgTs...), C0 c0)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0);
}

template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(B0, ArgTs...) const, C0 c0)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0);
}

template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(B0, ArgTs...) volatile, C0 c0)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0);
}

template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(B0, ArgTs...) const volatile, C0 c0)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0);
}

template <typename R, typename B0, typename C0, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(B0, ArgTs...)> cb, C0 c0)
{
return Event<void(ArgTs...)>(this, cb, c0);
}

template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(B0, B1, ArgTs...), C0 c0, C1 c1)
{
return Event<void(ArgTs...)>(this, func, c0, c1);
}

template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(B0, B1, ArgTs...), C0 c0, C1 c1)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1);
}

template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(B0, B1, ArgTs...) const, C0 c0, C1 c1)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1);
}

template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, ArgTs...) volatile, C0 c0, C1 c1)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1);
}

template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, ArgTs...) const volatile, C0 c0, C1 c1)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1);
}

template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(B0, B1, ArgTs...)> cb, C0 c0, C1 c1)
{
return Event<void(ArgTs...)>(this, cb, c0, c1);
}

template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2)
{
return Event<void(ArgTs...)>(this, func, c0, c1, c2);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const, C0 c0, C1 c1, C2 c2)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) volatile, C0 c0, C1 c1, C2 c2)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2);
}

template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(B0, B1, B2, ArgTs...)> cb, C0 c0, C1 c1, C2 c2)
{
return Event<void(ArgTs...)>(this, cb, c0, c1, c2);
}

template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3)
{
return Event<void(ArgTs...)>(this, func, c0, c1, c2, c3);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}

template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2, C3 c3)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3);
}

template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3)
{
return Event<void(ArgTs...)>(this, cb, c0, c1, c2, c3);
}

template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(R(*func)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
{
return Event<void(ArgTs...)>(this, func, context_args...);
return Event<void(ArgTs...)>(this, func, c0, c1, c2, c3, c4);
}

template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(BoundArgTs..., ArgTs...), impl::type_identity_t<BoundArgTs>... context_args)
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}

template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const, impl::type_identity_t<BoundArgTs>... context_args)
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}

template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) volatile, impl::type_identity_t<BoundArgTs>... context_args)
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}

template <typename T, typename R, typename... BoundArgTs, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(BoundArgTs..., ArgTs...) const volatile, impl::type_identity_t<BoundArgTs>... context_args)
template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
{
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), context_args...);
return Event<void(ArgTs...)>(this, mbed::callback(obj, method), c0, c1, c2, c3, c4);
}

template <typename R, typename... BoundArgTs, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(BoundArgTs..., ArgTs...)> cb, impl::type_identity_t<BoundArgTs>... context_args)
template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
Event<void(ArgTs...)> EventQueue::event(mbed::Callback<R(B0, B1, B2, B3, B4, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
{
return Event<void(ArgTs...)>(this, cb, context_args...);
return Event<void(ArgTs...)>(this, cb, c0, c1, c2, c3, c4);
}
}

Expand Down
Loading