Skip to content

Commit e7c077e

Browse files
authored
Merge 2018-11 CWG Motion 4
P1084R2 Today’s return-type-requirements Are Insufficient Fixes #2397
2 parents de65470 + fb22bbd commit e7c077e

File tree

2 files changed

+68
-77
lines changed

2 files changed

+68
-77
lines changed

source/concepts.tex

+30-31
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,7 @@
479479
is_lvalue_reference_v<LHS> &&
480480
CommonReference<const remove_reference_t<LHS>&, const remove_reference_t<RHS>&> &&
481481
requires(LHS lhs, RHS&& rhs) {
482-
lhs = std::forward<RHS>(rhs);
483-
requires Same<decltype(lhs = std::forward<RHS>(rhs)), LHS>;
482+
{ lhs = std::forward<RHS>(rhs) } -> Same<LHS>;
484483
};
485484
\end{itemdecl}
486485

@@ -757,19 +756,19 @@
757756
requires(const remove_reference_t<B>& b1,
758757
const remove_reference_t<B>& b2, const bool a) {
759758
requires ConvertibleTo<const remove_reference_t<B>&, bool>;
760-
!b1; requires ConvertibleTo<decltype(!b1), bool>;
761-
b1 && a; requires Same<decltype(b1 && a), bool>;
762-
b1 || a; requires Same<decltype(b1 || a), bool>;
763-
b1 && b2; requires Same<decltype(b1 && b2), bool>;
764-
a && b2; requires Same<decltype( a && b2), bool>;
765-
b1 || b2; requires Same<decltype(b1 || b2), bool>;
766-
a || b2; requires Same<decltype( a || b2), bool>;
767-
b1 == b2; requires ConvertibleTo<decltype(b1 == b2), bool>;
768-
b1 == a; requires ConvertibleTo<decltype(b1 == a), bool>;
769-
a == b2; requires ConvertibleTo<decltype( a == b2), bool>;
770-
b1 != b2; requires ConvertibleTo<decltype(b1 != b2), bool>;
771-
b1 != a; requires ConvertibleTo<decltype(b1 != a), bool>;
772-
a != b2; requires ConvertibleTo<decltype( a != b2), bool>;
759+
{ !b1 } -> ConvertibleTo<bool>;
760+
{ b1 && a } -> Same<bool>;
761+
{ b1 || a } -> Same<bool>;
762+
{ b1 && b2 } -> Same<bool>;
763+
{ a && b2 } -> Same<bool>;
764+
{ b1 || b2 } -> Same<bool>;
765+
{ a || b2 } -> Same<bool>;
766+
{ b1 == b2 } -> ConvertibleTo<bool>;
767+
{ b1 == a } -> ConvertibleTo<bool>;
768+
{ a == b2 } -> ConvertibleTo<bool>;
769+
{ b1 != b2 } -> ConvertibleTo<bool>;
770+
{ b1 != a } -> ConvertibleTo<bool>;
771+
{ a != b2 } -> ConvertibleTo<bool>;
773772
};
774773
\end{itemdecl}
775774

@@ -811,10 +810,10 @@
811810
concept @\placeholder{weakly-equality-comparable-with}@ = // \expos
812811
requires(const remove_reference_t<T>& t,
813812
const remove_reference_t<U>& u) {
814-
t == u; requires Boolean<decltype(t == u)>;
815-
t != u; requires Boolean<decltype(t != u)>;
816-
u == t; requires Boolean<decltype(u == t)>;
817-
u != t; requires Boolean<decltype(u != t)>;
813+
{ t == u } -> Boolean;
814+
{ t != u } -> Boolean;
815+
{ u == t } -> Boolean;
816+
{ u != t } -> Boolean;
818817
};
819818
\end{itemdecl}
820819

