On 10 November 2014 11:13, John McCall <[email protected]> wrote: > On Nov 10, 2014, at 10:56 AM, Richard Smith <[email protected]> > wrote: > > On 10 November 2014 10:30, John McCall <[email protected]> wrote: > >> On Nov 8, 2014, at 9:16 AM, Richard Smith <[email protected]> >> wrote: >> > Hi, >> > >> > WG21 is voting on a proposal for "fold-expressions" today. These are >> syntactically of the form: >> > >> > ( .... + pack ) >> > ( pack + ... ) >> > ( p0 + ... + pack ) >> > ( pack + ... + pn ) >> > >> > (where + can be any binary operator). These expand to >> > >> > (((p0 + p1) + ...) + pn) >> > >> > for the first and third cases and >> > >> > (p0 + (p1 + (... + pn))) >> > >> > for the other two cases. >> > > I should add: > - in the first and second cases, the pack is p0 ... pn > - in the third case, the pack is p1 ... pn > - in the fourth case, the pack is p0 ... p{n-1} > > > Your notation is terrible, Richard. :) >
Yeah, sorry. I should have just attached the paper rather than trying to summarize. (Now attached.) > Okay, so the idea is that: > E op … op P => (((E op P1) op P2) op …) op Pn > P op … op E => P1 op (P2 op (… op (Pn op E))) > > How are E and P determined? Everything preceding/following the … term, or > does this actually follow the grammar’s associativity rules if you had e.g. > 1+2+…+packref+3+4 > or does it only work within parentheses? > Parentheses are required, and only cast-expressions are allowed before / after the operators, so there are no precedence / associativity issues. (The initial proposal was deliberately very conservative in this regard.) > > These need a mangling; I suggest (and have implemented): >> > >> > <expression> ::= >> > fl <binary operator-name> <expression> # ( ... op pack ) >> > fr <binary operator-name> <expression> # ( pack op ... ) >> > fx <binary operator-name> <expression> <expression> # ( expr op ... >> op expr ) >> >> This doesn’t seem to correspond to one of your examples. > > > You get this for the third and fourth cases. > > > Okay, and you’re saying that left/right folding are disambiguated because > one of the expressions contains a pack and the other doesn’t? I think I > would prefer this to be explicit in the mangling. > OK. Then fl / fr / fL / fR?Title: Fold expressions
Folding expressions
Date: 2014-11-07
Document number: N4295
Revises: N4191
Wording
5.1. Primary expressions [expr.prim]
Modify the grammar of primary-_expression_ in [expr.prim] to include fold expressions.
primary-_expression_:
fold-_expression_
Add the a new subsection to [expr.prim] called "Fold expressions".
5.1.3 Fold expressions [expr.prim.fold]
A fold _expression_ performs a fold of a template parameter pack ([temp.variadic]) over a binary operator.
fold-_expression_:
( cast-_expression_ fold-operator ... )
( ... fold-operator cast-_expression_ )
( cast-_expression_ fold-operator ... fold-operator cast-_expression_ )
fold-operator: one of
+ - * / % ^ & | = < > << >>
+= -= *= /= %= ^= &= |= <<= >>=
== != <= >= && || , .* ->*
An _expression_ of the form (... op e) where op is a fold-operator is
called a unary left fold.
An _expression_ of the form (e op ...) where op is a fold-operator is
called a unary right fold.
Unary left folds and unary right folds are collectively called unary folds.
In a unary fold, the cast-_expression_ shall contain an
unexpanded parameter pack.
An _expression_ of the form (e1 op1 ... op2 e2) where op1 and op2 are fold-operators is
called a binary fold. In a binary fold, op1 and op2 shall be the same fold-operator,
and either e1 shall contain
an unexpanded parameter pack or e2 shall contain an unexpanded parameter
pack, but not both.
If e2 contains an unexpanded parameter pack, the _expression_ is called a binary left fold.
If e1 contains an unexpanded parameter pack, the _expression_ is called a binary right fold.
[ Example:
template<typename... Args>
bool f(Args... args) {
return (true + ... + args); // OK
}
template<typename... Args>
bool f(Args... args) {
return (args && ... && args); // error: both operands contain unexpanded parameter packs
}
end example]
14.5.3 Variadic templates [temp.variadic]
Add a new bullet to paragraph 4:
- In a fold-_expression_ (5.1.3); the pattern is the cast-_expression_ that contains an unexpanded parameter pack.
Change in paragraph 7:
The instantiation of a pack expansion that is
notneither a sizeof... _expression_ nor a fold-_expression_ produces a list E1, E2, ..., EN [...]
Add a new paragraph after paragraph 8:
The instantiation of a fold-_expression_ produces:
((E1 op E2) op ...) op ENfor a unary left fold,E1 op (... op (EN-1 op EN))for a unary right fold,(((E op E1) op E2) op ...) op ENfor a binary left fold, andE1 op (... op (EN-1 op (EN op E)))for a binary right fold.In each case,
opis the fold-operator,Nis the number of elements in the pack expansion parameters, and eachEiis generated by instantiating the pattern and replacing each pack expansion parameter with itsith element. For a binary fold-_expression_,Eis generated by instantiating the cast-_expression_ that did not contain an unexpanded parameter pack. [ Example:template<typename... Args> bool all(Args... args) { return (args && ...); } bool b = all(true, true, true, false);Within the instantiation of
all, the returned _expression_ expands to((true && true) && true) && false, which evalutes tofalse. end example ] IfNis zero for a unary fold-_expression_, the value of the _expression_ is shown in Table N; if the operator is not listed in Table N, the instantiation is ill-formed.
Table N. Value of folding empty sequences Operator Value when parameter pack is empty * 1 + int() & -1 | int() && true || false , void()
14.6.2.2 Type-dependent expressions [temp.dep.expr]
Add a new paragraph after paragraph 6:
A fold-_expression_ is type-dependent.
14.6.2.3 Value-dependent expressions [temp.dep.constexpr]
Change in paragraph 4:
Expressions of the following form are value-dependent:
sizeof...(identifier)fold-_expression_
_______________________________________________ cxx-abi-dev mailing list [email protected] http://sourcerytools.com/cgi-bin/mailman/listinfo/cxx-abi-dev
