<!DOCTYPE html>
<html><head><meta content="text/html;charset=US-ASCII" http-equiv="Content-Type"><title>A minimal std::range&lt;Iter&gt;</title><style type="text/css">
body {color: #000000; background-color: #FFFFFF;}

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

pre > code:only-child {display: inline-block; white-space: inherit}
code {white-space: nowrap}
code wbr {white-space: normal}

section.function {}
.attribute {margin-left: 2em}
.attribute dt {float: left; font-style: italic; padding-right: 1ex}
.attribute dd {margin-left: 0}
.attribute li {clear: left}

.docinfo {float: right}
.docinfo p {margin: 0; text-align:right; font-style: italic}

section {padding-left: 1em}
section header {margin-left: -1em}

h2, h3, h4, h5, h6 { margin-bottom: .75em }
p {margin-top: .5em; margin-bottom: .5em}
p:first-child, ul, ol {margin-top: 0}
.todo dt:not(:first-child) {margin-top: .5em}
p, li, dd {max-width: 80ex}

figure {display: inline-block; margin: 1ex 1em;
        border: thin solid #f88; background-color: #eef; padding: 1ex}
figcaption + p { margin-top: 0 }
figure > p:last-child { margin-bottom:0 }
figure > * { margin-left: 1em }
figure > figcaption { margin-left: 0 }
figcaption { font-weight: bold }

div.example {display: inline-block; clear: both; margin-left: 1ex;
             border: thin solid #dfd; background-color: #f8f8f8; padding: 1ex}

div.note > *:first-child::before {content: "Note: "; display: inline; font-weight: bold}
div.note {display: inline-block; margin-left: 1ex; border: thin solid #8f8;
          padding: 1ex; background-color: #efe}

:target {background-color: #fed}
</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script><script type="text/javascript">$(function() {
    var next_id = 0
    function find_id(node) {
        // Look down the first children of 'node' until we find one
        // with an id. If we don't find one, give 'node' an id and
        // return that.
        var cur = node[0];
        while (cur) {
            if (cur.id) return curid;
            if (cur.tagName == 'A' && cur.name)
                return cur.name;
            cur = cur.firstChild;
        };
        // No id.
        node.attr('id', 'gensection-' + next_id++);
        return node.attr('id');
    };

    // Put a table of contents in the #toc nav.

    // This is a list of <ol> elements, where toc[N] is the list for
    // the current sequence of <h(N+2)> tags. When a header of an
    // existing level is encountered, all higher levels are popped,
    // and an <li> is appended to the level
    var toc = [$("<ol/>")];
    $(':header').not('h1').each(function() {
        var header = $(this);
        // For each <hN> tag, add a link to the toc at the appropriate
        // level.  When toc is one element too short, start a new list
        var levels = {H2: 0, H3: 1, H4: 2, H5: 3, H6: 4};
        var level = levels[this.tagName];
        if (typeof level == 'undefined') {
            throw 'Unexpected tag: ' + this.tagName;
        }
        // Truncate to the new level.
        toc.splice(level + 1, toc.length);
        if (toc.length < level) {
            // Omit TOC entries for skipped header levels.
            return;
        }
        if (toc.length == level) {
            // Add a <ol> to the previous level's last <li> and push
            // it into the array.
            var ol = $('<ol/>')
            toc[toc.length - 1].children().last().append(ol);
            toc.push(ol);
        }
        var header_text = header.text();
        toc[toc.length - 1].append(
            $('<li/>').append($('<a href="#' + find_id(header) + '"/>')
                              .text(header_text)));
    });
    $('#toc').append(toc[0]);
})
</script></head><body><header><div class="docinfo"><p>ISO/IEC JTC1 SC22 WG21 N3350=12-0040</p><p>Date: <time pubdate="">2012-01-16</time></p><address><p>Jeffrey Yasskin &lt;<a href="mailto:jyasskin@google.com">jyasskin@google.com</a>&gt; </p><p>Source at <a href="http://code.google.com/p/cxx1y-range/">http://code.google.com/p/cxx1y-range/</a></p></address></div><h1>A minimal std::range&lt;Iter&gt;</h1></header><nav id="toc"></nav>
<section>
<header><h2><a name="index_1overview">Overview</a></h2></header>
<p>Ranges are ubiquitous in programs that use STL algorithms, but they're always written as adjacent iterator arguments, which makes them hard to use. Several groups have proposed a new set of range concepts that would allow ranges to be passed around as single objects. Two notable examples are the <a href="http://www.boost.org/libs/range/doc/html/index.html">Boost.Range</a> library and <a href="http://www.informit.com/articles/printerfriendly.aspx?p=1407357">Andrei Alexandrescu's range concepts</a> <a href="http://www.d-programming-language.org/phobos/std_range.html">in D</a>.</p><p>This paper, and the library at <a href="http://code.google.com/p/cxx1y-range/">http://code.google.com/p/cxx1y-range/</a>, attempt to take these ideas and produce a minimal library that's useful today and is suitable for standardization.</p></section>
<section>
<header><h2><a name="index_1inventions">Changes from existing libraries</a></h2></header>
<p>This library makes certain changes from the existing range libraries:</p><p>Boost's range library focuses on defining a set of Range concepts that allow Containers to be Ranges. Because Containers are heavy-weight, this forces Boost to use references for all of their uses of Ranges, including Ranges that are captured by Range Adapters. This worked fine in C++98, where users couldn't name the types of the Range Adapters in order to declare local variables, but with C++11's <code>auto</code> keyword, users can now save adapted ranges. Since Boost's adapted ranges capture references to their arguments, which can be temporaries, this is no longer a safe design.</p><p>This paper makes the opposite choice: it defines a concrete type and no concepts, and the concrete type is a lightweight view into a container. This implies that algorithms can't treat Ranges and Containers interchangeably, but there are ways around this, which I explore below. Of the Boost types, this paper's <code><a href="#classstd_1_1range">std::range</a></code> is most like <a href="http://www.boost.org/doc/libs/1_48_0/libs/range/doc/html/range/reference/utilities/iterator_range.html"><code>boost::iterator_range</code></a>.</p><p>Andrei Alexandrescu's range concepts provide a complete replacement for iterators. However, they require that the whole machinery be adopted at once, which isn't appropriate for a widely-used language like C++. This paper's <code><a href="#classstd_1_1range">std::range</a></code> allows users to program against the Range concepts while still accepting data from iterator-oriented containers.</p><p>This paper's <code>range&lt;&gt;</code> omits Alexandrescu's <code>ForwardRange.save()</code> operation, on the theory that it's just a type assertion for most ForwardRanges (since they provide a full-featured copy operation), so most algorithms would forget to call <code>save()</code>. This would introduce bugs when those algorithms were used with the rare ForwardRange that could take advantage of it to save work on plain copies. It's better to omit the optimization than to lay traps.</p><p>Like the D ranges, but unlike the STL's iterators, this paper's <code>range</code> uses the same names for O(1) and O(N) operations. Some reviewers found the O(N) names (<code>advance</code> and <code>shorten</code>) confusing, and with <code>static_assert()</code>, users can now check the category explicitly if they're concerned. The one operation we didn't make work for all categories was <code>operator[]</code> on the theory that indexing is much more likely to indicate a programmer mistake than other operations.</p><p>This proposal allows negative indices for indexing operations, following the lead of several scripting languages. Neither of the earlier range implementations does this for arbitrary ranges, but D does allow users to <a href="http://www.d-programming-language.org/arrays.html#array-length">offset from the end</a> of a random-access range.</p></section>
<section>
<header><h2><a name="index_1writing_algorithms">How to write algorithms that use ranges</a></h2></header>
<p>As mentioned above, you can't simply write an algorithm that takes either Containers or <code>std::range&lt;&gt;</code>s and treats them interchangeably: <div><div class="example"><code><span class="normal"></span><span class="keyword">template</span><span class="normal">&lt;</span><span class="keyword">typename</span><span class="normal">&#160;T&gt;</span></code><br><code><span class="normal"></span><span class="keywordtype">void</span><span class="normal">&#160;my_algorithm(T&#160;argument)&#160;{&#160;&#160;</span><span class="comment">//&#160;Copies&#160;any&#160;containers.</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;</span><span class="keywordflow">while</span><span class="normal">&#160;(!argument.empty())&#160;{</span></code><br><code><span class="normal">&#160;&#160;&#160;&#160;process(argument.front());</span></code><br><code><span class="normal">&#160;&#160;&#160;&#160;</span><span class="comment">//&#160;Fails&#160;on&#160;vectors;&#160;destructive&#160;on&#160;deques;&#160;fine&#160;on&#160;ranges:</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;&#160;&#160;argument.pop_front();</span></code><br><code><span class="normal">&#160;&#160;}</span></code><br><code><span class="normal">}</span></code><br></div></div></p><p>The limits of template argument deduction make it inconvenient to take a <code><a href="#classstd_1_1range">std::range</a></code> explicitly: <div><div class="example"><code><span class="normal"></span><span class="keyword">template</span><span class="normal">&lt;</span><span class="keyword">typename</span><span class="normal">&#160;Iter&gt;</span></code><br><code><span class="normal"></span><span class="keywordtype">void</span><span class="normal">&#160;my_algorithm(<a href="#classstd_1_1range">std::range&lt;Iter&gt;</a>&#160;argument)&#160;{</span></code><br><code><span class="normal">&#160;&#160;</span><span class="keywordflow">while</span><span class="normal">&#160;(!argument.<a href="#classstd_1_1range_1a12a363c143862c0d46788e1e2c6629c8">empty</a>())&#160;{</span></code><br><code><span class="normal">&#160;&#160;&#160;&#160;process(argument.<a href="#classstd_1_1range_1aac6135ec81b3afc37f6050dd0769aa6d">front</a>());</span></code><br><code><span class="normal">&#160;&#160;&#160;&#160;argument.<a href="#classstd_1_1range_1a3c743e4e4b85290682234af4c2d7e50f">pop_front</a>();</span></code><br><code><span class="normal">&#160;&#160;}</span></code><br><code><span class="normal">}</span></code><br><code><span class="normal"></span></code><br><code><span class="normal"></span><span class="keywordtype">void</span><span class="normal">&#160;user()&#160;{</span></code><br><code><span class="normal">&#160;&#160;ContainerT&#160;my_container;</span></code><br><code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;Fails!&#160;std::range&lt;ContainerT::iterator&gt;&#160;has&#160;an&#160;implicit</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;conversion&#160;from&#160;ContainerT,&#160;but&#160;because&#160;the&#160;type&#160;of&#160;the</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;explicit&#160;argument&#160;doesn't&#160;match&#160;"std::range&lt;*&gt;",&#160;the</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;compiler&#160;can't&#160;deduce&#160;the&#160;template&#160;argument.</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;my_algorithm(my_container);</span></code><br><code><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;Works,&#160;but&#160;verbose:</span><span class="normal"></span></code><br><code><span class="normal">&#160;&#160;my_algorithm(std::make_range(my_container));</span></code><br><code><span class="normal">}</span></code><br></div></div></p><p>The best option seems to be for algorithms that want to take either containers or ranges, and use ranges internally, to take their parameter by <code>T&amp;</code> or <code>const T&amp;</code> and use <a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range()</a> to build a range out of it explicitly: <div><div class="example"><code><span class="keyword">template</span><span class="normal">&lt;</span><span class="keyword">typename</span><span class="normal">&#160;T&gt;</span></code><br>
<code><span class="normal"></span><span class="keywordtype">void</span><span class="normal">&#160;partial_sum(T&amp;&#160;container)&#160;{</span></code><br>
<code><span class="normal">&#160;&#160;</span><span class="keyword">using</span><span class="normal">&#160;std::make_range;</span></code><br>
<code><span class="normal">&#160;&#160;</span><span class="keyword">auto</span><span class="normal">&#160;range&#160;=&#160;make_range(container);</span></code><br>
<code><span class="normal">&#160;&#160;</span><span class="keyword">typename</span><span class="normal">&#160;T::value_type&#160;sum&#160;=&#160;0;</span></code><br>
<code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;One&#160;would&#160;actually&#160;use&#160;a&#160;range-based&#160;for&#160;loop</span><span class="normal"></span></code><br>
<code><span class="normal">&#160;&#160;</span><span class="comment">//&#160;in&#160;this&#160;case,&#160;but&#160;you&#160;get&#160;the&#160;idea:</span><span class="normal"></span></code><br>
<code><span class="normal">&#160;&#160;</span><span class="keywordflow">for</span><span class="normal">&#160;(;&#160;!range.empty();&#160;range.pop_front())&#160;{</span></code><br>
<code><span class="normal">&#160;&#160;&#160;&#160;sum&#160;+=&#160;range.front();</span></code><br>
<code><span class="normal">&#160;&#160;&#160;&#160;range.front()&#160;=&#160;sum;</span></code><br>
<code><span class="normal">&#160;&#160;}</span></code><br>
<code><span class="normal">}</span></code><br>
<code><span class="normal"></span></code><br>
<code><span class="normal"></span><span class="keywordtype">void</span><span class="normal">&#160;user1()&#160;{</span></code><br>
<code><span class="normal">&#160;&#160;std::vector&lt;int&gt;&#160;v(5,&#160;2);</span></code><br>
<code><span class="normal">&#160;&#160;partial_sum(v);</span></code><br>
<code><span class="normal">&#160;&#160;assert(v[3]&#160;==&#160;8);</span></code><br>
<code><span class="normal">}</span></code><br>
</div></div> <p>By storing the result of <code><a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range()</a></code> in an <code>auto</code> variable, we allow authors of future range types to overload it as the identity operation on types that are already ranges.</p>
<p>The one case where taking <code><a href="#classstd_1_1range">std::range</a></code> explicitly seems to make sense is <code>range&lt;T*&gt;</code>. If an algorithm needs contiguous iterators, this can allow its authors to avoid making it a template: <div><div class="example"><code><span class="keywordtype">void</span><span class="normal">&#160;my_write(</span><span class="keywordtype">int</span><span class="normal">&#160;fd,&#160;<a href="#classstd_1_1range">std::range&lt;const char*&gt;</a>&#160;buffer)&#160;{</span></code><br>
<code><span class="normal">&#160;&#160;write(fd,&#160;buffer.begin(),&#160;buffer.<a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size</a>());</span></code><br>
<code><span class="normal">}</span></code><br>
<code><span class="normal"></span></code><br>
<code><span class="normal"></span><span class="keywordtype">void</span><span class="normal">&#160;user2()&#160;{</span></code><br>
<code><span class="normal">&#160;&#160;std::string&#160;s(</span><span class="stringliteral">"Hello&#160;world"</span><span class="normal">);</span></code><br>
<code><span class="normal">&#160;&#160;my_write(1,&#160;s);</span></code><br>
<code><span class="normal">}</span></code><br>
</div></div> </p>
<header><h2><a name="classstd_1_1range">std::range</a></h2></header>
    
<p>A <code>std::range&lt;Iterator&gt;</code> represents a half-open iterator range built from two iterators, <code>'begin'</code>, and <code>'end'</code>. If <code>end</code> is not reachable from <code>begin</code>, the behavior is undefined.</p><p>The mutability of elements of the range is controlled by the Iterator argument. Instantiate <code>range&lt;<em>Foo</em>::iterator&gt;</code> or <code>range&lt;<em>T</em>*&gt;</code>, or call <code>make_range(<em>non_const_container</em>)</code>, and you get a mutable range. Instantiate <code>range&lt;<em>Foo</em>::const_iterator&gt;</code> or <code>range&lt;const <em>T</em>*&gt;</code>, or call <code>make_range(<em>const_container</em>)</code>, and you get a constant range.</p><div><figure id="todo_1_todo000001"><figcaption>Todo</figcaption><p>Inherit from std::pair&lt;Iterator, Iterator&gt;?</p></figure></div><div><figure id="todo_1_todo000002"><figcaption>Todo</figcaption><p>This interface contains some functions that could be provided as free algorithms rather than member functions, and all of the <code>pop_*()</code> functions could be replaced by <code><a href="#classstd_1_1range_1a8b430c86ee0091b6be6f42e6419fd017">slice()</a></code> at the cost of some extra iterator copies. This makes them more awkward to use, but makes it easier for users to write their own types that follow the same interface. On the other hand, a <code>range_facade</code> could be provided to help users write new ranges, and it could provide the members. Such functions are marked with a note in their documentation. (Of course, all of these member functions could be provided as free functions using the iterator access methods, but one goal here is to allow people to program without touching iterators at all.) </p></figure></div>    <h3>Class definition</h3><pre><code>namespace std {
  template&lt;typename Iterator&gt;
  class range {
    // types
    typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1a3516021e4ad332dab8b907d32846ee22">iterator_category</a> iterator_category;
    typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1ab71d14f14787348c175a63b06b8a0d31">value_type</a> value_type;
    typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> difference_type;
    typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> reference;
    typedef iterator_traits&lt; Iterator &gt;::pointer pointer;

    // constructors
    <a href="#classstd_1_1range_1aa73760e7d0b4c96ff695f21a2546db21">range</a>();
    constexpr <a href="#classstd_1_1range_1a53c608a692b4822190e77410a2be90de">range</a>(Iterator begin, Iterator end);
    template&lt;typename R&gt;
    constexpr <a href="#classstd_1_1range_1a1fe901239d3406edeabe135d3bccf78a">range</a>(R &amp;&amp; r);
    template&lt;typename R&gt;
    constexpr <a href="#classstd_1_1range_1a351095ba467e28fc74a8c9d69d5b8572">range</a>(R &amp;&amp; r);

    // iterator access
    constexpr Iterator begin() const;
    constexpr Iterator end() const;

    // element access
    constexpr <a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> <a href="#classstd_1_1range_1aac6135ec81b3afc37f6050dd0769aa6d">front</a>() const;
    constexpr <a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> <a href="#classstd_1_1range_1ac32adf0e04a6143f46c94a9b85ff4c0d">back</a>() const;
    constexpr <a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> <a href="#classstd_1_1range_1a0262bc193551b1da78e7ce926d10a210">operator[]</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> index) const;

    // size
    constexpr bool <a href="#classstd_1_1range_1a12a363c143862c0d46788e1e2c6629c8">empty</a>() const;
    constexpr <a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size</a>() const;

    // traversal from the beginning of the range
    void <a href="#classstd_1_1range_1a3c743e4e4b85290682234af4c2d7e50f">pop_front</a>();
    void <a href="#classstd_1_1range_1a5950b340056ed991842d5d06f98183e8">pop_front</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);
    void <a href="#classstd_1_1range_1adb685e81c599a20d1b032780b5cd9ca4">pop_front_upto</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);

    // traversal from the end of the range
    void <a href="#classstd_1_1range_1ab0442c13f74e5eec08d52a2ec8e01fca">pop_back</a>();
    void <a href="#classstd_1_1range_1a661b21d93c3fe92df0e0d47c82b429c8">pop_back</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);
    void <a href="#classstd_1_1range_1aed33f09af3250edd4753173996a72501">pop_back_upto</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);

    // creating derived ranges
    pair&lt; <a href="#classstd_1_1range">range</a>, <a href="#classstd_1_1range">range</a> &gt; <a href="#classstd_1_1range_1ab2949efd4bb256eb3d5348b5c8e243c6">split</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> index) const;
    <a href="#classstd_1_1range">range</a> <a href="#classstd_1_1range_1a8b430c86ee0091b6be6f42e6419fd017">slice</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> start, <a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> stop) const;
    <a href="#classstd_1_1range">range</a> slice(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> start) const;
  };

  // deducing constructor wrappers
  template&lt;typename Iterator&gt;
  constexpr <a href="#classstd_1_1range">range</a>&lt; Iterator &gt; <a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range</a>(Iterator begin, Iterator end);
  template&lt;typename Range&gt;
  constexpr auto <a href="#classstd_1_1range_1a34ff75ae35290fa60412e4f508445586">make_range</a>(Range &amp;&amp; r) -&gt; range&lt; decltype(begin(r))&gt;;
  template&lt;typename Range&gt;
  constexpr auto <a href="#classstd_1_1range_1ac07971f6e8515537fdaa65e0039c8bd6">make_ptr_range</a>(Range &amp;&amp; r) -&gt; range&lt; decltype(&amp;*begin(r))&gt;;
}</code></pre><section><header><h3>Member semantics</h3></header><section><header><h4>deducing constructor wrappers</h4></header><p>These functions do the same thing as the constructor with the same signature. They just allow users to avoid writing the iterator type. </p><section class="function"><header><code id="classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">template&lt;typename Iterator&gt;
constexpr <a href="#classstd_1_1range">range</a>&lt; Iterator &gt; <a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range</a>(Iterator begin, Iterator end);
</code></header>
        
