<!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 TS “Ready” Issues for the July 2017 (Toronto) meeting</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>
  <style type="text/css">
  ins {
    background-color: lime; text-decoration:underline;
  }
  
  del {
    background-color: #ff8080; text-decoration:line-through;
  }
  
  ednote {
    color:blue;
  }
  
  table {
    border-collapse: collapse;
  }
  
  table, th, td {
    border: 1px solid black;
  }
  
  code.diff > span.st {
    color: darkred;
  }
  
  </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">
      P0663R0
    </td>
  </tr>
  <tr>
    <td width="172" align="left" valign="top">Date:</td>
    <td width="435">2017-06-19</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>
    </td>
  </tr>
</table>
<div id="header">
<h1 class="title">Ranges TS “Ready” Issues for the July 2017 (Toronto) meeting</h1>
</div>
<h2 id="comparison-concepts-and-reference-types"><a href="https://github.com/ericniebler/stl2/issues/155">155</a>: Comparison concepts and reference types</h2>
<p>Many concepts in the TS are well-defined over value types - un-cv-qualified non-array object types - but have unclear meaning for non-value types. For example, <code>EqualityComparable&lt;foo&gt;()</code> has a straight-forward meaning for a value type <code>foo</code>:</p>
<ul>
<li><code>bool(a == b)</code> iff <code>a</code> equals <code>b</code> (<code>==</code> means “equals”)</li>
<li><code>bool(a != b) == !bool(a == b)</code> (As relations, <code>!=</code> is the complement of <code>==</code>)</li>
<li><code>a == b</code> and <code>a != b</code> are valid non-modifying equality-preserving expressions if both <code>a</code> and <code>b</code> are expressions with type <code>foo</code> or <code>const foo</code> and any value category.</li>
</ul>
<p>What meaning, if any, should <code>EqualityComparable&lt;const foo&gt;()</code> have? <code>EqualityComparable&lt;foo&amp;&gt;()</code>? <code>EqualityComparable&lt;volatile foo&amp;&amp;&gt;()</code>?</p>
<p>P0547 corrects the problem in the definitions of the Object concepts, but not the Comparison concepts.</p>
<h3 id="proposed-resolution">Proposed Resolution</h3>
<p>Change the definition of the <code>Booolean</code> concept ([concepts.lib.compare.boolean]/p1) as follows (includes the resolution for #330):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class B&gt;
concept bool Boolean() {
<span class="st">-  return MoveConstructible&lt;B&gt;() &amp;&amp; // (see 4.5.4)</span>
<span class="st">-    requires(const B b1, const B b2, const bool a) {</span>
<span class="st">-      bool(b1);</span>
<span class="st">-      { b1 } -&gt; bool;</span>
<span class="st">-      bool(!b1);</span>
<span class="st">-      { !b1 } -&gt; bool;</span>
<span class="st">-      { b1 &amp;&amp; b2 } -&gt; Same&lt;bool&gt;;</span>
<span class="st">-      { b1 &amp;&amp; a } -&gt; Same&lt;bool&gt;;</span>
<span class="st">-      { a &amp;&amp; b1 } -&gt; Same&lt;bool&gt;;</span>
<span class="st">-      { b1 || b2 } -&gt; Same&lt;bool&gt;;</span>
<span class="st">-      { b1 || a } -&gt; Same&lt;bool&gt;;</span>
<span class="st">-      { a || b1 } -&gt; Same&lt;bool&gt;;</span>
<span class="st">-      { b1 == b2 } -&gt; bool;</span>
<span class="st">-      { b1 != b2 } -&gt; bool;</span>
<span class="st">-      { b1 == a } -&gt; bool;</span>
<span class="st">-      { a == b1 } -&gt; bool;</span>
<span class="st">-      { b1 != a } -&gt; bool;</span>
<span class="st">-      { a != b1 } -&gt; bool;</span>
<span class="ot">+  return Movable&lt;decay_t&lt;B&gt;&gt;() &amp;&amp; // (see \ref{concepts.lib.object.movable})</span>
<span class="ot">+    requires(const remove_reference_t&lt;B&gt;&amp; b1,</span>
<span class="ot">+             const remove_reference_t&lt;B&gt;&amp; b2, const bool a) {</span>
<span class="ot">+      { b1 } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { !b1 } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 &amp;&amp; a } -&gt;  Same&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 || a } -&gt;  Same&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 &amp;&amp; b2 } -&gt; Same&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { a &amp;&amp; b2  } -&gt; Same&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 || b2 } -&gt; Same&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { a || b2  } -&gt; Same&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 == b2 } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 == a  } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { a == b2  } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 != b2 } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { b1 != a  } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
<span class="ot">+      { a != b2  } -&gt; ConvertibleTo&lt;bool&gt;&amp;&amp;;</span>
    };
 }</code></pre></div>
