Eggs.Invoke is a C++11/14/17/20 single-header implementation of
INVOKE
and its related facilities. See the documentation at
http://eggs-cpp.github.io/invoke/.
Define INVOKE(f, t1, t2, ..., tN)
as follows:
-
(t1.*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andstd::is_base_of_v<T, std::remove_reference_t<decltype(t1)>>
istrue
; -
(t1.get().*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andstd::remove_cvref_t<decltype(t1)>
is a specialization ofstd::reference_wrapper
; -
((*t1).*f)(t2, ..., tN)
whenf
is a pointer to a member function of a classT
andt1
does not satisfy the previous two items; -
t1.*f
whenN == 1
andf
is a pointer to data member of a classT
andstd::is_base_of_v<T, std::remove_reference_t<decltype(t1)>>
istrue
; -
t1.get().*f
whenN == 1
andf
is a pointer to data member of a classT
andstd::remove_cvref_t<decltype(t1)>
is a specialization ofstd::reference_wrapper
; -
(*t1).*f
whenN == 1
andf
is a pointer to data member of a classT
andt1
does not satisfy the previous two items; -
f(t1, t2, ..., tN)
in all other cases.
Define INVOKE<R>(f, t1, t2, ..., tN)
as static_cast<void>(INVOKE(f, t1, t2, ..., tN))
if R
is cv void
, otherwise INVOKE(f, t1, t2, ..., tN)
implicitly converted to R
.
template <class F, class... Args>
constexpr eggs::invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
noexcept(eggs::is_nothrow_invocable_v<F, Args...>);
-
Returns:
INVOKE(std::forward<F>(f), std::forward<Args>(args)...)
. -
Remarks: This function shall not participate in overload resolution unless
eggs::is_invocable_v<F, Args...>
istrue
.
template <class R, class F, class... Args> // (extension)
constexpr R eggs::invoke_r(F&& f, Args&&... args)
noexcept(eggs::is_nothrow_invocable_r_v<R, F, Args...>);
-
Returns:
INVOKE<R>(std::forward<F>(f), std::forward<Args>(args)...)
. -
Remarks: This function shall not participate in overload resolution unless
eggs::is_invocable_r_v<R, F, Args...>
istrue
.
template <class Fn, class... ArgTypes> struct invoke_result;
-
Comments: If the expression
INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand, the member typedeftype
names the typedecltype(INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...))
; otherwise, there shall be no membertype
. Access checking is performed as if in a context unrelated toFn
andArgTypes
. Only the validity of the immediate context of the expression is considered. -
Preconditions:
Fn
and all types in the template parameter packArgTypes
are complete types, cvvoid
, or arrays of unknown bound.
template <class Fn, class... ArgTypes>
using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type;
template <class Fn, class... ArgTypes> struct is_invocable;
-
Condition: The expression
INVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand. -
Comments:
Fn
and all types in the template parameter packArgTypes
shall be complete types, cvvoid
, or arrays of unknown bound.
template <class Fn, class... ArgTypes> // (C++14)
inline constexpr bool is_invocable_v =
eggs::is_invocable<Fn, ArgTypes...>::value;
template <class R, class Fn, class... ArgTypes> struct is_invocable_r;
-
Condition: The expression
INVOKE<R>(std::declval<Fn>(), std::declval<ArgTypes>()...)
is well-formed when treated as an unevaluated operand. -
Comments:
Fn
,R
, and all types in the template parameter packArgTypes
shall be complete types, cvvoid
, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes> // (C++14)
inline constexpr bool is_invocable_r_v =
eggs::is_invocable_r<R, Fn, ArgTypes...>::value;
template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
-
Condition:
eggs::is_invocable_v<Fn, ArgTypes...>
istrue
and the expressionINVOKE(std::declval<Fn>(), std::declval<ArgTypes>()...)
is known not to throw any exceptions. -
Comments:
Fn
and all types in the template parameter packArgTypes
shall be complete types, cvvoid
, or arrays of unknown bound.
template <class Fn, class... ArgTypes> // (C++14)
inline constexpr bool is_nothrow_invocable_v =
eggs::is_nothrow_invocable<Fn, ArgTypes...>::value;
template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
-
Condition:
eggs::is_invocable_r_v<R, Fn, ArgTypes...>
istrue
and the expressionINVOKE<R>(std::declval<Fn>(), std::declval<ArgTypes>()...)
is known not to throw any exceptions. -
Comments:
Fn
,R
, and all types in the template parameter packArgTypes
shall be complete types, cvvoid
, or arrays of unknown bound.
template <class R, class Fn, class... ArgTypes> // (C++14)
inline constexpr bool is_nothrow_invocable_r_v =
eggs::is_nothrow_invocable_r<R, Fn, ArgTypes...>::value;
#define EGGS_INVOKE(F, ...) // (extension)
- Returns:
INVOKE(F __VA_OPT__(,) __VA_ARGS__)
.
#define EGGS_INVOKE_R(R, F, ...) // (extension)
- Returns:
INVOKE<R>(F __VA_OPT__(,) __VA_ARGS__)
.
Copyright Agustín Bergé, Fusion Fenix 2017-2020
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)