<div><figure id="todo_1_todo000003"><figcaption>Todo</figcaption><p>I'd like to define a <code>make_range</code> taking a single iterator argument representing the beginning of a range that ends with a default-constructed <code>Iterator</code>. This would help with using iterators like <code>istream_iterator</code>. However, using just <code><a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range()</a></code> could be confusing and lead to people writing incorrect ranges of more common iterators. Is there a better name? </p></figure></div>        </section><section class="function"><header><code id="classstd_1_1range_1a34ff75ae35290fa60412e4f508445586">template&lt;typename Range&gt;
constexpr auto <a href="#classstd_1_1range_1a34ff75ae35290fa60412e4f508445586">make_range</a>(Range &amp;&amp; r) -&gt; range&lt; decltype(begin(r))&gt;;
</code></header>
        
<dl class="attribute"><dt>Participates in overload resolution if:</dt><dd><p><code>begin(r)</code> and <code>end(r)</code> return the same type. </p></dd></dl>
        </section><section class="function"><header><code id="classstd_1_1range_1ac07971f6e8515537fdaa65e0039c8bd6">template&lt;typename Range&gt;
constexpr auto <a href="#classstd_1_1range_1ac07971f6e8515537fdaa65e0039c8bd6">make_ptr_range</a>(Range &amp;&amp; r) -&gt; range&lt; decltype(&amp;*begin(r))&gt;;
</code></header>
        
