<html>
<head>
    <title>Fold expressions</title>
<style>
h1 {
  text-align: center;
}

body {
  width: 8.5in;
  text-align: justify;
  counter-reset: section;
}

del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #007100; }

h2:before {
  content: counter(section) ". ";
  counter-increment: section
}

table {
  text-align: center;
  border: 1px solid black;
  border-collapse: collapse;
}
th, td {
  padding-left: 1em;
  padding-right: 1em;
  border-left: 1px solid black;
}
</style>
</head>
<body>
<h1>Folding expressions</h1>

<div style="text-align:center">
Andrew Sutton, Richard Smith<br/>
Date: 2014-11-07<br/>
Document number: N4295<br/>
Revises: N4191
</div>

<h2>Wording</h2>

<h3>5.1. Primary expressions [expr.prim]</h3>

<p>Modify the grammar of <em>primary-expression</em> in [expr.prim] to include
fold expressions.</p>

<blockquote>
<pre><i>primary-expression</i>:
    <ins><i>fold-expression</i></ins>
</pre>
</blockquote>

<p>Add the a new subsection to [expr.prim] called "Fold expressions".</p>

<h4>5.1.3 Fold expressions [expr.prim.fold]</h4>

<p>A fold expression performs a fold of a template parameter pack
([temp.variadic]) over a binary operator.</p>

<pre><i>fold-expression</i>:
      ( <i>cast-expression</i> <i>fold-operator</i> ... )
      ( ... <i>fold-operator</i> <i>cast-expression</i> )
      ( <i>cast-expression</i> <i>fold-operator</i> ... <i>fold-operator</i> <i>cast-expression</i> )

<i>fold-operator</i>: one of
    +  -  *  /  %  ^  &  |  ~  =  &lt;  >  &lt;&lt;  >>
    +=  -=  *=  /=  %=  ^=  &=  |=  &lt;&lt;=  >>=
    ==  !=  <=  >=  &&  ||  ,  .*  ->*
</pre>

<p>An expression of the form <code>(... op e)</code> where <code>op</code> is a <em>fold-operator</em> is
called a <em>unary left fold</em>.
An expression of the form <code>(e op ...)</code> where <code>op</code> is a <em>fold-operator</em> is
called a <em>unary right fold</em>.
Unary left folds and unary right folds are collectively called <em>unary folds</em>.
In a unary fold, the <em>cast-expression</em> shall contain an
unexpanded parameter pack.</p>

<p>An expression of the form <code>(e1 op1 ... op2 e2)</code> where <code>op1</code> and <code>op2</code> are <em>fold-operator</em>s is
called a <em>binary fold</em>. In a binary fold, <code>op1</code> and <code>op2</code> shall be the same <em>fold-operator</em>,
and either <code>e1</code> shall contain
an unexpanded parameter pack or <code>e2</code> shall contain an unexpanded parameter
pack, but not both.
If <code>e2</code> contains an unexpanded parameter pack, the expression is called a <em>binary left fold</em>.
If <code>e1</code> contains an unexpanded parameter pack, the expression is called a <em>binary right fold</em>.
[ <i>Example</i>:</p>

<pre>
template&lt;typename... Args>
  bool f(Args... args) { 
    return (true + ... + args); // <i>OK</i>
  } 

template&lt;typename... Args>
  bool f(Args... args) { 
    return (args && ... && args); // <i>error: both operands contain unexpanded parameter packs</i>
  }
</pre>                              

<p>&mdash; <i>end example</i>]</p>

<h4>14.5.3 Variadic templates [temp.variadic]</h4>

<p>Add a new bullet to paragraph 4:</p>

<blockquote>
  <ul>
<li><ins>In a <em>fold-expression</em> (5.1.3); the pattern is the <em>cast-expression</em>
that contains an unexpanded parameter pack.</ins></li>
</ul>
</blockquote>

<p>Change in paragraph 7:</p>

<blockquote>
  <p>The instantiation of a pack expansion that is <del>not</del><ins>neither</ins>
a <tt>sizeof...</tt> expression <ins>nor a <em>fold-expression</em></ins> produces a
list E<sub>1</sub>, E<sub>2</sub>, ..., E<sub>N</sub> [...]</p>
</blockquote>

<p>Add a new paragraph after paragraph 8:</p>

<blockquote>
  <p>The instantiation of a <em>fold-expression</em> produces:</p>

<ul>
<li><code>((E1 op E2) op ...) op EN</code> for a unary left fold,</li>
<li><code>E1 op (... op (EN-1 op EN))</code> for a unary right fold,</li>
<li><code>(((E op E1) op E2) op ...) op EN</code> for a binary left fold, and</li>
<li><code>E1 op (... op (EN-1 op (EN op E)))</code> for a binary right fold.</li>
</ul>

<p>In each case,
<code>op</code> is the <em>fold-operator</em>,
<code>N</code> is the number of elements in the pack expansion parameters, and
each <code>Ei</code> is
generated by instantiating the pattern and replacing each pack expansion
parameter with its <code>i</code>th element.
For a binary <em>fold-expression</em>, <code>E</code> is generated by instantiating
the <em>cast-expression</em> that did not
contain an unexpanded parameter pack. [ <i>Example:</i></p>

<pre>
template&lt;typename... Args>
  bool all(Args... args) { return (args && ...); }

bool b = all(true, true, true, false);
</pre>

<p>Within the instantiation of <code>all</code>, the returned expression expands to
<code>((true &amp;&amp; true) &amp;&amp; true) &amp;&amp; false</code>, which evalutes to <code>false</code>.
&mdash; <i>end example</i> ]
If <code>N</code> is zero for a unary <em>fold-expression</em>,
the value of the expression is shown in Table N; if the operator
is not listed in Table N, the instantiation is ill-formed.</p>

<table>
<caption>Table N. Value of folding empty sequences</caption>
<tr><th>Operator</th>    <th>Value when parameter pack is empty</th></tr>
<tr><td><tt>*</tt></td>  <td><tt>1</tt></td>                        </tr>
<tr><td><tt>+</tt></td>  <td><tt>int()</tt></td>                    </tr>
<tr><td><tt>&</tt></td>  <td><tt>-1</tt></td>                       </tr>
<tr><td><tt>|</tt></td>  <td><tt>int()</tt></td>                    </tr>
<tr><td><tt>&&</tt></td> <td><tt>true</tt></td>                     </tr>
<tr><td><tt>||</tt></td> <td><tt>false</tt></td>                    </tr>
<tr><td><tt>,</tt></td>  <td><tt>void()</tt></td>                   </tr>
</table>
</blockquote>

<h4>14.6.2.2 Type-dependent expressions [temp.dep.expr]</h4>

<p>Add a new paragraph after paragraph 6:</p>

<blockquote>
  <p>A <em>fold-expression</em> is type-dependent.</p>
</blockquote>

<h4>14.6.2.3 Value-dependent expressions [temp.dep.constexpr]</h4>

<p>Change in paragraph 4:</p>

<blockquote>
  <p>Expressions of the following form are value-dependent:</p>

<blockquote>
  <p><code>sizeof...(</code> <em>identifier</em> <code>)</code></p>

<p><em><ins>fold-expression</ins></em></p>
</blockquote>

<p></blockquote></p>

</body>
