<!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>Ranges: Merging Writable and MoveWritable</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
div.sourceCode { overflow-x: auto; }
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
  margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; } /* Keyword */
code > span.dt { color: #902000; } /* DataType */
code > span.dv { color: #40a070; } /* DecVal */
code > span.bn { color: #40a070; } /* BaseN */
code > span.fl { color: #40a070; } /* Float */
code > span.ch { color: #4070a0; } /* Char */
code > span.st { color: #4070a0; } /* String */
code > span.co { color: #60a0b0; font-style: italic; } /* Comment */
code > span.ot { color: #007020; } /* Other */
code > span.al { color: #ff0000; font-weight: bold; } /* Alert */
code > span.fu { color: #06287e; } /* Function */
code > span.er { color: #ff0000; font-weight: bold; } /* Error */
code > span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
code > span.cn { color: #880000; } /* Constant */
code > span.sc { color: #4070a0; } /* SpecialChar */
code > span.vs { color: #4070a0; } /* VerbatimString */
code > span.ss { color: #bb6688; } /* SpecialString */
code > span.im { } /* Import */
code > span.va { color: #19177c; } /* Variable */
code > span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code > span.op { color: #666666; } /* Operator */
code > span.bu { } /* BuiltIn */
code > span.ex { } /* Extension */
code > span.pp { color: #bc7a00; } /* Preprocessor */
code > span.at { color: #7d9029; } /* Attribute */
code > span.do { color: #ba2121; font-style: italic; } /* Documentation */
code > span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code > span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code > span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
  </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">
      P0441R1
    </td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Date:</td>
    <td width="435">2016-11-17</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Project:</td>
    <td width="435">C++ Extensions for Ranges, Library Working Group</td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Reply-to:</td>
    <td width="435">
      Casey Carter &lt;<a href="mailto:Casey@Carter.net">Casey@Carter.net</a>&gt;<br>
      Eric Niebler &lt;<a href="mailto:Eric.Niebler@gmail.com">Eric.Niebler@gmail.com</a>&gt;
    </td>
  </tr>
</table>
<div id="header">
<h1 class="title">Ranges: Merging Writable and MoveWritable</h1>
</div>
<div id="TOC">
<ul>
<li><a href="#introduction"><span class="toc-section-number">1</span> Introduction</a><ul>
<li><a href="#revision-history"><span class="toc-section-number">1.1</span> Revision history</a><ul>
<li><a href="#r0---r1"><span class="toc-section-number">1.1.1</span> R0 -&gt; R1</a></li>
</ul></li>
<li><a href="#motivation"><span class="toc-section-number">1.2</span> Motivation</a></li>
</ul></li>
<li><a href="#proposed-design"><span class="toc-section-number">2</span> Proposed Design</a><ul>
<li><a href="#coalescing-writable-and-movewritable"><span class="toc-section-number">2.1</span> Coalescing <code>Writable</code> and <code>MoveWritable</code></a></li>
<li><a href="#storable-concept-variants"><span class="toc-section-number">2.2</span> <code>Storable</code> concept variants</a></li>
<li><a href="#eliminating-merge_move-and-partition_move"><span class="toc-section-number">2.3</span> Eliminating <code>merge_move</code> and <code>partition_move</code></a><ul>
<li><a href="#addition-of-move_sentinel"><span class="toc-section-number">2.3.1</span> Addition of <code>move_sentinel</code></a></li>
</ul></li>
</ul></li>
<li><a href="#technical-specifications"><span class="toc-section-number">3</span> Technical Specifications</a><ul>
<li><a href="#implementation-experience"><span class="toc-section-number">3.1</span> Implementation Experience</a></li>
</ul></li>
<li><a href="#references">References</a></li>
</ul>
</div>
<h1 id="introduction"><span class="header-section-number">1</span> Introduction</h1>
<p>This paper presents a design change to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4560.pdf" title="Working Draft: C++ Extensions for Ranges">N4560, the working paper for the Technical Specification for C++ Extensions for Ranges (the “Ranges TS”)</a><span class="citation">[3]</span>. This work has already been speculatively integrated - along with the proposals in <a href="http://wg21.link/p0370">P0370 “Ranges TS Design Updates Omnibus”</a><span class="citation">[1]</span> - with the text of the working paper. The resulting document is <a href="http://wg21.link/p0459">P0459 “C++ Extensions for Ranges: Speculative Combined Proposals”</a><span class="citation">[4]</span>. We briefly discuss how the design of the <code>Writable</code> and <code>MoveWritable</code> concepts impacts the specification of algorithms, and propose to correct the problem by merging the two into a single concept.</p>
<h2 id="revision-history"><span class="header-section-number">1.1</span> Revision history</h2>
<h3 id="r0---r1"><span class="header-section-number">1.1.1</span> R0 -&gt; R1</h3>
<ul>
<li><p>Editorial wording cleanup from LWG review comments.</p></li>
<li><p>Don’t perpetrate the mis-use of “literal type” in the move_sentinel constructor that we corrected in the rest of the library with P0503.</p></li>
<li><p>Add a Returns element for move_sentinel’s assignment operator.</p></li>
<li><p>Correct occurrences of “Effects: Equivalent to <code>foo</code>.” to “Effects: Equivalent to: <code>return foo;</code>” when that is intended.</p></li>
</ul>
<h2 id="motivation"><span class="header-section-number">1.2</span> Motivation</h2>
<p>The current Ranges TS Working Paper (N4560) includes two concepts used to describe relationships between a readable and a writable iterator, <code>MoveWritable</code> and <code>Writable</code>:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> Out, <span class="kw">class</span> T&gt;
concept <span class="dt">bool</span> MoveWritable() {
  <span class="kw">return</span> Semiregular&lt;Out&gt;() &amp;&amp;
    requires(Out o, T t) {
      *o = std::move(t);
    }
}

<span class="kw">template</span> &lt;<span class="kw">class</span> Out, <span class="kw">class</span> T&gt;
concept <span class="dt">bool</span> Writable() {
  <span class="kw">return</span> MoveWritable&lt;Out, T&gt;() &amp;&amp;
    requires(Out o, <span class="dt">const</span> T t) {
      *o = t;
    }
}</code></pre></div>
<p>with similar semantics for the assignment expressions, except that <code>t</code> is left unchanged by the assignment in <code>Writable</code> whereas <code>MoveWritable</code> leaves <code>t</code> in a valid but unspecified state. These concepts describe how an algorithm transfers values into its outputs. We could implement, e.g., <code>fill_n</code> as:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> T, WeaklyIncrementable Out&gt;
  requires Writable&lt;Out, T&gt;()
<span class="dt">void</span> fill_n(Out out, difference_type_t&lt;Out&gt; n, <span class="dt">const</span> T&amp; value) {
  <span class="kw">for</span> (; n &gt; <span class="dv">0</span>; --n, ++out) {
    *out = value;
  }
}</code></pre></div>
<p>and know that the expression <code>*out = value;</code> has the effect of “copying” <code>value</code> into the output sequence thanks to the <code>Writable</code> constraint.</p>
<p>The existence of the two distinct concepts results in a partitioning of algorithms into two sets: those that are based on <code>MoveWritable</code> or refinements thereof that always move, and those based on <code>Writable</code> or refinements thereof that could copy or move or do <em>both</em>. In practice, algorithms in the <code>Writable</code>/<code>IndirectlyCopyable</code> are always specified to copy; passing <code>move_iterator</code>s to these algorithms results in either (a) a diagnosis that the program is ill-formed when the value type of the iterator is not copyable, or (b) undefined behavior when the value type of the iterator <em>is</em> copyable, but the expression <code>*out = *in</code> does not leave the value of <code>*in</code> unchanged as required by the semantic constraints of <code>Writable</code>. As a result, we need distinct “copy” and “move” variants of algorithms resulting in proliferation. In N4560, for example, there are <code>partition_move</code> and <code>merge_move</code> algorithms as a result of this issue.</p>
<p>The need to choose between <code>Writable</code> and <code>MoveWritable</code> also complicates generic code. Consider a simplified variant of the <code>transform</code> algorithm:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span>&lt;InputIterator I, Sentinel&lt;I&gt; S, WeaklyIncrementable O, <span class="kw">class</span> F&gt;
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(I)&gt;&gt;()
<span class="dt">void</span> transform(I first, S last, O result, F op);</code></pre></div>
<p>Presumably, implementation of this algorithm requires an assignment expression like <code>*result = op(*first);</code>. We’re again constrained (pun intended) by the choice of concepts: if <code>op(*first)</code> returns an rvalue of type <code>T</code>, <code>Writable</code> unnecesarily requires <code>T</code> to be copyable. If <code>op(*first)</code> returns an lvalue, <code>MoveWritable</code> would allow it to be modified by the assignment. None of the concepts defined in N4560 enable us to constrain <code>transform</code> in a manner that is compatible with its semantics in C++14.</p>
<p>Separately, there is a problem using the existing concepts to constrain algorithms that create temporaries. Such algorithms typically require the ability to:</p>
<ol>
<li>construct a temporary object of an iterator’s value type from a dereferenced iterator</li>
<li>replace the stored value of a temporary by assigning from a dereferenced iterator</li>
<li>transfer values between multiple temporaries</li>
<li>transfer a value from a temporary into an output sequence</li>
</ol>
<p>These algorithms are underconstrained in N4560. Wrapping the requirements up into convenient named packages would ease the specification of algorithms.</p>
<h1 id="proposed-design"><span class="header-section-number">2</span> Proposed Design</h1>
<p>We propose coalescing the existing <code>Writable</code> and <code>MoveWritable</code> concepts into a single <code>Writable</code> concept, and adding concepts <code>IndirectlyMovableStorable</code> and <code>IndirectlyCopyableStorable</code> for constraining algorithms that use temporaries.</p>
<h2 id="coalescing-writable-and-movewritable"><span class="header-section-number">2.1</span> Coalescing <code>Writable</code> and <code>MoveWritable</code></h2>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> O, <span class="kw">class</span> T&gt;
concept <span class="dt">bool</span> Writable() {
  <span class="kw">return</span> Semiregular&lt;O&gt;() &amp;&amp; requires(O o, T&amp;&amp; t) {
    *o = std::forward&lt;T&gt;(t); <span class="co">// not required to be equality-preserving</span>
  };
}</code></pre></div>
<p>Intuitively, <code>Writable&lt;O, T&gt;()</code> is satisfied when an expression with type and value category <code>T</code> can be assigned through an iterator with type <code>O</code>. For a possibly-cv-qualified non-reference type <code>T</code>, <code>Writable&lt;O, T&gt;</code> is roughly equivalent to N4560’s <code>MoveWritable&lt;O, T&gt;</code> and <code>Writable&lt;O, const T&gt;</code> is roughly equivalent to N4560’s <code>Writable&lt;O, T&gt;</code>.</p>
<p>Note that since <code>OutputIterator&lt;I, T&gt;()</code> requires <code>Writable&lt;I, T&gt;()</code> and <code>OutputRange&lt;R, T&gt;()</code> requires <code>OutputIterator&lt;iterator_t&lt;R&gt;, T&gt;()</code>, the meaning of those two concepts is changed as well. <code>OutputIterator&lt;I, T&gt;</code> no longer means “a value of type <code>T</code> can be assigned through an iterator of type <code>I</code>,” but instead “an <em>expression</em> of type and value category <code>T</code> can be assigned through an iterator of type <code>I</code>.” We also need to flow the <code>Writable</code> change into <code>IndirectlyCopyable</code> and <code>IndirectlyMovable</code>. We’ll define a new type alias <code>rvalue_reference_t&lt;In&gt;</code> for the type of <code>std::move(*i)</code> to make the symmetry nicely apparent:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> In&gt;
<span class="kw">using</span> rvalue_reference_t = <span class="kw">decltype</span>(std::move(declval&lt;reference_t&lt;In&amp;&gt;&gt;()));

<span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
concept <span class="dt">bool</span> IndirectlyMovable() {
  <span class="kw">return</span> Readable&lt;In&gt;() &amp;&amp; Writable&lt;Out, rvalue_reference_t&lt;In&gt;&gt;();
}

<span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
concept <span class="dt">bool</span> IndirectlyCopyable() {
  <span class="kw">return</span> Readable&lt;In&gt;() &amp;&amp; Writable&lt;Out, reference_t&lt;In&gt;&gt;();
}</code></pre></div>
<p>Note that <code>IndirectlyCopyable</code> does not refine <code>IndirectlyMovable</code> as in N4560: there are no algorithms that use both copy syntax (<code>*out = *in;</code>) and move syntax (<code>*out = std::move(*in);</code>) to transfer values between their input and output sequences. Even if the <code>IndirectlyMovable</code> requirements hold for every “sane” model of <code>IndirectlyCopyable</code>, it seems pointless to invest the compile time to validate the “extra” requirements when the algorithm will never use the additional capabilities they provide.</p>
<h2 id="storable-concept-variants"><span class="header-section-number">2.2</span> <code>Storable</code> concept variants</h2>
<p>We define <code>Storable</code> refinements of the <code>IndirectlyMovable</code> and <code>IndirectlyCopyable</code> concepts to constrain algorithms that sometimes interject temporaries into the communication of values between their input and output sequences:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
concept <span class="dt">bool</span> IndirectlyMovableStorable() {
  <span class="kw">return</span> IndirectlyMovable&lt;In, Out&gt;() &amp;&amp;
    Writable&lt;Out, value_type_t&lt;In&gt;&gt;() &amp;&amp;
    Movable&lt;value_type_t&lt;In&gt;&gt;() &amp;&amp;
    Constructible&lt;value_type_t&lt;In&gt;, rvalue_reference_t&lt;In&gt;&gt;() &amp;&amp;
    Assignable&lt;value_type_t&lt;In&gt;&amp;, rvalue_reference_t&lt;In&gt;&gt;();
}

<span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
concept <span class="dt">bool</span> IndirectlyCopyableStorable() {
  <span class="kw">return</span> IndirectlyCopyable&lt;In, Out&gt;() &amp;&amp;
    Writable&lt;Out, <span class="dt">const</span> value_type_t&lt;In&gt;&amp;&gt;() &amp;&amp;
    Copyable&lt;value_type_t&lt;In&gt;&gt;() &amp;&amp;
    Constructible&lt;value_type_t&lt;In&gt;, reference_t&lt;In&gt;&gt;() &amp;&amp;
    Assignable&lt;value_type_t&lt;In&gt;&amp;, reference_t&lt;In&gt;&gt;();
}</code></pre></div>
<p>These definitions include the requirements described earlier for constructing and assigning temporaries from the input sequence, moving/copying between temporaries, and writing temporaries into the output sequence. The names of the concepts themselves are a bit of a mouthful, which issue is ameliorated by the fact that they rarely need to be used directly in the algorithm specifications. If we add an <code>IndirectlyMovableStorable</code> requirement to the <code>Permutable</code> concept, which is used to constrain the many algorithms that mutate their input sequence by swapping values between elements, the only remaining algorithm needing a constraint is <code>unique_copy</code>.</p>
<h2 id="eliminating-merge_move-and-partition_move"><span class="header-section-number">2.3</span> Eliminating <code>merge_move</code> and <code>partition_move</code></h2>
<p>With the changes to <code>Writable</code> in place, there is no longer a need for separate “copy” and “move” algorithm variants. It is again possible obtain the effect of a “move” algorithm by wrapping an iterator pair in <code>move_iterator</code>s and calling the “copy” algorithm. We therefore propose to remove the <code>merge_move</code> and <code>partition_move</code> algorithms that were added to the TS to workaround this issue.</p>
<h3 id="addition-of-move_sentinel"><span class="header-section-number">2.3.1</span> Addition of <code>move_sentinel</code></h3>
<p>But wait - what if I have an [iterator, sentinel) range instead of an iterator pair? One cannot wrap a sentinel in a <code>move_iterator</code>. There are at least three potential solutions:</p>
<ol>
<li><p>Define a <code>move_sentinel&lt;S&gt;</code> wrapper class that satisfies <code>Sentinel&lt;move_sentinel&lt;S&gt;, move_iterator&lt;I&gt;&gt;()</code> when <code>Sentinel&lt;S, I&gt;()</code> is satisfied. For ease of use, and consistency of interface, define a <code>make_move_sentinel</code> deducing helper function. This approach maintains a clear distinction between the adapted range and the underlying range. The definition of <code>foo</code> becomes:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;InputIterator I, Sentinel&lt;I&gt; S&gt;
<span class="dt">void</span> foo(I first, S last) {
  bar(make_move_iterator(first), make_move_sentinel(last));
}</code></pre></div>
<p>This approach is straightforward, and while perhaps lacking elegance, gets the job done.</p></li>
<li><p>Define operator overloads for <code>==</code> and <code>!=</code> that accept <code>move_iterator&lt;I&gt;</code> and <code>Sentinel&lt;I&gt;</code> so that move iterators can use the sentinels of their base iterators directly:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">Sentinel{S, I}
<span class="dt">bool</span> <span class="kw">operator</span>==(<span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> S&amp; s) {
  <span class="kw">return</span> i.current_ == s;
}
<span class="co">// Define != similarly, and the symmetric overloads.</span></code></pre></div>
<p><code>foo</code> can be simpler since it passes the sentinel directly:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;InputIterator I, Sentinel&lt;I&gt; S&gt;
<span class="dt">void</span> foo(I first, S last) {
  bar(make_move_iterator(first), last);
}</code></pre></div>
<p>This approach requires less syntax at the callsite. It is a bit lax in that it allows comparing adapted iterators with unadapted sentinels, potentially creating confusion in code readers about which iterators/sentinels are adapted and which are from the base range.</p></li>
<li><p>Ignore the problem until Ranges TS2 comes along with support for view adaptors, and the solution will look something like:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;InputIterator I, Sentinel&lt;I&gt; S&gt;
<span class="dt">void</span> foo(I first, S last) {
  bar(make_iterator_range(first, last) | view::move);
}
<span class="co">// Or even better:</span>
<span class="dt">void</span> foo(InputRange&amp;&amp; rng) {
  bar(rng | view::move);
}</code></pre></div>
<p>Adapting iterator/sentinel pairs together instead of individually is preferable: it allows the library to check for errors, and to optimize the special case when <code>last</code> is also an iterator by producing a bounded range (a range whose <code>begin</code> and <code>end</code> have the same type).</p></li>
</ol>
<p>The view adapter is clearly the preferable solution in the long run, but would require the introduction of too much additional machinery into the current TS to be a viable solution in the short-term. Implementation experience using the underlying sentinels directly with the move iterators was not positive: it results in less clear code, and is fragile in the face of poorly constrained iterators/sentinels. We therefore propose the first approach as an interim solution to this problem.</p>
<h1 id="technical-specifications"><span class="header-section-number">3</span> Technical Specifications</h1>
<p>Rename the section [iterators.movewritable] “Concept MoveWritable” to [iterators.writable] “Concept Writable” and replace its content with:</p>
<blockquote>
<p>The <code>Writable</code> concept describes the requirements for writing a value into an iterator’s referenced object.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">  <span class="kw">template</span> &lt;<span class="kw">class</span> Out, <span class="kw">class</span> T&gt;
  concept <span class="dt">bool</span> Writable() {
    <span class="kw">return</span> Semiregular&lt;Out&gt;() &amp;&amp;
      requires(Out o, T&amp;&amp; t) {
        *o = std::forward&lt;T&gt;(t); <span class="co">// not required to be equality preserving</span>
      };
  }</code></pre></div>
<p>Let <code>E</code> be an expression such that <code>decltype((E))</code> is <code>T</code>, and let <code>o</code> be a dereferenceable object of type <code>Out</code>. Then <code>Writable&lt;Out, T&gt;()</code> is satisfied if and only if</p>
<ul>
<li>If <code>Readable&lt;Out&gt;() &amp;&amp; Same&lt;value_type_t&lt;Out&gt;, decay_t&lt;T&gt;&gt;()</code> is satisfied, then <code>*o</code> after the assignment is equal to the value of <code>E</code> before the assignment.</li>
</ul>
<p>After evaluating the assignment expression, <code>o</code> is not required to be dereferenceable.</p>
<p>If <code>E</code> is an xvalue, the resulting state of the object it denotes is unspecified. [ Note: The object must still meet the requirements of any library component that is using it. The operations listed in those requirements must work as specified whether the object has been moved from or not. —end note ]</p>
</blockquote>
<p>Remove the following sections [iterators.writable], [iterators.indirectlymovable], and [iterators.indirectlycopyable].</p>
<p>Relocate [iterators.indirectlyswappable] to before [commonalgoreq.indirectlycomparable]. Replace its stable name (and all references thereto) with [commonalgoreq.indirectlyswappable].</p>
<p>Replace the content of [commonalgoreq.general] with:</p>
<blockquote>
<p>There are several additional iterator concepts that are commonly applied to families of algorithms. These group together iterator requirements of algorithm families. There are three relational concepts that specify how element values are transferred between <code>Readable</code> and <code>Writable</code> types: <code>IndirectlyMovable</code>, <code>IndirectlyCopyable</code>, and <code>IndirectlySwappable</code>. There are three relational concepts for rearrangements: <code>Permutable</code>, <code>Mergeable</code>, and <code>Sortable</code>. There is one relational concept for comparing values from different sequences: <code>IndirectlyComparable</code>.</p>
<p>[ Note: The <code>equal_to&lt;&gt;</code> and <code>less&lt;&gt;</code> function types used in the concepts below impose additional constraints on their arguments beyond those that appear explicitly in the concepts’ bodies. <code>equal_to&lt;&gt;</code> requires its arguments satisfy <code>EqualityComparable</code>, and <code>less&lt;&gt;</code> requires its arguments satisfy <code>StrictTotallyOrdered</code>. —end note ]</p>
</blockquote>
<p>Immediately thereafter, add a new section [commonalgoreq.indirectlymovable] “Concept IndirectlyMovable”, replacing all references to [iterators.indirectlymovable] with [commonalgoreq.indirectlymovable] - and content:</p>
<blockquote>
<p>The <code>IndirectlyMovable</code> concept specifies the relationship between a <code>Readable</code> type and a <code>Writable</code> type between which values may be moved.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">  <span class="kw">template</span> &lt;<span class="kw">class</span> In&gt;
  <span class="kw">using</span> rvalue_reference_t =
    <span class="kw">decltype</span>(std::move(declval&lt;reference_t&lt;In&gt;&gt;()));

  <span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
  concept <span class="dt">bool</span> IndirectlyMovable() {
    <span class="kw">return</span> Readable&lt;In&gt;() &amp;&amp;
      Writable&lt;Out, rvalue_reference_t&lt;In&gt;&gt;();
  }</code></pre></div>
<p>The <code>IndirectlyMovableStorable</code> concept augments <code>IndirectlyMovable</code> with additional requirements enabling the transfer to be performed through an intermediate object of the <code>Readable</code> type’s value type.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">  <span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
  concept <span class="dt">bool</span> IndirectlyMovableStorable() {
    <span class="kw">return</span> IndirectlyMovable&lt;In, Out&gt;() &amp;&amp;
      Writable&lt;Out, value_type_t&lt;In&gt;&gt;() &amp;&amp;
      Movable&lt;value_type_t&lt;In&gt;&gt;() &amp;&amp;
      Constructible&lt;value_type_t&lt;In&gt;, rvalue_reference_t&lt;In&gt;&gt;() &amp;&amp;
      Assignable&lt;value_type_t&lt;In&gt;&amp;, rvalue_reference_t&lt;In&gt;&gt;();
  }</code></pre></div>
</blockquote>
<p>Immediately thereafter, add a new section [commonalgoreq.indirectlycopyable] “Concept IndirectlyCopyable”, replacing all references to [iterators.indirectlycopyable] with [commonalgoreq.indirectlycopyable] - and content:</p>
<blockquote>
<p>The <code>IndirectlyCopyable</code> concept specifies the relationship between a <code>Readable</code> type and a <code>Writable</code> type between which values may be copied.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">  <span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
  concept <span class="dt">bool</span> IndirectlyCopyable() {
    <span class="kw">return</span> Readable&lt;In&gt;() &amp;&amp;
      Writable&lt;Out, reference_t&lt;In&gt;&gt;();
  }</code></pre></div>
<p>The <code>IndirectlyCopyableStorable</code> concept augments <code>IndirectlyCopyable</code> with additional requirements enabling the transfer to be performed through an intermediate object of the <code>Readable</code> type’s value type. It also requires the capability to make copies of values.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">  <span class="kw">template</span> &lt;<span class="kw">class</span> In, <span class="kw">class</span> Out&gt;
  concept <span class="dt">bool</span> IndirectlyCopyableStorable() {
    <span class="kw">return</span> IndirectlyCopyable&lt;In, Out&gt;() &amp;&amp;
      Writable&lt;Out, <span class="dt">const</span> value_type_t&lt;In&gt;&amp;&gt;() &amp;&amp;
      Copyable&lt;value_type_t&lt;In&gt;&gt;() &amp;&amp;
      Constructible&lt;value_type_t&lt;In&gt;, reference_t&lt;In&gt;&gt;() &amp;&amp;
      Assignable&lt;value_type_t&lt;In&gt;&amp;, reference_t&lt;In&gt;&gt;();
  }</code></pre></div>
</blockquote>
<p>In [commonalgoreq.permutable], replace the concept definition with:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">  <span class="kw">template</span> &lt;<span class="kw">class</span> I&gt;
  concept <span class="dt">bool</span> Permutable() {
    <span class="kw">return</span> ForwardIterator&lt;I&gt;() &amp;&amp;
      IndirectlyMovableStorable&lt;I, I&gt;() &amp;&amp;
      IndirectlySwappable&lt;I, I&gt;();
  }</code></pre></div>
<p>Remove the section [commonalgoreq.mergemovable].</p>
<p>Add the following declarations to the synopsis of the <code>&lt;experimental/ranges/iterator&gt;</code> header in [iterator.synopsis], between the <code>move_iterator</code> and <code>common_iterator</code> declarations:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;Semiregular S&gt; <span class="kw">class</span> move_sentinel;

<span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>==(
    <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);
<span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>==(
    <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);
<span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>!=(
    <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);
<span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>!=(
    <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);

<span class="kw">template</span> &lt;<span class="kw">class</span> I, SizedSentinel&lt;I&gt; S&gt;
  difference_type_t&lt;I&gt; <span class="kw">operator</span>-(
    <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);
<span class="kw">template</span> &lt;<span class="kw">class</span> I, SizedSentinel&lt;I&gt; S&gt;
  difference_type_t&lt;I&gt; <span class="kw">operator</span>-(
    <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);

<span class="kw">template</span> &lt;Semiregular S&gt;
  move_sentinel&lt;S&gt; make_move_sentinel(S s);</code></pre></div>
</blockquote>
<p>In [iterators.move]/1 unstrike the text “Some generic algorithms can be called with move iterators to replace copying with moving.” and remove the now-inaccurate editorial note that follows. After the example, add new paragraphs:</p>
<blockquote>
<p>Class template <code>move_sentinel</code> is a sentinel adaptor useful for denoting ranges together with <code>move_iterator</code>. When an input iterator type <code>I</code> and sentinel type <code>S</code> satisfy <code>Sentinel&lt;S, I&gt;()</code>, <code>Sentinel&lt;move_sentinel&lt;S&gt;, move_iterator&lt;I&gt;&gt;()</code> is satisfied as well.</p>
<p>[ Example: A <code>move_if</code> algorithm is easily implemented with <code>copy_if</code> using <code>move_iterator</code> and <code>move_sentinel</code>:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;InputIterator I, Sentinel&lt;I&gt; S, WeaklyIncrementable O,
          IndirectCallablePredicate&lt;I&gt; Pred&gt;
  requires IndirectlyMovable&lt;I, O&gt;()
<span class="dt">void</span> move_if(I first, S last, O out, Pred pred)
{
  copy_if(move_iterator&lt;I&gt;{first}, move_sentinel&lt;S&gt;{last}, out, pred);
}</code></pre></div>
<p>—end example ]</p>
</blockquote>
<p>Insert a new subsection [move.sentinel] after [move.iter.nonmember]:</p>
<blockquote>
<p>24.7.3.4 Class template <code>move_sentinel</code> [move.sentinel]</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">namespace</span> std { <span class="kw">namespace</span> experimental { <span class="kw">namespace</span> ranges { <span class="kw">inline</span> <span class="kw">namespace</span> v1 {
  <span class="kw">template</span> &lt;Semiregular S&gt;
  <span class="kw">class</span> move_sentinel {
  <span class="kw">public</span>:
    <span class="kw">constexpr</span> move_sentinel();
    <span class="kw">explicit</span> move_sentinel(S s);
    move_sentinel(<span class="dt">const</span> move_sentinel&lt;ConvertibleTo&lt;S&gt;&gt;&amp; s);
    move_sentinel&amp; <span class="kw">operator</span>=(<span class="dt">const</span> move_sentinel&lt;ConvertibleTo&lt;S&gt;&gt;&amp; s);

    S base() <span class="dt">const</span>;

  <span class="kw">private</span>:
    S last; <span class="co">// exposition only</span>
  };

  <span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
    <span class="dt">bool</span> <span class="kw">operator</span>==(
      <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);
  <span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
    <span class="dt">bool</span> <span class="kw">operator</span>==(
      <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);
  <span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
    <span class="dt">bool</span> <span class="kw">operator</span>!=(
      <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);
  <span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
    <span class="dt">bool</span> <span class="kw">operator</span>!=(
      <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);

  <span class="kw">template</span> &lt;<span class="kw">class</span> I, SizedSentinel&lt;I&gt; S&gt;
    difference_type_t&lt;I&gt; <span class="kw">operator</span>-(
      <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);
  <span class="kw">template</span> &lt;<span class="kw">class</span> I, SizedSentinel&lt;I&gt; S&gt;
    difference_type_t&lt;I&gt; <span class="kw">operator</span>-(
      <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);

  <span class="kw">template</span> &lt;Semiregular S&gt;
    move_sentinel&lt;S&gt; make_move_sentinel(S s);
}}}}</code></pre></div>
<p>24.7.3.5 <code>move_sentinel</code> operations [move.sent.ops]<br />
24.7.3.5.1 <code>move_sentinel</code> constructors [move.sent.op.const]</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">constexpr</span> move_sentinel();</code></pre></div>
<p>1 Effects: Constructs a <code>move_sentinel</code>, value-initializing <code>last</code>. If <code>is_trivially_default_constructible&lt;S&gt;::value</code> is <code>true</code>, then this constructor is a <code>constexpr</code> constructor.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">explicit</span> move_sentinel(S s);</code></pre></div>
<p>2 Effects: Constructs a <code>move_sentinel</code>, initializing <code>last</code> with <code>s</code>.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">move_sentinel(<span class="dt">const</span> move_sentinel&lt;ConvertibleTo&lt;S&gt;&gt;&amp; s);</code></pre></div>
<p>3 Effects: Constructs a <code>move_sentinel</code>, initializing <code>last</code> with <code>s.last</code>.</p>
<p>24.7.3.5.2 <code>move_sentinel::operator=</code> [move.sent.op=]</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">move_sentinel&amp; <span class="kw">operator</span>=(<span class="dt">const</span> move_sentinel&lt;ConvertibleTo&lt;S&gt;&gt;&amp; s);</code></pre></div>
<p>1 Effects: Assigns <code>s.last</code> to <code>last</code>.</p>
<p>2 Returns: <code>*this</code></p>
<p>24.7.3.5.3 <code>move_sentinel</code> comparisons [move.sent.op.comp]</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>==(
    <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);
<span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>==(
    <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);</code></pre></div>
<p>1 Effects: Equivalent to: <code>return i.current == s.last;</code></p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>!=(
    <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);
<span class="kw">template</span> &lt;<span class="kw">class</span> I, Sentinel&lt;I&gt; S&gt;
  <span class="dt">bool</span> <span class="kw">operator</span>!=(
    <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);</code></pre></div>
<p>2 Effects: Equivalent to: <code>return !(i == s);</code></p>
<p>24.7.3.5.4 <code>move_sentinel</code> non-member functions [move.sent.nonmember]</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> I, SizedSentinel&lt;I&gt; S&gt;
  difference_type_t&lt;I&gt; <span class="kw">operator</span>-(
    <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s, <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i);</code></pre></div>
<p>1 Effects: Equivalent to: <code>return s.last - i.current;</code></p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;<span class="kw">class</span> I, SizedSentinel&lt;I&gt; S&gt;
  difference_type_t&lt;I&gt; <span class="kw">operator</span>-(
    <span class="dt">const</span> move_iterator&lt;I&gt;&amp; i, <span class="dt">const</span> move_sentinel&lt;S&gt;&amp; s);</code></pre></div>
<p>2 Effects: Equivalent to: <code>return i.current - s.last;</code></p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">template</span> &lt;Semiregular S&gt;
move_sentinel&lt;S&gt; make_move_sentinel(S s);</code></pre></div>
<p>3 Returns: <code>move_sentinel&lt;S&gt;(s)</code>.</p>
</blockquote>
<p>Throughout Clause 25 [algorithms] replace occurrences of <code>Writable&lt;I, T&gt;</code>, <code>OutputIterator&lt;T&gt;</code>, and <code>OutputRange&lt;T&gt;</code> with <code>Writable&lt;I, const T&amp;&gt;</code>, <code>OutputIterator&lt;const T&amp;&gt;</code>, and <code>OutputRange&lt;const T&amp;&gt;</code> respectively.</p>
<p>In the synopsis of the <code>&lt;experimental/ranges/algorithm&gt;</code> header in [algorithms.general], in the declarations of <code>unique_copy</code>, replace the constraint clause <code>Copyable&lt;value_type_t&lt;I&gt;&gt;()</code> (resp. <code>Copyable&lt;value_type_t&lt;iterator_t&lt;Rng&gt;&gt;&gt;()</code>) with <code>IndirectlyCopyableStorable&lt;I, O&gt;()</code> (resp. <code>IndirectlyCopyableStorable&lt;iterator_t&lt;Rng&gt;, O&gt;()</code>). Remove both declarations of <code>partition_move</code> and <code>merge_move</code>.</p>
<p>In [alg.unique], in the declarations of <code>unique_copy</code>, again replace the constraint clauses <code>Copyable&lt;value_type_t&lt;I&gt;&gt;()</code> (resp. <code>Copyable&lt;value_type_t&lt;iterator_t&lt;Rng&gt;&gt;&gt;()</code>) with <code>IndirectlyCopyableStorable&lt;I, O&gt;()</code> (resp. <code>IndirectlyCopyableStorable&lt;iterator_t&lt;Rng&gt;, O&gt;()</code>).</p>
<p>In [alg.partitions], strike the declarations of <code>partition_move</code> and remove paragraphs 16-19 that specify its behavior.</p>
<p>In [alg.merge], strike the declarations of <code>merge_move</code> and remove paragraphs 6-10 that specify its behavior.</p>
<h2 id="implementation-experience"><span class="header-section-number">3.1</span> Implementation Experience</h2>
<p>The proposed design changes are implemented in both <a href="https://github.com/CaseyCarter/cmcstl2" title="CMCSTL2: Casey Carter&#39;s reference implementation of STL2">CMCSTL2, a full implementation of the Ranges TS with proxy extensions</a><span class="citation">[2]</span>, and <a href="http://github.com/ericniebler/range-v3" title="Range v3">range-v3</a><span class="citation">[5]</span>.</p>
<h1 id="references" class="unnumbered">References</h1>
<div id="refs" class="references">
<div id="ref-p0370">
<p>[1] Carter, C. and Niebler, E. 2016. P0370R1: Ranges TS Design Updates Omnibus.</p>
</div>
<div id="ref-cmcstl2">
<p>[2] CMCSTL2: <em><a href="https://github.com/CaseyCarter/cmcstl2" class="uri">https://github.com/CaseyCarter/cmcstl2</a></em>. Accessed: 2016-05-26.</p>
</div>
<div id="ref-n4560">
<p>[3] Niebler, E. and Carter, C. 2015. N4560: Working Draft: C++ Extensions for Ranges.</p>
</div>
<div id="ref-p0459">
<p>[4] Niebler, E. and Carter, C. 2016. P0459: C++ Extensions for Ranges: Speculative Combined Proposals.</p>
</div>
<div id="ref-range-v3">
<p>[5] Range v3: <em><a href="http://github.com/ericniebler/range-v3" class="uri">http://github.com/ericniebler/range-v3</a></em>. Accessed: 2014-10-08.</p>
</div>
</div>
</body>
</html>