<p>Change [concepts.lib.compare.boolean]/p2 as follows (depends on the resolution of #167):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-2 Given values b1 and b2 of type B, then Boolean&lt;B&gt;() is satisfied if and only if</span>
<span class="ot">+2 Given const lvalues b1 and b2 of type remove_reference_t&lt;B&gt;, then</span>
<span class="ot">+  Boolean&lt;B&gt;() is satisfied if and only if</span>
<span class="st">-(2.1) — bool(b1) == [](bool x) { return x; }(b1).</span>
 (2.2) — bool(b1) == !bool(!b1).
 (2.3) — (b1 &amp;&amp; b2), (b1 &amp;&amp; bool(b2)), and (bool(b1) &amp;&amp; b2) are all equal to
         (bool(b1) &amp;&amp; bool(b2)), and have the same short-circuit evaluation.
 (2.4) — (b1 || b2), (b1 || bool(b2)), and (bool(b1) || b2) are all equal to
         (bool(b1) || bool(b2)), and have the same short-circuit evaluation.
 (2.5) — bool(b1 == b2), bool(b1 == bool(b2)), and bool(bool(b1) == b2) are
         all equal to (bool(b1) == bool(b2)).
 (2.6) — bool(b1 != b2), bool(b1 != bool(b2)), and bool(bool(b1) != b2) are
         all equal to (bool(b1) != bool(b2)).</code></pre></div>
<p>Change concept <code>WeaklyEqualityComparable</code> ([concepts.lib.compare.equalitycomparable]) as follows (includes the resolution for #330):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T, class U&gt;
 concept bool WeaklyEqualityComparable() {
<span class="st">-  return requires(const T&amp; t, const U&amp; u) {</span>
<span class="st">-    { t == u } -&gt; Boolean;</span>
<span class="st">-    { u == t } -&gt; Boolean;</span>
<span class="st">-    { t != u } -&gt; Boolean;</span>
<span class="st">-    { u != t } -&gt; Boolean;</span>
<span class="ot">+  return requires(const remove_reference_t&lt;T&gt;&amp; t,</span>
<span class="ot">+                  const remove_reference_t&lt;U&gt;&amp; u) {</span>
<span class="ot">+    { t == u } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+    { t != u } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+    { u == t } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+    { u != t } -&gt; Boolean&amp;&amp;;</span>
   };
 }</code></pre></div>
<p>Change [concepts.lib.compare.equalitycomparable]/p1 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-1 Let t and u be objects of types T and U.</span>
<span class="ot">+1 Let t and u be const lvalues of types remove_reference_t&lt;T&gt; and remove_reference_t&lt;U&gt;.</span>
   WeaklyEqualityComparable&lt;T, U&gt;() is satisfied if and only if:
 (1.1) — t == u, u == t, t != u, and u != t have the same domain.
 (1.2) — bool(u == t) == bool(t == u).
 (1.3) — bool(t != u) == !bool(t == u).</code></pre></div>
<p>Change cross-type concept <code>EqualityComparable</code> ([concepts.lib.compare.equalitycomparable]) as follows (includes the resolution for #330):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T, class U&gt;
 concept bool EqualityComparable() {
<span class="st">-  return CommonReference&lt;const T&amp;, const U&amp;&gt;() &amp;&amp;</span>
<span class="ot">+  return</span>
     EqualityComparable&lt;T&gt;() &amp;&amp;
     EqualityComparable&lt;U&gt;() &amp;&amp;
<span class="st">-    EqualityComparable&lt;</span>
<span class="st">-        remove_cv_t&lt;remove_reference_t&lt;common_reference_t&lt;const T&amp;, const U&amp;&gt;&gt;&gt;&gt;() &amp;&amp;</span>
<span class="ot">+    CommonReference&lt;</span>
<span class="ot">+      const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+      const remove_reference_t&lt;U&gt;&amp;&gt;() &amp;&amp;</span>
<span class="ot">+    EqualityComparable&lt;</span>
<span class="ot">+      common_reference_t&lt;</span>
<span class="ot">+        const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+        const remove_reference_t&lt;U&gt;&amp;&gt;&gt;() &amp;&amp;</span>
     WeaklyEqualityComparable&lt;T, U&gt;();
 }</code></pre></div>
<p>Change [concepts.lib.compare.equalitycomparable]/p4 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-4 Let a be an object of type T, b be an object of type U, and C be</span>
<span class="st">-  common_reference_t&lt;const T&amp;, const U&amp;&gt;.</span>
<span class="ot">+4 Let a be a const lvalue of type remove_reference_t&lt;T&gt;, b be a</span>
<span class="ot">+  const lvalue of type remove_reference_t&lt;U&gt;, and C be</span>
<span class="ot">+  common_reference_t&lt;const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+  const remove_reference_t&lt;U&gt;&amp;&gt;.</span>
   Then EqualityComparable&lt;T, U&gt;() is satisfied if and only if:
 (4.1) — bool(a == b) == bool(C(a) == C(b)).</code></pre></div>
<p>Change concept <code>StrictTotallyOrdered</code> ([concepts.lib.compare.stricttotallyordered]) as follows (includes the resolution for #330):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T&gt;
 concept bool StrictTotallyOrdered() {
   return EqualityComparable&lt;T&gt;() &amp;&amp;
<span class="st">-    requires(const T a, const T b) {</span>
<span class="ot">+    requires(const remove_reference_t&lt;T&gt;&amp; t,</span>
<span class="ot">+             const remove_reference_t&lt;U&gt;&amp; u) {</span>
<span class="st">-      { a &lt; b } -&gt; Boolean;</span>
<span class="st">-      { a &gt; b } -&gt; Boolean;</span>
<span class="st">-      { a &lt;= b } -&gt; Boolean;</span>
<span class="st">-      { a &gt;= b } -&gt; Boolean;</span>
<span class="ot">+      { a &lt; b } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { a &gt; b } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { a &lt;= b } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { a &gt;= b } -&gt; Boolean&amp;&amp;;</span>
     };
 }</code></pre></div>
<p>Change [concepts.lib.compare.stricttotallyordered]/p1 to be:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-1 Let a, b, and c be objects of type T.</span>
<span class="ot">+1 Let a, b, and c be const lvalues of type remove_reference_t&lt;T&gt;.</span>
 Then StrictTotallyOrdered&lt;T&gt;() is satisfied if and only if
 (1.1) — Exactly one of bool(a &lt; b), bool(b &lt; a), or bool(a == b) is true.
 (1.2) — If bool(a &lt; b) and bool(b &lt; c), then bool(a &lt; c).
 (1.3) — bool(a &gt; b) == bool(b &lt; a).
 (1.4) — bool(a &lt;= b) == !bool(b &lt; a).
 (1.5) — bool(a &gt;= b) == !bool(a &lt; b).</code></pre></div>
<p>Change cross-type concept <code>StrictTotallyOrdered</code> ([concepts.lib.compare.stricttotallyordered]) as follows (includes the resolution for #330):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T, class U&gt;
 concept bool StrictTotallyOrdered() {
<span class="st">-  return CommonReference&lt;const T&amp;, const U&amp;&gt;() &amp;&amp;</span>
<span class="ot">+  return</span>
     StrictTotallyOrdered&lt;T&gt;() &amp;&amp;
     StrictTotallyOrdered&lt;U&gt;() &amp;&amp;
<span class="st">-    StrictTotallyOrdered&lt;</span>
<span class="st">-      remove_cv_t&lt;remove_reference_t&lt;common_reference_t&lt;const T&amp;, const U&amp;&gt;&gt;&gt;&gt;() &amp;&amp;</span>
<span class="ot">+    CommonReference&lt;</span>
<span class="ot">+      const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+      const remove_reference_t&lt;U&gt;&amp;&gt;() &amp;&amp;</span>
<span class="ot">+    StrictTotallyOrdered&lt;</span>
<span class="ot">+      common_reference_t&lt;</span>
<span class="ot">+        const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+        const remove_reference_t&lt;U&gt;&amp;&gt;&gt;() &amp;&amp;</span>
     EqualityComparable&lt;T, U&gt;() &amp;&amp;
<span class="st">-    requires(const T t, const U u) {</span>
<span class="ot">+    requires(const remove_reference_t&lt;T&gt;&amp; t,</span>
<span class="ot">+             const remove_reference_t&lt;U&gt;&amp; u) {</span>
<span class="st">-      { t &lt; u } -&gt; Boolean;</span>
<span class="st">-      { t &gt; u } -&gt; Boolean;</span>
<span class="st">-      { t &lt;= u } -&gt; Boolean;</span>
<span class="st">-      { t &gt;= u } -&gt; Boolean;</span>
<span class="st">-      { u &lt; t } -&gt; Boolean;</span>
<span class="st">-      { u &gt; t } -&gt; Boolean;</span>
<span class="st">-      { u &lt;= t } -&gt; Boolean;</span>
<span class="st">-      { u &gt;= t } -&gt; Boolean;</span>
<span class="ot">+      { t &lt; u } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { t &gt; u } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { t &lt;= u } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { t &gt;= u } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { u &lt; t } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { u &gt; t } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { u &lt;= t } -&gt; Boolean&amp;&amp;;</span>
<span class="ot">+      { u &gt;= t } -&gt; Boolean&amp;&amp;;</span>
     };
 }</code></pre></div>
<p>Change [concepts.lib.compare.stricttotallyordered]/p2 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-2 Let t be an object of type T, u be an object of type U,</span>
<span class="ot">+2 Let t be a const lvalue of type remove_reference_t&lt;T&gt;,</span>
<span class="ot">+  u be a const lvalue of type remove_reference_t&lt;U&gt;,</span>
<span class="st">-  and C be common_reference_t&lt;const T&amp;, const U&amp;&gt;.</span>
<span class="ot">+  and C be common_reference_t&lt;const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+  const remove_reference_t&lt;U&gt;&amp;&gt;.</span>
   Then StrictTotallyOrdered&lt;T, U&gt;() is satisfied if and only if
 (2.1) — bool(t &lt; u) == bool(C(t) &lt; C(u)).
 (2.2) — bool(t &gt; u) == bool(C(t) &gt; C(u)).
 (2.3) — bool(t &lt;= u) == bool(C(t) &lt;= C(u)).
 (2.4) — bool(t &gt;= u) == bool(C(t) &gt;= C(u)).
 (2.5) — bool(u &lt; t) == bool(C(u) &lt; C(t)).
 (2.6) — bool(u &gt; t) == bool(C(u) &gt; C(t)).
 (2.7) — bool(u &lt;= t) == bool(C(u) &lt;= C(t)).
 (2.8) — bool(u &gt;= t) == bool(C(u) &gt;= C(t)).</code></pre></div>
<p>Change section “Concept <code>Relation</code>” ([concepts.lib.callable.relation]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class R, class T, class U&gt;
concept bool Relation() {
  return Relation&lt;R, T&gt;() &amp;&amp;
    Relation&lt;R, U&gt;() &amp;&amp;
<span class="st">-    CommonReference&lt;const T&amp;, const U&amp;&gt;() &amp;&amp;</span>
<span class="st">-    Relation&lt;R,</span>
<span class="st">-      common_reference_t&lt;const T&amp;, const U&amp;&gt;&gt;() &amp;&amp;</span>
<span class="ot">+    CommonReference&lt;</span>
<span class="ot">+      const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+      const remove_reference_t&lt;U&gt;&amp;&gt;() &amp;&amp;</span>
<span class="ot">+    Relation&lt;R,</span>
<span class="ot">+      common_reference_t&lt;</span>
<span class="ot">+        const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+        const remove_reference_t&lt;U&gt;&amp;&gt;&gt;() &amp;&amp;</span>
    Predicate&lt;R, T, U&gt;() &amp;&amp;
    Predicate&lt;R, U, T&gt;();
}

<span class="st">-1 Let r be any object of type R,</span>
<span class="ot">+1 Let r be an expression such that decltype((r)) is R,</span>
<span class="st">-  a be any object of type T,</span>
<span class="ot">+  a be an expression such that decltype((a)) is T,</span>
<span class="st">- b be any object of type U,</span>
<span class="ot">+  b be an expression such that decltype((b)) is U,</span>
<span class="st">-  and C be common_reference_t&lt;const T&amp;, const U&amp;&gt;.</span>
<span class="ot">+  and C be common_reference_t&lt;const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+  const remove_reference_t&lt;U&gt;&amp;&gt;.</span>
  Then Relation&lt;R, T, U&gt;() is satisfied if and only if
(1.1) — bool(r(a, b)) == bool(r(C(a), C(b))).
(1.2) — bool(r(b, a)) == bool(r(C(b), C(a))).</code></pre></div>
<p>Change “Concept <code>Swappable</code>” ([concepts.lib.corelang.swappable]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class T&gt;
concept bool Swappable() {
  return requires(T&amp;&amp; a, T&amp;&amp; b) {
    ranges::swap(std::forward&lt;T&gt;(a), std::forward&lt;T&gt;(b));
  };
}

template &lt;class T, class U&gt;
concept bool Swappable() {
  return Swappable&lt;T&gt;() &amp;&amp;
  Swappable&lt;U&gt;() &amp;&amp;
<span class="st">- CommonReference&lt;const T&amp;, const U&amp;&gt;() &amp;&amp;</span>
<span class="ot">+ CommonReference&lt;</span>
<span class="ot">+   const remove_reference_t&lt;T&gt;&amp;,</span>
<span class="ot">+   const remove_reference_t&lt;U&gt;&amp;&gt;() &amp;&amp;</span>
  requires(T&amp;&amp; t, U&amp;&amp; u) {
    ranges::swap(std::forward&lt;T&gt;(t), std::forward&lt;U&gt;(u));
    ranges::swap(std::forward&lt;U&gt;(u), std::forward&lt;T&gt;(t));
  };
}</code></pre></div>
<h2 id="taggedbase...-should-be-implicitly-constructible-from-base"><a href="https://github.com/ericniebler/stl2/issues/172">172</a>: <code>tagged&lt;Base...&gt;</code> should be implicitly constructible from <code>Base</code></h2>
<p><code>tagged&lt;Base, Tags...&gt;</code> should be implicitly convertible from <code>Base&amp;&amp;</code> when <code>MoveConstructible&lt;Base&gt;()</code> is satisfied, and from <code>Base const&amp;</code> when <code>CopyConstructible&lt;Base&gt;()</code> is satisfied.</p>
<h3 id="proposed-resolution-1">Proposed Resolution</h3>
<p>Change the class synopsis of <code>tagged</code> in [taggedtup.tagged] as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class Base, TagSpecifier... Tags&gt;
   requires sizeof...(Tags) &lt;= tuple_size&lt;Base&gt;::value
 struct tagged :
   Base, TAGGET (tagged&lt;Base, Tags...&gt;, Ti, i)... { // see below
   using Base::Base;
   tagged() = default;
   tagged(tagged&amp;&amp;) = default;
   tagged(const tagged&amp;) = default;
<span class="ot">+  tagged(Base&amp;&amp;) noexcept(see below)</span>
<span class="ot">+    requires MoveConstructible&lt;Base&gt;();</span>
<span class="ot">+  tagged(const Base&amp;) noexcept(see below)</span>
<span class="ot">+    requires CopyConstructible&lt;Base&gt;();</span>
   tagged &amp;operator=(tagged&amp;&amp;) = default;
   tagged &amp;operator=(const tagged&amp;) = default;
   [...]</code></pre></div>
<p>After [taggedtup.tagged]/9, add the following:</p>
<blockquote>
<pre><code>tagged(Base &amp;&amp;that) noexcept(see below )
  requires MoveConstructible&lt;Base&gt;();</code></pre>
<p>10 <em>Remarks:</em> The expression in the <code>noexcept</code> is equivalent to:</p>
<pre><code>is_nothrow_move_constructible&lt;Base&gt;::value</code></pre>
<p>11 Effects: Initializes <code>Base</code> with <code>std::move(that)</code>.</p>
<pre><code>
tagged(const Base &amp;that) noexcept(see below )
  requires CopyConstructible&lt;Base&gt;();</code></pre>
<p>12 <em>Remarks:</em> The expression in the <code>noexcept</code> is equivalent to:</p>
<pre><code>is_nothrow_copy_constructible&lt;Base&gt;::value</code></pre>
<p>13 Effects: Initializes <code>Base</code> with <code>that</code>.</p>
</blockquote>
<h2 id="dont-slurp-entities-from-std-into-stdexperimentalrangesv1"><a href="https://github.com/ericniebler/stl2/issues/203">203</a>: Don’t slurp entities from <code>std</code> into <code>std::experimental::ranges::v1</code></h2>
<p>The Ranges TS, [function.objects]/p3 says:</p>
<blockquote>
<p>Any entities declared or defined directly in namespace std in header <code>&lt;functional&gt;</code> that are not already defined in namespace <code>std::experimental::ranges</code> in header <code>&lt;experimental/ranges/functional&gt;</code> are imported with <em>using-declarations</em> (7.3.3). [ <em>Example:</em></p>
<pre><code>namespace std { namespace experimental { namespace ranges { inline namespace v1 {
using std::reference_wrapper;
using std::ref;
// ... others
}}}}</code></pre>
<p>—<em>end example</em> ]</p>
</blockquote>
<p>This breaks forward compatibility should we ever decide that something in <code>std::</code> needs to have a parallel, constrained implementation in <code>ranges::</code>.</p>
<h3 id="proposed-resolution-2">Proposed resolution</h3>
<p>Strike paragraph 1 in [iterator.synopsis].</p>
<p>In [tagged.tuple]/p1, strike the text beginning with “Any entities declared or defined in namespace std in header <tuple>” and ending at the end of the example.</p>
<p>Strike p3 and p4 under [function.objects].</p>
<p>Strike p2 under [utility].</p>
<h2 id="kill-the-readability-requirement-for-i-for-inputiterators"><a href="https://github.com/ericniebler/stl2/issues/232">232</a>: Kill the Readability requirement for <code>i++</code> for <code>InputIterators</code></h2>
<p>The requirement for <code>InputIterator</code>s to provide a post-increment operator that returns a type satisfying the <code>Readable</code> concept presents significant implementation challenges for many input iterators, and makes some impossible to implement.</p>
<h3 id="proposed-resolution-3">Proposed resolution</h3>
<p>Adopt <a href="http://wg21.link/P0541">P0541</a>.</p>
<h2 id="trivial-example-breaks-common_type-from-p0022"><a href="https://github.com/ericniebler/stl2/issues/235">235</a>: Trivial example breaks common_type from P0022</h2>
<p>The following test case fails with <code>common_type</code> as specified in P0022.</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">struct</span> Int
{
    <span class="kw">operator</span> <span class="dt">int</span>();
};

<span class="co">// Whoops, fails:</span>
<span class="kw">static_assert</span>(std::is_same_v&lt;common_type_t&lt;Int, <span class="dt">int</span>&gt;, <span class="dt">int</span>&gt;);</code></pre></div>
<p>The issue is that P0022 mandates that the two template arguments be first transformed by adding <code>const &amp;</code> to each before trying them in the conditional expression, like <code>decltype(true ? declval&lt;const T&amp;&gt;() : declval&lt;const U&amp;&gt;())</code>. This is sometimes desirable — e.g., it finds <code>int</code> as the common type of <code>reference_wrapper&lt;int&gt;</code> and <code>int</code> — but in this case it causes the conditional expression to be ill-formed since <code>Int</code>’s implicit conversion operator is not <code>const</code>-qualified.</p>
<p>The fix is to first try the arguments as they are (after they are decayed) to see if the conditional expression is well-formed. If not, the conditional expression is then retried with <code>const</code> and <code>&amp;</code> qualification to see if that works.</p>
<p>With this fix, <code>common_type</code> as proposed passes all of libc++’s and libstdc++’s tests with the exception of <a href="https://github.com/gcc-mirror/gcc/blob/be58e01da55c6dbbfe20e7bcbac6b7b354052ca8/libstdc%2B%2B-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc#L270">one</a> that will be broken by the adoption of <a href="https://cplusplus.github.io/LWG/lwg-active.html#2763">LWG#2763</a> and <a href="https://github.com/gcc-mirror/gcc/blob/be58e01da55c6dbbfe20e7bcbac6b7b354052ca8/libstdc%2B%2B-v3/testsuite/20_util/common_type/requirements/sfinae_friendly_1.cc#L271-L273">two</a> that seem related to the lookup of private class members.</p>
<h3 id="proposed-resolution-4">Proposed Resolution</h3>
<p>This wording is based on P0022R2. It fixes the problem noted above and also adopts some of the wording from <a href="https://cplusplus.github.io/LWG/lwg-active.html#2763">LWG#2763</a>.</p>
<p>Change Table 57 to disallow user specialization of <code>common_reference</code>. Specialization of <code>basic_common_reference</code> is the way to influence the result of <code>common_reference</code>, and it avoids the combinatorial explosion of cv- and ref-qualifiers:</p>
<table style="width:49%;">
<colgroup>
<col width="15%" />
<col width="18%" />
<col width="15%" />
</colgroup>
<thead>
<tr class="header">
<th>Template</th>
<th>Condition</th>
<th>Comments</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><tt>template &lt;class… T&gt;</tt><br><tt>struct common_reference;</tt></td>
<td></td>
<td>The member typedef <tt>type</tt> shall be defined or omitted as specified below. If it is ommitted, there shall be no member <tt>type</tt>. Each type in the parameter pack <tt>T</tt> shall be complete or (possibly cv) <tt>void</tt>. <del>A program may specialize this trait if at least one template parameter in the specialization depends on a user-defined type and <tt>sizeof…(T) == 2</tt>. Remark: Such specializations are needed to properly handle proxy reference types in generic code.</del></td>
</tr>
</tbody>
</table>
<p>Change the description of <code>common_type</code> ([meta.trans.other]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-4. For the common_type trait applied to a parameter pack [...]</span>
<span class="ot">+4. Note A: For the common_type trait applied to a parameter pack [...]</span>
 [...]
 (4.3)     — Otherwise, if sizeof...(T) is two, let T1 and T2 denote the
             two types in the pack T, and let D1 and D2 be decay_t&lt;T1&gt; and
             decay_t&lt;T2&gt; respectively. Then
 (4.3.1)        — If D1 and T1 denote the same type and D2 and T2 denote
                  the same type, then
<span class="ot">+(4.3.1.?)               — If COND_RES(T1, T2) is well-formed, then the</span>
<span class="ot">+                          member typedef type denotes</span>
<span class="ot">+                          decay_t&lt;COND_RES(T1, T2)&gt;.</span>
 (4.3.1.1)               — If COMMON_REF(T1, T2) is well-formed, then the
                           member typedef type denotes that type.
 (4.3.1.2)               — Otherwise, there shall be no member type
 [...]
 (4.4.2)        — Otherwise, there shall be no member type.
<span class="ot">+?. Note B: A program may specialize the common_type trait for two</span>
<span class="ot">+   cv-unqualified non-reference types if at least one of them depends on a</span>
<span class="ot">+   user-defined type. [Note: Such specializations are needed when only</span>
<span class="ot">+   explicit conversions are desired among the template arguments.</span>
<span class="ot">+   — end note] Such a specialization need not have a member named</span>
<span class="ot">+   type, but if it does, that member shall be a typedef-name for a</span>
<span class="ot">+   cv-unqualified non-reference type that need not otherwise meet</span>
<span class="ot">+   the specification set forth in Note A, above.</span></code></pre></div>
<p>Change the description of <code>common_reference</code> ([meta.trans.other]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> 5. For the common_reference trait applied to a parameter pack [...]
 [...]
 (5.4.2)        — Otherwise, there shall be no member type.
<span class="ot">+?. A program may specialize the basic_common_reference trait for</span>
<span class="ot">+   two cv-unqualified non-reference types if at least one of them depends on a</span>
<span class="ot">+   user-defined type. Such a specialization need not have a member named</span>
<span class="ot">+   type.</span></code></pre></div>
<h2 id="the-iterator-adaptors-should-customize-iter_move-and-iter_swap"><a href="https://github.com/ericniebler/stl2/issues/245">245</a>: The iterator adaptors should customize <code>iter_move</code> and <code>iter_swap</code></h2>
<p>It may be the case that <code>iter_swap</code> of the base iterators is more efficient than <code>iter_move</code> construction + <code>iter_move</code> assignment + <code>move</code> assignment.</p>
<h3 id="proposed-resolution-5">Proposed resolution:</h3>
<p>In [reverse.iterator], add declarations to the synopsis:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">  reference operator[](difference_type n) const
    requires RandomAccessIterator&lt;I&gt;();
<span class="ot">+</span>
<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const reverse_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below);</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const reverse_iterator&amp; x, const reverse_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below);</span>
<span class="ot">+</span>
private:
  I current; // exposition only
};</code></pre></div>
</blockquote>
<p>Add new sections before [reverse.iter.make] as follows:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="ot">+ 24.7.1.3.? iter_move [reverse.iter.iter_move]</span>
<span class="ot">+</span>
<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const reverse_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below);</span>
<span class="ot">+</span>
<span class="ot">+ 1 Effects: Equivalent to: return ranges::iter_move(prev(i.current));</span>
<span class="ot">+</span>
<span class="ot">+ 2 Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+   noexcept(ranges::iter_move(declval&lt;I&amp;&gt;())) &amp;&amp; noexcept(--declval&lt;I&amp;&gt;()) &amp;&amp;</span>
<span class="ot">+   is_nothrow_copy_constructible&lt;I&gt;::value.</span>
<span class="ot">+</span>
<span class="ot">+ 24.7.1.3.? iter_swap [reverse.iter.iter_swap]</span>
<span class="ot">+</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const reverse_iterator&amp; x, const reverse_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below);</span>
<span class="ot">+</span>
<span class="ot">+ 1 Effects: Equivalent to ranges::iter_swap(prev(x.current), prev(y.current)).</span>
<span class="ot">+</span>
<span class="ot">+ 2 Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+   noexcept(ranges::iter_swap(declval&lt;I&gt;(), declval&lt;I&gt;())) &amp;&amp; noexcept(--declval&lt;I&amp;&gt;()).</span></code></pre></div>
</blockquote>
<p>In [move.iterator], add declarations to the synopsis:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">  reference operator[](difference_type n) const
    requires RandomAccessIterator&lt;I&gt;();

<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const move_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below);</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const move_iterator&amp; x, const move_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below);</span>
<span class="ot">+</span>
private:
  I current; // exposition only
};</code></pre></div>
</blockquote>
<p>Add new paragraphs to [move.iter.nonmember] as follows:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;RandomAccessIterator I&gt;
  move_iterator&lt;I&gt;
    operator+(
      difference_type_t&lt;I&gt; n,
      const move_iterator&lt;I&gt;&amp; x);

<span class="dt">2 Effects: Equivalent to x + n.</span>
<span class="ot">+</span>
<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const move_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below):</span>
<span class="ot">+</span>
<span class="ot">+ -?- Effects: Equivalent to: return ranges::iter_move(i.current);</span>
<span class="ot">+</span>
<span class="ot">+ -?- Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+     noexcept(ranges::iter_move(i.current)).</span>
<span class="ot">+</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const move_iterator&amp; x, const move_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below):</span>
<span class="ot">+</span>
<span class="ot">+ -?- Effects: Equivalent to ranges::iter_swap(x.current, y.current).</span>
<span class="ot">+</span>
<span class="ot">+ -?- Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+     noexcept(ranges::iter_swap(x.current, y.current)).</span>

template &lt;InputIterator I&gt;
  move_iterator&lt;I&gt; make_move_iterator(I i);

<span class="dt">3 Returns: move_iterator&lt;I&gt;(i).</span></code></pre></div>
</blockquote>
<p>In [common.iterator], add declarations to the synopsis:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">  common_iterator&amp; operator++();
  common_iterator operator++(int);
<span class="ot">+</span>
<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const common_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below)</span>
<span class="ot">+     requires InputIterator&lt;I&gt;();</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2, class S2&gt;</span>
<span class="ot">+   friend void iter_swap(const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below)</span>

private:
  bool is_sentinel; // exposition only</code></pre></div>
</blockquote>
<p>Add new sections after [common.iter.op.comp]:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="ot">+ 24.7.4.2.? iter_move [common.iter.op.iter_move]</span>
<span class="ot">+</span>
<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const common_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below)</span>
<span class="ot">+     requires InputIterator&lt;I&gt;();</span>
<span class="ot">+</span>
<span class="ot">+ 1 Requires: !i.is_sentinel.</span>
<span class="ot">+</span>
<span class="ot">+ 2 Effects: Equivalent to: return ranges::iter_move(i.iter);</span>
<span class="ot">+</span>
<span class="ot">+ 3 Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+   noexcept(ranges::iter_move(i.iter)).</span>
<span class="ot">+</span>
<span class="ot">+ 24.7.4.2.? iter_swap [common.iter.op.iter_swap]</span>
<span class="ot">+</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const common_iterator&amp; x, const common_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below);</span>
<span class="ot">+</span>
<span class="ot">+ 1 Requires: !x.is_sentinel &amp;&amp; !y.is_sentinel.</span>
<span class="ot">+</span>
<span class="ot">+ 2 Effects: Equivalent to ranges::iter_swap(x.iter, y.iter).</span>
<span class="ot">+</span>
<span class="ot">+ 3 Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+   noexcept(ranges::iter_swap(x.iter, y.iter)).</span></code></pre></div>
</blockquote>
<p>In [counted.iterator], add declarations to the synopsis:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">  see below operator[](difference_type n) const
    requires RandomAccessIterator&lt;I&gt;();