<dl class="attribute"><dt>Participates in overload resolution if:</dt><dd><ul>
<li><code>begin(r)</code> and <code>end(r)</code> return the same type,</li><li>that type satisfies the invariant that <code>&amp;*(i + N) == (&amp;*i) + N</code>, and</li><li><code>&amp;*begin</code>(r) has a pointer type. </li></ul>
</dd></dl>
        </section></section><section><header><h4>types</h4></header><section class="function"><header><code id="classstd_1_1range_1a3516021e4ad332dab8b907d32846ee22">typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1a3516021e4ad332dab8b907d32846ee22">iterator_category</a> iterator_category;
</code></header>
        
<p>The iterator category of <code>Iterator</code>. <div><figure id="todo_1_todo000004"><figcaption>Todo</figcaption><p>Consider defining range categories. If they don't add anything over the corresponding iterator categories, then they're probably not worth defining. </p></figure></div></p>        </section><section class="function"><header><code id="classstd_1_1range_1ab71d14f14787348c175a63b06b8a0d31">typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1ab71d14f14787348c175a63b06b8a0d31">value_type</a> value_type;
</code></header>
<p>The type of elements of the range. Not cv-qualified. </p>        
        </section><section class="function"><header><code id="classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> difference_type;
</code></header>
<p>The type of the size of the range and offsets within the range. </p>        
        </section><section class="function"><header><code id="classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">typedef iterator_traits&lt; Iterator &gt;::<a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> reference;