@@ -888,10 +887,10 @@
888887
EqualityComparable<T> &&
889888
requires(const remove_reference_t<T>& a,
890889
const remove_reference_t<T>& b) {
891-
a < b; requires Boolean<decltype(a < b)>;
892-
a > b; requires Boolean<decltype(a > b)>;
893-
a <= b; requires Boolean<decltype(a <= b)>;
894-
a >= b; requires Boolean<decltype(a >= b)>;
890+
{ a < b } -> Boolean;
891+
{ a > b } -> Boolean;
892+
{ a <= b } -> Boolean;
893+
{ a >= b } -> Boolean;
895894
};
896895
\end{itemdecl}
897896

@@ -925,14 +924,14 @@
925924
EqualityComparableWith<T, U> &&
926925
requires(const remove_reference_t<T>& t,
927926
const remove_reference_t<U>& u) {
928-
t < u; requires Boolean<decltype(t < u)>;
929-
t > u; requires Boolean<decltype(t > u)>;
930-
t <= u; requires Boolean<decltype(t <= u)>;
931-
t >= u; requires Boolean<decltype(t >= u)>;
932-
u < t; requires Boolean<decltype(u < t)>;
933-
u > t; requires Boolean<decltype(u > t)>;
934-
u <= t; requires Boolean<decltype(u <= t)>;
935-
u >= t; requires Boolean<decltype(u >= t)>;
927+
{ t < u } -> Boolean;
928+
{ t > u } -> Boolean;
929+
{ t <= u } -> Boolean;
930+
{ t >= u } -> Boolean;
931+
{ u < t } -> Boolean;
932+
{ u > t } -> Boolean;
933+
{ u <= t } -> Boolean;
934+
{ u >= t } -> Boolean;
936935
};
937936
\end{itemdecl}
938937

source/expressions.tex

+38-46
Original file line numberDiff line numberDiff line change
@@ -2597,7 +2597,7 @@
25972597
\begin{bnf}
25982598
\nontermdef{return-type-requirement}\br
25992599
trailing-return-type\br
2600-
\terminal{->} \opt{cv-qualifier-seq} constrained-parameter \opt{cv-qualifier-seq} \opt{abstract-declarator}
2600+
\terminal{->} qualified-concept-name
26012601
\end{bnf}
26022602

26032603
\pnum
@@ -2607,44 +2607,55 @@
26072607
semantic properties proceed in the following order:
26082608

26092609
\begin{itemize}
2610-
\item Substitution of template arguments (if any)
2610+
\item
2611+
Substitution of template arguments (if any)
26112612
into the \grammarterm{expression} is performed.
26122613

2613-
\item If the \tcode{noexcept} specifier is present,
2614+
\item
2615+
If the \tcode{noexcept} specifier is present,
26142616
\tcode{E} shall not be a potentially-throwing expression\iref{except.spec}.
26152617

2616-
\item If the \grammarterm{return-type-requirement} is present, then:
2618+
\item
2619+
If the \grammarterm{return-type-requirement} is present, then:
26172620

26182621
\begin{itemize}
2619-
\item Substitution of template arguments (if any)
2622+
\item
2623+
Substitution of template arguments (if any)
26202624
into the \grammarterm{return-type-requirement} is performed.
26212625

2622-
\item If the \grammarterm{return-type-requirement} is a
2623-
\grammarterm{trailing-return-type},
2626+
\item
2627+
If the \grammarterm{return-type-requirement} is a
2628+
\grammarterm{trailing-return-type}\iref{dcl.decl},
26242629
%%% FIXME: is -> shall be
26252630
\tcode{E} is implicitly convertible to
26262631
the type named by the \grammarterm{trailing-return-type}.
26272632
If conversion fails, the enclosing \grammarterm{requires-expression}
26282633
is \tcode{false}.
26292634