<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const counted_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below)</span>
<span class="ot">+     requires InputIterator&lt;I&gt;();</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const counted_iterator&amp; x, const counted_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below);</span>
<span class="ot">+</span>
private:
  I current; // exposition only</code></pre></div>
</blockquote>
<p>Add new paragraphs to [counted.iter.nonmember] as follows:</p>
<blockquote>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;RandomAccessIterator I&gt;
  counted_iterator&lt;I&gt;
    operator+(difference_type_t&lt;I&gt; n, const counted_iterator&lt;I&gt;&amp; x);

<span class="dt">5 Requires: n &lt;= x.cnt.</span>

<span class="dt">6 Effects: Equivalent to x + n.</span>
<span class="ot">+</span>
<span class="ot">+ friend constexpr rvalue_reference_t&lt;I&gt; iter_move(const counted_iterator&amp; i)</span>
<span class="ot">+   noexcept(see below)</span>
<span class="ot">+     requires InputIterator&lt;I&gt;();</span>
<span class="ot">+</span>
<span class="ot">+ -?- Effects: Equivalent to: return ranges::iter_move(i.current).</span>
<span class="ot">+</span>
<span class="ot">+ -?- Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+      noexcept(ranges::iter_move(i.current)).</span>
<span class="ot">+</span>
<span class="ot">+ template &lt;IndirectlySwappable&lt;I&gt; I2&gt;</span>
<span class="ot">+   friend void iter_swap(const counted_iterator&amp; x, const counted_iterator&lt;I2&gt;&amp; y)</span>
<span class="ot">+     noexcept(see below);</span>
<span class="ot">+</span>
<span class="ot">+ -?- Effects: Equivalent to ranges::iter_swap(x.current, y.current).</span>
<span class="ot">+</span>
<span class="ot">+ -?- Remarks: The expression in the noexcept clause is equivalent to</span>
<span class="ot">+     noexcept(ranges::iter_swap(x.current, y.current)).</span>

