<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="generator" content="pandoc" />
  <title>Generalizing the Range-Based For Loop</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
  ins {
    color:#009a9a; text-decoration:underline;
  }

  del {
    color:red; text-decoration:line-through;
  }

  ednote {
    color:blue;
  }

  table {
    border-collapse: collapse;
  }

  table, th, td {
    border: 1px solid black;
  }
  </style>
</head>
<body>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="607">
  <tr>
    <td width="172" align="left" valign="top">Document number:</td>
    <td width="435">
      P0184R0
    </td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Date:</td>
    <td width="435">2016-02-11</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Project:</td>
    <td width="435">Programming Language C++, Evolution Working Group</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Reply-to:</td>
    <td width="435">
      Eric Niebler &lt;<a href="mailto:eniebler@boost.org">eniebler@boost.org</a>&gt;,<br/>
    </td>
  </tr>
</table>
<div id="header">
<h1 class="title">Generalizing the Range-Based For Loop</h1>
</div>
<blockquote>
  <p>“In the end, we are self-perceiving, self-inventing, locked-in mirages that are little miracles of self-reference.”</p>
  <p>
    – Douglas Hofstadter, <em>I Am a [St]<strong>range Loop</strong></em>
  </p>
</blockquote>
<div id="TOC">
<ul>
<li><a href="#introduction"><span class="toc-section-number">1</span> Introduction</a></li>
<li><a href="#motivation-and-scope"><span class="toc-section-number">2</span> Motivation and Scope</a></li>
<li><a href="#implementation-experience"><span class="toc-section-number">3</span> Implementation Experience</a></li>
<li><a href="#technical-specifications"><span class="toc-section-number">4</span> Technical Specifications</a></li>
<li><a href="#acknowledgements"><span class="toc-section-number">5</span> Acknowledgements</a></li>
<li><a href="#references">References</a></li>
</ul>
</div>
<h1 id="introduction"><span class="header-section-number">1</span> Introduction</h1>
<p>The current draft of the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4560.pdf" title="Working Draft: C++ Extensions for Ranges">Ranges TS</a><span class="citation">[2]</span> loosens the requirements on the objects used to denote<br />
a range. Today, two iterators of the same type are used to denote a range. In the Ranges TS,<br />
a <em>sentinel</em> may be used to denote the end of a range, where the type of the sentinel may be<br />
different from the type of the range’s iterator. The motivation for the loosening of this<br />
requirement is given in section 3.3.5 of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4128.html" title="Ranges for the Standard Library, Revision 1">Ranges for the Standard Library, Revision 1</a><span class="citation">[3]</span>,<br />
but in short it is to facilitate better code generation for many interesting kinds of ranges, such<br />
as a range denoted by an iterator and a predicate.</p>
<p>Allowing the type of a range’s end to differ from that of its begin causes problems when the user<br />
tries to use such a range with the built-in range-based <code>for</code> loop, which requires a range’s begin<br />
and end to have the same type. This paper proposes to lift that restriction for C++17, thereby<br />
giving users of the Ranges TS the best possible experience.</p>
<h1 id="motivation-and-scope"><span class="header-section-number">2</span> Motivation and Scope</h1>
<p>The existing range-based <code>for</code> loop is over-constrained. The end iterator is never incremented,<br />
decremented, or dereferenced. Requiring it to be an iterator serves no practical purpose.</p>
<p>Today, STL algorithms require the begin and end of a range to have the same type. That is sensibile<br />
given the fact that algorithms take the begin and end of a range as separate parameters. In the<br />
absence of concept checking, allowing their types to differ makes it rather easy to pass mismatched<br />
iterators. The range-based <code>for</code> loop has no such problem since it deals with ranges in whole.</p>
<p>Loosening the type requirements of the range-based <code>for</code> loop gives users of the Ranges TS the best<br />
possible experience. If users create ranges with the Ranges TS are not usable with the built-in<br />
range-based <code>for</code> loop, they will be frustrated, and it will reflect poorly both on the Ranges TS<br />
and on the range-based <code>for</code> loop. In all likelihood, a macro-based solution like <a href="http://boost.org/libs/foreach" title="Boost.Foreach"><code>BOOST_FOREACH</code></a><span class="citation">[1]</span><br />
will be invented to fill the gap. That is best avoided.</p>
<h1 id="implementation-experience"><span class="header-section-number">3</span> Implementation Experience</h1>
<p>The author has implemented the described resolution in the clang compiler, and Casey Carter has<br />
implemented it in gcc. For clang, the implementation was as simple as removing the code that checks<br />
that <code>begin()</code> and <code>end()</code> return objects of the same type. The change for gcc was equally trivial.<br />
After this change was made, non-bounded ranges (those for which <code>end()</code> returns a sentinel that is<br />
not an iterator) work with the built-in range-based <code>for</code> loop.</p>
<h1 id="technical-specifications"><span class="header-section-number">4</span> Technical Specifications</h1>
<p><strong>6.5.4 The range-based <code>for</code> statement [stmt.ranges]</strong></p>
<p>1. A range-based <code>for</code> statement is equivalent to</p>
<blockquote><code><del>{
  auto && __range = <em>for-range-initializer</em>;
  for ( auto __begin = begin-expr,
             __end = end-expr;
        __begin != __end;
        ++__begin ) {
    <em>for-range-declaration</em> = *__begin;
    <em>statement</em>
  }
}</del></code></blockquote>
<blockquote><code><ins>{
  auto && __range = <em>for-range-initializer</em>;
  auto __begin = begin-expr;
  auto __end = end-expr;
  for ( ; __begin != __end; ++__begin ) {
    <em>for-range-declaration</em> = *__begin;
    <em>statement</em>
  }
}</ins></code></blockquote>
<p>where […] <ednote>[<em>Editorial note:</em> – … as in the current Working Draft. –<em>end note</em>]</ednote></p>
<h1 id="acknowledgements"><span class="header-section-number">5</span> Acknowledgements</h1>
<p>I would also like to thank Herb Sutter and the Standard C++ Foundation, without whose generous<br />
financial support the Ranges TS would not be possible.</p>
<h1 id="references" class="unnumbered">References</h1>
<div id="refs" class="references">
<div id="ref-boost-foreach">
<p>[1] Boost.Foreach: <em><a href="http://boost.org/libs/foreach" class="uri">http://boost.org/libs/foreach</a></em>. Accessed: 2015-11-18.</p>
</div>
<div id="ref-n4560">
<p>[2] Niebler, E. and Carter, C. 2015. N4560: Working Draft, C++ Extensions for Ranges.</p>
</div>
<div id="ref-n4128">
<p>[3] Niebler, E. et al. 2014. N4128: Ranges for the Standard Library, Revision 1.</p>
</div>
</div>
</body>
</html>