</code></header>
<p>The return type of element access methods: <code><a href="#classstd_1_1range_1aac6135ec81b3afc37f6050dd0769aa6d">front()</a></code>, <code><a href="#classstd_1_1range_1ac32adf0e04a6143f46c94a9b85ff4c0d">back()</a></code>, etc. </p>        
        </section></section><section><header><h4>constructors</h4></header><section class="function"><header><code id="classstd_1_1range_1aa73760e7d0b4c96ff695f21a2546db21"><a href="#classstd_1_1range_1aa73760e7d0b4c96ff695f21a2546db21">range</a>();
</code></header>
        
<p>Creates a range of default-constructed (<em>not</em> value-initialized) iterators. For most <code>Iterator</code> types, this will be an invalid range. </p>        </section><section class="function"><header><code id="classstd_1_1range_1a53c608a692b4822190e77410a2be90de">constexpr <a href="#classstd_1_1range_1a53c608a692b4822190e77410a2be90de">range</a>(Iterator begin, Iterator end);
</code></header>
        
<p><dl class="attribute"><dt>Requires:</dt><dd><p><code>end</code> is reachable from <code>begin</code>. </p></dd><dt>Postconditions:</dt><dd><p><code>this-&gt;begin() == begin &amp;&amp; this-&gt;end() == end</code> </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1a1fe901239d3406edeabe135d3bccf78a">template&lt;typename R&gt;
constexpr <a href="#classstd_1_1range_1a1fe901239d3406edeabe135d3bccf78a">range</a>(R &amp;&amp; r);
</code></header>
        