template &lt;Iterator I&gt;
  counted_iterator&lt;I&gt; make_counted_iterator(I i, difference_type_t&lt;I&gt; n);

<span class="dt">7 Requires: n &gt;= 0.</span>

<span class="dt">8 Returns: counted_iterator&lt;I&gt;(i, n).</span></code></pre></div>
</blockquote>
<h2 id="algorithms-incorrectly-specified-in-terms-of-swapab-instead-iter_swapab-and-movea-instead-of-iter_movea"><a href="https://github.com/ericniebler/stl2/issues/251">251</a>: algorithms incorrectly specified in terms of <code>swap(*a,*b)</code> instead <code>iter_swap(a,b)</code>, and <code>move(*a)</code> instead of <code>iter_move(a)</code></h2>
<p>This change is necessary for the algorithms to properly support P0022 proxy iterators.</p>
<h3 id="proposed-resolution-6">Proposed resolution</h3>
<p>In [alg.move], change p1 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> 1. Effects: Moves elements in the range [first,last) into the range
    [result, result + (last - first)) starting from first and proceeding
    to last. For each non-negative integer n &lt; (last-first), performs
<span class="st">-   *(result + n) = std::move(*(first + n)).</span>
<span class="ot">+   *(result + n) = ranges::iter_move(first + n).</span></code></pre></div>
<p>Change p5 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> 5. Effects: Moves elements in the range [first,last) into the range
    [result - (last-first),result) starting from last - 1 and proceeding
    to first.6 For each positive integer n &lt;= (last - first), performs
<span class="st">-   *(result - n) = std::move(*(last - n)).</span>
<span class="ot">+   *(result - n) = ranges::iter_move(last - n).</span></code></pre></div>
<p>Change [alg.swap]/p1 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> 1. Effects: For the first two overloads, let last2 be first2 + (last1 - first1).
    For each non-negative integer n &lt; min(last1 - first1, last2 - first2) performs:
<span class="st">-   swap(*(first1 + n), *(first2 + n)).</span>
<span class="ot">+   ranges::iter_swap(first1 + n, first2 + n).</span></code></pre></div>
<h2 id="is_swappable-type-traits-should-not-be-in-namespace-std"><a href="https://github.com/ericniebler/stl2/issues/259">259</a>: <code>is_swappable</code> type traits should not be in namespace <code>std</code></h2>
<p>They are defined in terms of unqualified calls to <code>swap</code>, but <code>swap</code> is unconstrained in C++14. Solution: move the <code>swappable</code> traits into the <code>std::experimental::ranges</code> namespace and define them in terms of the <code>ranges::swap</code> customization point object.</p>
<h3 id="proposed-wording">Proposed wording</h3>
<p>To Table 1 – Ranges TS library headers, add <code>&lt;experimental/ranges/type_traits&gt;</code>.</p>
<p>From the <code>&lt;type_traits&gt;</code> synopsis ([meta.type.synop]), remove the declarations of:</p>
<ul>
<li><code>is_swappable</code></li>
<li><code>is_swappable_with</code></li>
<li><code>is_nothrow_swappable</code></li>
<li><code>is_nothrow_swappable_with</code></li>
<li><code>is_swappable_v</code></li>
<li><code>is_swappable_with_v</code></li>
<li><code>is_nothrow_swappable_v</code></li>
<li><code>is_nothrow_swappable_with_v</code></li>
</ul>
<p>Remove subsection “Type properties” ([meta.unary.prop]).</p>
<p>After subsection “Other transformations” ([meta.trans.other]), add a new subsection “Header <code>&lt;experimental/ranges/type_traits&gt;</code> synopsis” ([meta.type.synop.rng]) with the following:</p>
<blockquote>
<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="co">// (REF), type properties:</span>
<span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> U&gt; <span class="kw">struct</span> is_swappable_with;
<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt; <span class="kw">struct</span> is_swappable;

<span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> U&gt; <span class="kw">struct</span> is_nothrow_swappable_with;
<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt; <span class="kw">struct</span> is_nothrow_swappable;

<span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> U&gt; <span class="kw">constexpr</span> <span class="dt">bool</span> is_swappable_with_v
    = is_swappable_with&lt;T, U&gt;::value;
<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt; <span class="kw">constexpr</span> <span class="dt">bool</span> is_swappable_v
    = is_swappable&lt;T&gt;::value;

<span class="kw">template</span> &lt;<span class="kw">class</span> T, <span class="kw">class</span> U&gt; <span class="kw">constexpr</span> <span class="dt">bool</span> is_nothrow_swappable_with_v
    = is_nothrow_swappable_with&lt;T, U&gt;::value;
