﻿<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="Content-Type"/>
    <meta charset="UTF-8"/>
    <title>Traversable arguments for container constructors and methods, wording revision 3</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 {display: inline-block; white-space: inherit}
code {white-space: nowrap}
code wbr {white-space: normal}
code .comment {white-space: pre-line; font-family: serif; font-style: italic}
code .comment code {font-style: normal}

/*
.wording { max-width: 90ex; }
.wording .sectnum { margin-right: 1em; }
.wording .sectname { display: block; float: right;  }

section.numbered { counter-reset: par-num; }
.wording p:before, .wording dt:before {
    content: counter(par-num) " "; counter-increment: par-num;
    font-size: 80%; position: absolute; left: 2em}
*/
.wording td { border-top: thin solid black; border-bottom: thin solid black; }

section.function { clear: both; }
.attributes, .attribute {margin-left: 2em}

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

section {padding-left: 16px}
section h2, section h3, section h4, section h5, section h6 {margin-left: -16px}

h2, h3, h4, h5, h6 { margin-bottom: .75em }
h5, h6 { font-size: 1em; }
.wording h4 { font-size: 1.17em }
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, table {max-width: 80ex}

table { border: double; margin: 1em; border-collapse: collapse; }
td { text-align: left; }

.example {display: inline-block; clear: both; margin-left: 1ex;
          border: thin solid #0e0; 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>
</head>
<body>
  <header>
    <div class="docinfo">
      <p>ISO/IEC JTC1 SC22 WG21 N3686</p>
      <p>Date: <time pubdate="">2013-05-03</time></p>
      <address>
        <p>Jeffrey Yasskin &lt;<a href="mailto:jyasskin@google.com">jyasskin@google.com</a>&gt;</p>
      </address>
    </div>
    <h1>Traversable arguments for container constructors and methods, wording revision 3</h1>
  </header>

  <p><small><a href="#maincontent">Skip table of contents</a></small></p>
  <nav id="toc"></nav>

  <a id="maincontent"></a>
  <section>
    <h2 id="overview">Overview</h2>
    <p>The STL brought the notion of a <dfn>range</dfn> to C++, expressed as a
    pair of iterators.  C++11 added the range-based for loop, which iterates
    over a single object for which <code>begin(x)</code> and <code>end(x)</code>
    return that pair of iterators.  The <a
    href="http://www.boost.org/libs/range">Boost.Range</a> library extends this
    to a full library of algorithms based on ranges as single objects.  We don't
    yet know the full design of the library we want to standardize, but a simple
    step we already know is needed is to allow the output of that library to be
    passed to existing functions in the standard library that already take an
    iterator-pair range.</p>

    <p>I drew inspiration from two places in adding this support.  First, the
    range-based for loop ([stmt.ranged]) defines the minimal interface for a
    range object:</p>
    <ul>
      <li><code>range</code> must be an array, or have <code>begin()</code> and
      <code>end()</code> methods, or the expressions <code>begin(range)</code>
      and <code>end(range)</code> must be valid with namespace <code>std</code>
      as an associated namespace.  These functions must return types that can
      initialize variables in the same <code>auto</code>-typed declaration.
      (This implies they must return the same type.)</li>

      <li>The type returned by <code>begin(range)</code> and
      <code>end(range)</code> supports <code>operator*</code>,
      <code>operator++</code>, and <code>operator!=</code> in the pattern
      defined by Input Iterators.  This proposal slightly strengthens that into
      a requirement that <code>begin(range)</code> and <code>end(range)</code>
      actually return an Input Iterator type, although the
      <code>enable_if</code> logic for implementations is only required to check
      for the presence of <code>operator*</code>.</li>
    </ul>

    <p>Second, many container methods have an overload taking an
    <code>initializer_list&lt;value_type></code> argument.  This proposal takes
    that as a good indication of the methods that can usefully take a range
    argument and adds such an overload parallel to each one of those.  This is
    the same as the set of methods taking a templated Iterator pair except for
    one <code>priority_queue</code> constructor.</p>
  </section>

  <section>
    <h2 id="naming">On Naming</h2>

    <p>The term "Range" is ambiguous between two different meanings.  We have
    "Containers" (loosely), which own the values they refer to.  We have
    "Lightweight Ranges" which only refer to values and don't own them, and we
    have the union of the two concepts, which <i>Elements of Programming</i>
    refers to as "Linearizable".  "Range" could refer either to "Lightweight
    Range" or the union concept.  To avoid that ambiguity, <a
    href="http://wiki.edg.com/twiki/bin/view/Wg21bristol/SG9#Wednesday_08_45">SG9
    voted</a> to call the concept in this paper (the union concept)
    "Traversable".</p>
  </section>

  <section>
    <h2 id="range-arg">The <code>Traversable</code> template argument</h2>

    <p>There are many sorts of range types, so container methods taking ranges
    have to be templated.  C++ provides two ways to define templates taking any
    object as an input parameter: "<code>const Traversable&amp;</code>" or
    "<code>Traversable&amp;&amp;</code>" (where <code>Traversable</code> is a
    template argument).  This section discusses my choice to use
    "<code>Traversable&amp;&amp;</code>".</p>

    <p>Methods taking <code>Traversable</code> arguments are overloaded with
    other methods taking more precise argument types.  Using "<code>const
    Traversable&amp;</code>" would naturally leave <code>Container&amp;</code>
    arguments for the <code>const Container&amp;</code> overload, but it would
    incorrectly capture <code>DerivedFromContainer</code> arguments, just like
    "<code>Traversable&amp;&amp;</code>" would.
    "<code>Traversable&amp;&amp;</code>" has the benefit that it lets us allow
    library authors to move elements from rvalue arguments.  Because the
    necessary <code>enable_if</code> logic seems similar in both cases, I chose
    to take <code>Traversable&amp;&amp;</code>.</p>

    <p>The <a href="#range.requirements.implementations"><code>enable_if</code>
    logic</a> is specified as:</p>

    <blockquote>
      <p>Several functions in the standard library take a template argument
      named "<code>Traversable</code>". These functions shall not participate in
      overload resolution if <code>Traversable</code> is not deduced to a range
      type. Further, if the function is a container or string’s constructor or
      operator=, and <code>decay&lt;Traversable>::type</code> is the type of the
      container or a type derived from the container type, the function shall
      not participate in overload resolution.</p>

      <p>Additionally, implementations may exclude these functions from overload
      resolution if <code>Traversable</code>'s iterator type is not an Input
      Iterator type ([input.iterators]) or its value type is not convertible to
      the container’s value type, but the extent to which they do so is
      unspecified.</p>
    </blockquote>

    <p>Even with this text, <em>range types that define an implicit conversion
    to the container type with a non-default allocator, comparator, or hash
    instance</em> are going to have strange behavior when a conversion is
    requested.  With current language rules, it appears that copy-initialization
    will call the conversion operator, but direct-initialization will call the
    templated range constructor, losing any custom allocator, comparator, or
    hash instance the conversion operator attempts to set.  It's possible to
    work around this by explicitly passing them to the range constructor, but
    it's unlikely users will know to do so.  I believe such types are rare
    enough that this surprise is acceptable, and <a
    href="http://wiki.edg.com/twiki/bin/view/Wg21bristol/SG9#Wednesday_08_45">SG9
    agreed</a>.</p>

    <p>The proposed text also says that <a href="#unspecified-state">ranges
    passed as rvalues are "left in an unspecified state after the call."</a>
    When a range is just a reference to objects owned elsewhere, this text
    doesn't allow moving those objects, since that leaves more than just the
    <em>range</em> in an unspecified state.  However, if the implementation can
    detect that the range owns the objects it iterates over, this wording allows
    those objects to be moved.  I leave the technique for detecting this as a
    QoI issue.</p>
  </section>

  <section>
    <h2 id="fix-begin">That pesky ADL problem</h2>

    <p><a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3257.pdf">N3257</a>
    modified the definition of the range-based for loop in order to make user
    code work when an unconstrained <code>begin()</code> or <code>end()</code>
    template is found by ADL.  We'd like to follow that behavior in the
    implementations of each of the functions proposed in this paper, but
    specifying the fallback behavior in a concept definition is messy.  The best
    solution would be to make <code>std::begin()</code> and
    <code>std::end()</code> Just Work, but I was unable to find a technique that
    could remove them from the overload set when <code>std</code> was an
    associated namespace of the argument type and no more-specialized
    <code>begin()</code> was defined.  The technique I was using resulted in an
    infinite template instantiation recursion in deducing the return type of
    <code>begin</code>, which is a hard error in clang, and possibly undefined
    behavior in the standard.</p>

    <p>This proposal defines <code>std::traversable_begin()</code> and
    <code>std::traversable_end()</code> functions in order to simplify the
    specification of the concept, but a future revision could find wording to
    leave those functions notional instead of defined for users to call.</p>
  </section>

  <section>
    <h2 id="examples">Examples</h2>

    <section>
      <h3 id="boost.range.example">Using Boost.Range with standard containers</h3>
      <p>Boost has a fairly extensive collection of range-based algorithms, but
      they can't quite interoperate perfectly with standard containers because
      the containers are missing appropriate constructors.  This paper allows
      the following code (adapted from the <a
      href="http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/adaptors/reference/replaced.html">Boost.Range
      docs</a>) to work:</p>

<pre class="example"><code>#include &lt;boost/range/adaptor/replaced.hpp>
#include &lt;boost/range/adaptor/reversed.hpp>
#include &lt;boost/range/algorithm/copy.hpp>
#include &lt;deque>
#include &lt;iostream>
#include &lt;vector>

int main() {
    using namespace boost::adaptors;

    std::deque&lt;int> input{1,2,3,2,5,2,7,2,9};

    std::vector&lt;int> output{
      input | replaced(2, 10) | reversed};

    boost::copy(output, std::ostream_iterator&lt;int>(std::cout, ","));
}
</code></pre>

      <p>This prints "<samp>9,10,7,10,5,10,3,10,1,</samp>".</p>

      <p>You'll note that this paper doesn't propose any new algorithm overloads
      taking ranges, so the above example still needs to call
      <code>boost::copy</code> instead of <code>std::copy</code>. That's to keep
      this first proposal simple and because we don't yet know the more detailed
      concepts needed for a full range library, even though we do know the simple
      Traversable concept needed for the container methods.</p>
    </section>

    <section>
      <h3 id="split.example"><a
      href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3430.html">N3430's
      split()</a> without a conversion operator</h3>

      <p>The primary discomfort the LWG had with the <code>split()</code> proposal
      was that its implicit conversion operator to any container type was just a
      hack around the lack of range support (<a
      href="http://wiki.edg.com/twiki/bin/view/Wg21portland2012/LibraryWorkingGroup#Afternoon_AN2">Portland
      discussion</a>).  This paper delivers enough range support to remove
      <code>split()</code>'s conversion operator.</p>

<pre class="example"><code>vector&lt;string> v{std::split("a,b,c", ",")};
deque&lt;string> d{std::split("a,b,c", ",")};
set&lt;string> s{std::split("a,b,c", ",")};
list&lt;string> l{std::split("a,b,c", ",")};
vector&lt;string_ref> v2{std::split("a,b,c", ",")};  // No data copied.
assert(v.size() == 3);  // "a", "b", "c" </code></pre>

      <p>Conversion to either <code>string</code> or <code>string_ref</code> is
      accomplished by having <code>split()</code>'s result's iterator return proxy
      objects that are implicitly convertible to either type.  The <a
      href="#range.requirements.implementations"><code>enable_if</code> logic</a>
      specifically allows implicit conversions to the container's
      <code>value_type</code> so that this works.</p>
    </section>
  </section>

  <section>
    <h2 id="revision-history">Paper revision history</h2>

    <p>This paper updates <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3513.html">N3513</a>
    by renaming "Range" to "Traversable" and by specifying the requirements to
    search for <code>begin()</code> functions in the same way as the range-based
    for loop.</p>

    <p>N3513 updated <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3456.html">N3456</a>
    by moving the range requirements out of [containers] and into the library's
    introduction ([utility.requirements]).</p>

    <p>The <a
    href="https://github.com/google/cxx-std-draft/blob/range-args-paper/range_args.html">most
    recent version of this paper</a> is maintained on GitHub.</p>
  </section>

  <hr/>

  <section class="wording">
    <h2 id="wording">Wording</h2>

    <!--<p>Wording changes are being maintained at <a
    href="https://github.com/google/cxx-std-draft/compare/range-args">https://github.com/google/cxx-std-draft/compare/range-args</a>
    and a snapshot of the changes, relative to <a
    href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf">N3485</a>,
    is copied below.  An early implementation is at <a
    href="https://github.com/google/libcxx/compare/range-args">https://github.com/google/libcxx/compare/range-args</a>.
    Patches and pull requests are welcome against both.</p>-->

    <p>As an editorial matter, several of these new functions could be specified
    more concisely using [structure.specifications]'s "equivalent to" wording.
    They're specified more verbosely in order to match the existing functions
    around them.</p>

<h3 id="library">Clause 17, Library introduction</h3>

<h4>Modify [utility.requirements]</h4>
<p>[utility.arg.requirements] describes requirements on types and expressions
used to instantiate templates defined in the C++ standard
library. [swappable.requirements] describes the requirements on swappable types
and swappable expressions. [nullablepointer.requirements] describes the
requirements on pointer-like types that support null values. [hash.requirements]
describes the requirements on hash function objects. [allocator.requirements]
describes the requirements on storage allocators.<ins> [range.requirements]
describes the requirements on range types.</ins></p>

<h4 id="range.requirements">Add a sub-section under [utility.requirements],  "# Traversable requirements [range.requirements]"</h4>

<p>Objects of <code>Traversable</code> type (<code>Traversable</code> objects) refer to a
sequence of other objects using a pair of iterators accessed by
<code>std::traversable_begin()</code> and <code>std::traversable_end()</code> functions. <code>Traversable</code>
objects may or may not contain and own these other objects.</p>

<p>This subclause provides definitions for <code>Traversable</code> types and
expressions. In this subclause, <code>t</code> is an instance of a
<code>Traversable</code> type <code>T</code>. <code>i</code> is an instance of
<code>I</code>, known as <code>T</code>'s iterator type. <code>V</code> is
<code>T</code>'s and <code>I</code>'s value type.</p>

<p>[Note: These requirements are intended to match the requirements on
<code>_RangeT</code> in the range-based for loop ([stmt.ranged]). —endnote]</p>

<h5 id="range.requirements.implementations">Add a sub-section under [range.requirements],  "#.1 Functions taking Traversable types [range.requirements.implementations]"</h5>

<p>R is a <code>Traversable</code> type if it satisfies the requirements in Table 29
when the expressions are evaluated in the context described below.</p>

<table>
<caption>Table 29 &#x2014; <code>Traversable</code> requirements</caption>
<tr><th>Expression</th><th>Return type</th></tr>
<tr><td><code>std::traversable_begin(t)</code></td><td><code>I</code></td></tr>
<tr><td><code>std::traversable_end(t)</code></td><td><code>I</code></td></tr>
<tr><td><code>*i</code></td><td>implicitly convertible to <code>V</code></td></tr>
</table>

<p>[ Note: It is unspecified whether a library component that has a
<code>Traversable</code> requirement includes the header &lt;iterator> to
declare <code>std::traversable_begin</code> and
<code>std::traversable_end</code>. — end note ]</p>

<p>Several functions in the standard library take a template argument named
"<code>Traversable</code>". These functions shall not participate in overload
resolution if <code>Traversable</code> is not deduced to a <code>Traversable</code>
type. Further, if the function is a container or string’s constructor or
<code>operator=</code>, and <code>decay&lt;Traversable>::type</code> is the type of
the container or a type derived from the container type, the function shall not
participate in overload resolution.</p>

<p>Additionally, implementations may exclude these functions from overload
resolution if <code>Traversable</code>'s iterator type is not an Input Iterator type
([input.iterators]) or its value type is not convertible to the container's
value type, but the extent to which they do so is unspecified.</p>

<p id="unspecified-state">If the <code>Traversable</code> is passed as an rvalue, it
is left in an unspecified state after the call. [Footnote: This allows
implementations to detect arguments that are containers and move, instead of
copying, their contents. -- end footnote]</p>

<h5 id="range.requirements.calls">Add a sub-section under [range.requirements],  "#.2 Passing Traversable arguments [range.requirements.calls]"</h5>

<p>In calls to functions taking template arguments named <code>Traversable</code>, if
<code>Traversable</code>'s iterator type does not satisfy at least the Input Iterator
requirements ([input.iterators]), the program is ill-formed, no diagnostic
required.  If a Traversable object <code>t</code> is passed such that
<code>[std::traversable_begin(t),std::traversable_end(t))</code> is not a valid range
([iterator.requirements.general]), the behavior is undefined.</p>


<h3 id="strings">Clause 21, Strings library</h3>

<h4>Add to the std::basic_string definition in [basic.string]</h4>
<pre><code>    template&lt;class Traversable>
      explicit basic_string(Traversable&&, const Allocator& = Allocator());
    template&lt;class Traversable>
      basic_string& operator=(Traversable&&);
    template&lt;class Traversable>
      basic_string& operator+=(Traversable&&);
    template&lt;class Traversable>
      basic_string& append(Traversable&&);
    template&lt;class Traversable>
      basic_string& assign(Traversable&&);
    template&lt;class Traversable>
      iterator insert(const_iterator p, Traversable&&);
    template&lt;class Traversable>
      basic_string& replace(const_iterator, const_iterator, Traversable&&);</code></pre>

<h4>Add overloads to [string.cons]</h4>
<pre><code>template&lt;typename Traversable>
  explicit basic_string(Traversable&& range, const Allocator& a = Allocator());</code></pre>
<div class="attributes">
  <p>Effects: Same as basic_string(std::traversable_begin(range), std::traversable_end(range), a).</p>
</div>

<pre><code>template&lt;typename Traversable>
  basic_string& operator=(Traversable&& range);</code></pre>
<div class="attributes">
  <p>Effects: this->assign(std::forward&lt;Traversable>(range).</p>
  <p>Returns: *this.</p>
</div>

<h4>Add an overload to [string::op+=]</h4>
<pre><code>template&lt;class Traversable>
  basic_string& operator+=(Traversable&& range);</code></pre>
<div class="attributes">
  <p>Effects: Calls append(std::forward&lt;Traversable>(range)).</p>
  <p>Returns: *this.</p>
</div>

<h4>Add an overload to [string::append]</h4>
<pre><code>template&lt;class Traversable>
  basic_string& append(Traversable&& range);</code></pre>
<div class="attributes">
  <p>Effects: Calls append(std::traversable_begin(range), std::traversable_end(range)).</p>
  <p>Returns: *this.</p>
</div>

<h4>Add an overload to [string::assign]</h4>
<pre><code>template&lt;class Traversable>
  basic_string& assign(Traversable&& range);</code></pre>
<div class="attributes">
  <p>Effects: Calls assign(std::traversable_begin(range), std::traversable_end(range)).</p>
  <p>Returns: *this.</p>
</div>

<h4>Add an overload to [string::insert]</h4>
<pre><code>template&lt;class Traversable>
  iterator insert(const_iterator p, Traversable&& range);</code></pre>
<div class="attributes">
  <p>Effects: insert(p, std::traversable_begin(range), std::traversable_end(range)).</p>
  <p>Returns: An iterator which refers to the copy of the first inserted
  character, or p if <code>[std::traversable_begin(range),std::traversable_end(range))</code> is an empty
  range.</p>
</div>

<h4>Add an overload to [string::replace]</h4>
<pre><code>template&lt;class Traversable>
  basic_string& replace(const_iterator i1, const_iterator i2,
                        Traversable&& range);</code></pre>
<div class="attributes">
  <p>Requires: [std::traversable_begin(),i1), [i1,i2), and [std::traversable_begin(range),std::traversable_end(range)) are valid ranges.</p>
  <p>Effects: Calls replace(i1 - std::traversable_begin(), i2 - i1, std::traversable_begin(range), std::traversable_end(range)).</p>
  <p>Returns: *this.</p>
</div>


<h3 id="containers">Clause 23, Containers library</h3>

<h4>Modify [sequence.reqmts]</h4>
<p>In Tables 101 and 102, X denotes a sequence container class, a denotes a
value of X containing elements of type T, A denotes X::allocator_type if it
exists and std::allocator&lt;T> if it doesn’t, i and j denote iterators
satisfying input iterator requirements and refer to elements implicitly
convertible to value_type, [i, j) denotes a valid range, <ins>r denotes a
<code>Traversable</code> object ([range.requirements.implementations]) whose value
type is implicitly convertible to value_type and for which [std::traversable_begin(r),std::traversable_end(r)) is
a valid range ([iterator.requirements.general]), </ins>il designates an object
of type
initializer_list&lt;value_type>, n denotes a value of X::size_type, p denotes a
valid const iterator to a, q denotes a valid dereferenceable const iterator to
a, [q1, q2) denotes a valid range of const iterators in a, t denotes an lvalue
or a const rvalue of X::value_- type, and rv denotes a non-const rvalue of
X::value_type. Args denotes a template parameter pack; args denotes a function
parameter pack with the pattern Args&&.</p>

<h4>Add rows to Table 101 — Sequence container requirements (in addition to container)</h4>

<table>
  <tr><th>Expression</th><th>Return type</th><th>Assertion/note<br/>pre-/post-condition</th></tr>
  <tr><td>X(r);</td><td></td><td>Equivalent to X(std::traversable_begin(r), std::traversable_end(r))</td></tr>
<tr><td>a = r;</td>
<td>X&</td><td>Requires: T is CopyInsertable into X and CopyAssignable. Assigns the range
[std::traversable_begin(r),std::traversable_end(r)) into a. All existing elements of a are either assigned to or destroyed.
Returns: *this.</td></tr>
<tr><td>a.insert(p, r);</td><td>iterator</td><td>a.insert(p, std::traversable_begin(r), std::traversable_end(r)).</td></tr>
<tr><td>a.assign(r)</td><td>void</td><td>a.assign(std::traversable_begin(r), std::traversable_end(r)).</td></tr>
</table>

<h4>Modify [associative.reqmts]</h4>
<p>In Table 103, X denotes an associative container class, a denotes a value of
X, a_uniq denotes a value of X when X supports unique keys, a_eq denotes a value
of X when X supports multiple keys, u denotes an identifier, i and j satisfy
input iterator requirements and refer to elements implicitly convertible to
value_type, [i,j) denotes a valid range, p denotes a valid const iterator to a,
q denotes a valid dereferenceable const iterator to a, [q1, q2) denotes a valid
range of const iterators in a, <ins>r denotes a <code>Traversable</code> object
([range.requirements.implementations]) whose value type is implicitly
convertible to value_type and for which [std::traversable_begin(r),std::traversable_end(r)) is a valid range
([iterator.requirements.general]), </ins>il designates an object of type
initializer_list&lt;value_type>, t denotes a value of X::value_type, k denotes a
value of X::key_type and c denotes a value of type X::key_compare. A denotes the
storage allocator used by X, if any, or std::allocator&lt;X::value_type>
otherwise, and m denotes an allocator of a type convertible to A.</p>

<h4>Add rows to Table 103 — Associative container requirements (in addition to container)</h4>
<table>
  <tr><th>Expression</th><th>Return type</th><th>Assertion/note<br/>pre-/post-condition</th><th>Complexity</th></tr>
<tr><td>X(r);</td><td></td><td>Same as X(std::traversable_begin(r), std::traversable_end(r)).</td><td>same as X(std::traversable_begin(r), std::traversable_end(r)).</td></tr>
<tr><td>a = r</td><td>X&</td>
<td>Requires: value_type is CopyInsertable into X and CopyAssignable.
Effects: Assigns the range [std::traversable_begin(r),std::traversable_end(r)) into a. All existing elements of a are either assigned to or destroyed.</td>
<td>NlogN in general (where N has the value distance(std::traversable_begin(r), std::traversable_end(r)) + a.size()); linear if [std::traversable_begin(r),std::traversable_end(r)) is sorted with value_comp().</td></tr>
<tr><td>a.insert(r)</td><td>void</td><td>Equivalent to a.insert(std::traversable_begin(r),
std::traversable_end(r)).</td><td></td></tr>
</table>

<h4>Modify [unord.req]</h4>

<p>In table 104: X is an unordered associative container class, a is an object
of type X, b is a possibly const object of type X, a_uniq is an object of type X
when X supports unique keys, a_eq is an object of type X when X supports
equivalent keys, i and j are input iterators that refer to value_type, [i, j) is
a valid range, p and q2 are valid const iterators to a, q and q1 are valid
dereferenceable const iterators to a, [q1, q2) is a valid range in a, <ins>r
denotes a <code>Traversable</code> object ([range.requirements.implementations]) whose
value type is implicitly convertible to value_type and for which
[std::traversable_begin(r),std::traversable_end(r)) is a valid range ([iterator.requirements.general]), </ins>il
designates an object of type
initializer_list&lt;value_type>, t is a value of type X::value_type, k is a
value of type key_type, hf is a possibly const value of type hasher, eq is a
possibly const value of type key_equal, n is a value of type size_type, and z is
a value of type float.</p>

<h4>Add rows to Table 104 — Unordered associative container requirements (in addition to container)</h4>
<table>
  <tr><th>Expression</th><th>Return type</th><th>Assertion/note<br/>pre-/post-condition</th><th>Complexity</th></tr>
<tr><td>X(r)</td><td>X</td><td>Same as X(std::traversable_begin(r), std::traversable_end(r)).</td><td>Same as X(std::traversable_begin(r), std::traversable_end(r)).</td></tr>
<tr><td>a = r</td><td>X&</td>
<td>Requires: value_type is CopyInsertable into X and CopyAssignable.
Effects: Assigns the range [std::traversable_begin(r),std::traversable_end(r)) into a. All existing elements of a are either assigned to or destroyed.</td>
<td>Same as a = X(r).</td></tr>
<tr><td>a.insert(r)</td><td>void</td><td>Same as a.insert(std::traversable_begin(r), std::traversable_end(r)).</td><td>Same as a.insert( std::traversable_begin(r),
std::traversable_end(r)).</td></tr>
</table>

<h4>Add to the std::deque definition in [deque.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit deque(Traversable&&, const Allocator& = Allocator());
    template &lt;class Traversable>
      deque& operator=(Traversable&&);
    template &lt;class Traversable>
      void assign(Traversable&&);
    template &lt;class Traversable>
      iterator insert(const_iterator position, Traversable&&);
</code></pre>

<h4>Add an insert overload to [deque.modifiers]</h4>
<pre><code>template &lt;class Traversable>
  iterator insert(const_iterator position, Traversable&&);</code></pre>


<h4>Add to the std::forward_list definition in [forwardlist.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit forward_list(Traversable&&, const Allocator& = Allocator());
    template &lt;class Traversable>
      forward_list& operator=(Traversable&&);
    template &lt;class Traversable>
      void assign(Traversable&&);
    template &lt;class Traversable>
      iterator insert_after(const_iterator position, Traversable&& range);</code></pre>

<h4>Add an insert_after overload to [forwardlist.modifiers]</h4>

<pre><code>template &lt;class Traversable>
  iterator insert_after(const_iterator position, Traversable&& range);</code></pre>
<div class="attributes">
  <p>Effects: insert_after(p, std::traversable_begin(range), std::traversable_end(range)).</p>
  <p>Returns: An iterator pointing to the last inserted element or
  <code>position</code> if <code>[std::traversable_begin(range),std::traversable_end(range))</code> is an empty
  range.</p>
</div>


<h4>Add to the std::list definition in [list.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit list(Traversable&&, const Allocator& = Allocator());
    template &lt;class Traversable>
      list& operator=(Traversable&&);
    template &lt;class Traversable>
      void assign(Traversable&&);
    template &lt;class Traversable>
      iterator insert(const_iterator position, Traversable&& range);</code></pre>

<h4>Add an insert overload to [list.modifiers]</h4>
<pre><code>template &lt;class Traversable>
  iterator insert(const_iterator position, Traversable&&);</code></pre>

<h4>Add to the std::vector definition in [vector.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit vector(Traversable&&, const Allocator& = Allocator());
    template &lt;class Traversable>
      vector& operator=(Traversable&&);
    template &lt;class Traversable>
      void assign(Traversable&&);
    template &lt;class Traversable>
      iterator   insert(const_iterator position, Traversable&& range);</code></pre>

<h4>Add an insert overload to [vector.modifiers]</h4>
<pre><code>template &lt;class Traversable>
  iterator insert(const_iterator position, Traversable&&);</code></pre>

<h4>Add to the std::vector&lt;bool> definition in [vector.bool]</h4>
<pre><code>    template &lt;class Traversable>
      vector(Traversable&&, const Allocator& = Allocator()));
    template &lt;class Traversable>
      vector operator=(Traversable&&);
    template &lt;class Traversable>
      void assign(Traversable&&);
    template &lt;class Traversable>
        iterator insert(const_iterator position, Traversable&& range);</code></pre>

<h4>Add to the std::map definition in [map.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit map(Traversable&&,
        const Compare& = Compare(),
        const Allocator& = Allocator());
    template &lt;class Traversable>
      map& operator=(Traversable&&);
    template &lt;class Traversable>
      void insert(Traversable&&);</code></pre>

<h4>Add to the std::multimap definition in [multimap.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit multimap(Traversable&&,
        const Compare& = Compare(),
        const Allocator& = Allocator());
    template &lt;class Traversable>
      multimap& operator=(Traversable&&);
    template &lt;class Traversable> void insert(Traversable&&);</code></pre>


<h4>Add to the std::set definition in [set.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit set(Traversable&&,
        const Compare& = Compare(),
        const Allocator& = Allocator());
    template &lt;class Traversable>
      set& operator=(Traversable&&);
    template &lt;class Traversable>
      void insert(Traversable&&);</code></pre>

<h4>Add to the std::multiset definition in [multiset.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit multiset(Traversable&&,
        const Compare& = Compare(),
        const Allocator& = Allocator());
    template &lt;class Traversable>
      multiset& operator=(Traversable&&);
    template &lt;class Traversable>
      void insert(Traversable&&);</code></pre>

<h4>Add to the std::unordered_map definition in [unord.map.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit unordered_map(Traversable&&,
        size_type = see below,
        const hasher& hf = hasher(),
        const key_equal& eql = key_equal(),
        const allocator_type& a = allocator_type());
    template &lt;class Traversable>
      unordered_map& operator=(Traversable&&);
    template &lt;class Traversable> void insert(Traversable&&);</code></pre>

<h4>Add to the std::unordered_multimap definition in [unord.multimap.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit unordered_multimap(Traversable&&,
        size_type = see below,
        const hasher& hf = hasher(),
        const key_equal& eql = key_equal(),
        const allocator_type& a = allocator_type());
    template &lt;class Traversable>
      unordered_multimap& operator=(Traversable&&);
    template &lt;class Traversable> void insert(Traversable&&);</code></pre>

<h4>Add to the std::unordered_set definition in [unord.set.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit unordered_set(Traversable&&,
        size_type = see below,
        const hasher& hf = hasher(),
        const key_equal& eql = key_equal(),
        const allocator_type& a = allocator_type());
    template &lt;class Traversable>
      unordered_set& operator=(Traversable&&);
    template &lt;class Traversable> void insert(Traversable&&);</code></pre>

<h4>Add to the std::unordered_multiset definition in [unord.multiset.overview]</h4>
<pre><code>    template &lt;class Traversable>
      explicit unordered_multiset(Traversable&&,
        size_type = see below,
        const hasher& hf = hasher(),
        const key_equal& eql = key_equal(),
        const allocator_type& a = allocator_type());
    template &lt;class Traversable>
      unordered_multiset& operator=(Traversable&&);
    template &lt;class Traversable> void insert(Traversable&&);</code></pre>

<h3 id="iterators">Clause 24, Iterators library</h3>

    <h4>Add to [iterator.range]</h4>
    <pre><code>template &lt;class C> auto traversable_begin(C&& c) -> <em>see below</em>;</code></pre>

    <div class="attributes">
      <p><i>Returns:</i> <code>std::forward&lt;C>(c).begin()</code> if that
      expression is well-formed. Otherwise,
      <code>begin(std::forward&lt;C>(c))</code>.</p>

      <p><ins><i>Remarks:</i> If <code>std::forward&lt;C>(c).begin()</code> and
      <code>begin(std::forward&lt;C>(c))</code> are not valid expressions, this
      function shall not participate in overload resolution.</ins></p>

      <p>[ Note: This function (and similarly <code>traversable_end</code>
      below) does not simply call <code>begin(std::forward&lt;C>(c))</code>
      (respectively <code>end(std::forward&lt;C>(c))</code>) unqualified because
      that wouldn't prefer member functions in the same way as the range-based
      for loop, which would result in ambiguities in the presence of other
      libraries defining unconstrained <code>begin()</code> functions like the
      <code>std::begin()</code> above. — end note ]</p>
    </div>

    <pre><code>template &lt;class C> auto traversable_end(C&& c) -> <em>see below</em>;</code></pre>

    <div class="attributes">
      <p><i>Returns:</i> <code>std::forward&lt;C>(c).end()</code> if that
      expression is well-formed. Otherwise,
      <code>end(std::forward&lt;C>(c))</code>.</p>

      <p><ins><i>Remarks:</i> If <code>std::forward&lt;C>(c).end()</code> and
      <code>end(std::forward&lt;C>(c))</code> are not valid expressions, this
      function shall not participate in overload resolution.</ins></p>
    </div>


  </section>

  <section>
    <h2 id="acknowledgements">Acknowledgements</h2>

    <p>I'd like to thank Daniel Krügler for help with the wording in this
    paper, although any remaining mistakes are mine.</p>
  </section>

  <script type="text/javascript"><!--
/**
 * This code is compiled from h5o, with the patches in issues 18, 19, and 2
 * (https://code.google.com/p/h5o/issues/list).
 *
 * This code contains an implementation of HTML5 outlining algorithm, as described by WHATWG at [1]
 *
 * The copyright notice at [2] says:
 *              (c) Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA.
 *              You are granted a license to use, reproduce and create derivative works of this document.
 *
 * [1] http://www.whatwg.org/specs/web-apps/current-work/multipage/sections.html#outlines
 * [2] http://www.whatwg.org/specs/web-apps/current-work/multipage/index.html
 */
(function(){var j=function(b){this.sections=[];this.startingNode=b};j.prototype={heading:!1,append:function(b){b.container=this;this.sections.push(b)},asHTML:function(b){"object"!=typeof b&&(b={createLinks:b});var a;a=this.heading;g(a)?("HGROUP"==a.tagName.toUpperCase()&&(a=a.getElementsByTagName("h"+-k(a))[0]),a=a.textContent||a.innerText||"<i>No text content inside "+a.nodeName+"</i>"):a=""+a;if(b.createLinks){var e;a:{e=this.startingNode;for(var d,c=e;;){if(d=c.getAttribute("id")){e=d;break a}for(c=
c.firstChild;c&&3==c.nodeType&&!/\S/.test(c.data);)c=c.nextSibling;if(!g(c))break}do d="h5o-"+ ++q;while(r.getElementById(d));e.setAttribute("id",d);e=d}a='<a href="#'+e+'">'+a+"</a>"}return a+n(this.sections,b)}};var n=function(b,a){if(a.skipTopHeader)return a.skipTopHeader=!1,n(b[0].sections,a);for(var c="",d=0;d<b.length;d++){var f=b[d];a.skipUntitled&&"string"==typeof f.heading||(c+="<li>"+f.asHTML(a)+"</li>")}return""==c?c:"<ol>"+c+"</ol>"},s=function(b){b=b.heading;return g(b)?k(b):1},c,d,f,
q,r,t=function(b){if(!g(f[f.length-1]))if(l(b)||m(b))null!=c&&f.push(c),c=b,d=new j(b),c.outline={sections:[d],startingNode:b,asHTML:function(a){return n(this.sections,a)}};else if(null!=c&&g(b)){if(d.heading)if(k(b)>=s(c.outline.sections[c.outline.sections.length-1])){var a=new j(b);c.outline.sections.push(a);d=a;d.heading=b}else{var a=!1,e=d;do k(b)<s(e)&&(a=new j(b),e.append(a),d=a,d.heading=b,a=!0),e=e.container;while(!a)}else d.heading=b;f.push(b)}},p=function(b){return function(a){return a&&
a.tagName&&RegExp(b,"i").test(a.tagName.toUpperCase())}},m=p("^BLOCKQUOTE|BODY|DETAILS|FIELDSET|FIGURE|TD$"),l=p("^ARTICLE|ASIDE|NAV|SECTION$"),g=p("^H[1-6]|HGROUP$"),k=function(b){var a=b.tagName.toUpperCase();if("HGROUP"==a)for(a=1;6>=a;a++){if(0<b.getElementsByTagName("H"+a).length)return-a}else return-parseInt(a.substr(1))};HTML5Outline=function(b){q=0;r=b.ownerDocument||window.document;d=c=null;f=[];var a=b;a:for(;a;){t(a);if(a.firstChild){a=a.firstChild;continue a}for(;a;){var e=a,h=f[f.length-
1];if(g(h))h==e&&f.pop();else{if((l(e)||m(e))&&!d.heading)d.heading="<i>Untitled "+e.tagName.toUpperCase()+"</i>";if(l(e)&&0<f.length){c=f.pop();d=c.outline.sections[c.outline.sections.length-1];for(h=0;h<e.outline.sections.length;h++)d.append(e.outline.sections[h])}else if(m(e)&&0<f.length){c=f.pop();for(d=c.outline.sections[c.outline.sections.length-1];0<d.sections.length;)d=d.sections[d.sections.length-1]}else if(l(e)||m(e))d=c.outline.sections[0]}if(a.nextSibling){a=a.nextSibling;continue a}a=
a==b?null:a.parentNode}}return null!=c?c.outline:null}})();


    var outline = HTML5Outline(document.body);
    document.getElementById('toc').innerHTML =
        outline.asHTML({createLinks: true, skipTopHeader: true, skipUntitled: true});
  //--></script>
</body>
</html>