<p><dl class="attribute"><dt>Participates in overload resolution if:</dt><dd><ul>
<li><code>Iterator</code> is not a pointer type,</li><li><code>begin(r)</code> and <code>end(r)</code> return the same type, and</li><li>that type is convertible to <code>Iterator</code>.</li></ul>
</dd></dl>
<div><figure id="todo_1_todo000005"><figcaption>Todo</figcaption><p>std::begin and std::end are overloaded between T&amp; and const T&amp;, which means that if a container has only a non-const begin or end method, then it's ill-formed to pass an rvalue to the free function. To avoid that problem, we don't use std::forward&lt;&gt; here, so begin() and end() are always called with an lvalue. Another option would be to insist that rvalue arguments to <a href="#classstd_1_1range_1aa73760e7d0b4c96ff695f21a2546db21">range()</a> must have const begin() and end() methods. </p></figure></div></p>        </section><section class="function"><header><code id="classstd_1_1range_1a351095ba467e28fc74a8c9d69d5b8572">template&lt;typename R&gt;
constexpr <a href="#classstd_1_1range_1a351095ba467e28fc74a8c9d69d5b8572">range</a>(R &amp;&amp; r);
</code></header>
        
<p>This constructor creates a <code>range&lt;T*&gt;</code> from any range with contiguous iterators. Because dereferencing a past-the-end iterator can be undefined behavior, empty ranges get initialized with <code>nullptr</code> rather than <code>&amp;*begin</code>().</p><p><dl class="attribute"><dt>Participates in overload resolution if:</dt><dd><ul>
<li><code>Iterator</code> is a pointer type <code>T*</code>,</li><li><code>begin(r)</code> and <code>end(r)</code> return the same type,</li><li>elements <code>i</code> of that type satisfy the invariant <code>&amp;*(i + N) == (&amp;*i) + N</code>, and</li><li>The result of <code>&amp;*begin()</code> is convertible to <code>T*</code> using only qualification conversions [conv.qual] (since pointer conversions stop the pointer from pointing to an array element).</li></ul>
</dd></dl>
<div><figure id="todo_1_todo000006"><figcaption>Todo</figcaption><p>The <code>&amp;*(i + N) == (&amp;*i) + N</code> invariant is currently impossible to check for user-defined types. We need a <code>contiguous_iterator_tag</code> to let users assert it. </p></figure></div></p>        </section></section><section><header><h4>element access</h4></header><section class="function"><header><code id="classstd_1_1range_1aac6135ec81b3afc37f6050dd0769aa6d">constexpr <a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> <a href="#classstd_1_1range_1aac6135ec81b3afc37f6050dd0769aa6d">front</a>() const;
</code></header>
        