<span class="kw">template</span> &lt;<span class="kw">class</span> T&gt; <span class="kw">constexpr</span> <span class="dt">bool</span> is_nothrow_swappable_v
    = is_nothrow_swappable&lt;T&gt;::value;
}}}}</code></pre></div>
</blockquote>
<p>After subsection “Header <code>&lt;experimental/ranges/type_traits&gt;</code> synopsis” ([meta.type.synop.rng]), add a new subsection “Additional type properties” ([meta.unary.prop.rng]) with the following:</p>
<p>[<em>Editor’s note:</em> Taken from latest C++17 working draft.]</p>
<blockquote>
<ol>
<li>These templates provide access to some of the more important properties of types.</li>
<li>It is unspecified whether the library defines any full or partial specializations of any of these templates.</li>
<li>For all of the class templates X declared in this subclause, instantiating that template with a template argument that is a class template specialization may result in the implicit instantiation of the template argument if and only if the semantics of X require that the argument must be a complete type.</li>
<li>For the purpose of defining the templates in this subclause, a function call expression declval&lt;T&gt;() for any type T is considered to be a trivial (3.9, 12) function call that is not an odr-use (3.2) of declval in the context of the corresponding definition notwithstanding the restrictions of 20.2.7.</li>
</ol>
<p><em>Table XX - Additional type property predicates</em></p>
<table style="width:53%;">
<colgroup>
<col width="15%" />
<col width="16%" />
<col width="20%" />
</colgroup>
<thead>
<tr class="header">
<th>Template</th>
<th>Condition</th>
<th>Precondition</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><tt>template &lt;class T, class U&gt;</tt><br/><tt>struct is_swappable_with</tt>;</td>
<td>The expressions <tt><u>ranges::</u>swap(declval&lt;T&gt;(), declval&lt;U&gt;())</tt> and <code>ranges::swap(declval&lt;U&gt;(), declval&lt;T&gt;())</code> are each well-formed when treated as an unevaluated operand (Clause 5) <del>in an overload-resolution context for swappable values (17.5.3.2)</del>. Access checking is performed as if in a context unrelated to <code>T</code> and <code>U</code>. Only the validity of the immediate context of the <code>swap</code> expressions is considered. [ <em>Note:</em> The compilation of the expressions can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed. –<em>end note</em> ]</td>
<td><code>T</code> and <code>U</code> shall be complete types, <em>cv</em> <code>void</code>, or arrays of unknown bound.</td>
</tr>
<tr class="even">
<td><code>template &lt;class T&gt;</code><br/><code>struct is_swappable;</code></td>
<td>For a referenceable type <code>T</code>, the same result as <code>is_swappable_with_v&lt;T&amp;, T&amp;&gt;</code>, otherwise <code>false</code>.</td>
<td><code>T</code> shall be a complete type, <em>cv</em> <code>void</code>, or an array of unknown bound.</td>
</tr>
<tr class="odd">
<td><code>template &lt;class T, class U&gt;</code><br/><code>struct is_nothrow_swappable_with;</code></td>
<td><code>is_swappable_with_v&lt;T, U&gt;</code> is <code>true</code> and each <code>swap</code> expression of the definition of <code>is_swappable_with&lt;T, U&gt;</code> is known not to throw any exceptions (5.3.7).</td>
<td><code>T</code> and <code>U</code> shall be complete types, <em>cv</em> <code>void</code>, or arrays of unknown bound.</td>
</tr>
<tr class="even">
<td><code>template &lt;class T&gt;</code><br/><code>struct is_nothrow_swappable;</code></td>
<td>For a referenceable type <code>T</code>, the same result as <code>is_nothrow_swappable_with_v&lt;T&amp;, T&amp;&gt;</code>, otherwise <code>false</code>.</td>
<td><code>T</code> shall be a complete type, <em>cv</em> <code>void</code>, or an array of unknown bound.</td>
</tr>
</tbody>
</table>
</blockquote>
<h2 id="resolve-inconsistency-in-indirect_result_of"><a href="https://github.com/ericniebler/stl2/issues/286">286</a>: Resolve inconsistency in <code>indirect_result_of</code></h2>
<p>Issue #238 repairs <code>indirect_result_of</code> in a way that makes it inconsistent. I think the error is using <code>IndirectInvocable</code> to (over-)constrain the template arguments. Really, the user of <code>indirect_result_of</code> is asking: “Can I invoke a type <code>F</code> with the reference type of a bunch of iterators?`”</p>
<p>In contrast, <code>IndirectInvocable</code> exists to give algorithms the leeway to call algorithms with a cross-product of iterators’ value and reference types, and also check that the callable thingie is <code>CopyConstructible</code> (after #189), because that’s a useful clustering of requirements when looking at how the algorithms use callables.</p>
<p>I suggest that <code>indirect_result_of</code> be constrained with <code>Invocable</code> instead of <code>IndirectlyInvocable</code>.</p>
<h3 id="proposed-resolution-7">Proposed Resolution</h3>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class F, class... Is&gt;
<span class="st">-    requires IndirectInvocable&lt;decay_t&lt;F&gt;, Is...&gt;()</span>
<span class="ot">+    requires Invocable&lt;F, reference_t&lt;Is&gt;...&gt;()</span>
struct indirect_result_of&lt;F(Is...)&gt; :
<span class="st">-   result_of&lt;F(reference_t&lt;Is&gt;...)&gt; { };</span>
<span class="ot">+   result_of&lt;F(reference_t&lt;Is&gt;&amp;&amp;...)&gt; { };</span></code></pre></div>
<p><code>transform</code> gets the <code>CopyConstructible</code> requirement for its function parameter from <code>indirect_result_of</code>. We need to fix that up.</p>
<p>In the <code>&lt;experimental/ranges/algorithm&gt;</code> synopsis:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-template &lt;InputIterator I, Sentinel&lt;I&gt; S, WeaklyIncrementable O, class F, class Proj = identity&gt;</span>
<span class="ot">+template &lt;InputIterator I, Sentinel&lt;I&gt; S, WeaklyIncrementable O,</span>
<span class="ot">+    CopyConstructible F, class Proj = identity&gt;</span>
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(projected&lt;I, Proj&gt;)&gt;&gt;()
  tagged_pair&lt;tag::in(I), tag::out(O)&gt;
    transform(I first, S last, O result, F op, Proj proj = Proj{});

<span class="st">-template &lt;InputRange Rng, WeaklyIncrementable O, class F, class Proj = identity&gt;</span>
<span class="ot">+template &lt;InputRange Rng, WeaklyIncrementable O, CopyConstructible F, class Proj = identity&gt;</span>
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(
    projected&lt;iterator_t&lt;R&gt;, Proj&gt;)&gt;&gt;()
  tagged_pair&lt;tag::in(safe_iterator_t&lt;Rng&gt;), tag::out(O)&gt;
    transform(Rng&amp;&amp; rng, O result, F op, Proj proj = Proj{});

// A.2 (deprecated):
template &lt;InputIterator I1, Sentinel&lt;I1&gt; S1, InputIterator I2, WeaklyIncrementable O,
<span class="st">-    class F, class Proj1 = identity, class Proj2 = identity&gt;</span>
<span class="ot">+    CopyConstructible F, class Proj1 = identity, class Proj2 = identity&gt;</span>
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(projected&lt;I1, Proj1&gt;,
    projected&lt;I2, Proj2&gt;)&gt;&gt;()
  tagged_tuple&lt;tag::in1(I1), tag::in2(I2), tag::out(O)&gt;
    transform(I1 first1, S1 last1, I2 first2, O result,
              F binary_op, Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{});

// A.2 (deprecated):
<span class="st">-template &lt;InputRange Rng, InputIterator I, WeaklyIncrementable O, class F,</span>
<span class="ot">+template &lt;InputRange Rng, InputIterator I, WeaklyIncrementable O, CopyConstructible F,</span>
    class Proj1 = identity, class Proj2 = identity&gt;
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(
    projected&lt;iterator_t&lt;Rng&gt;, Proj1&gt;, projected&lt;I, Proj2&gt;&gt;)&gt;()
  tagged_tuple&lt;tag::in1(safe_iterator_t&lt;Rng&gt;), tag::in2(I), tag::out(O)&gt;
  transform(Rng&amp;&amp; rng1, I first2, O result,
            F binary_op, Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{});

template &lt;InputIterator I1, Sentinel&lt;I1&gt; S1, InputIterator I2, Sentinel&lt;I2&gt; S2,
<span class="st">-    WeaklyIncrementable O, class F, class Proj1 = identity, class Proj2 = identity&gt;</span>
<span class="ot">+    WeaklyIncrementable O, CopyConstructible F, class Proj1 = identity, class Proj2 = identity&gt;</span>
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(projected&lt;I1, Proj1&gt;,
    projected&lt;I2, Proj2&gt;)&gt;&gt;()
  tagged_tuple&lt;tag::in1(I1), tag::in2(I2), tag::out(O)&gt;
  transform(I1 first1, S1 last1, I2 first2, S2 last2, O result,
            F binary_op, Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{});

<span class="st">-template &lt;InputRange Rng1, InputRange Rng2, WeaklyIncrementable O, class F,</span>
<span class="ot">+template &lt;InputRange Rng1, InputRange Rng2, WeaklyIncrementable O, CopyConstructible F,</span>
    class Proj1 = identity, class Proj2 = identity&gt;
  requires Writable&lt;O, indirect_result_of_t&lt;F&amp;(
    projected&lt;iterator_t&lt;Rng1&gt;, Proj1&gt;, projected&lt;iterator_t&lt;Rng2&gt;, Proj2&gt;)&gt;&gt;()
  tagged_tuple&lt;tag::in1(safe_iterator_t&lt;Rng1&gt;),
               tag::in2(safe_iterator_t&lt;Rng2&gt;),
               tag::out(O)&gt;
  transform(Rng1&amp;&amp; rng1, Rng2&amp;&amp; rng2, O result,
            F binary_op, Proj1 proj1 = Proj1{}, Proj2 proj2 = Proj2{});</code></pre></div>
<p>with identical changes to the declarations in [alg.transform] and [depr.algo.range-and-a-half]</p>
<h2 id="regular-function-regularinvocable"><a href="https://github.com/ericniebler/stl2/issues/288">288</a>: “regular function” != <code>RegularInvocable</code></h2>
<p>Per the discussion in ericniebler/range-v3#499. <code>f</code> is an “operand” of the expression <code>invoke(f, args...)</code>, and both an “input” and (if mutable) an “output” thereof. <code>RegularInvocable</code>’s requirement that “The <code>invoke</code> function call expression shall be equality-preserving” is therefore not sufficient to ensure that the result of invoking <code>f</code> with <code>args...</code> depends only on the value of <code>args...</code>.</p>
<p>This fundamentally breaks equational reasoning in the algorithms, e.g., I cannot prove that the result of calling <code>sort(range, comp)</code> on a sequence is a sorted sequence if the comparator can be stateful. We need to restore the equivalence of regular functions and <code>RegularInvocable</code>s.</p>
<h3 id="proposed-resolution-8">Proposed Resolution:</h3>
<p>Modify [concepts.lib.callable.regularinvocable] to read:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> 1 The invoke function call expression shall be equality-preserving
<span class="ot">+  and shall not modify the function object or the arguments.</span>
   (4.1.1). [ Note: This requirement supersedes the annotation in the
   definition of Invocable. —end note ]</code></pre></div>
<h2 id="value_type-of-classes-with-member-element_type"><a href="https://github.com/ericniebler/stl2/issues/199">299</a>: <code>value_type</code> of classes with member <code>element_type</code></h2>
<p><code>element_type</code> in <code>std::pointer_traits</code> and in the smart pointers is the type of the object the pointer denotes, not the value type of that object (i.e., it can be a cv-qualified type). The specialization of <code>value_type</code> that uses <code>typename T::element_type</code> should strip cv-qualifiers from the type.</p>
<h3 id="proposed-resolution-9">Proposed Resolution:</h3>
<p>Modify [iterator.assoc.types.value_type] as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> [...]

 2 A Readable type has an associated value type that can be accessed with the value_type_t alias
   template.

     [...]
     template &lt;class T&gt;
       requires requires { typename T::value_type; }
     struct value_type&lt;T&gt;
       : enable_if&lt;is_object&lt;typename T::value_type&gt;::value, typename T::value_type&gt; { };

     template &lt;class T&gt;
       requires requires { typename T::element_type; }
     struct value_type&lt;T&gt;
<span class="st">-      : enable_if&lt;is_object&lt;typename T::element_type&gt;::value, typename T::element_type&gt; { };</span>
<span class="ot">+      : enable_if&lt;</span>
<span class="ot">+          is_object&lt;typename T::element_type&gt;::value,</span>
<span class="ot">+          remove_cv_t&lt;typename T::element_type&gt;&gt;</span>
<span class="ot">+    { };</span>

     template &lt;class T&gt;
       using value_type_t = typename value_type&lt;T&gt;::type;

 [...]

 5 When instantiated with a type I such that I::value_type is valid and denotes a type, [...]

 6 When instantiated with a type I such that I::element_type is valid and denotes a type,
<span class="st">-  value_type&lt;I&gt;::type names that type,</span>
<span class="ot">+  value_type&lt;I&gt;::type names the type remove_cv_t&lt;I::element_type&gt;,</span>
   unless it is not an object type (ISO/IEC 14882:2014 §3.9)
   in which case value_type&lt;I&gt; shall have no nested type type. [ Note: Smart pointers like
   shared_ptr&lt;int&gt; are Readable and have an associated value type. But a smart pointer like
   shared_ptr&lt;void&gt; is not Readable and has no associated value type.—end note ]</code></pre></div>
<h2 id="insert_iterator-and-ostreambuf_iterator-dont-properly-support-o-t"><a href="https://github.com/ericniebler/stl2/issues/302">302</a>: <code>insert_iterator</code> and <code>ostreambuf_iterator</code> don’t properly support <code>*o++ = t;</code></h2>
<p>See the discussion at <a href="https://github.com/CaseyCarter/cmcstl2/pull/60#issuecomment-265629745">CaseyCarter/cmcstl2#60 (comment)</a>. Both iterators internally store state that must be updated on each write. We made a blanket change to have output iterators’ <code>operator++(int)</code> return a copy instead of a reference after the discussion in #137 (and IIRC discussion with LWG at Kona) we broke <code>insert_iterator</code> and <code>ostreambuf_iterator</code>. The expression <code>*o++ = t</code> results in updating the state of the temporary immediately before throwing it on the floor. Later use of the iterator sees the “old” state and does terrible things.</p>
<p>The fix is to change the postfix increment of at least <code>insert_iterator</code> and <code>ostreambuf_iterator</code>, if not all of the output iterators specified in the TS, to again return by reference as in Standard C++.</p>
<h3 id="proposed-resolution-10">Proposed Resolution</h3>
<p>Adopt <a href="http://wg21.link/P0541">P0541</a>.</p>
<h2 id="incomplete-edit-to-inputiterator-to-support-proxy-iterators"><a href="https://github.com/ericniebler/stl2/issues/307">307</a>: Incomplete edit to <code>InputIterator</code> to support proxy iterators</h2>
<p>The proxy iterators paper (P0022) made essential changes to the <code>Readable</code> concept to support proxy iterators but neglected to make a similar necessary edit to <code>InputIterator</code>. The <code>InputIterator</code> concept is currently requiring that the expression <code>*ci</code>, where <code>ci</code> is a <code>const</code>-qualified <code>InputIterator</code> <code>I</code>, is convertible to <code>const value_type_t&lt;I&gt;&amp;</code>. This requirement is unsatisfiable for some proxy iterator types.</p>
<p>Consider a zip range with a reference type <code>pair&lt;unique_ptr&lt;int&gt;&amp;, int&amp;&gt;</code> and a value type <code>pair&lt;unique_ptr&lt;int&gt;, int&gt;</code>. There is no valid conversion from the former type to the latter since it would require copying a <code>unique_ptr</code>.</p>
<h3 id="proposed-resolution-11">Proposed resolution</h3>
<p>Adopt the wording in <a href="http://wg21.link/P0541">P0541</a>.</p>
<h2 id="missing-returns-clause-of-sortstable_sortpartial_sortnth_element"><a href="https://github.com/ericniebler/stl2/issues/309">309</a>: Missing “Returns:” clause of <code>sort</code>/<code>stable_sort</code>/<code>partial_sort</code>/<code>nth_element</code></h2>
<h3 id="proposed-resolution-12">Proposed Resolution</h3>
<p>Change <strong><code>sort</code></strong> ([sort]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;RandomAccessIterator I, Sentinel&lt;I&gt; S, class Comp = less&lt;&gt;,
     class Proj = identity&gt;
   requires Sortable&lt;I, Comp, Proj&gt;()
   I sort(I first, S last, Comp comp = Comp{}, Proj proj = Proj{});

 template &lt;RandomAccessRange Rng, class Comp = less&lt;&gt;, class Proj = identity&gt;
     requires Sortable&lt;iterator_t&lt;Rng&gt;, Comp, Proj&gt;()
   safe_iterator_t&lt;Rng&gt;
   sort(Rng&amp;&amp; rng, Comp comp = Comp{}, Proj proj = Proj{});

 1 Effects: Sorts the elements in the range [first,last).
 2 Complexity: O(N log(N)) (where N == last - first) comparisons.
<span class="ot">+3 Returns: last.</span></code></pre></div>
<p>Change <strong><code>stable_sort</code></strong> ([stable.sort]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;RandomAccessIterator I, Sentinel&lt;I&gt; S, class Comp = less&lt;&gt;,
     class Proj = identity&gt;
   requires Sortable&lt;I, Comp, Proj&gt;()
   I stable_sort(I first, S last, Comp comp = Comp{}, Proj proj = Proj{});

 template &lt;RandomAccessRange Rng, class Comp = less&lt;&gt;, class Proj = identity&gt;
     requires Sortable&lt;iterator_t&lt;Rng&gt;, Comp, Proj&gt;()
   safe_iterator_t&lt;Rng&gt;
   stable_sort(Rng&amp;&amp; rng, Comp comp = Comp{}, Proj proj = Proj{});

 1 Effects: Sorts the elements in the range [first,last).
 2 Complexity: It does at most N log2(N) (where N == last - first) comparisons; if enough extra
memory is available, it is N log(N).
 3 Remarks: Stable (ISO/IEC 14882:2014 §17.6.5.7).
<span class="ot">+4 Returns: last.</span></code></pre></div>
<p>Change <strong><code>partial_sort</code></strong> ([partial.sort]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;RandomAccessIterator I, Sentinel&lt;I&gt; S, class Comp = less&lt;&gt;,
     class Proj = identity&gt;
   requires Sortable&lt;I, Comp, Proj&gt;()
   I partial_sort(I first, I middle, S last, Comp comp = Comp{}, Proj proj = Proj{});

 template &lt;RandomAccessRange Rng, class Comp = less&lt;&gt;, class Proj = identity&gt;
     requires Sortable&lt;iterator_t&lt;Rng&gt;, Comp, Proj&gt;()
   safe_iterator_t&lt;Rng&gt;
   partial_sort(Rng&amp;&amp; rng, iterator_t&lt;Rng&gt; middle, Comp comp = Comp{}, Proj proj = Proj{});
 1 Effects: Places the first middle - first sorted elements from the range [first,last) into the range
[first,middle). The rest of the elements in the range [middle,last) are placed in an unspecified
order.
 2 Complexity: It takes approximately (last - first) * log(middle - first) comparisons.
<span class="ot">+3 Returns: last.</span></code></pre></div>
<p>Change Nth element ([alg.nth.element]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;RandomAccessIterator I, Sentinel&lt;I&gt; S, class Comp = less&lt;&gt;,
     class Proj = identity&gt;
   requires Sortable&lt;I, Comp, Proj&gt;()
   I nth_element(I first, I nth, S last, Comp comp = Comp{}, Proj proj = Proj{});

 template &lt;RandomAccessRange Rng, class Comp = less&lt;&gt;, class Proj = identity&gt;
     requires Sortable&lt;iterator_t&lt;Rng&gt;, Comp, Proj&gt;()
   safe_iterator_t&lt;Rng&gt;
   nth_element(Rng&amp;&amp; rng, iterator_t&lt;Rng&gt; nth, Comp comp = Comp{}, Proj proj = Proj{});

 1 After nth_element the element in the position pointed to by nth is the element that would be in that
 position if the whole range were sorted, unless nth == last. Also for every iterator i in the range [
 first,nth) and every iterator j in the range [nth,last) it holds that: invoke(comp, invoke(proj,
 *j), invoke(proj, *i)) == false.
 2 Complexity: Linear on average.
<span class="ot">+3 Returns: last.</span></code></pre></div>
<h2 id="common-and-commonreference-should-use-convertibleto-to-test-for-implicit-convertibility"><a href="https://github.com/ericniebler/stl2/issues/311">311</a>: <code>Common</code> and <code>CommonReference</code> should use <code>ConvertibleTo</code> to test for implicit convertibility</h2>
<p><strong>Issue # 1:</strong> the expressions <code>common_type_t&lt;T, U&gt;(t())</code> and <code>common_reference_t&lt;T, U&gt;(t())</code> in the <code>Common</code> and <code>CommonReference</code> concepts could potentially be interpreted as function-style casts depending on the types involved, which could amount to <code>reinterpret_cast</code>s. That was not the intention.</p>
<p>The intention was to test that expressions of type <code>T</code> and <code>U</code> can be converted to the common type (or the common reference). The fix is to simply test that requirement instead with <code>ConvertibleTo</code>.</p>
<p><strong>Issue # 2:</strong> One of the potential uses for <code>common_</code>(<code>type</code>|<code>reference</code>) is to have a way to declare monomorphic functions that satisfy e.g., <code>IndirectRelation</code> for use with the std:: algorithms. Indeed, <code>IndirectReference</code> requires the invocable to be callable with common-reference parameters. Consider:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span class="kw">auto</span> rng = view::zip(vec1, vec2); <span class="co">// from range-v3</span>
<span class="kw">using</span> R = iter_common_reference_t&lt;iterator_t&lt;<span class="kw">decltype</span>(rng)&gt;&gt;;
<span class="co">// Note: R might be different than decltype(*begin(rng)) for, e.g. a proxy iterator.</span>
<span class="kw">auto</span> pred = [](R a, R b) { <span class="kw">return</span> a &lt; b; };
ranges::sort( rng, pred );</code></pre></div>
<p>Right now all the higher order functions are more or less broken because they just do <code>pred(*here, *there)</code>. For an iterator whose reference type is explicitly-but-not-implicitly convertible to the common reference type, the call will pass the concept check but fail to instantiate. That’s Bad.</p>
<p>As above, the fix is to change <code>Common</code> and <code>CommonReference</code> to use <code>ConvertibleTo</code>. That requires <em>implicit</em> convertibility, rather than the explicit convertibility that was being checked with the function-style cast.</p>
<p><em>Note:</em> The underlying traits <code>common_type</code> and <code>common_reference</code> only require explicit convertibility. We think it’s fine, indeed essential for generic code, for the concepts to be more strict than the underlying type traits.</p>
<h3 id="proposed-resolution-13">Proposed Resolution</h3>
<p>Change the definition of <code>CommonReference</code> in [concepts.lib.corelang.commonref]/1 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T, class U&gt;
 concept bool CommonReference() {
<span class="st">-  return requires(T (&amp;t)(), U (&amp;u)()) {</span>
<span class="st">-    typename common_reference_t&lt;T, U&gt;;</span>
<span class="st">-    typename common_reference_t&lt;U, T&gt;;</span>
<span class="st">-    requires Same&lt;common_reference_t&lt;T, U&gt;, common_reference_t&lt;U, T&gt;&gt;();</span>
<span class="st">-    common_reference_t&lt;T, U&gt;(t());</span>
<span class="st">-    common_reference_t&lt;T, U&gt;(u());</span>
<span class="st">-  };</span>
<span class="ot">+  return</span>
<span class="ot">+    Same&lt;common_reference_t&lt;T, U&gt;, common_reference_t&lt;U, T&gt;&gt;() &amp;&amp;</span>
<span class="ot">+    ConvertibleTo&lt;T, common_reference_t&lt;T, U&gt;&gt;() &amp;&amp;</span>
<span class="ot">+    ConvertibleTo&lt;U, common_reference_t&lt;T, U&gt;&gt;();</span>
 }</code></pre></div>
<p><em>Note:</em> this removes the <code>typename common_reference_t...</code> constraints since they are superfluous.</p>
<p>Change the definition of <code>Common</code> in [concepts.lib.corelang.common]/1 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T, class U&gt;
 concept bool Common() {
<span class="st">-   return CommonReference&lt;const T&amp;, const U&amp;&gt;() &amp;&amp;</span>
<span class="st">-    requires(T (&amp;t)(), U (&amp;u)()) {</span>
<span class="st">-    typename common_type_t&lt;T, U&gt;;</span>
<span class="st">-    typename common_type_t&lt;U, T&gt;;</span>
<span class="st">-    requires Same&lt;common_type_t&lt;U, T&gt;, common_type_t&lt;T, U&gt;&gt;();</span>
<span class="st">-    common_type_t&lt;T, U&gt;(t());</span>
<span class="st">-    common_type_t&lt;T, U&gt;(u());</span>
<span class="st">-    requires CommonReference&lt;add_lvalue_reference_t&lt;common_type_t&lt;T, U&gt;&gt;,</span>
<span class="st">-                             common_reference_t&lt;add_lvalue_reference_t&lt;const T&gt;,</span>
<span class="st">-                                                add_lvalue_reference_t&lt;const U&gt;&gt;&gt;();</span>
<span class="st">- };</span>
<span class="ot">+ return</span>
<span class="ot">+   Same&lt;common_type_t&lt;T, U&gt;, common_type_t&lt;U, T&gt;&gt;() &amp;&amp;</span>
<span class="ot">+   ConvertibleTo&lt;T, common_type_t&lt;T, U&gt;&gt;() &amp;&amp;</span>
<span class="ot">+   ConvertibleTo&lt;U, common_type_t&lt;T, U&gt;&gt;() &amp;&amp;</span>
<span class="ot">+   CommonReference&lt;add_lvalue_reference_t&lt;const T&gt;,</span>
<span class="ot">+                   add_lvalue_reference_t&lt;const U&gt;&gt;() &amp;&amp;</span>
<span class="ot">+   CommonReference&lt;add_lvalue_reference_t&lt;common_type_t&lt;T, U&gt;&gt;,</span>
<span class="ot">+                   common_reference_t&lt;add_lvalue_reference_t&lt;const T&gt;,</span>
<span class="ot">+                                      add_lvalue_reference_t&lt;const U&gt;&gt;&gt;()</span>
}</code></pre></div>
<p><em>Note:</em> this removes the <code>typename common_type_t...</code> constraints since they are superfluous. It also fixes a bug where the original <code>Common</code> definition was trying to form the types <code>const T&amp;</code> and <code>const U&amp;</code>. That fails for <em>cv</em> <code>void</code>. We would like <code>Common&lt;void, void&gt;()</code> to be <code>true</code>.</p>
<h2 id="copy_if-returns-clause-incorrect"><a href="https://github.com/ericniebler/stl2/issues/316">316</a>: <code>copy_if</code> “Returns” clause incorrect</h2>
<p>It’s currently specified to return <code>{last, result + (last - first)}</code>, the second part of which makes no sense since fewer than <code>last - first</code> elements may be copied.</p>
<h3 id="proposed-resolution-14">Proposed Resolution:</h3>
<p>Add a new paragraph before [alg.copy]/8 and change the following paragraphs to read:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;InputIterator I, Sentinel&lt;I&gt; S, WeaklyIncrementable O, class Proj = identity,
     IndirectPredicate&lt;projected&lt;I, Proj&gt;&gt; Pred&gt;
   requires IndirectlyCopyable&lt;I, O&gt;()
   tagged_pair&lt;tag::in(I), tag::out(O)&gt;
     copy_if(I first, S last, O result, Pred pred, Proj proj = Proj{});

 template &lt;InputRange Rng, WeaklyIncrementable O, class Proj = identity,
     IndirectPredicate&lt;projected&lt;iterator_t&lt;Rng&gt;, Proj&gt;&gt; Pred&gt;
   requires IndirectlyCopyable&lt;iterator_t&lt;Rng&gt;, O&gt;()
   tagged_pair&lt;tag::in(safe_iterator_t&lt;Rng&gt;), tag::out(O)&gt;
     copy_if(Rng&amp;&amp; rng, O result, Pred pred, Proj proj = Proj{});

<span class="ot">+-?- Let N be the number of iterators i in the range [first,last) for which the condition</span>
<span class="ot">+    invoke(pred, invoke(proj, *i)) holds.</span>
<span class="st">-  8 Requires: The ranges [first,last) and [result,result + (last - first)) shall not overlap.</span>
<span class="ot">+  8 Requires: The ranges [first,last) and [result,result + N) shall not overlap.</span>
   9 Effects: Copies all of the elements referred to by the iterator i in the range [first,last)
     for which invoke(pred, invoke(proj, *i)) is true.
<span class="st">- 10 Returns: {last, result + (last - first)}.</span>
<span class="ot">+ 10 Returns: {last, result + N}.</span>
  11 Complexity: Exactly last - first applications of the corresponding predicate and projection.
  12 Remarks: Stable (ISO/IEC 14882:2014 §17.6.5.7).</code></pre></div>
<h2 id="is_nothrow_indirectly_movable-could-be-true-even-when-iter_move-is-noexceptfalse"><a href="https://github.com/ericniebler/stl2/issues/317">317</a>: <code>is_nothrow_indirectly_movable</code> could be <code>true</code> even when <code>iter_move</code> is <code>noexcept(false)</code></h2>
<p><code>is_nothrow_indirectly_movable</code> is currently defined as follows:</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;
    requires IndirectlyMovable&lt;In, Out&gt;()
<span class="kw">struct</span> is_nothrow_indirectly_movable&lt;In, Out&gt; :
  std::integral_constant&lt;<span class="dt">bool</span>,
    is_nothrow_constructible&lt;value_type_t&lt;In&gt;, rvalue_reference_t&lt;In&gt;&gt;::value &amp;&amp;
    is_nothrow_assignable&lt;value_type_t&lt;In&gt; &amp;, rvalue_reference_t&lt;In&gt;&gt;::value &amp;&amp;
    is_nothrow_assignable&lt;reference_t&lt;Out&gt;, rvalue_reference_t&lt;In&gt;&gt;::value &amp;&amp;
    is_nothrow_assignable&lt;reference_t&lt;Out&gt;, value_type_t&lt;In&gt;&gt;::value&gt;
{ };</code></pre></div>
<p>This doesn’t take into account that <code>iter_move(declval&lt;In&amp;&gt;())</code> could be <code>noexcept(false)</code>. That makes it misleading at best. (Never mind the fact that <code>iter_move</code> should not ever be <code>noexcept(false)</code>).</p>
<p><code>is_nothrow_indirectly_movable</code> should be defined in terms of <code>iter_move</code>.</p>
<h3 id="proposed-resolution-15">Proposed resolution</h3>
<p>Change the definition of <code>is_nothrow_indirectly_movable</code> in [iterator.traits]/9 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class In, class Out&gt;
     requires IndirectlyMovable&lt;In, Out&gt;()
 struct is_nothrow_indirectly_movable&lt;In, Out&gt; :
   std::integral_constant&lt;bool,
<span class="ot">+    noexcept(ranges::iter_move(declval&lt;In&amp;&gt;())) &amp;&amp;</span>
     is_nothrow_constructible&lt;value_type_t&lt;In&gt;, rvalue_reference_t&lt;In&gt;&gt;::value &amp;&amp;
     is_nothrow_assignable&lt;value_type_t&lt;In&gt; &amp;, rvalue_reference_t&lt;In&gt;&gt;::value &amp;&amp;
     is_nothrow_assignable&lt;reference_t&lt;Out&gt;, rvalue_reference_t&lt;In&gt;&gt;::value &amp;&amp;
     is_nothrow_assignable&lt;reference_t&lt;Out&gt;, value_type_t&lt;In&gt;&gt;::value&gt;
 { };</code></pre></div>
<h2 id="common_iteratoroperator--does-not-specify-its-return-type"><a href="https://github.com/ericniebler/stl2/issues/318">318</a>: <code>common_iterator::operator-&gt;</code> does not specify its return type</h2>
<p>Its return type is listed as “<em>see below</em>”, and its <em>Effects:</em> clause describes the return values, but we should be more explicit about what the actual return type is in all cases.</p>
<h3 id="proposed-resolution-16">Proposed Resolution</h3>
<p>After [common.iter.op.star]/2 add a subsection title “<strong><code>common_iterator::operator-&gt;</code></strong>” with stable name [common.iter.op.ref]. Then change the following specification of <code>common_iterator::operator-&gt;</code> as follows.</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-see below operator-&gt;() const requires Readable&lt;I&gt;();</span>
<span class="ot">+decltype(auto) operator-&gt;() const requires Readable&lt;I&gt;();</span>

 1 Requires: !is_sentinel

<span class="st">-2 Effects: Given an object i of type I</span>
<span class="ot">+2 Effects: Equivalent to:</span>

<span class="st">-(2.1) — if I is a pointer type or if the expression i.operator-&gt;() is well-formed,</span>
<span class="st">-        this function returns iter.</span>
<span class="ot">+(2.1) — return iter; if I is a pointer type or if the expression iter.operator-&gt;() is</span>
<span class="ot">+        well-formed.</span>

<span class="st">-(2.2) — Otherwise, if the expression *iter is a glvalue, this function is equivalent</span>
<span class="st">-        to return addressof(*iter);</span>
<span class="ot">+(2.2) — Otherwise, if the expression *iter is a glvalue:</span>

<span class="ot">+       auto&amp;&amp; tmp = *iter;</span>
<span class="ot">+       return addressof(tmp);</span>

<span class="st">-(2.3) — Otherwise, this function returns a proxy object of an unspecified type</span>
<span class="st">-        equivalent to the following:</span>
<span class="ot">+(2.3) — Otherwise, return proxy(*iter); where proxy is the exposition-only class:</span>

     class proxy {
      value_type_t&lt;I&gt; keep_;
      proxy(reference_t&lt;I&gt;&amp;&amp; x)
        : keep_(std::move(x)) {}
     public:
       const value_type_t&lt;I&gt;* operator-&gt;() const {
          return addressof(keep_);
       }
    };</code></pre></div>
<h2 id="concepts-that-use-type-traits-are-inadvertently-subsuming-them"><a href="https://github.com/ericniebler/stl2/issues/321">321</a>: Concepts that use type traits are inadvertently subsuming them</h2>
<p>Implementors may want the freedom to implement the concepts directly in terms of the same compiler intrinsics that are used to implement the traits. However, by specifying the concepts directly in terms of the type traits, we create a subsumption relationship between the concept and the trait. Implementations no longer have the freedom to <em>not</em> use the library trait because that has observable effects on overload resolution.</p>
<p>We propose eliminating the subsumption relationships, thereby giving implementors the freedom to innovate under the as-if rule.</p>
<h3 id="proposed-resolution-17">Proposed Resolution</h3>
<p>Change [concepts.lib.corelang.same] as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T, class U&gt;
 concept bool Same() {
<span class="st">-  return see below ;</span>
<span class="ot">+  return is_same&lt;T, U&gt;::value; // see below</span>
 }

<span class="st">-1 Same&lt;T, U&gt;() is satisfied if and only if T and U denote the same</span>
<span class="st">-  type.</span>
<span class="ot">+1 There need not be any subsumption relationship between Same&lt;T, U&gt;() and</span>
<span class="ot">+  is_same&lt;T, U&gt;::value.</span>

 2 Remarks: For the purposes of constraint checking, Same&lt;T, U&gt;()
   implies Same&lt;U, T&gt;().</code></pre></div>
<p>Change [concepts.lib.corelang.derived] as suggested in #255.</p>
<p>Change [concepts.lib.corelang.convertibleto] as suggested in #167.</p>
<p>Change [concepts.lib.corelang.integral] as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T&gt;
 concept bool Integral() {
<span class="st">-  return is_integral&lt;T&gt;::value;</span>
<span class="ot">+  return is_integral&lt;T&gt;::value; // see below</span>
 }

<span class="ot">+1 There need not be any subsumption relationship between Integral&lt;T&gt;() and</span>
<span class="ot">+  is_integral&lt;T&gt;::value.</span></code></pre></div>
<p>Change [concepts.lib.corelang.signedintegral] as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T&gt;
 concept bool SignedIntegral() {
<span class="st">-  return Integral&lt;T&gt;() &amp;&amp; is_signed&lt;T&gt;::value;</span>
<span class="ot">+  return Integral&lt;T&gt;() &amp;&amp; is_signed&lt;T&gt;::value; // see below</span>
 }

<span class="ot">+1 There need not be any subsumption relationship between SignedIntegral&lt;T&gt;()</span>
<span class="ot">+  and is_signed&lt;T&gt;::value.</span></code></pre></div>
<h2 id="argument-deduction-constraints-are-specified-incorrectly"><a href="https://github.com/ericniebler/stl2/issues/330">330</a>: Argument deduction constraints are specified incorrectly</h2>
<p>See #155 for detailed discussion, but basically we’ve been operating under the faulty assumption that the following:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">requires(<span class="dt">const</span> T&amp; t) {  {t} -&gt; Same&lt;<span class="dt">const</span> T&amp;&gt;; }</code></pre></div>
<p>was trivially satisfied. It is not. Argument deduction constraints are handled as if the placeholder were made the argument type of an invented function <code>f</code>, like <code>void f(Same&lt;const T&amp;&gt;)</code>, and then a call were made like <code>f(t)</code>. That causes the type of <code>t</code> to decay.</p>
<p>This should instead be written as:</p>
<div class="sourceCode"><pre class="sourceCode cpp"><code class="sourceCode cpp">requires(<span class="dt">const</span> T&amp; t) {  {t} -&gt; Same&lt;<span class="dt">const</span> T&amp;&gt;&amp;&amp;; }</code></pre></div>
<p>That prevents argument decay from happening, which recovers the value category information.</p>
<p>We need to review and amend <em>all</em> the definitions and uses of concepts in the ranges ts.</p>
<p>(In our defense, this slipped through because early concepts implementations didn’t do argument deduction constraints, so we invented a workaround, and the workaround was buggy because we didn’t understand the model.)</p>
<h3 id="proposed-resolution-18">Proposed Resolution:</h3>
<p>Update section “Concept <code>Assignable</code>” ([concepts.lib.corelang.assignable]) and “Concept <code>Destructible</code>” ([concepts.lib.object.destructible]) as specified in <a href="http://wiki.edg.com/pub/Wg21kona2017/LibraryWorkingGroup/D0547R1.html">P0547R1</a>.</p>
<p>Update sections “Concept <code>Boolean</code>” [concepts.lib.compare.boolean]), “Concept <code>EqualityComparable</code>” ([concepts.lib.compare.equalitycomparable]), “Concept <code>StrictTotallyOrdered</code>” ([concepts.lib.compare.stricttotallyordered]) as specified in #155.</p>
<p>Update section “Concept <code>Readable</code>” ([iterators.readable]) as follows (also fixes #339):</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class I&gt;
concept bool Readable() {
<span class="st">- return Movable&lt;I&gt;() &amp;&amp; DefaultConstructible&lt;I&gt;() &amp;&amp;</span>
<span class="st">-   requires(const I&amp; i) {</span>
<span class="ot">+ return requires {</span>
    typename value_type_t&lt;I&gt;;
    typename reference_t&lt;I&gt;;
    typename rvalue_reference_t&lt;I&gt;;
<span class="st">-   { *i } -&gt; Same&lt;reference_t&lt;I&gt;&gt;;</span>
<span class="st">-   { ranges::iter_move(i) } -&gt; Same&lt;rvalue_reference_t&lt;I&gt;&gt;;</span>
  } &amp;&amp;
  CommonReference&lt;reference_t&lt;I&gt;, value_type_t&lt;I&gt;&amp;&gt;() &amp;&amp;
  CommonReference&lt;reference_t&lt;I&gt;, rvalue_reference_t&lt;I&gt;&gt;() &amp;&amp;
  CommonReference&lt;rvalue_reference_t&lt;I&gt;, const value_type_t&lt;I&gt;&amp;&gt;();
}</code></pre></div>
<p>Change section “Concept <code>WeaklyIncrementable</code>” ([iterators.weaklyincrementable]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class I&gt;
concept bool WeaklyIncrementable() {
  return Semiregular&lt;I&gt;() &amp;&amp;
  requires(I i) {
    typename difference_type_t&lt;I&gt;;
    requires SignedIntegral&lt;difference_type_t&lt;I&gt;&gt;();
<span class="st">-   { ++i } -&gt; Same&lt;I&amp;&gt;; // not required to be equality preserving</span>
<span class="ot">+   { ++i } -&gt; Same&lt;I&gt;&amp;; // not required to be equality preserving</span>
    i++; // not required to be equality preserving
  };
}</code></pre></div>
<p>Change section “Concept <code>Incrementable</code>” ([iterators.incrementable]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class I&gt;
concept bool Incrementable() {
  return Regular&lt;I&gt;() &amp;&amp;
    WeaklyIncrementable&lt;I&gt;() &amp;&amp;
    requires(I i) {
<span class="st">-     { i++ } -&gt; Same&lt;I&gt;; // not required to be equality preserving</span>
<span class="ot">+     { i++ } -&gt; Same&lt;I&gt;&amp;&amp;; // not required to be equality preserving</span>
    };
}</code></pre></div>
<p>Change section “Concept <code>SizedSentinel</code>” ([iterators.sizedsentinel]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class S, class I&gt;
concept bool SizedSentinel() {
  return Sentinel&lt;S, I&gt;() &amp;&amp;
    !disable_sized_sentinel&lt;remove_cv_t&lt;S&gt;, remove_cv_t&lt;I&gt;&gt; &amp;&amp;
    requires(const I&amp; i, const S&amp; s) {
<span class="st">-     { s - i } -&gt; Same&lt;difference_type_t&lt;I&gt;&gt;;</span>
<span class="st">-     { i - s } -&gt; Same&lt;difference_type_t&lt;I&gt;&gt;;</span>
<span class="ot">+     { s - i } -&gt; Same&lt;difference_type_t&lt;I&gt;&gt;&amp;&amp;;</span>
<span class="ot">+     { i - s } -&gt; Same&lt;difference_type_t&lt;I&gt;&gt;&amp;&amp;;</span>
    };
}</code></pre></div>
<p>Take the definition of concept <code>InputIterator</code> ([iterators.input]) from <a href="http://wg21.link/P0541">P0541</a>.</p>
<p>Change section “Concept <code>BidirectionalIterator</code>” ([iterators.bidirectional]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class I&gt;
concept bool BidirectionalIterator() {
  return ForwardIterator&lt;I&gt;() &amp;&amp;
    DerivedFrom&lt;iterator_category_t&lt;I&gt;, bidirectional_iterator_tag&gt;() &amp;&amp;
    requires(I i) {
<span class="st">-     { --i } -&gt; Same&lt;I&amp;&gt;;</span>
<span class="st">-     { i-- } -&gt; Same&lt;I&gt;;</span>
<span class="ot">+     { --i } -&gt; Same&lt;I&gt;&amp;;</span>
<span class="ot">+     { i-- } -&gt; Same&lt;I&gt;&amp;&amp;;</span>
    };
}</code></pre></div>
<p>Change section “Concept <code>RandomAccessIterator</code>” ([iterators.random.access]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class I&gt;
concept bool RandomAccessIterator() {
  return BidirectionalIterator&lt;I&gt;() &amp;&amp;
    DerivedFrom&lt;iterator_category_t&lt;I&gt;, random_access_iterator_tag&gt;() &amp;&amp;
    StrictTotallyOrdered&lt;I&gt;() &amp;&amp;
    SizedSentinel&lt;I, I&gt;() &amp;&amp;
    requires(I i, const I j, const difference_type_t&lt;I&gt; n) {
<span class="st">-     { i += n } -&gt; Same&lt;I&amp;&gt;;</span>
<span class="st">-     { j + n } -&gt; Same&lt;I&gt;;</span>
<span class="st">-     { n + j } -&gt; Same&lt;I&gt;;</span>
<span class="st">-     { i -= n } -&gt; Same&lt;I&amp;&gt;;</span>
<span class="st">-     { j - n } -&gt; Same&lt;I&gt;;</span>
<span class="st">-     { j[n] } -&gt; Same&lt;reference_t&lt;I&gt;&gt;;</span>
<span class="ot">+     { i += n } -&gt; Same&lt;I&gt;&amp;;</span>
<span class="ot">+     { j + n } -&gt; Same&lt;I&gt;&amp;&amp;;</span>
<span class="ot">+     { n + j } -&gt; Same&lt;I&gt;&amp;&amp;;</span>
<span class="ot">+     { i -= n } -&gt; Same&lt;I&gt;&amp;;</span>
<span class="ot">+     { j - n } -&gt; Same&lt;I&gt;&amp;&amp;;</span>
<span class="ot">+     j[n];</span>
<span class="ot">+     requires Same&lt;decltype(j[n]), reference_t&lt;I&gt;&gt;();</span>
    };
}</code></pre></div>
<p>Change section “Concept <code>UniformRandomNumberGenerator</code>” ([rand.req.urng]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff">template &lt;class G&gt;
concept bool UniformRandomNumberGenerator() {
<span class="st">- return requires(G g) {</span>
<span class="st">-   { g() } -&gt; UnsignedIntegral; // not required to be equality preserving</span>
<span class="st">-   { G::min() } -&gt; Same&lt;result_of_t&lt;G&amp;()&gt;&gt;;</span>
<span class="st">-   { G::max() } -&gt; Same&lt;result_of_t&lt;G&amp;()&gt;&gt;;</span>
<span class="ot">+ return Invocable&lt;G&amp;&gt;() &amp;&amp;</span>
<span class="ot">+   UnsignedIntegral&lt;result_of_t&lt;G&amp;()&gt;&gt;() &amp;&amp;</span>
<span class="ot">+   requires {</span>
<span class="ot">+     { G::min() } -&gt; Same&lt;result_of_t&lt;G&amp;()&gt;&gt;&amp;&amp;;</span>
<span class="ot">+     { G::max() } -&gt; Same&lt;result_of_t&lt;G&amp;()&gt;&gt;&amp;&amp;;</span>
    };
}</code></pre></div>
<h2 id="reorder-requirements-in-concept-iterator"><a href="https://github.com/ericniebler/stl2/issues/331">331</a>: Reorder requirements in concept <code>Iterator</code></h2>
<p>When passing a <code>std::vector&lt;MoveOnly&gt;</code> to <code>sort</code>, overload resolution causes the evaluation of <code>Iterator&lt;std::vector&lt;MoveOnly&gt;&gt;</code>, which tests the vector type for assignability. Vectors of move-only types are <em>not</em> assignable, but their assignment operators are not properly constrained. That leads to a hard error rather than a concept check failure.</p>
<p>The problem can be mostly avoided by testing for dereferenceability <em>first</em> in concept <code>Iterator</code>, as shows in the Proposed Resolution below.</p>
<h3 id="proposed-resolution-19">Proposed Resolution</h3>
<p>Change concept <code>Iterator</code> ([iterators.iterator]) as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class I&gt;
 concept bool Iterator() {
<span class="st">-   return WeaklyIncrementable&lt;I&gt;() &amp;&amp;</span>
<span class="st">-     requires(I i) {</span>
<span class="st">-       { *i } -&gt; auto&amp;&amp;; // Requires: i is dereferenceable</span>
<span class="st">-     };</span>
<span class="ot">+   return requires(I i) {</span>
<span class="ot">+     { *i } -&gt; auto&amp;&amp;; // Requires: i is dereferenceable</span>
<span class="ot">+   } &amp;&amp; WeaklyIncrementable&lt;I&gt;();</span>
 }</code></pre></div>
<h2 id="us-2-006-2.1.1-update-ranged-for-loop-wording"><a href="https://github.com/ericniebler/stl2/issues/345">345</a>: US 2 (006): 2.1.1: Update ranged-for-loop wording</h2>
<p>This is US national body comment 2 on the PDTS.</p>
<h3 id="editorial-comment">Editorial Comment</h3>
<p>The wording no longer matches the more thoroughly reviewed form in the C++17 Working Draft.</p>
<h3 id="proposed-change">Proposed Change</h3>
<p>Entirely replace this wording with the proposed wording for C++17.</p>
<h3 id="proposed-resolution-20">Proposed Resolution</h3>
<p>Accept the wording changes in P0662R0 “Wording for Ranges TS Issue 234 / US-2.”</p>
<h2 id="jp-1-015-6.9.2.21-range-doesnt-require-begin"><a href="https://github.com/ericniebler/stl2/issues/354">354</a>: JP 1 (015): 6.9.2.2/1: Range doesn’t require begin</h2>
<p>This is JP national body comment 1 on the PDTS.</p>
<h3 id="editorial-comment-1">Editorial Comment</h3>
<p><code>ranges::begin(t)</code> is missing in “requires” for <code>Range</code>.</p>
<h3 id="proposed-change-1">Proposed Change</h3>
<p>Add <code>ranges::begin(t);</code> to “requires”.</p>
<h3 id="proposed-resolution-21">Proposed Resolution</h3>
<p>Modify the definition of the <code>Range</code> concept in [ranges.range] as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"> template &lt;class T&gt;
 concept bool Range() {
   return requires(T&amp;&amp; t) {
<span class="ot">+    ranges::begin(t);</span>
     ranges::end(t);
   };
 }</code></pre></div>
<h2 id="jp-3-018-7.4.45-transform-does-not-include-projection-calls-in-complexity"><a href="https://github.com/ericniebler/stl2/issues/357">357</a>: JP 3 (018): 7.4.4/5: transform does not include projection calls in Complexity</h2>
<p>This is JP national body comment 3 on the PDTS.</p>
<h3 id="editorial-comment-2">Editorial Comment</h3>
<p>Lack of consideration about projection in Complexity.</p>
<h3 id="proposed-change-2">Proposed Change</h3>
<p>Add a description about projection.</p>
<h3 id="proposed-resolution-22">Proposed Resolution</h3>
<p>Modify [alg.transform]/5 as follows:</p>
<div class="sourceCode"><pre class="sourceCode diff"><code class="sourceCode diff"><span class="st">-Complexity: Exactly N applications of op or binary_op.</span>
<span class="ot">+Complexity: Exactly N applications of the projection(s) and of op or binary_op.</span></code></pre></div>
<div id="refs" class="references">

</div>
</body>
</html>