2630-
\item If the \grammarterm{return-type-requirement}
2631-
starts with a \grammarterm{constrained-parameter}\iref{temp.param},
2632-
the \grammarterm{expression} is deduced against
2633-
an invented function template \tcode{F}
2634-
using the rules in \ref{temp.deduct.call}.
2635-
\tcode{F} is a \tcode{void} function template
2636-
with a single type template parameter \tcode{T}
2637-
declared with the \grammarterm{constrained-parameter}.
2638-
A \grammarterm{cv-qualifier-seq} \cv{} is formed
2639-
as the union of \tcode{const} and \tcode{volatile} specifiers
2640-
around the \grammarterm{constrained-parameter}.
2641-
\tcode{F} has a single parameter
2642-
whose \grammarterm{type-specifier} is \cv{}~\tcode{T}
2643-
followed by the \grammarterm{abstract-declarator}.
2644-
%%% FIXME: Remove this; if deduction fails, the construct should
2645-
%%% be ill-formed.
2646-
If deduction fails,
2647-
the enclosing \grammarterm{requires-expression} is \tcode{false}.
2635+
\item
2636+
If the \grammarterm{return-type-requirement} has
2637+
a \grammarterm{qualified-concept-name}\iref{temp.param} of the form
2638+
\opt{\grammarterm{nested-name-specifier}} \grammarterm{concept-name},
2639+
the concept it denotes shall be satisfied with
2640+
\tcode{decltype((E))} as its sole argument.
2641+
If the \grammarterm{return-type-requirement} has
2642+
a \grammarterm{qualified-concept-name} of the form
2643+
\opt{\grammarterm{nested-name-specifier}} \grammarterm{concept-name}
2644+
\tcode{<} \opt{\grammarterm{template-argument-list}} \tcode{>},
2645+
the concept it denotes shall be satisfied with
2646+
\tcode{decltype((E))} as its first argument and with
2647+
the elements, in the order listed, of
2648+
the \grammarterm{template-argument-list}
2649+
comprising the concept's subsequent arguments.
2650+
\begin{note}
2651+
Thus, requirements of the form
2652+
\tcode{\{ E \} -> Concept;} or of the form
2653+
\tcode{\{ E \} -> Concept<>;} are equivalent to
2654+
\tcode{E; requires Concept<decltype((E))>;}
2655+
while a requirements of the form
2656+
\tcode{\{ E \} -> Concept<A$_1$, A$_2$, $\cdots$, A$_n$>;} is equivalent to
2657+
\tcode{E; requires Concept<decltype((E)), A$_1$, A$_2$, $\cdots$, A$_n$>;}.
2658+
\end{note}
26482659
\end{itemize}
26492660
\end{itemize}
26502661

@@ -2672,32 +2683,13 @@
26722683
\tcode{typename T::inner}.
26732684

26742685
\begin{codeblock}
2675-
template<typename T, typename U> concept C3 = requires (T t, U u) {
2676-
t == u;
2677-
};
2678-
template<typename T> concept C4 = requires(T x) {
2679-
{*x} -> C3<int> const&;
2680-
};
2681-
\end{codeblock}
2682-
The \grammarterm{compound-requirement}
2683-
requires that \tcode{*x} be deduced
2684-
as an argument for the invented function:
2685-
\begin{codeblock}
2686-
template<C3<int> X> void f(X const&);
2687-
\end{codeblock}
2688-
In this case, deduction only succeeds if
2689-
an expression of the type deduced for \tcode{X}
2690-
can be compared to an \tcode{int}
2691-
with the \tcode{==} operator.
2692-
2693-
\begin{codeblock}
2694-
template<typename T> concept C5 =
2686+
template<typename T> concept C3 =
26952687
requires(T x) {
26962688
{g(x)} noexcept;
26972689
};
26982690
\end{codeblock}
26992691

2700-
The \grammarterm{compound-requirement} in \tcode{C5}
2692+
The \grammarterm{compound-requirement} in \tcode{C3}
27012693
requires that \tcode{g(x)} is a valid expression and
27022694
that \tcode{g(x)} is non-throwing.
27032695
\end{example}

0 commit comments

Comments
 (0)