<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>

  <meta http-equiv="Content-Language" content="en-us">
  <meta name="GENERATOR" content="Microsoft FrontPage 5.0">
  <meta name="ProgId" content="FrontPage.Editor.Document">
  <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

  <title>Range-Based For Loop Wording (Without Concepts)</title>

  <style type="text/css">
ins {background-color:#A0FFA0}
del {background-color:#FFA0A0}
  </style>
</head><body>

<table style="border-collapse: collapse;" border="0" bordercolor="#111111" cellpadding="0" cellspacing="0" width="496">
  <tbody><tr>
    <td>Document number:&nbsp; </td>
    <td>N2930=09-0120</td>
  </tr>
  <tr>
    <td>Date:</td>
    <td>
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2009-07-16<!--webbot bot="Timestamp" endspan i-checksum="12487" --></td>
  </tr>
  <tr>
    <td>Project:</td>
    <td>Programming Language C++, Library Working Group</td>
  </tr>
  <tr>
    <td valign="top">Reply-to:</td>
    <td>Douglas Gregor &lt;doug.gregor at gmail.com&gt;<br> Beman Dawes &lt;bdawes at acm.org&gt;</td>
  </tr>
</tbody></table>


<h1>Range-Based For Loop Wording (Without Concepts)</h1>

<p><a href="#Introduction">Introduction</a><br>
<a href="#Summary">Summary of proposed changes</a><br>
<a href="#Proposed-wording">Proposed wording</a><br>
<a href="#Acknowledgements">Acknowledgements</a></p>

<h2><a name="Introduction">Introduction</a></h2>

<p>With the removal of concepts from the C++0x working paper, the
range-based for loop requires new wording that does not rely on
concepts. This proposal provides such wording. It also addresses CD1
comments UK 78 and UK 79, whih essentially ask that the range-based <i>for</i> 
statement "just work" for arrays (without requiring the user to include a header), e.g.,</p>

<blockquote>
  <p>[ <i>Example:</i></p>
  <blockquote>
    <pre>int array[5] = { 1, 2, 3, 4, 5 };
for (int&amp; x : array)
  x *= 2;</pre>
  </blockquote>
  <p><i>end example</i> ]</p>
</blockquote>
<h2><a name="Summary">Summary</a> of proposed changes</h2>

<ul>
  <li>Specify range-based for statements without the use of concepts, using argument-dependent lookup of <code>begin</code> and <code>end</code> (which always includes those <code>begin</code> and <code>end</code> functions in namespace <code>std</code>) to provide the 
  iterator to the beginning and ending of the sequence.</li>
  <li>Specify range-based for statements so that arrays and initializer lists 
  have no dependencies on <code>&lt;iterator&gt;</code>.</li>
  <li>Refactor <code>&lt;initializer_list&gt;</code> so that it as no dependencies on 
  other headers and includes no other headers.</li>
  <li>Specify the library headers that are to <code>#include &lt;initializer_list&gt;</code>.</li>
</ul>

<h2><a name="Proposed-wording">Proposed wording</a></h2>

<p><i>The wording here is based on the current working paper once the concepts proposals and previous range-based for loop (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2778.htm">N2778</a>)
have been removed. The first two sections have an editorial note that
specifies that the text of the current working paper and the net result
of removing those previous proposals will be the same. Text to be
removed is shown in <span style="background-color: rgb(255, 160, 160); text-decoration: line-through;">red</span>, 
text to be added is shown in <span style="background-color: rgb(160, 255, 160);">green</span>.&nbsp; 
Underbars are not shown for additions because the many underscores in the 
affected text become unreadable. </i></p>

<p><i>Modify paragraph 4 of 3.3.3 [basic.scope.local] as follows</i>: </p><ol start="4">
  <li>Names declared in the <i>for-init-statement</i><span style="background-color: rgb(160, 255, 160);">, the <i>for-range-declaration</i></span>, and in the condition of if, while, for, 
and switch statements are local to the if, while, for, or switch statement (including the controlled 
statement), and shall not be redeclared in a subsequent condition of that statement nor in the outermost 
block (or, for the if statement, any of the outermost blocks) of the controlled statement; see 6.4.
</li></ol>

<p><b>Editorial Note</b>: the wording above is identical to what is in the current working paper. It is given here for completeness.</p>

<p><i>Modify paragraph 1 of 6.5 [stmt.iter] as follows:</i></p>

<ol>
  <li>Iteration statements specify looping.
<blockquote>
<i>iteration-statement</i>:<br>
&nbsp;&nbsp;&nbsp;&nbsp;    while ( <i>condition</i> ) <i>statement</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;    do <i>statement</i> while ( <i>expression</i> ) ; <br>
&nbsp;&nbsp;&nbsp;&nbsp;    for ( <i>for-init-statement</i> <i>condition<sub>opt</sub></i> ; <i>expression<sub>opt</sub></i> ) <i>statement</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;    <span style="background-color: rgb(160, 255, 160);">for ( <i>for-range-declaration</i> : <i>expression</i> ) <i>statement</i></span><br>
<i>for-init-statement</i>:<br>
&nbsp;&nbsp;&nbsp;&nbsp;    <i>expression-statement</i><br>
&nbsp;&nbsp;&nbsp;&nbsp;    <i>simple-declaration</i><br>
<span style="background-color: rgb(160, 255, 160);"><i>for-range-declaration</i>:</span><br>
&nbsp;&nbsp;&nbsp;&nbsp;    <span style="background-color: rgb(160, 255, 160);"><i>type-specifier-seq</i> <i>attribute-specifier<sub>opt</sub></i> <i>declarator</i></span>
</blockquote>
  
[ <i>Note</i>: a for-init-statement ends with a semicolon. -- <i>end note</i> ] 
</li></ol>

<p><b>Editorial Note</b>: the wording above is identical to what is in the current working paper. It is given here for completeness.</p>

<p><i>Add a new section <span style="background-color: rgb(160, 255, 160);"> 6.5.4 Range-based for statement [stmt.ranged]</span>, as indicated: </i>
</p>


<blockquote>


<p><span style="background-color: rgb(160, 255, 160);">The range-based for statement</span> </p>


  <blockquote>


<p><span style="background-color: rgb(160, 255, 160);"><code>for (</code> <i>for-range-declaration </i><code>:</code><i> expression</i>
<code>)</code> <i>statement</i></span></p>


  </blockquote>


<p><span style="background-color: rgb(160, 255, 160);">&nbsp;is equivalent to</span></p>


  <blockquote>
    <pre><span style="background-color: rgb(160, 255, 160);">{</span>
  <span style="background-color: rgb(160, 255, 160);">auto &amp;&amp; __range = ( <i>expression</i> );</span>
  <span style="background-color: rgb(160, 255, 160);">for (auto __begin = <i>begin-expr</i>, __end = <i>end-expr</i>; __begin != __end; ++__begin ) {</span>
  <span style="background-color: rgb(160, 255, 160);">  <i>for-range-declaration</i> = *__begin;</span>
  <span style="background-color: rgb(160, 255, 160);">  <i>statement</i></span>
  <span style="background-color: rgb(160, 255, 160);">}</span>
<span style="background-color: rgb(160, 255, 160);">}</span></pre>
  </blockquote>
  <p><span style="background-color: rgb(160, 255, 160);">where <code>__range</code>, <code>__begin</code>, and <code>__end</code> are 
  variables defined for exposition only, 
  <code>_RangeT</code> is the type 
  of the <i><code>expression</code></i>, and <i>
  <code>begin-expr</code></i> and
  <i><code>end-expr</code></i> are determined 
  as follows:</span></p>
  <ul>
    <li><span style="background-color: rgb(160, 255, 160);">If </span> <code>
    <span style="background-color: rgb(160, 255, 160);">_RangeT</span></code><span style="background-color: rgb(160, 255, 160);"> 
    is an array type,
    </span> <i><code><span style="background-color: rgb(160, 255, 160);">begin-expr</span></code></i><span style="background-color: rgb(160, 255, 160);"> and
    </span> 
    <i><code><span style="background-color: rgb(160, 255, 160);">end-expr</span></code></i><span style="background-color: rgb(160, 255, 160);"> are
    </span> <code><span style="background-color: rgb(160, 255, 160);">__range</span></code><span style="background-color: rgb(160, 255, 160);"> and
    </span> 
  <code><span style="background-color: rgb(160, 255, 160);">__range + __bound</span></code><span style="background-color: rgb(160, 255, 160);">, respectively, where
    </span> 
  <code><span style="background-color: rgb(160, 255, 160);">__bound</span></code><span style="background-color: rgb(160, 255, 160);"> is the array bound. If <code>_RangeT</code> is an array of unknown size or an array of incomplete type, the program is ill-formed.</span><br>
&nbsp;</li>
    <li><span style="background-color: rgb(160, 255, 160);">Otherwise, <i><code>
begin-expr</code></i> and <i><code>end-expr</code></i> are
    <code>begin(__range)</code>and
    <code>end(__range)</code>, 
    respectively, where <code>begin</code> and <code>end</code> are looked up with argument-dependent lookup ([basic.lookup.argdep]). For the purposes of this name lookup, namespace <code>std</code> is an associated namespace.</span><br>
&nbsp;</li>
</ul>
    <p><span style="background-color: rgb(160, 255, 160);">[ <i>Example:</i></span></p>
    <blockquote>
      <pre><span style="background-color: rgb(160, 255, 160);">int array[5] = { 1, 2, 3, 4, 5 };
for (int&amp; x : array)</span>
  <span style="background-color: rgb(160, 255, 160);">x *= 2;</span></pre>
    </blockquote>
    <p><span style="background-color: rgb(160, 255, 160);"><i>--end example</i>]</span></p>


</blockquote>

<p><i>Modify the header &lt;initializer_list&gt; synopsis in section
18.9 Initializer lists [support.initlist] by adding the following to
the synopsis:</i></p>

<pre>namespace std {
  <i>// ...</i>

  <span style="background-color: rgb(160, 255, 160);"><i>// 18.9.3 initializer list range access [support.initlist.range]</i></span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename E&gt; const E* begin(initializer_list&lt;E&gt; il);</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename E&gt; const E* end(initializer_list&lt;E&gt; il);</span>
}
</pre>

<p><i>Add a new section <span style="background-color: rgb(160, 255, 160);">18.9.3 initializer list range access [support.initlist.range]</span>, with the following text</i>:</p>

<blockquote>
<pre>  <span style="background-color: rgb(160, 255, 160);">template&lt;typename E&gt; const E* begin(initializer_list&lt;E&gt; il);</span>
</pre>
<ol>
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>il.begin()</code></span></li>
</ol>

<pre>  <span style="background-color: rgb(160, 255, 160);">template&lt;typename E&gt; const E* end(initializer_list&lt;E&gt; il);</span>
</pre>
<ol start="2">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>il.end()</code></span></li>
</ol>
</blockquote>

<p><i>Modify the section 20.2 Header &lt;utility&gt; synopsis by adding the following to the synopsis</i>:</p>
<blockquote>
<pre>  <span style="background-color: rgb(160, 255, 160);"><i>// 20.2.3 pair range access [pair.range]</i></span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
    <span style="background-color: rgb(160, 255, 160);">InputIterator begin(const std::pair&lt;InputIterator, InputIterator&gt;&amp; p);</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
    <span style="background-color: rgb(160, 255, 160);">InputIterator end(const std::pair&lt;InputIterator, InputIterator&gt;&amp; p);</span>
</pre>
</blockquote>

<p><i>Add a new section <span style="background-color: rgb(160, 255, 160);">20.2.3 pair range access [pair.range]</span>, with the following text</i>:</p>

<blockquote>
<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
  <span style="background-color: rgb(160, 255, 160);">InputIterator begin(const std::pair&lt;InputIterator, InputIterator&gt;&amp; p);</span>
</pre>
<ol>
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>p.first</code></span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
  <span style="background-color: rgb(160, 255, 160);">InputIterator end(const std::pair&lt;InputIterator, InputIterator&gt;&amp; p);</span>
</pre>
<ol start="2">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>p.second</code></span></li>
</ol>
</blockquote>

<p><i>Modify the section 20.5.1 Header &lt;tuple&gt; synopsis by adding the following to the synopsis</i>:</p>
<blockquote>
<pre>  <span style="background-color: rgb(160, 255, 160);"><i>// 20.5.2.8 tuple range access [tuple.range]</i></span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
    <span style="background-color: rgb(160, 255, 160);">InputIterator begin(const std::tuple&lt;InputIterator, InputIterator&gt;&amp; t);</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
    <span style="background-color: rgb(160, 255, 160);">InputIterator end(const std::tuple&lt;InputIterator, InputIterator&gt;&amp; t);</span>
</pre>
</blockquote>

<p><i>Add a new section <span style="background-color: rgb(160, 255, 160);">20.5.2.8 tuple range access [tuple.range]</span>, with the following text</i>:</p>

<blockquote>
<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
  <span style="background-color: rgb(160, 255, 160);">InputIterator begin(const std::tuple&lt;InputIterator, InputIterator&gt;&amp; t);</span>
</pre>
<ol>
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>std::get&lt;0&gt;(t)</code></span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename InputIterator&gt;</span>
  <span style="background-color: rgb(160, 255, 160);">InputIterator end(const std::tuple&lt;InputIterator, InputIterator&gt;&amp; t);</span>
</pre>
<ol start="2">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>std::get&lt;1&gt;(t)</code></span></li>
</ol>
</blockquote>

<p><i>Modify the section 24.3 Header &lt;iterator&gt; synopsis [iterator.syn] by adding the following at the end of the synopsis:</i></p>

<blockquote>
<pre>  <span style="background-color: rgb(160, 255, 160);"><i>// 24.7 range access [iterator.range]</i></span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto begin(C&amp; c) -&gt; decltype(c.begin());</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto begin(const C&amp; c) -&gt; decltype(c.begin());</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto end(C&amp; c) -&gt; decltype(c.end());</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto end(const C&amp; c) -&gt; decltype(c.end());</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename T, size_t N&gt; T* begin(T (&amp;array)[N]);</span>
  <span style="background-color: rgb(160, 255, 160);">template&lt;typename T, size_t N&gt; T* end(T (&amp;array)[N]);</span>
</pre>
</blockquote>

<p><i>Add a new section <span style="background-color: rgb(160, 255, 160);">24.7 range access [iterator.range]</span> containing the following:</i></p>

<blockquote>
<ol>
  <li><span style="background-color: rgb(160, 255, 160);">In addition to being available via inclusion of the &lt;<code>iterator</code>&gt; header, the function templates in [iterator.range] are also available when any of the following headers are included: &lt;<code>array</code>&gt;, &lt;<code>deque</code>&gt;, &lt;<code>forward_list</code>&gt;, &lt;<code>list</code>&gt;, &lt;<code>map</code>&gt;, &lt;<code>regex</code>&gt;, &lt;<code>set</code>&gt;, &lt;<code>string</code>&gt;, &lt;<code>unordered_map</code>&gt;, &lt;<code>unordered_set</code>&gt;, or &lt;<code>vector</code>&gt;.</span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto begin(C&amp; c) -&gt; decltype(c.begin());</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto begin(const C&amp; c) -&gt; decltype(c.begin());</span>
</pre>
<ol start="2">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>c.begin()</code></span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto end(C&amp; c) -&gt; decltype(c.end());</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename C&gt; auto end(const C&amp; c) -&gt; decltype(c.end());</span>
</pre>
<ol start="3">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>c.end()</code></span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename T, size_t N&gt; T* begin(T (&amp;array)[N]);</span>
</pre>
<ol start="4">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>array</code></span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename T, size_t N&gt; T* end(T (&amp;array)[N]);</span>
</pre>
<ol start="5">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: <code>array + N</code></span></li>
</ol>
</blockquote>

<p><i>Modify the section 24.6.1 Header &lt;valarray&gt; synopsis [valarray.syn] by adding the following at the end of the synopsis:</i></p>

<blockquote>
<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-1</i> begin(valarray&lt;T&gt;&amp; v);</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-2</i> begin(const valarray&lt;T&gt;&amp; v);</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-1</i> end(valarray&lt;T&gt;&amp; v);</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-2</i> end(const valarray&lt;T&gt;&amp; v);</span>
</pre>
</blockquote>

<p><i>Add a new section <span style="background-color: rgb(160, 255, 160);">26.6.10 valarray range access [valarray.range]</span> containing the following:</i></p>

<blockquote>
<ol>
  <li><span style="background-color: rgb(160, 255, 160);">In the <code>begin</code> and <code>end</code> function templates that follow, <i>unspecified-1</i> is a type that meets the requirements of a mutable random access iterator ([random.access.iterators]) whose <code>value_type</code> is the template parameter <code>T</code> and whose <code>reference</code> type is <code>T&amp;</code>. <i>unspecified-2</i> is a type that meets the requirements of a constant random access iterator ([random.access.iterators]) whose <code>value_type</code> is the template parameter <code>T</code> and whose <code>reference</code> type is <code>const T&amp;</code>.</span></li></ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-1</i> begin(valarray&lt;T&gt;&amp; v);</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-2</i> begin(const valarray&lt;T&gt;&amp; v);</span>
</pre>
<ol start="2">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: an iterator referencing the first value in the numeric array</span></li>
</ol>

<pre><span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-1</i> end(valarray&lt;T&gt;&amp; v);</span>
<span style="background-color: rgb(160, 255, 160);">template&lt;typename T&gt; <i>unspecified-2</i> end(const valarray&lt;T&gt;&amp; v);</span>
</pre>
<ol start="3">
  <li><span style="background-color: rgb(160, 255, 160);"><i>Returns</i>: an iterator referencing one past the last value in the numeric array</span></li>
</ol>
</blockquote>

<p dir="ltr"><i>Add </i><ins><code>#include &lt;initializer_list&gt;</code></ins> <i>to the 
synopsis for the following headers:</i></p>

<blockquote>

<table border="1" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" cellpadding="3">
  <tr>
    <td><code>&lt;string&gt;</code></td>
    <td>21.3 String classes [string.classes]</td>
  </tr>
  <tr>
    <td><code>&lt;array&gt;</code>, <code>&lt;deque&gt;</code>, <code>&lt;forward_list&gt;</code>, 
    <code>&lt;list&gt;</code>, <code>&lt;queue&gt;</code>, <code>&lt;stack&gt;</code>, and 
    <code>&lt;vector&gt;</code></td>
    <td>23.3 Sequence containers [sequences]</td>
  </tr>
  <tr>
    <td><code>&lt;map&gt;</code> and <code>&lt;set&gt;</code></td>
    <td>23.4 Associative containers [associative]</td>
  </tr>
  <tr>
    <td><code>&lt;unordered_map&gt;</code> and <code>&lt;unordered_set&gt;</code></td>
    <td>23.5 Unordered associative containers [unord]</td>
  </tr>
  <tr>
    <td><code>&lt;algorithm&gt;</code></td>
    <td>25.2 Header &lt;algorithm&gt; synopsis [algorithms.syn]</td>
  </tr>
  <tr>
    <td><code>&lt;random&gt;</code></td>
    <td>26.5.1 Header &lt;random&gt; synopsis [rand.synopsis]</td>
  </tr>
  <tr>
    <td><code>&lt;valarray&gt;</code></td>
    <td>26.6.1 Header &lt;valarray&gt; synopsis [valarray.syn]</td>
  </tr>
  <tr>
    <td><code>&lt;regex&gt;</code></td>
    <td>28.4 Header &lt;regex&gt; synopsis [re.syn]</td>
  </tr>
</table>

</blockquote>

<h2><a name="Acknowledgements">Acknowledgements</a></h2>

<p>James Widman identified several deficiencies in drafts of this proposal and 
provided fixes for them.</p>
<p>Steve Adamczyk, Alberto Ganesh Barbati, Walter E Brown, Gabriel Dos Reis, Daniel Krgler, Jens Maurer, Thorsten Ottosen, 
Bjarne Stroustrup, Herb Sutter, 
and James Widman participated in discussions, reviewed drafts, and suggested 
improvements.</p>
<hr>


</body></html>