Skip to content

Commit 0cbfd0c

Browse files
committed
P2963R3 Ordering of constraints involving fold expressions
1 parent 6d67d20 commit 0cbfd0c

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

source/compatibility.tex

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
\end{codeblock}
3434
\end{example}
3535

36-
\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: Declarations}
36+
\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: declarations}
3737

3838
\diffref{dcl.init.list}
3939
\change
@@ -76,6 +76,32 @@
7676
\end{codeblock}
7777
\end{example}
7878

79+
\rSec2[diff.cpp23.temp]{\ref{temp}: templates}
80+
81+
\diffref{temp.constr}
82+
\change
83+
Some atomic constraints become fold expanded constraints.
84+
\rationale
85+
Permit the subsumption of fold expressions.
86+
\effect
87+
Valid \CppXXIII{} code may become ill-formed.
88+
\begin{example}
89+
\begin{codeblock}
90+
template <typename ...V> struct A;
91+
struct S {
92+
static constexpr int compare(const S&) { return 1; }
93+
};
94+
95+
template <typename ...T, typename ...U>
96+
void f(A<T ...> *, A<U ...> *)
97+
requires (T::compare(U{}) && ...); // was well-formed (atomic constraint of type \tcode{bool}),
98+
// now ill-formed (results in an atomic constraint of type \tcode{int})
99+
void g(A<S, S> *ap) {
100+
f(ap, ap);
101+
}
102+
\end{codeblock}
103+
\end{example}
104+
79105
\rSec2[diff.cpp23.library]{\ref{library}: library introduction}
80106

81107
\diffref{headers}

source/templates.tex

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,11 +1480,12 @@
14801480
A \defn{constraint} is a sequence of logical operations and
14811481
operands that specifies requirements on template arguments.
14821482
The operands of a logical operation are constraints.
1483-
There are three different kinds of constraints:
1483+
There are four different kinds of constraints:
14841484
\begin{itemize}
14851485
\item conjunctions\iref{temp.constr.op},
1486-
\item disjunctions\iref{temp.constr.op}, and
1487-
\item atomic constraints\iref{temp.constr.atomic}.
1486+
\item disjunctions\iref{temp.constr.op},
1487+
\item atomic constraints\iref{temp.constr.atomic}, and
1488+
\item fold expanded constraints\iref{temp.constr.fold}.
14881489
\end{itemize}
14891490

14901491
\pnum
@@ -1719,6 +1720,47 @@
17191720
\end{codeblock}
17201721
\end{example}
17211722

1723+
\rSec3[temp.constr.fold]{Fold expanded constraint}
1724+
1725+
\pnum
1726+
A \defnadj{fold expanded}{constraint} is formed from a constraint $C$ and
1727+
a \grammarterm{fold-operator}
1728+
which can either be \tcode{\&\&} or \tcode{||}.
1729+
A fold expanded constraint is a pack expansion\iref{temp.variadic}.
1730+
Let $N$ be the number of elements
1731+
in the pack expansion parameters\iref{temp.variadic}.
1732+
1733+
\pnum
1734+
A fold expanded constraint whose \grammarterm{fold-operator} is \tcode{\&\&}
1735+
is satisfied if it is a valid pack expansion and
1736+
if $N = 0$ or if for each $i$ where $0 \le i < N$ in increasing order,
1737+
$C$ is satisfied
1738+
when replacing each pack expansion parameter
1739+
with the corresponding $i$-th element.
1740+
No substitution takes place for any $i$ greater than
1741+
the smallest $i$ for which the constraint is not satisfied.
1742+
1743+
\pnum
1744+
A fold expanded constraint whose \grammarterm{fold-operator} is \tcode{||}
1745+
is satisfied if it is a valid pack expansion,
1746+
$N > 0$, and if for $i$ where $0 \le i < N$ in increasing order,
1747+
there is a smallest $i$ for which $C$ is satisfied
1748+
when replacing each pack expansion parameter
1749+
with the corresponding $i$-th element.
1750+
No substitution takes place for any $i$ greater than
1751+
the smallest $i$ for which the constraint is satisfied.
1752+
1753+
\pnum
1754+
\begin{note}
1755+
If the pack expansion expands packs of different size,
1756+
then it is invalid and the fold expanded constraint is not satisfied.
1757+
\end{note}
1758+
1759+
\pnum
1760+
Two fold expanded constraints are \defn{compatible for subsumption}
1761+
if their respective constraints both contain
1762+
an equivalent unexpanded pack\iref{temp.over.link}.
1763+
17221764
\rSec2[temp.constr.decl]{Constrained declarations}
17231765

