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

Andrew Sutton, Richard Smith
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 EN for a unary left fold,
  • E1 op (... op (EN-1 op EN)) for a unary right fold,
  • (((E op E1) op E2) op ...) op EN for a binary left fold, and
  • E1 op (... op (EN-1 op (EN op E))) for a binary right fold.

In each case, op is the fold-operator, N is the number of elements in the pack expansion parameters, and each Ei is generated by instantiating the pattern and replacing each pack expansion parameter with its ith element. For a binary fold-_expression_, E is 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 to false. — end example ] If N is 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

Reply via email to