<p><dl class="attribute"><dt>Complexity:</dt><dd><p>O(1) </p></dd><dt>Requires:</dt><dd><p><code>!empty</code>() </p></dd><dt>Returns:</dt><dd><p>a reference to the element at the front of the range. </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1ac32adf0e04a6143f46c94a9b85ff4c0d">constexpr <a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> <a href="#classstd_1_1range_1ac32adf0e04a6143f46c94a9b85ff4c0d">back</a>() const;
</code></header>
        
<p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>bidirectional_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><p>O(2) (Involves copying and decrementing an iterator, so not quite as cheap as <code><a href="#classstd_1_1range_1aac6135ec81b3afc37f6050dd0769aa6d">front()</a></code>)</p></dd><dt>Requires:</dt><dd><p><code>!empty</code>() </p></dd><dt>Returns:</dt><dd><p>a reference to the element at the front of the range. </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1a0262bc193551b1da78e7ce926d10a210">constexpr <a href="#classstd_1_1range_1a5b246055b9fda3998f442667283b2aa5">reference</a> <a href="#classstd_1_1range_1a0262bc193551b1da78e7ce926d10a210">operator[]</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> index) const;
</code></header>
        
<p>This method is drawn from scripting language indexing. It indexes forward from the beginning of the range if the argument is positive, or backwards from the end of the array if the argument is negative.</p><p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>random_access_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><p>O(1)</p></dd><dt>Requires:</dt><dd><p><code>abs(index) &lt; <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a> || index == -size()</code></p></dd><dt>Returns:</dt><dd><p>if <code>index &gt;= 0</code>, a reference to the <code>index</code>'th element in the range. Otherwise, a reference to the <code><a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a>+index</code>'th element. </p></dd></dl>
</p>        </section></section><section><header><h4>size</h4></header><section class="function"><header><code id="classstd_1_1range_1a12a363c143862c0d46788e1e2c6629c8">constexpr bool <a href="#classstd_1_1range_1a12a363c143862c0d46788e1e2c6629c8">empty</a>() const;
</code></header>
        
<p><dl class="attribute"><dt>Complexity:</dt><dd><p>O(1) </p></dd><dt>Returns:</dt><dd><p><code>true</code> if the range contains no elements. </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">constexpr <a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size</a>() const;
</code></header>
        
<p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>forward_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><p>O(1) if <code>iterator_category</code> is convertible to <code>random_access_iterator_tag</code>. O(<code><a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a></code>) otherwise.</p></dd><dt>Returns:</dt><dd><p>the number of times <code><a href="#classstd_1_1range_1a3c743e4e4b85290682234af4c2d7e50f">pop_front()</a></code> can be called before <code><a href="#classstd_1_1range_1a12a363c143862c0d46788e1e2c6629c8">empty()</a></code> becomes true. </p></dd></dl>
</p>        </section></section><section><header><h4>traversal from the beginning of the range</h4></header><section class="function"><header><code id="classstd_1_1range_1a3c743e4e4b85290682234af4c2d7e50f">void <a href="#classstd_1_1range_1a3c743e4e4b85290682234af4c2d7e50f">pop_front</a>();
</code></header>
        
<p>Advances the beginning of the range by one element. <dl class="attribute"><dt>Requires:</dt><dd><p><code>!empty</code>() </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1a5950b340056ed991842d5d06f98183e8">void <a href="#classstd_1_1range_1a5950b340056ed991842d5d06f98183e8">pop_front</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);
</code></header>
        
<p>Advances the beginning of the range by <code>n</code> elements.</p><p><dl class="attribute"><dt>Complexity:</dt><dd><p>O(1) if <code>iterator_category</code> is convertible to <code>random_access_iterator_tag</code>, O(<code>n</code>) otherwise.</p></dd><dt>Requires:</dt><dd><p><code>n &gt;= 0</code>, and there must be at least <code>n</code> elements in the range. </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1adb685e81c599a20d1b032780b5cd9ca4">void <a href="#classstd_1_1range_1adb685e81c599a20d1b032780b5cd9ca4">pop_front_upto</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);
</code></header>
        