17241766
\pnum
@@ -1894,6 +1936,40 @@
18941936
in the parameter mapping.
18951937
\end{example}
18961938

1939+
\item
1940+
For a \grammarterm{fold-operator}\iref{expr.prim.fold}
1941+
that is either \tcode{\&\&} or \tcode{||},
1942+
the normal form of an expression
1943+
\tcode{( ... \grammarterm{fold-operator} E )} is the normal form of
1944+
\tcode{( E \grammarterm{fold-operator} ... )}.
1945+
1946+
\item
1947+
For a \grammarterm{fold-operator}
1948+
that is either \tcode{\&\&} or \tcode{||},
1949+
the normal form of an expression
1950+
\tcode{( E1 \grammarterm{fold-operator} ... \grammarterm{fold-operator} E2 )}
1951+
is the the normal form of
1952+
\begin{itemize}
1953+
\item
1954+
\tcode{( E1 \grammarterm{fold-operator} ... ) \grammarterm{fold-operator} E2}
1955+
if \tcode{E1} contains an unexpanded pack, or
1956+
\item
1957+
\tcode{E1 \grammarterm{fold-operator} ( E2 \grammarterm{fold-operator} ... )}
1958+
otherwise.
1959+
\end{itemize}
1960+
1961+
\item
1962+
The normal form of \tcode{( E \&\& ... )} is
1963+
a fold expanded constraint\iref{temp.constr.fold}
1964+
whose constraint is the normal form of \tcode{E} and
1965+
whose \grammarterm{fold-operator} is \tcode{\&\&}.
1966+
1967+
\item
1968+
The normal form of \tcode{( E || ... )} is
1969+
a fold expanded constraint
1970+
whose constraint is the normal form of \tcode{E} and
1971+
whose \grammarterm{fold-operator} is \tcode{||}.
1972+
18971973
\item
18981974
The normal form of any other expression \tcode{E} is
18991975
the atomic constraint
@@ -1971,11 +2047,17 @@
19712047
\item
19722048
a disjunctive clause $P_i$ subsumes a conjunctive clause $Q_j$ if and only
19732049
if there exists an atomic constraint $P_{ia}$ in $P_i$ for which there exists
1974-
an atomic constraint $Q_{jb}$ in $Q_j$ such that $P_{ia}$ subsumes $Q_{jb}$, and
2050+
an atomic constraint $Q_{jb}$ in $Q_j$ such that $P_{ia}$ subsumes $Q_{jb}$,
19752051

19762052
\item an atomic constraint $A$ subsumes another atomic constraint
19772053
$B$ if and only if $A$ and $B$ are identical using the
1978-
rules described in \ref{temp.constr.atomic}.
2054+
rules described in \ref{temp.constr.atomic}, and
2055+
2056+
\item a fold expanded constraint $A$ subsumes
2057+
another fold expanded constraint $B$
2058+
if they are compatible for subsumption,
2059+
have the same \grammarterm{fold-operator}, and
2060+
the constraint of $A$ subsumes that of $B$.
19792061
\end{itemize}
19802062
%
19812063
\begin{example}
@@ -2789,6 +2871,9 @@
27892871
\item In a \grammarterm{fold-expression}\iref{expr.prim.fold};
27902872
the pattern is the \grammarterm{cast-expression}
27912873
that contains an unexpanded pack.
2874+
2875+
\item In a fold expanded constraint\iref{temp.constr.fold};
2876+
the pattern is the constraint of that fold expanded constraint.
27922877
\end{itemize}
27932878

27942879
\begin{example}
@@ -2976,6 +3061,9 @@
29763061
\tcode{,} & \tcode{void()} \\
29773062
\end{floattable}
29783063

3064+
\pnum
3065+
A fold expanded constraint is not instantiated\iref{temp.constr.fold}.
3066+
29793067
\pnum
29803068
The instantiation of any other pack expansion
29813069
produces a list of elements $\tcode{E}_1, \tcode{E}_2, \dotsc, \tcode{E}_N$.

0 commit comments

Comments
 (0)