Define INVOKE(f, t, t, …, t) as follows:

- (t.*f)(t, …, t) when f is a pointer to a member function of a class T and is_base_of_v<T, remove_reference_t<decltype(t)>> is true;
- (t.get().*f)(t, …, t) when f is a pointer to a member function of a class T and remove_cvref_t<decltype(t)> is a specialization of reference_wrapper;
- ((*t).*f)(t, …, t) when f is a pointer to a member function of a class T and t does not satisfy the previous two items;
- t.*f when N == 1 and f is a pointer to data member of a class T and is_base_of_v<T, remove_reference_t<decltype(t)>> is true;
- t.get().*f when N == 1 and f is a pointer to data member of a class T and remove_cvref_t<decltype(t)> is a specialization of reference_wrapper;
- (*t).*f when N == 1 and f is a pointer to data member of a class T and t does not satisfy the previous two items;
- f(t, t, …, t) in all other cases.

Define INVOKE<R>(f, t, t, …, t) as
static_cast<void>(INVOKE(f, t, t, …, t))
if R is cv void, otherwise
INVOKE(f, t, t, …, t) implicitly converted
to R.

A *forwarding call wrapper* is a
call wrapper that can be called with an arbitrary argument list
and delivers the arguments to the wrapped callable object as references.

This forwarding step shall ensure that rvalue arguments are delivered as rvalue references
and lvalue arguments are delivered as lvalue references.

A *simple call wrapper* is a forwarding call wrapper that is
CopyConstructible and CopyAssignable and
whose copy constructor, move constructor, copy assignment operator,
and move assignment operator do not throw exceptions.

[ Note

: *end note*

]In a typical implementation
forwarding call wrappers have an overloaded function call
operator of
the form

— ```
template<class... UnBoundArgs>
R operator()(UnBoundArgs&&... unbound_args) cv-qual;
```