<p>Advances the beginning of the range by at most <code>n</code> elements, stopping if the range becomes empty. A negative argument causes no change.</p><p><dl class="attribute"><dt>Complexity:</dt><dd><p>O(1) if <code>iterator_category</code> is convertible to <code>random_access_iterator_tag</code>, O(<code>min(n, <em>#-elements-in-range</em>)</code>) otherwise.</p></dd></dl>
<div><div class="note"><p>Could be provided as a free function with little-to-no loss in efficiency. </p></div></div>
</p>        </section></section><section><header><h4>traversal from the end of the range</h4></header><section class="function"><header><code id="classstd_1_1range_1ab0442c13f74e5eec08d52a2ec8e01fca">void <a href="#classstd_1_1range_1ab0442c13f74e5eec08d52a2ec8e01fca">pop_back</a>();
</code></header>
        
<p>Moves the end of the range earlier by one element.</p><p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>bidirectional_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><p>O(1)</p></dd><dt>Requires:</dt><dd><p><code>!empty</code>() </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1a661b21d93c3fe92df0e0d47c82b429c8">void <a href="#classstd_1_1range_1a661b21d93c3fe92df0e0d47c82b429c8">pop_back</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);
</code></header>
        
<p>Moves the end of the range earlier by <code>n</code> elements.</p><p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>bidirectional_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><p>O(1) if <code>iterator_category</code> is convertible to <code>random_access_iterator_tag</code>, O(<code>n</code>) otherwise.</p></dd><dt>Requires:</dt><dd><p><code>n &gt;= 0</code>, and there must be at least <code>n</code> elements in the range. </p></dd></dl>
</p>        </section><section class="function"><header><code id="classstd_1_1range_1aed33f09af3250edd4753173996a72501">void <a href="#classstd_1_1range_1aed33f09af3250edd4753173996a72501">pop_back_upto</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> n);
</code></header>
        
<p>Moves the end of the range earlier by <code>min(n, <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a>)</code> elements. A negative argument causes no change.</p><p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>bidirectional_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><p>O(1) if <code>iterator_category</code> is convertible to <code>random_access_iterator_tag</code>, O(<code>min(n, <em>#-elements-in-range</em>)</code>) otherwise.</p></dd></dl>
<div><div class="note"><p>Could be provided as a free function with little-to-no loss in efficiency. </p></div></div>
</p>        </section></section><section><header><h4>creating derived ranges</h4></header><section class="function"><header><code id="classstd_1_1range_1ab2949efd4bb256eb3d5348b5c8e243c6">pair&lt; <a href="#classstd_1_1range">range</a>, <a href="#classstd_1_1range">range</a> &gt; <a href="#classstd_1_1range_1ab2949efd4bb256eb3d5348b5c8e243c6">split</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> index) const;
</code></header>
        
<p>Divides the range into two pieces at <code>index</code>, where a positive <code>index</code> represents an offset from the beginning of the range and a negative <code>index</code> represents an offset from the end. <code>range[index]</code> is the first element in the second piece. If <code>index &gt;= <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a></code>, the second piece will be empty. If <code>index &lt; -size()</code>, the first piece will be empty.</p><p><dl class="attribute"><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>forward_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><ul>
<li>If <code>iterator_category</code> is convertible to <code>random_access_iterator_tag:</code> O(1)</li><li>Otherwise, if <code>iterator_category</code> is convertible to <code>bidirectional_iterator_tag</code>, <code>abs(index)</code> iterator increments or decrements</li><li>Otherwise, if <code>index &gt;= 0</code>, <code>index</code> iterator increments</li><li>Otherwise, <code><a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a> + (<a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a> + index)</code> iterator increments.</li></ul>
</dd><dt>Returns:</dt><dd><p>a pair of adjacent ranges.</p></dd><dt>Postconditions:</dt><dd><ul>
<li><code>result.first.size() == min(index, this-&gt;<a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a>)</code></li><li><code>result.first.end() == result.second.begin()</code></li><li><code>result.first.size() + result.second.size()</code> <code>== this-&gt;<a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a></code></li></ul>
</dd></dl>
<div><figure id="todo_1_todo000007"><figcaption>Todo</figcaption><p><a href="#classstd_1_1range_1ab2949efd4bb256eb3d5348b5c8e243c6">split()</a> could take an arbitrary number of indices and return an <code>N+1</code>-element <code>tuple&lt;&gt;</code>. This is tricky to implement with negative indices in the optimal number of increments or decrements for a bidirectional iterator, but it should be possible. Do we want it? </p></figure></div></p>        </section><section class="function"><header><code id="classstd_1_1range_1a8b430c86ee0091b6be6f42e6419fd017"><a href="#classstd_1_1range">range</a> <a href="#classstd_1_1range_1a8b430c86ee0091b6be6f42e6419fd017">slice</a>(<a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> start, <a href="#classstd_1_1range_1aa425a72dcc8bb0555746b70ad379ec98">difference_type</a> stop) const;
</code></header>
        
<p><dl class="attribute"><dt>Returns:</dt><dd><p>A sub-range from <code>start</code> to <code>stop</code> (not including <code>stop</code>, as usual). <code>start</code> and <code>stop</code> are interpreted as for <code>operator[]</code>, with negative values offsetting from the end of the range. Omitting the <code>stop</code> argument makes the sub-range continue to the end of the original range. Positive arguments saturate to the end of the range, and negative arguments saturate to the beginning. If <code>stop</code> is before <code>start</code>, returns an empty range beginning and ending at <code>start</code>.</p></dd><dt>Ill-formed unless:</dt><dd><p><code>iterator_category</code> is convertible to <code>forward_iterator_tag</code>.</p></dd><dt>Complexity:</dt><dd><ul>
<li>If <code>iterator_category</code> is convertible to <code>random_access_iterator_tag:</code> O(1)</li><li>Otherwise, if <code>iterator_category</code> is convertible to <code>bidirectional_iterator_tag</code>, at most <code>min(abs(start), <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a>) + min(abs(stop), <a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a>)</code> iterator increments or decrements</li><li>Otherwise, if <code>start &gt;= 0 &amp;&amp; stop &gt;= 0</code>, <code>max(start, stop)</code> iterator increments</li><li>Otherwise, <code><a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a> + max(start', stop')</code> iterator increments, where <code>start'</code> and <code>stop'</code> are the offsets of the elements <code>start</code> and <code>stop</code> refer to.</li></ul>
</dd></dl>
<div><div class="note"><p><code>slice(start)</code> should be implemented with a different overload, rather than defaulting <code>stop</code> to <code>numeric_limits&lt;difference_type&gt;::max()</code>, because using a default would force non-random-access ranges to use an O(<code><a href="#classstd_1_1range_1a210f2b71bc217e88709470d3d3ba4b30">size()</a></code>) algorithm to compute the end rather than the O(1) they're capable of. </p></div></div>
</p>        </section></section></section>
</p></section>
<section>
<header><h2><a name="index_1misc">Miscellaneous other changes</a></h2></header>
<p>Certain other pieces of the library should change to make life easier for <code>range&lt;&gt;</code>.</p><ul>
<li><code>std::begin()</code>, <code>std::end()</code>, and <code>std::distance</code> should become <code>constexpr</code>.</li><li>We need a <code>contiguous_iterator_tag</code> to let <code>range&lt;T*&gt;</code> safely construct from user-defined types that control contiguous sequences of objects.</li><li>The <code>*_upto</code> methods could take advantage of a <code>std::advance_upto(it, n, end)</code> algorithm on plain iterators, which advances the iterator either n increments or to 'end', whichever comes first.</li></ul>
</section>
<section>
<header><h2><a name="index_1future">Future work</a></h2></header>
<p>Many functions will be able to take either Ranges or Containers as arguments. We should work out what concept their argument follows. "Iterable"?</p><p>Versions of all of the algorithms should be added that accept ranges. While it would be possible to make them take <code>std::range&lt;&gt;</code> itself, a set of Range concepts will likely work better in the long run, leaving <code>std::range&lt;&gt;</code> as an interface between the iterator and range worlds.</p><p><a href="http://www.boost.org/doc/libs/1_48_0/libs/range/doc/html/range/reference/adaptors/introduction.html">Boost's adapters</a> are a great idea and should be added to the standard.</p><p>Infinite ranges could be defined, whose <code>empty()</code> method returns <code>std::false_type</code>.</p><p>We should figure out how to fit OutputIterators into the range framework.</p><p>A collection of <code>any_range</code> types would be useful.</p><header><h2>Open questions</h2></header>
<dl class="todo"><dt><a id="todo_1_todo000003"></a>Member <a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range</a>  </dt><dd>I'd like to define a <code>make_range</code> taking a single iterator argument representing the beginning of a range that ends with a default-constructed <code>Iterator</code>. This would help with using iterators like <code>istream_iterator</code>. However, using just <code><a href="#classstd_1_1range_1a36eaf64d667fdc4f24a43220023751fc">make_range()</a></code> could be confusing and lead to people writing incorrect ranges of more common iterators. Is there a better name?  </dd><dt><a id="todo_1_todo000001"></a>Class <a href="#classstd_1_1range">std::range&lt; Iterator &gt;</a>  </dt><dd><p>Inherit from std::pair&lt;Iterator, Iterator&gt;?</p><p>This interface contains some functions that could be provided as free algorithms rather than member functions, and all of the <code>pop_*()</code> functions could be replaced by <code>slice()</code> at the cost of some extra iterator copies. This makes them more awkward to use, but makes it easier for users to write their own types that follow the same interface. On the other hand, a <code>range_facade</code> could be provided to help users write new ranges, and it could provide the members. Such functions are marked with a note in their documentation. (Of course, all of these member functions could be provided as free functions using the iterator access methods, but one goal here is to allow people to program without touching iterators at all.)  </p></dd><dt><a id="todo_1_todo000004"></a>Member <a href="#classstd_1_1range_1a3516021e4ad332dab8b907d32846ee22">std::range&lt; Iterator &gt;::iterator_category</a>  </dt><dd>Consider defining range categories. If they don't add anything over the corresponding iterator categories, then they're probably not worth defining.  </dd><dt><a id="todo_1_todo000006"></a>Member <a href="#classstd_1_1range_1a351095ba467e28fc74a8c9d69d5b8572">std::range&lt; Iterator &gt;::range</a>  (R &amp;&amp;r, typename enable_if&lt; is_pointer&lt; Iterator &gt;::value &amp;&amp;detail::is_contiguous_range&lt; R &gt;::value &amp;&amp;detail::conversion_preserves_array_indexing&lt; decltype(&amp;*detail::adl_begin(r)), Iterator &gt;::value &gt;::type *=0)</dt><dd>The <code>&amp;*(i + N) == (&amp;*i) + N</code> invariant is currently impossible to check for user-defined types. We need a <code>contiguous_iterator_tag</code> to let users assert it.  </dd><dt><a id="todo_1_todo000005"></a>Member <a href="#classstd_1_1range_1a1fe901239d3406edeabe135d3bccf78a">std::range&lt; Iterator &gt;::range</a>  (R &amp;&amp;r, typename enable_if&lt;!is_pointer&lt; Iterator &gt;::value &amp;&amp;detail::is_range&lt; R &gt;::value &amp;&amp;is_convertible&lt; typename detail::begin_result&lt; R &gt;::type, Iterator &gt;::value &gt;::type *=0)</dt><dd>std::begin and std::end are overloaded between T&amp; and const T&amp;, which means that if a container has only a non-const begin or end method, then it's ill-formed to pass an rvalue to the free function. To avoid that problem, we don't use std::forward&lt;&gt; here, so begin() and end() are always called with an lvalue. Another option would be to insist that rvalue arguments to range() must have const begin() and end() methods.  </dd><dt><a id="todo_1_todo000007"></a>Member <a href="#classstd_1_1range_1ab2949efd4bb256eb3d5348b5c8e243c6">std::range&lt; Iterator &gt;::split</a>  (difference_type index) const </dt><dd>split() could take an arbitrary number of indices and return an <code>N+1</code>-element <code>tuple&lt;&gt;</code>. This is tricky to implement with negative indices in the optimal number of increments or decrements for a bidirectional iterator, but it should be possible. Do we want it? </dd></dl>
    
</section>
    </body></html>