diff --git a/source/concepts.tex b/source/concepts.tex index defd96dcb7..b35446a51e 100644 --- a/source/concepts.tex +++ b/source/concepts.tex @@ -479,8 +479,7 @@ is_lvalue_reference_v && CommonReference&, const remove_reference_t&> && requires(LHS lhs, RHS&& rhs) { - lhs = std::forward(rhs); - requires Same(rhs)), LHS>; + { lhs = std::forward(rhs) } -> Same; }; \end{itemdecl} @@ -757,19 +756,19 @@ requires(const remove_reference_t& b1, const remove_reference_t& b2, const bool a) { requires ConvertibleTo&, bool>; - !b1; requires ConvertibleTo; - b1 && a; requires Same; - b1 || a; requires Same; - b1 && b2; requires Same; - a && b2; requires Same; - b1 || b2; requires Same; - a || b2; requires Same; - b1 == b2; requires ConvertibleTo; - b1 == a; requires ConvertibleTo; - a == b2; requires ConvertibleTo; - b1 != b2; requires ConvertibleTo; - b1 != a; requires ConvertibleTo; - a != b2; requires ConvertibleTo; + { !b1 } -> ConvertibleTo; + { b1 && a } -> Same; + { b1 || a } -> Same; + { b1 && b2 } -> Same; + { a && b2 } -> Same; + { b1 || b2 } -> Same; + { a || b2 } -> Same; + { b1 == b2 } -> ConvertibleTo; + { b1 == a } -> ConvertibleTo; + { a == b2 } -> ConvertibleTo; + { b1 != b2 } -> ConvertibleTo; + { b1 != a } -> ConvertibleTo; + { a != b2 } -> ConvertibleTo; }; \end{itemdecl} @@ -811,10 +810,10 @@ concept @\placeholder{weakly-equality-comparable-with}@ = // \expos requires(const remove_reference_t& t, const remove_reference_t& u) { - t == u; requires Boolean; - t != u; requires Boolean; - u == t; requires Boolean; - u != t; requires Boolean; + { t == u } -> Boolean; + { t != u } -> Boolean; + { u == t } -> Boolean; + { u != t } -> Boolean; }; \end{itemdecl} @@ -888,10 +887,10 @@ EqualityComparable && requires(const remove_reference_t& a, const remove_reference_t& b) { - a < b; requires Boolean; - a > b; requires Boolean b)>; - a <= b; requires Boolean; - a >= b; requires Boolean= b)>; + { a < b } -> Boolean; + { a > b } -> Boolean; + { a <= b } -> Boolean; + { a >= b } -> Boolean; }; \end{itemdecl} @@ -925,14 +924,14 @@ EqualityComparableWith && requires(const remove_reference_t& t, const remove_reference_t& u) { - t < u; requires Boolean; - t > u; requires Boolean u)>; - t <= u; requires Boolean; - t >= u; requires Boolean= u)>; - u < t; requires Boolean; - u > t; requires Boolean t)>; - u <= t; requires Boolean; - u >= t; requires Boolean= t)>; + { t < u } -> Boolean; + { t > u } -> Boolean; + { t <= u } -> Boolean; + { t >= u } -> Boolean; + { u < t } -> Boolean; + { u > t } -> Boolean; + { u <= t } -> Boolean; + { u >= t } -> Boolean; }; \end{itemdecl} diff --git a/source/expressions.tex b/source/expressions.tex index 0d4993009c..fd971051db 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2600,7 +2600,7 @@ \begin{bnf} \nontermdef{return-type-requirement}\br trailing-return-type\br - \terminal{->} \opt{cv-qualifier-seq} constrained-parameter \opt{cv-qualifier-seq} \opt{abstract-declarator} + \terminal{->} type-constraint \end{bnf} \pnum @@ -2610,45 +2610,43 @@ semantic properties proceed in the following order: \begin{itemize} -\item Substitution of template arguments (if any) -into the \grammarterm{expression} is performed. - -\item If the \tcode{noexcept} specifier is present, -\tcode{E} shall not be a potentially-throwing expression\iref{except.spec}. - -\item If the \grammarterm{return-type-requirement} is present, then: - -\begin{itemize} -\item Substitution of template arguments (if any) -into the \grammarterm{return-type-requirement} is performed. - -\item If the \grammarterm{return-type-requirement} is a -\grammarterm{trailing-return-type}, -%%% FIXME: is -> shall be -\tcode{E} is implicitly convertible to -the type named by the \grammarterm{trailing-return-type}. -If conversion fails, the enclosing \grammarterm{requires-expression} -is \tcode{false}. - -\item If the \grammarterm{return-type-requirement} -starts with a \grammarterm{constrained-parameter}\iref{temp.param}, -the \grammarterm{expression} is deduced against -an invented function template \tcode{F} -using the rules in \ref{temp.deduct.call}. -\tcode{F} is a \tcode{void} function template -with a single type template parameter \tcode{T} -declared with the \grammarterm{constrained-parameter}. -A \grammarterm{cv-qualifier-seq} \cv{} is formed -as the union of \tcode{const} and \tcode{volatile} specifiers -around the \grammarterm{constrained-parameter}. -\tcode{F} has a single parameter -whose \grammarterm{type-specifier} is \cv{}~\tcode{T} -followed by the \grammarterm{abstract-declarator}. -%%% FIXME: Remove this; if deduction fails, the construct should -%%% be ill-formed. -If deduction fails, -the enclosing \grammarterm{requires-expression} is \tcode{false}. -\end{itemize} +\item + Substitution of template arguments (if any) + into the \grammarterm{expression} is performed. +\item + If the \tcode{noexcept} specifier is present, + \tcode{E} shall not be a potentially-throwing expression\iref{except.spec}. +\item + If the \grammarterm{return-type-requirement} is present, then: + \begin{itemize} + \item + Substitution of template arguments (if any) + into the \grammarterm{return-type-requirement} is performed. + \item + If the \grammarterm{return-type-requirement} is a + \grammarterm{trailing-return-type}\iref{dcl.decl}, + %%% FIXME: is -> shall be + \tcode{E} is implicitly convertible to + the type named by the \grammarterm{trailing-return-type}. + If conversion fails, the enclosing \grammarterm{requires-expression} + is \tcode{false}. + \item + If the \grammarterm{return-type-requirement} + is of the form \tcode{->} \grammarterm{type-constraint}, then + the contextually-determined type being constrained + is \tcode{decltype((E))}. + The immediately-declared constraint\iref{temp} of \tcode{decltype((E))} + shall be satisfied. + \begin{note} + Thus, constraints of the form + \tcode{\{ E \} -> Concept;} or of the form + \tcode{\{ E \} -> Concept<>;} are equivalent to + \tcode{E; requires Concept;} + while a constraint of the form + \tcode{\{ E \} -> Concept;} is equivalent to + \tcode{E; requires Concept;}. + \end{note} + \end{itemize} \end{itemize} \begin{example} @@ -2675,32 +2673,13 @@ \tcode{typename T::inner}. \begin{codeblock} -template concept C3 = requires (T t, U u) { - t == u; -}; -template concept C4 = requires(T x) { - {*x} -> C3 const&; -}; -\end{codeblock} -The \grammarterm{compound-requirement} -requires that \tcode{*x} be deduced -as an argument for the invented function: -\begin{codeblock} -template X> void f(X const&); -\end{codeblock} -In this case, deduction only succeeds if -an expression of the type deduced for \tcode{X} -can be compared to an \tcode{int} -with the \tcode{==} operator. - -\begin{codeblock} -template concept C5 = +template concept C3 = requires(T x) { {g(x)} noexcept; }; \end{codeblock} -The \grammarterm{compound-requirement} in \tcode{C5} +The \grammarterm{compound-requirement} in \tcode{C3} requires that \tcode{g(x)} is a valid expression and that \tcode{g(x)} is non-throwing. \end{example}