diff --git a/source/meta.tex b/source/meta.tex index cb8e6e7ade..6a7d79b2bc 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -276,6 +276,9 @@ template struct is_nothrow_invocable; template struct is_nothrow_invocable_r; + template struct is_applicable; + template struct is_nothrow_applicable; + // \ref{meta.trans.cv}, const-volatile modifications template struct remove_const; template struct remove_volatile; @@ -348,6 +351,7 @@ template struct common_reference; template struct underlying_type; template struct invoke_result; + template struct apply_result; template struct unwrap_reference; template struct unwrap_ref_decay; @@ -369,6 +373,8 @@ using @\libglobal{underlying_type_t}@ = typename underlying_type::type; template using @\libglobal{invoke_result_t}@ = typename invoke_result::type; + template + using @\libglobal{apply_result_t}@ = typename apply_result::type; template using unwrap_reference_t = typename unwrap_reference::type; template @@ -575,6 +581,11 @@ template constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r::value; + template + constexpr bool @\libglobal{is_applicable_v}@ = is_applicable::value; + template + constexpr bool @\libglobal{is_nothrow_applicable_v}@ + = is_nothrow_applicable::value; // \ref{meta.logical}, logical operator traits template @@ -639,6 +650,13 @@ \tcode{true_type} if the corresponding condition is \tcode{true}, otherwise \tcode{false_type}. +\pnum +Let \tcode{\placeholdernc{ELEMS-OF}(T)} be the parameter pack +\tcode{get<\exposid{N}>(declval())}, where \exposid{N} is the pack of +\tcode{size_t} template arguments of the specialization of +\tcode{index_sequence} denoted by +\tcode{make_index_sequence>>}. + \rSec3[meta.unary.cat]{Primary type categories} \pnum @@ -1588,6 +1606,27 @@ is known not to throw any exceptions\iref{expr.unary.noexcept} & \tcode{Fn}, \tcode{R}, and all types in the template parameter pack \tcode{ArgTypes} shall be complete types, \cv{}~\keyword{void}, or + arrays of unknown bound. \\ \rowsep + +\indexlibraryglobal{is_applicable}% +\tcode{template}\br + \tcode{struct is_applicable;} & + \tcode{\exposconcept{tuple-like}} is \tcode{true} and + the expression + \tcode{\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...)} + is well-formed when treated as an unevaluated operand. & + \tcode{Fn} and \tcode{Tuple} + shall be complete types, \cv{}~\keyword{void}, or + arrays of unknown bound. \\ \rowsep + +\indexlibraryglobal{is_nothrow_applicable}% +\tcode{template}\br + \tcode{struct is_nothrow_applicable;} & + \tcode{is_applicable_v<}\br\tcode{Fn, Tuple>} is \tcode{true} and + the expression \tcode{\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...)} + is known not to throw any exceptions\iref{expr.unary.noexcept}. & + \tcode{Fn} and \tcode{Tuple} + shall be complete types, \cv{}~\keyword{void}, or arrays of unknown bound. \\ \end{libreqtab3f} @@ -2029,6 +2068,32 @@ are complete types, \cv{}~\keyword{void}, or arrays of unknown bound.\\ \rowsep +\tcode{template}\br + \tcode{struct \libglobal{apply_result};} + & + If \tcode{\exposconcept{tuple-like}} is \tcode{true} + and the expression + \tcode{\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...)}\iref{func.require} + is well-formed + when treated as an unevaluated operand\iref{term.unevaluated.operand}, + the member typedef \tcode{type} denotes the type + \tcode{decltype(\placeholdernc{INVOKE}(declval(), \placeholdernc{ELEMS-OF}(Tuple)...))}; + otherwise, there shall be no member \tcode{type}. + Access checking is performed as if in a context unrelated to \tcode{Fn} + and \tcode{Tuple}. + Only the validity of the immediate context of the expression is considered. + \begin{note} + The compilation of the expression can result in side effects + such as the instantiation of class template specializations + and function template specializations, + the generation of implicitly-defined functions, and so on. + Such side effects are not in the ``immediate context'' + and can result in the program being ill-formed. + \end{note} + \expects + \tcode{Fn} and \tcode{Tuple} are complete types, \cv{}~\keyword{void}, + or arrays of unknown bound.\\ \rowsep + \tcode{template} \tcode{struct \libglobal{unwrap_reference};} & If \tcode{T} is diff --git a/source/utilities.tex b/source/utilities.tex index ced638f3f7..ca964f69f4 100644 --- a/source/utilities.tex +++ b/source/utilities.tex @@ -1569,7 +1569,8 @@ // \ref{tuple.apply}, calling a function with a tuple of arguments template - constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(@\seebelow@); + constexpr apply_result_t apply(F&& f, Tuple&& t) + noexcept(is_nothrow_applicable_v); template constexpr T make_from_tuple(Tuple&& t); @@ -2688,7 +2689,8 @@ \indexlibraryglobal{apply}% \begin{itemdecl} template - constexpr decltype(auto) apply(F&& f, Tuple&& t) noexcept(@\seebelow@); + constexpr apply_result_t apply(F&& f, Tuple&& t) + noexcept(is_nothrow_applicable_v); \end{itemdecl} \begin{itemdescr} @@ -2709,15 +2711,6 @@ return @\placeholdernc{apply-impl}@(std::forward(f), std::forward(t), make_index_sequence>>{}); \end{codeblock} - -\pnum -\remarks -Let \tcode{I} be the pack -\tcode{0, 1, $\dotsc$, (tuple_size_v> - 1)}. -The exception specification is equivalent to: -\begin{codeblock} -noexcept(invoke(std::forward(f), get(std::forward(t))...)) -\end{codeblock} \end{itemdescr} \indexlibraryglobal{make_from_tuple}%