Skip to content

Commit 10e913b

Browse files
committed
Merge 2014-11 CWG Motion 13
2 parents 898a7ff + 84c3e66 commit 10e913b

2 files changed

Lines changed: 155 additions & 3 deletions

File tree

source/expressions.tex

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@
323323
\terminal{this}\br
324324
\terminal{(} expression \terminal{)}\br
325325
id-expression\br
326-
lambda-expression
326+
lambda-expression\br
327+
fold-expression
327328
\end{bnf}
328329

329330
\begin{bnf}
@@ -1165,6 +1166,76 @@
11651166
\indextext{expression!lambda|)}%
11661167
\indextext{expression!primary|)}
11671168

1169+
\rSec2[expr.prim.fold]{Fold expressions}%
1170+
\indextext{expression!fold|(}
1171+
1172+
\pnum
1173+
A fold expression performs a fold of a template parameter
1174+
pack~(\ref{temp.variadic}) over a binary operator.
1175+
1176+
\begin{bnf}
1177+
\nontermdef{fold-expression}\br
1178+
\terminal{(} cast-expression fold-operator \terminal{...} \terminal{)}\br
1179+
\terminal{(} \terminal{...} fold-operator cast-expression \terminal{)}\br
1180+
\terminal{(} cast-expression fold-operator \terminal{...} fold-operator cast-expression \terminal{)}
1181+
\end{bnf}
1182+
1183+
\begin{bnf}
1184+
\nontermdef{fold-operator} \textnormal{one of}\br
1185+
\terminal{+ }\quad\terminal{- }\quad\terminal{* }\quad\terminal{/ }\quad\terminal{\% }\quad\terminal{\^{} }\quad\terminal{\& }\quad\terminal{| }\quad\terminal{\shl\ }\quad\terminal{\shr }\br
1186+
\terminal{+=}\quad\terminal{-=}\quad\terminal{*=}\quad\terminal{/=}\quad\terminal{\%=}\quad\terminal{\^{}=}\quad\terminal{\&=}\quad\terminal{|=}\quad\terminal{\shl=}\quad\terminal{\shr=}\quad\terminal{=}\br
1187+
\terminal{==}\quad\terminal{!=}\quad\terminal{< }\quad\terminal{> }\quad\terminal{<=}\quad\terminal{>=}\quad\terminal{\&\&}\quad\terminal{||}\quad\terminal{, }\quad\terminal{.* }\quad\terminal{->*}
1188+
\end{bnf}
1189+
1190+
\pnum
1191+
\indextext{fold!unary}%
1192+
An expression of the form
1193+
\tcode{(...} \placeholder{op} \tcode{e)}
1194+
where \placeholder{op} is a \grammarterm{fold-operator}
1195+
is called a \defn{unary left fold}.
1196+
An expression of the form
1197+
\tcode{(e} \placeholder{op} \tcode{...)}
1198+
where \placeholder{op} is a \grammarterm{fold-operator}
1199+
is called a \defn{unary right fold}.
1200+
Unary left folds and unary right folds
1201+
are collectively called \defnx{unary folds}{unary fold}.
1202+
In a unary fold,
1203+
the \grammarterm{cast-expression}
1204+
shall contain an unexpanded parameter pack~(\ref{temp.variadic}).
1205+
1206+
\pnum
1207+
\indextext{fold!binary}%
1208+
An expression of the form
1209+
\tcode{(e1} \placeholder{op1} \tcode{...} \placeholder{op2} \tcode{e2)}
1210+
where \placeholder{op1} and \placeholder{op2} are \grammarterm{fold-operator}{s}
1211+
is called a \defn{binary fold}.
1212+
In a binary fold,
1213+
\placeholder{op1} and \placeholder{op2}
1214+
shall be the same \grammarterm{fold-operator},
1215+
and either \tcode{e1}
1216+
shall contain an unexpanded parameter pack
1217+
or \tcode{e2}
1218+
shall contain an unexpanded parameter pack,
1219+
but not both.
1220+
If \tcode{e2} contains an unexpanded parameter pack,
1221+
the expression is called a \defn{binary left fold}.
1222+
If \tcode{e1} contains an unexpanded parameter pack,
1223+
the expression is called a \defn{binary right fold}.
1224+
\enterexample
1225+
\begin{codeblock}
1226+
template<typename ...Args>
1227+
bool f(Args ...args) {
1228+
return (true && ... && args); // OK
1229+
}
1230+
1231+
template<typename ...Args>
1232+
bool f(Args ...args) {
1233+
return (args + ... + args); // error: both operands contain unexpanded parameter packs
1234+
}
1235+
\end{codeblock}
1236+
\exitexample
1237+
\indextext{expression!fold|)}
1238+
11681239
\rSec1[expr.post]{Postfix expressions}%
11691240
\indextext{expression!postfix|(}
11701241

source/templates.tex

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,6 +1745,10 @@
17451745

17461746
\item In a \tcode{sizeof...} expression~(\ref{expr.sizeof}); the pattern is an
17471747
\grammarterm{identifier}.
1748+
1749+
\item In a \grammarterm{fold-expression} (\ref{expr.prim.fold});
1750+
the pattern is the \grammarterm{cast-expression}
1751+
that contains an unexpanded parameter pack.
17481752
\end{itemize}
17491753

17501754
\pnum
@@ -1804,7 +1808,8 @@
18041808

18051809
\pnum
18061810
The instantiation of a pack expansion
1807-
that is not a \tcode{sizeof...} expression
1811+
that is neither a \tcode{sizeof...} expression
1812+
nor a \grammarterm{fold-expression}
18081813
produces a
18091814
list
18101815
$\mathtt{E}_1, \mathtt{E}_2, ..., \mathtt{E}_N$,
@@ -1855,6 +1860,78 @@
18551860
an integral constant containing the number of elements in the parameter pack
18561861
it expands.
18571862

1863+
\pnum
1864+
The instantiation of a \grammarterm{fold-expression} produces:
1865+
1866+
\begin{itemize}
1867+
\item
1868+
\tcode{((}$\mathtt{E}_1$
1869+
\placeholder{op} $\mathtt{E}_2$\tcode{)}
1870+
\placeholder{op} $\cdots$\tcode{)}
1871+
\placeholder{op} $\mathtt{E}_N$
1872+
for a unary left fold,
1873+
\item
1874+
$\mathtt{E}_1$ \placeholder{op}
1875+
\tcode{(}$\cdots$ \placeholder{op}
1876+
\tcode{(}$\mathtt{E}_{N-1}$ \placeholder{op}
1877+
$\mathtt{E}_N$\tcode{))}
1878+
for a unary right fold,
1879+
\item
1880+
\tcode{(((}$\mathtt{E}$
1881+
\placeholder{op} $\mathtt{E}_1$\tcode{)}
1882+
\placeholder{op} $\mathtt{E}_2$\tcode{)}
1883+
\placeholder{op} $\cdots$\tcode{)}
1884+
\placeholder{op} $\mathtt{E}_N$
1885+
for a binary left fold, and
1886+
\item
1887+
$\mathtt{E}_1$ \placeholder{op}
1888+
\tcode{(}$\cdots$ \placeholder{op}
1889+
\tcode{(}$\mathtt{E}_{N-1}$ \placeholder{op}
1890+
\tcode{(}$\mathtt{E}_{N}$ \placeholder{op}
1891+
$\mathtt{E}$\tcode{)))}
1892+
for a binary right fold.
1893+
\end{itemize}
1894+
1895+
In each case,
1896+
\placeholder{op} is the \grammarterm{fold-operator},
1897+
$N$ is the number of elements in the pack expansion parameters,
1898+
and each $\mathtt{E}_i$ is generated by instantiating the pattern
1899+
and replacing each pack expansion parameter with its $i$th element.
1900+
For a binary fold-expression,
1901+
$\mathtt{E}$ is generated
1902+
by instantiating the \grammarterm{cast-expression}
1903+
that did not contain an unexpanded parameter pack.
1904+
\enterexample
1905+
\begin{codeblock}
1906+
template<typename ...Args>
1907+
bool all(Args ...args) { return (... && args); }
1908+
1909+
bool b = all(true, true, true, false);
1910+
\end{codeblock}
1911+
Within the instantiation of \tcode{all},
1912+
the returned expression expands to
1913+
\tcode{((true \&\& true) \&\& true) \&\& false},
1914+
which evalutes to \tcode{false}.
1915+
\exitexample
1916+
If $N$ is zero for a unary fold-expression,
1917+
the value of the expression is shown in Table~\ref{tab:fold.empty};
1918+
if the operator is not listed in Table~\ref{tab:fold.empty},
1919+
the instantiation is ill-formed.
1920+
1921+
\begin{floattable}{Value of folding empty sequences}{tab:fold.empty}
1922+
{ll}
1923+
\topline
1924+
\lhdr{Operator} & \rhdr{Value when parameter pack is empty} \\
1925+
\capsep
1926+
\tcode{*} & \tcode{1} \\
1927+
\tcode{+} & \tcode{int()} \\
1928+
\tcode{\&} & \tcode{-1} \\
1929+
\tcode{|} & \tcode{int()} \\
1930+
\tcode{\&\&} & \tcode{true} \\
1931+
\tcode{||} & \tcode{false} \\
1932+
\tcode{,} & \tcode{void()} \\
1933+
\end{floattable}
1934+
18581935
\rSec2[temp.friend]{Friends}
18591936

18601937
\pnum
@@ -3954,6 +4031,9 @@
39544031
A \grammarterm{braced-init-list} is type-dependent if any element is
39554032
type-dependent or is a pack expansion.
39564033

4034+
\pnum
4035+
A \grammarterm{fold-expression} is type-dependent.
4036+
39574037
\rSec3[temp.dep.constexpr]{Value-dependent expressions}
39584038

39594039
\pnum
@@ -4024,7 +4104,8 @@
40244104
Expressions of the following form are value-dependent:
40254105

40264106
\begin{ncbnftab}
4027-
\terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}
4107+
\terminal{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br
4108+
fold-expression
40284109
\end{ncbnftab}
40294110

40304111
\pnum

0 commit comments

Comments
 (0)