<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta charset="utf-8">
<title>C++ Standard Library Issues to be moved in Virtual Plenary, Oct. 2021</title>
<style type="text/css">
  p {text-align:justify}
  li {text-align:justify}
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table {border-collapse: collapse;}
</style>
</head>
<body>
<h1>C++ Standard Library Issues to be moved in Virtual Plenary, Oct. 2021</h1>
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">P2450R0</td>
</tr>
<tr>
<td align="left">Date:</td>
<td align="left"><p>2021-09-24</p>
</td>
</tr>
<tr>
<td align="left">Audience:</td>
<td align="left">WG21</td>
</tr>
<tr>
<td align="left">Reply to:</td>
<td align="left">Jonathan Wakely &lt;<a href="mailto:lwgchair@gmail.com">lwgchair@gmail.com</a>&gt;</td>
</tr>
</table>
<ul>
<li><a href="#tentatively_ready">Tentatively Ready Issues</a></li>
</ul>
<h2 id="tentatively_ready">Tentatively Ready Issues</h2>
<hr>
<h3><a name="2191" href="https://cplusplus.github.io/LWG/lwg-active.html#2191">2191</a>. Incorrect specification of <tt>match_results(match_results&amp;&amp;)</tt></h3>
<p><b>Section:</b> 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Pete Becker <b>Opened:</b> 2012-10-02 <b>Last modified:</b> 2021-07-17</p>
<p><b>Priority: </b>4
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#re.results.const">issues</a> in [re.results.const].</p>
<p><b>Discussion:</b></p>

<p>
30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a>/3: "Move-constructs an object of class <tt>match_results</tt> satisfying the same 
postconditions as Table 141."
</p>
<p>
Table 141 lists various member functions and says that their results should be the results of the corresponding member 
function calls on <tt>m</tt>. But <tt>m</tt> has been moved from, so the actual requirement ought to be based on the 
value that <tt>m</tt> had <em>before</em> the move construction, not on <tt>m</tt> itself.
</p>
<p>
In addition to that, the requirements for the copy constructor should refer to Table 141.
<p/>
<u>Ganesh</u>:
<p/>
Also, the requirements for move-assignment should refer to Table 141. Further it seems as if in Table 141 all phrases of
"for all integers <tt>n &lt; m.size()</tt>" should be replaced by "for all <em>unsigned</em> integers 
<tt>n &lt; m.size()</tt>".
</p>

<p><i>[2019-03-26; Daniel comments and provides wording]</i></p>

<p>
The previous Table 141 (Now Table 128 in <a href="https://wg21.link/n4810">N4810</a>) has been modified to cover now
the effects of move/copy constructors and move/copy assignment operators. Newly added wording now clarifies that for
move operations the corresponding values refer to the values of the move source <em>before</em> the operation has started.
<p/>
Re Ganesh's proposal: Note that no further wording is needed for the move-assignment operator, because in the current 
working draft the move-assignment operator's <i>Effects:</i> element refers already to Table 128. The suggested clarification
of <em>unsigned</em> integers has been implemented by referring to <em>non-negative</em> integers instead.
<p/>
Upon suggestion from Casey, the wording also introduces <i>Ensures:</i> elements that refer to Table 128 and as drive-by fix
eliminates a "<i>Throws:</i> Nothing." element from a <tt>noexcept</tt> function.
</p>

<strong>Previous resolution [SUPERSEDED]:</strong>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4810">N4810</a>.</p>

<ol>
<li><p>Add a new paragraph at the beginning of 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> as indicated:</p>

<blockquote><p>
<ins>-?- Table 128 lists the postconditions of <tt>match_results</tt> copy/move constructors and copy/move assignment
operators. For move operations, the results of the expressions depending on the parameter <tt>m</tt> denote the values
they had before the respective function calls.</ins>
</p></blockquote>

</li>

<li><p>Modify 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> as indicated:</p>

<blockquote>
<pre>
match_results(const match_results&amp; m);
</pre>
<blockquote>
<p>
-3- <i>Effects:</i> Constructs <del>an object of class <tt>match_results</tt>, as</del> a copy of <tt>m</tt>.
<p/>
<ins>-?- <i>Ensures:</i> As indicated in Table 128.</ins>
</p>
</blockquote>
<pre>
match_results(match_results&amp;&amp; m) noexcept;
</pre>
<blockquote>
<p>
-4- <i>Effects:</i> Move constructs <del>an object of class <tt>match_results</tt></del> from <tt>m</tt> 
<del>satisfying the same postconditions as Table 128. Additionally</del>, the stored <tt>Allocator</tt> value 
is move constructed from <tt>m.get_allocator()</tt>.
<p/>
<ins>-?- <i>Ensures:</i> As indicated in Table 128.</ins>
<p/>
<del>-5- <i>Throws:</i> Nothing.</del>
</p>
</blockquote>
<pre>
match_results&amp; operator=(const match_results&amp; m);
</pre>
<blockquote>
<p>
-6- <i>Effects:</i> Assigns <tt>m</tt> to <tt>*this</tt>. <del>The postconditions of this function are indicated 
in Table 128.</del>
<p/>
<ins>-?- <i>Ensures:</i> As indicated in Table 128.</ins>
</p>
</blockquote>
<pre>
match_results&amp; operator=(match_results&amp;&amp; m);
</pre>
<blockquote>
<p>
-7- <i>Effects:</i> Move<del>-</del><ins> </ins>assigns <tt>m</tt> to <tt>*this</tt>. <del>The postconditions of 
this function are indicated in Table 128.</del>
<p/>
<ins>-?- <i>Ensures:</i> As indicated in Table 128.</ins>
</p>
</blockquote>
</blockquote>

</li>

<li><p>Modify 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a>, Table 128 &mdash; "<tt>match_results</tt> assignment operator effects", as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 128 &mdash; <tt>match_results</tt> <del>assignment operator effects</del><ins>copy/move operation postconditions</ins></caption>
<tr style="text-align:center">
<th>Element</th>
<th>Value</th>
</tr>
<tr>
<td>
<tt>ready()</tt>
</td>
<td>
<tt>m.ready()</tt>
</td>
</tr>
<tr>
<td>
<tt>size()</tt>
</td>
<td>
<tt>m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>str(n)</tt>
</td>
<td>
<tt>m.str(n)</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>prefix()</tt>
</td>
<td>
<tt>m.prefix()</tt>
</td>
</tr>
<tr>
<td>
<tt>suffix()</tt>
</td>
<td>
<tt>m.suffix()</tt>
</td>
</tr>
<tr>
<td>
<tt>(*this)[n]</tt>
</td>
<td>
<tt>m[n]</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>length(n)</tt>
</td>
<td>
<tt>m.length(n)</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>position(n)</tt>
</td>
<td>
<tt>m.position(n)</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
</table>
</blockquote>


</li>

</ol>
</blockquote>

<p><i>[2021-06-25; Daniel comments and provides new wording]</i></p>

<p>
The revised wording has been rebased to <a href="https://wg21.link/n4892">N4892</a>. It replaces the now
obsolete <i>Ensures:</i> element by the <i>Postconditions:</i> element and also restores the copy constructor
prototype that has been eliminated by <a href="https://wg21.link/P1722R2">P1722R2</a> as anchor point for the link to Table 140.
</p>

<p><i>[2021-06-30; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll. 
</p>


<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.</p>

<ol>
<li><p>Add a new paragraph at the beginning of 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> as indicated:</p>

<blockquote><p>
<ins>-?- Table 140 [tab:re.results.const] lists the postconditions of <tt>match_results</tt> copy/move constructors 
and copy/move assignment operators. For move operations, the results of the expressions depending on the parameter 
<tt>m</tt> denote the values they had before the respective function calls.</ins>
</p></blockquote>

</li>

<li><p>Modify 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a> as indicated:</p>

<blockquote>
<pre>
explicit match_results(const Allocator&amp; a);
</pre>
<blockquote>
<p>
-1- <i>Postconditions:</i> <tt>ready()</tt> returns <tt>false</tt>. <tt>size()</tt> returns <tt>0</tt>.
</p>
</blockquote>
<pre>
<ins>match_results(const match_results&amp; m);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Postconditions:</i> As specified in Table 140.</ins>
</p>
</blockquote>
<pre>
match_results(match_results&amp;&amp; m) noexcept;
</pre>
<blockquote>
<p>
-2- <i>Effects:</i> The stored <tt>Allocator</tt> value is move constructed from <tt>m.get_allocator()</tt>.
<p/>
-3- <i>Postconditions:</i> As specified in Table 140.
</p>
</blockquote>
<pre>
match_results&amp; operator=(const match_results&amp; m);
</pre>
<blockquote>
<p>
-4- <i>Postconditions:</i> As specified in Table 140.
</p>
</blockquote>
<pre>
match_results&amp; operator=(match_results&amp;&amp; m);
</pre>
<blockquote>
<p>
-5- <i>Postconditions:</i> As specified in Table 140.
</p>
</blockquote>
</blockquote>

</li>

<li><p>Modify 30.9.2 <a href="https://wg21.link/re.results.const">[re.results.const]</a>, Table 140 &mdash; "<tt>match_results</tt> assignment operator effects",
[tab:re.results.const], as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 140 &mdash; <tt>match_results</tt> <del>assignment operator effects</del><ins>copy/move operation postconditions</ins></caption>
<tr style="text-align:center">
<th>Element</th>
<th>Value</th>
</tr>
<tr>
<td>
<tt>ready()</tt>
</td>
<td>
<tt>m.ready()</tt>
</td>
</tr>
<tr>
<td>
<tt>size()</tt>
</td>
<td>
<tt>m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>str(n)</tt>
</td>
<td>
<tt>m.str(n)</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>prefix()</tt>
</td>
<td>
<tt>m.prefix()</tt>
</td>
</tr>
<tr>
<td>
<tt>suffix()</tt>
</td>
<td>
<tt>m.suffix()</tt>
</td>
</tr>
<tr>
<td>
<tt>(*this)[n]</tt>
</td>
<td>
<tt>m[n]</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>length(n)</tt>
</td>
<td>
<tt>m.length(n)</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
<tr>
<td>
<tt>position(n)</tt>
</td>
<td>
<tt>m.position(n)</tt> for all <ins>non-negative</ins> integers <tt>n &lt; m.size()</tt>
</td>
</tr>
</table>
</blockquote>


</li>

</ol>





<hr>
<h3><a name="2381" href="https://cplusplus.github.io/LWG/lwg-active.html#2381">2381</a>. Inconsistency in parsing floating point numbers</h3>
<p><b>Section:</b> 28.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Marshall Clow <b>Opened:</b> 2014-04-30 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p>
<p><b>Discussion:</b></p>
<p>
In 28.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a> we have:
</p>
<blockquote><p>
Stage 3: The sequence of chars accumulated in stage 2 (the field) is converted to a numeric value by the
rules of one of the functions declared in the header <tt>&lt;cstdlib&gt;</tt>:
</p>
<ul>
<li><p>For a signed integer value, the function <tt>strtoll</tt>.</p></li>
<li><p>For an unsigned integer value, the function <tt>strtoull</tt>.</p></li>
<li><p>For a floating-point value, the function <tt>strtold</tt>.</p></li>
</ul>
</blockquote>
<p>
This implies that for many cases, this routine should return true:
</p>
<blockquote><pre>
bool is_same(const char* p)
{
  std::string str{p};
  double val1 = std::strtod(str.c_str(), nullptr);
  std::stringstream ss(str);
  double val2;
  ss &gt;&gt; val2;
  return std::isinf(val1) == std::isinf(val2) &amp;&amp;                 // either they're both infinity
         std::isnan(val1) == std::isnan(val2) &amp;&amp;                 // or they're both NaN
         (std::isinf(val1) || std::isnan(val1) || val1 == val2); // or they're equal
}
</pre></blockquote>
<p>
and this is indeed true, for many strings:
</p>
<blockquote><pre>
assert(is_same("0"));
assert(is_same("1.0"));
assert(is_same("-1.0"));
assert(is_same("100.123"));
assert(is_same("1234.456e89"));
</pre></blockquote>
<p>
but not for others
</p>
<blockquote><pre>
assert(is_same("0xABp-4")); // hex float
assert(is_same("inf"));
assert(is_same("+inf"));
assert(is_same("-inf"));
assert(is_same("nan"));
assert(is_same("+nan"));
assert(is_same("-nan"));

assert(is_same("infinity"));
assert(is_same("+infinity"));
assert(is_same("-infinity"));
</pre></blockquote>
<p>
These are all strings that are correctly parsed by <tt>std::strtod</tt>, but not by the stream extraction operators.
They contain characters that are deemed invalid in stage 2 of parsing.
<p/>
If we're going to say that we're converting by the rules of <tt>strtold</tt>, then we should accept all the things that
<tt>strtold</tt> accepts.
</p>

<p><i>[2016-04, Issues Telecon]</i></p>

<p>
People are much more interested in round-tripping hex floats than handling <tt>inf</tt> and <tt>nan</tt>. Priority changed to P2.
</p>
<p>
Marshall says he'll try to write some wording, noting that this is a very closely specified part of the standard, and has remained unchanged for a long time. Also, there will need to be a sample implementation.
</p>

<p><i>[2016-08, Chicago]</i></p>

<p>Zhihao provides wording</p>
<p>The <tt>src</tt> array in Stage 2 does narrowing only.  The actual
input validation is delegated to <tt>strtold</tt> (independent from
the parsing in Stage 3 which is again being delegated
to <tt>strtold</tt>) by saying:</p>

<p>  [...] If it is not discarded, then a check is made to determine
  if c is allowed as the next character of an input field of the
  conversion specifier returned by Stage 1.</p>

<p>So a conforming C++11 <tt>num_get</tt> is supposed to magically
accept an hexfloat without an exponent</p>

<p>  0x3.AB</p>

<p>because we refers to C99, and the fix to this issue should be
just expanding the <tt>src</tt> array.</p>

<p>Support for Infs and NaNs are not proposed because of the
complexity of nan(n-chars).</p>

<p><i>[2016-08, Chicago]</i></p>

<p>Tues PM: Move to Open</p>

<p><i>[2016-09-08, Zhihao Yuan comments and updates proposed wording]</i></p>

<p>
Examples added.
</p>

<p><i>[2018-08-23 Batavia Issues processing]</i></p>

<p>Needs an Annex C entry. Tim to write Annex C.</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to N4606.</p>

<ol>
<li><p>Change 28.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a>/3 Stage 2 as indicated:</p>

<blockquote>
<p><tt>static const char src[] = "0123456789abcdef<ins>p</ins>xABCDEF<ins>P</ins>X+-";</tt></p>
</blockquote>
</li>

<li><p>Append the following examples to 28.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a>/3 Stage 2 as indicated:</p>
<blockquote>
<p>
<ins>[<i>Example:</i></ins>
</p>
<blockquote>
<p>
<ins>Given an input sequence of <tt>"0x1a.bp+07p"</tt>,</ins>
</p>
<ul>
<li><p><ins>if Stage 1 returns <tt>%d</tt>, <tt>"0"</tt> is accumulated;</ins></p></li>
<li><p><ins>if Stage 1 returns <tt>%i</tt>, <tt>"0x1a"</tt> are accumulated;</ins></p></li>
<li><p><ins>if Stage 1 returns <tt>%g</tt>, <tt>"0x1a.bp+07"</tt> are accumulated.</ins></p></li>
</ul>
<p>
<ins>In all cases, leaving the rest in the input.</ins>
</p>
</blockquote>
<p><ins>&mdash; end example]</ins></p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2021-05-18 Tim updates wording]</i></p>

<p>Based on the git history, libc++ appears to have always included
<tt>p</tt> and <tt>P</tt> in <tt>src</tt>.</p>

<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after eight votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.</p>

<ol>
<li><p>Change 28.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a>/3 Stage 2 as indicated:</p>

<blockquote>
<p>
&mdash; Stage 2:
<p/>
If <tt>in == end</tt> then stage 2 terminates. Otherwise a <tt>charT</tt>
is taken from <tt>in</tt> and local variables are initialized as if by
</p>
<blockquote>
<pre>
char_type ct = *in;
char c = src[find(atoms, atoms + sizeof(src) - 1, ct) - atoms];
if (ct == use_facet&lt;numpunct&lt;charT&gt;&gt;(loc).decimal_point())
c = '.';
bool discard =
  ct == use_facet&lt;numpunct&lt;charT&gt;&gt;(loc).thousands_sep()
  &amp;&amp; use_facet&lt;numpunct&lt;charT&gt;&gt;(loc).grouping().length() != 0;
</pre>
</blockquote>
<p>
where the values <tt>src</tt> and <tt>atoms</tt> are defined as if by:
</p>
<blockquote>
<pre>
static const char src[] = "0123456789abcdef<ins>p</ins>xABCDEF<ins>P</ins>X+-";
char_type atoms[sizeof(src)];
use_facet&lt;ctype&lt;charT&gt;&gt;(loc).widen(src, src + sizeof(src), atoms);
</pre>
</blockquote>
<p>
for this value of <tt>loc</tt>.
<p/>
If <tt>discard</tt> is true, then if <tt>'.'</tt> has not yet been accumulated,
then the position of the character is remembered, but the character is otherwise
ignored. Otherwise, if <tt>'.'</tt> has already been accumulated, the character
is discarded and Stage 2 terminates. If it is not discarded, then a check is
made to determine if <tt>c</tt> is allowed as the next character of an input
field of the conversion specifier returned by Stage 1. If so, it is accumulated.
<p/>
If the character is either discarded or accumulated then <tt>in</tt> is advanced
by <tt>++in</tt> and processing returns to the beginning of stage 2.
<p/>
<ins>[<i>Example:</i></ins>
</p>
<blockquote>
<p>
<ins>Given an input sequence of <tt>"0x1a.bp+07p"</tt>,</ins>
</p>
<ul>
<li><p><ins>if the conversion specifier returned by Stage 1 is <tt>%d</tt>, <tt>"0"</tt> is accumulated;</ins></p></li>
<li><p><ins>if the conversion specifier returned by Stage 1 is <tt>%i</tt>, <tt>"0x1a"</tt> are accumulated;</ins></p></li>
<li><p><ins>if the conversion specifier returned by Stage 1 is <tt>%g</tt>, <tt>"0x1a.bp+07"</tt> are accumulated.</ins></p></li>
</ul>
<p>
<ins>In all cases, the remainder is left in the input.</ins>
</p>
</blockquote>
<p><ins>&mdash; end example]</ins></p>
</blockquote>
</li>
<li>
<p>Add the following new subclause to C.5 <a href="https://wg21.link/diff.cpp03">[diff.cpp03]</a>:</p>
<blockquote>
<p>
<ins><b>C.4.? [locale]: localization library [diff.cpp03.locale]</b></ins>
<p/>
<ins><b>Affected subclause:</b> 28.4.3.2.3 <a href="https://wg21.link/facet.num.get.virtuals">[facet.num.get.virtuals]</a><br/>
<b>Change:</b> The <tt>num_get</tt> facet recognizes hexadecimal floating point values.<br/>
<b>Rationale:</b> Required by new feature.<br/>
<b>Effect on original feature:</b> Valid C++2003 code may have different behavior in this
revision of C++.
</ins>
</p>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="2762" href="https://cplusplus.github.io/LWG/lwg-active.html#2762">2762</a>. <tt>unique_ptr operator*()</tt> should be <tt>noexcept</tt></h3>
<p><b>Section:</b> 20.11.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Ville Voutilainen <b>Opened:</b> 2016-08-04 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#unique.ptr.single.observers">issues</a> in [unique.ptr.single.observers].</p>
<p><b>Discussion:</b></p>
<p>
See LWG <a href="https://cplusplus.github.io/LWG/lwg-closed.html#2337">2337</a>. Since we aren't removing <tt>noexcept</tt> from <tt>shared_ptr</tt>'s
<tt>operator*</tt>, we should consider adding <tt>noexcept</tt> to <tt>unique_ptr</tt>'s <tt>operator*</tt>.
</p>

<p><i>[2016-08 &mdash; Chicago]</i></p>

<p>Thurs PM: P3, and status to 'LEWG'</p>

<p><i>[2016-08-05 Chicago]</i></p>

<p>
Ville provides an initial proposed wording.
</p>

<p><i>[LEWG Kona 2017]</i></p>

<p>-&gt;Open: Believe these should be <tt>noexcept</tt> for consistency. We like these. We agree with the proposed resolution.
<tt>operator-&gt;()</tt> already has <tt>noexcept</tt>.</p>
<p>Also adds <tt>optional::operator*</tt></p>
<p>Alisdair points out that fancy pointers might intentionally throw from <tt>operator*</tt>, and we don't want to prohibit that.</p>
<p>Go forward with conditional <tt>noexcept(noexcept(*decltype()))</tt>.</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to N4606.</p>

<blockquote class="note">
<p>
[Drafting note: since this issue is all about consistency, <tt>optional</tt>'s pointer-like operators
are additionally included.]
</p>
</blockquote>

<ol>
<li><p>In 20.11.1.3 <a href="https://wg21.link/unique.ptr.single">[unique.ptr.single]</a> synopsis, edit as follows:</p>

<blockquote>
<pre>
add_lvalue_reference_t&lt;T&gt; operator*() const <ins>noexcept</ins>;
</pre>
</blockquote>
</li>

<li><p>Before 20.11.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a>/1, edit as follows:</p>

<blockquote>
<pre>
add_lvalue_reference_t&lt;T&gt; operator*() const <ins>noexcept</ins>;
</pre>
</blockquote>
</li>

<li><p>In 20.6.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a> synopsis, edit as follows:</p>

<blockquote>
<pre>
constexpr T const *operator-&gt;() const <ins>noexcept</ins>;
constexpr T *operator-&gt;() <ins>noexcept</ins>;
constexpr T const &amp;operator*() const &amp; <ins>noexcept</ins>;
constexpr T &amp;operator*() &amp; <ins>noexcept</ins>;
constexpr T &amp;&amp;operator*() &amp;&amp; <ins>noexcept</ins>;
constexpr const T &amp;&amp;operator*() const &amp;&amp; <ins>noexcept</ins>;
</pre>
</blockquote>
</li>

<li><p>Before  [optional.object.observe]/1, edit as follows:</p>

<blockquote>
<pre>
constexpr T const* operator-&gt;() const <ins>noexcept</ins>;
constexpr T* operator-&gt;() <ins>noexcept</ins>;
</pre>
</blockquote>
</li>

<li><p>Before  [optional.object.observe]/5, edit as follows:</p>

<blockquote>
<pre>
constexpr T const&amp; operator*() const &amp; <ins>noexcept</ins>;
constexpr T&amp; operator*() &amp; <ins>noexcept</ins>;
</pre>
</blockquote>
</li>

<li><p>Before  [optional.object.observe]/9, edit as follows:</p>

<blockquote>
<pre>
constexpr T&amp;&amp; operator*() &amp;&amp; <ins>noexcept</ins>;
constexpr const T&amp;&amp; operator*() const &amp;&amp; <ins>noexcept</ins>;
</pre>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2021-06-19 Tim updates wording]</i></p>


<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/N4892">N4892</a>.</p>

<blockquote class="note">
<p>
[Drafting note: since this issue is all about consistency, <tt>optional</tt>'s pointer-like operators
are additionally included.]
</p>
</blockquote>

<ol>
<li><p>Edit 20.11.1.3.1 <a href="https://wg21.link/unique.ptr.single.general">[unique.ptr.single.general]</a>, class template <tt>unique_ptr</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
namespace std {
  template&lt;class T, class D = default_delete&lt;T&gt;&gt; class unique_ptr {
  public:
    [&hellip;]

    // 20.11.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a>, observers
    add_lvalue_reference_t&lt;T&gt; operator*() const <ins>noexcept(<i>see below</i>)</ins>;
    [&hellip;]
  };
}
</pre>
</blockquote>
</li>

<li><p>Edit 20.11.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a> as indicated:</p>

<blockquote>
<pre>
add_lvalue_reference_t&lt;T&gt; operator*() const <ins>noexcept(noexcept(*declval&lt;pointer&gt;()))</ins>;
</pre>
<blockquote>
<p>
-1- <i>Preconditions</i>: <tt>get() != nullptr</tt>.
<p/>
-2- <i>Returns</i>: <tt>*get()</tt>.
</p>
</blockquote>
</blockquote>
</li>

<li><p>Edit 20.6.3.1 <a href="https://wg21.link/optional.optional.general">[optional.optional.general]</a>, class template <tt>optional</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
namespace std {
  template&lt;class T&gt;
  class optional {
  public:
    [&hellip;]

    // 20.6.3.6 <a href="https://wg21.link/optional.observe">[optional.observe]</a>, observers
    constexpr const T* operator-&gt;() const <ins>noexcept</ins>;
    constexpr T* operator-&gt;() <ins>noexcept</ins>;
    constexpr const T&amp; operator*() const &amp; <ins>noexcept</ins>;
    constexpr T&amp; operator*() &amp; <ins>noexcept</ins>;
    constexpr T&amp;&amp; operator*() &amp;&amp; <ins>noexcept</ins>;
    constexpr const T&amp;&amp; operator*() const &amp;&amp; <ins>noexcept</ins>;

    [&hellip;]
  };
}
</pre>
</blockquote>
</li>

<li><p>Edit 20.6.3.6 <a href="https://wg21.link/optional.observe">[optional.observe]</a> as indicated:</p>

<blockquote>
<pre>
constexpr const T* operator-&gt;() const <ins>noexcept</ins>;
constexpr T* operator-&gt;() <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-1- <i>Preconditions</i>: <tt>*this</tt> contains a value.
<p/>
-2- <i>Returns</i>: <tt>val</tt>.
<p/>
<del>-3- <i>Throws</i>: Nothing.</del>
<p/>
-4- <i>Remarks:</i> These functions are constexpr functions.
</p>
</blockquote>
<pre>
constexpr const T&amp; operator*() const &amp; <ins>noexcept</ins>;
constexpr T&amp; operator*() &amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-5- <i>Preconditions</i>: <tt>*this</tt> contains a value.
<p/>
-6- <i>Returns</i>: <tt>*val</tt>.
<p/>
<del>-7- <i>Throws</i>: Nothing.</del>
<p/>
-8- <i>Remarks:</i> These functions are constexpr functions.
</p>
</blockquote>
<pre>
constexpr T&amp;&amp; operator*() &amp;&amp; <ins>noexcept</ins>;
constexpr const T&amp;&amp; operator*() const &amp;&amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-9- <i>Preconditions</i>: <tt>*this</tt> contains a value.
<p/>
-10- <i>Effects</i>: Equivalent to: <tt>return std::move(*val);</tt>
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3121" href="https://cplusplus.github.io/LWG/lwg-active.html#3121">3121</a>. <tt>tuple</tt> constructor constraints for <tt>UTypes&amp;&amp;...</tt> overloads</h3>
<p><b>Section:</b> 20.5.3.1 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Matt Calabrese <b>Opened:</b> 2018-06-12 <b>Last modified:</b> 2021-05-21</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#tuple.cnstr">active issues</a> in [tuple.cnstr].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#tuple.cnstr">issues</a> in [tuple.cnstr].</p>
<p><b>Discussion:</b></p>
<p>
Currently the <tt>tuple</tt> constructors of the form:
</p>
<blockquote>
<pre>
template&lt;class... UTypes&gt;
<i>EXPLICIT</i> constexpr tuple(UTypes&amp;&amp;...);
</pre>
</blockquote>
<p>
are not properly constrained in that in the 1-element <tt>tuple</tt> case, the constraints do no short-circuit when
the constructor would be (incorrectly) considered as a possible copy/move constructor candidate. libc++ has a
workaround for this, but the additional short-circuiting does not actually appear in the working draft.
<p/>
As an example of why this lack of short circuiting is a problem in practice, consider the following line:
</p>
<blockquote>
<pre>
bool a = std::is_copy_constructible_v&lt;std::tuple&lt;any&gt;&gt;;
</pre>
</blockquote>
<p>
The above code will cause a compile error because of a recursive trait definition. The copy constructibility
check implies doing substitution into the <tt>UTypes&amp;&amp;...</tt> constructor overloads, which in turn
will check if <tt>tuple&lt;any&gt;</tt> is convertible to any, which in turn will check if <tt>tuple&lt;any&gt;</tt>
is copy constructible (and so the trait is dependent on itself).
<p/>
I do not provide wording for the proposed fix in anticipation of requires clauses potentially changing how we
do the specification, however, the basic solution should be similar to what we've done for other standard library
types, which is to say that the very first constraint should be to check that if <tt>sizeof...(UTypes) == 1</tt>
and the type, after applying <tt>remove_cvref_t</tt>, is the <tt>tuple</tt> type itself, then we should force
substitution failure rather than checking any further constraints.
</p>

<p><i>[2018-06-23 after reflector discussion]</i></p>

<p>Priority set to 3</p>

<p><i>[2018-08-20, Jonathan provides wording]</i></p>


<p><i>[2018-08-20, Daniel comments]</i></p>

<p>
The wording changes by this issue are very near to those suggested for LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3155">3155</a>.
</p>

<p><i>[2018-11 San Diego Thursday night issue processing]</i></p>

<p>Jonathan to update wording - using conjunction. Priority set to 2</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4762">N4762</a>.</p>
<ul>
<li><p>Modify 20.5.3.1 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a> as indicated:</p>
<blockquote>
<pre>
template&lt;class... UTypes&gt; explicit(<i>see below</i>) constexpr tuple(UTypes&amp;&amp;... u);
</pre>
<blockquote>
<p>
-9- <i>Effects:</i> Initializes the elements in the tuple with the corresponding value in
<tt>std::forward&lt;UTypes&gt;(u)</tt>.
<p/>
-10- <i>Remarks:</i> This constructor shall not participate in overload resolution unless
<tt>sizeof...(Types) == sizeof...(UTypes)</tt> and <tt>sizeof...(Types) &gt;= 1</tt> <ins>and <tt>(sizeof...(Types)
&gt; 1 || !is_same_v&lt;remove_cvref_t&lt;U<sub>0</sub>&gt;, tuple&gt;)</tt></ins> and
<tt>is_constructible_v&lt;T<sub><i>i</i></sub>, U<sub><i>i</i></sub>&amp;&amp;&gt;</tt> is <tt>true</tt>
for all <tt><i>i</i></tt>. The expression inside <tt>explicit</tt> is equivalent to:
<p/>
<tt>!conjunction_v&lt;is_convertible&lt;UTypes, Types&gt;...&gt;</tt>
</p>
</blockquote>
</blockquote>
</li>
</ul>
</blockquote>
<p><i>[2021-05-20 Tim updates wording]</i></p>

<p>
The new wording below also resolves LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3155">3155</a>, relating to an
<tt>allocator_arg_t</tt> tag argument being treated by this constructor template
as converting to the first tuple element instead of as a tag. To minimize
collateral damage, this wording takes this constructor out of overload resolution
only if the tuple is of size 2 or 3, the first argument is an <tt>allocator_arg_t</tt>,
but the first tuple element isn't of type <tt>allocator_arg_t</tt> (in both cases
after removing cv/ref qualifiers). This avoids damaging tuples that actually
contain an <tt>allocator_arg_t</tt> as the first element (which can be formed
during uses-allocator construction, thanks to <tt>uses_allocator_construction_args</tt>).
<p/>
The proposed wording has been implemented and tested on top of libstdc++.
</p>

<p><i>[2021-08-20; LWG telecon]</i></p>

<p>
Set status to Tentatively Ready after telecon review.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4885">N4885</a>, and also resolves LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3155">3155</a>.</p>
<ol>
<li><p>Modify 20.5.3.1 <a href="https://wg21.link/tuple.cnstr">[tuple.cnstr]</a> as indicated:</p>
<blockquote>
<pre>
template&lt;class... UTypes&gt; explicit(<i>see below</i>) constexpr tuple(UTypes&amp;&amp;... u);
</pre>
<blockquote>
<p>
<ins>
-?- Let <i><tt>disambiguating-constraint</tt></i> be:
</ins>
</p>
<ol style="list-style-type: none">
<li><p><ins>(?.1) &mdash; <tt>negation&lt;is_same&lt;remove_cvref_t&lt;U<sub>0</sub>&gt;, tuple&gt;&gt;</tt> if <tt>sizeof...(Types)</tt> is 1;</ins></p></li>
<li><p><ins>(?.2) &mdash; otherwise, <tt>bool_constant&lt;!is_same_v&lt;remove_cvref_t&lt;U<sub>0</sub>&gt;, allocator_arg_t&gt; || is_same_v&lt;remove_cvref_t&lt;T<sub>0</sub>&gt;, allocator_arg_t&gt;&gt;</tt> if <tt>sizeof...(Types)</tt> is 2 or 3;</ins></p></li>
<li><p><ins>(?.3) &mdash; otherwise, <tt>true_type</tt>.</ins></p></li>
</ol>
<p>
-12- <i>Constraints:</i></p>
<ol style="list-style-type: none">
<li><p><ins>(12.1) &mdash;</ins> <tt>sizeof...(Types)</tt> equals <tt>sizeof...(UTypes)</tt><ins>,</ins> <del>and</del></p></li>
<li><p><ins>(12.2) &mdash;</ins> <tt>sizeof...(Types)</tt> &ge; 1<ins>,</ins> and</p></li>
<li><p><ins>(12.3) &mdash; <tt>conjunction_v&lt;<i>disambiguating-constraint</i>, is_constructible&lt;Types, UTypes&gt;...&gt;</tt> is <tt>true</tt></ins> <del><tt>is_constructible_v&lt;T<sub>i</sub>, U<sub>i</sub>&gt;</tt>
is <tt>true</tt> for all <i>i</i></del>.</p></li>
</ol>
<p>
-13- <i>Effects:</i> Initializes the elements in the tuple with the corresponding value in
<tt>std::forward&lt;UTypes&gt;(u)</tt>.
<p/>
-14- <i>Remarks:</i> The expression inside <tt>explicit</tt> is equivalent to:
<p/>
<tt>!conjunction_v&lt;is_convertible&lt;UTypes, Types&gt;...&gt;</tt>
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3123" href="https://cplusplus.github.io/LWG/lwg-active.html#3123">3123</a>. <tt>duration</tt> constructor from representation shouldn't be effectively non-throwing</h3>
<p><b>Section:</b> 27.5 <a href="https://wg21.link/time.duration">[time.duration]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Johel Ernesto Guerrero Pe&ntilde;a <b>Opened:</b> 2018-06-22 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#time.duration">issues</a> in [time.duration].</p>
<p><b>Discussion:</b></p>
<p>
[time.duration]/4 states:
</p>
<blockquote><p>
Members of duration shall not throw exceptions other than those thrown by the indicated operations on their representations.
</p></blockquote>
<p>
Where representation is defined in the non-normative, brief description at [time.duration]/1:
</p>
<blockquote><p>
[&hellip;] A duration has a representation which holds a count of ticks and a tick period. [&hellip;]
</p></blockquote>
<p>
[time.duration.cons]/2 doesn't indicate the operation undergone by its representation, merely stating a postcondition in [time.duration.cons]/3:
</p>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type <tt>duration</tt>.
<p/>
<i>Postconditions:</i> <tt>count() == static_cast&lt;rep&gt;(r)</tt>.
</p>
</blockquote>
<p>
I suggest this reformulation that follows the format of [time.duration.cons]/5.
</p>
<blockquote>
<p>
<i>Effects:</i> Constructs an object of type duration, constructing <tt>rep_</tt> from <tt>r</tt>.
</p>
</blockquote>
<p>
Now it is clear why the constructor would throw.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/n4750">N4750</a>.
</p>

<p>Change 27.5.2 <a href="https://wg21.link/time.duration.cons">[time.duration.cons]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class Rep2&gt;
  constexpr explicit duration(const Rep2&amp; r);
</pre>
<blockquote>
<p>
-1- <i>Remarks:</i> This constructor shall not participate in overload resolution unless [&hellip;]
<p/>
-2- <i>Effects:</i> Constructs an object of type <tt>duration</tt><ins>, constructing <tt>rep_</tt> from <tt>r</tt></ins>.
<p/>
-3- <i>Postconditions:</i> <tt>count() == static_cast&lt;rep&gt;(r)</tt>.
</p>
</blockquote>
</blockquote></blockquote>

<p><i>[2018-06-27 after reflector discussion]</i></p>

<p>Priority set to 3. Improved wording as result of that discussion.</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/n4750">N4750</a>.
</p>

<p>Change 27.5.2 <a href="https://wg21.link/time.duration.cons">[time.duration.cons]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class Rep2&gt;
  constexpr explicit duration(const Rep2&amp; r);
</pre>
<blockquote>
<p>
-1- <i>Remarks:</i> This constructor shall not participate in overload resolution unless [&hellip;]
<p/>
-2- <i>Effects:</i> <del>Constructs an object of type <tt>duration</tt></del><ins>Initializes <tt>rep_</tt> with <tt>r</tt></ins>.
<p/>
<del>-3- <i>Postconditions:</i> <tt>count() == static_cast&lt;rep&gt;(r)</tt>.</del>
</p>
</blockquote>
</blockquote>
</blockquote>

<p><i>[2020-05-02; Daniel resyncs wording with recent working draft]</i></p>


<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4861">N4861</a>.
</p>

<p>Change 27.5.2 <a href="https://wg21.link/time.duration.cons">[time.duration.cons]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class Rep2&gt;
  constexpr explicit duration(const Rep2&amp; r);
</pre>
<blockquote>
<p>
-1- <i>Constraints:</i> <tt>is_convertible_v&lt;const Rep2&amp;, rep&gt;</tt> is <tt>true</tt> and
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <tt>treat_as_floating_point_v&lt;rep&gt;</tt> is <tt>true</tt> or</p></li>
<li><p>(1.2) &mdash; <tt>treat_as_floating_point_v&lt;Rep2&gt;</tt> is <tt>false</tt>.</p></li>
</ol>
<p>
[<i>Example:</i> [&hellip;] <i>end example</i>]
<p/>
<ins>-?- <i>Effects:</i> Initializes <tt>rep_</tt> with <tt>r</tt>.</ins>
<p/>
<del>-2- <i>Postconditions:</i> <tt>count() == static_cast&lt;rep&gt;(r)</tt>.</del>
</p>
</blockquote>
</blockquote>





<hr>
<h3><a name="3146" href="https://cplusplus.github.io/LWG/lwg-active.html#3146">3146</a>. Excessive unwrapping in <tt>std::ref</tt>/<tt>cref</tt></h3>
<p><b>Section:</b> 20.14.6.6 <a href="https://wg21.link/refwrap.helpers">[refwrap.helpers]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Agust&iacute;n K-ballo Berg&eacute; <b>Opened:</b> 2018-07-10 <b>Last modified:</b> 2021-05-22</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<p>
The overloads of <tt>std::ref</tt>/<tt>cref</tt> that take a <tt>reference_wrapper</tt> as argument are
defined as calling <tt>std::ref</tt>/<tt>cref</tt> recursively, whereas the return type is defined as
unwrapping just one level. Calling these functions with arguments of multiple level of wrapping leads
to ill-formed programs:
</p>
<blockquote><pre>
int i = 0;
std::reference_wrapper&lt;int&gt; ri(i);
std::reference_wrapper&lt;std::reference_wrapper&lt;int&gt;&gt; rri(ri);
std::ref(rri); <i>// error within 'std::ref'</i>
</pre></blockquote>
<p>
[Note: these overloads were added by issue resolution 10.29 for TR1, which can be found at
<a href="https://wg21.link/n1688">N1688</a>, at Redmond 2004]
</p>
<p><i>[2018-08-20 Priority set to 3 after reflector discussion]</i></p>

<p><i>[2021-05-22 Tim syncs wording to the current working draft]</i></p>


<p><i>[2021-08-20; LWG telecon]</i></p>

<p>
Set status to Tentatively Ready after telecon review.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4885">N4885</a>.
</p>

<ol>
<li>
<p>Change 20.14.6.6 <a href="https://wg21.link/refwrap.helpers">[refwrap.helpers]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T&gt; constexpr reference_wrapper&lt;T&gt; ref(reference_wrapper&lt;T&gt; t) noexcept;
</pre>
<blockquote>
<p>
-3- <i>Returns:</i> <tt><del>ref(t.get())</del><ins>t</ins></tt>.
</p>
</blockquote>
[&hellip;]
<pre>
template&lt;class T&gt; constexpr reference_wrapper&lt;const T&gt; cref(reference_wrapper&lt;T&gt; t) noexcept;
</pre>
<blockquote>
<p>
-5- <i>Returns:</i> <tt><del>cref(t.get())</del><ins>t</ins></tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3152" href="https://cplusplus.github.io/LWG/lwg-active.html#3152">3152</a>. <tt>common_type</tt> and <tt>common_reference</tt> have flaws in common</h3>
<p><b>Section:</b> 20.15.8.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2018-08-10 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#meta.trans.other">active issues</a> in [meta.trans.other].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#meta.trans.other">issues</a> in [meta.trans.other].</p>
<p><b>Discussion:</b></p>
<p>
20.15.8.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a> p5 characterizes the requirements for
program-defined specializations of <tt>common_type</tt> with the sentence:
</p>
<blockquote>
Such a specialization need not have a member named <tt>type</tt>, but if it does,
that member shall be a <i>typedef-name</i> for an accessible and unambiguous
cv-unqualified non-reference type <tt>C</tt> to which each of the types
<tt>T1</tt> and <tt>T2</tt> is explicitly convertible.
</blockquote>
<p>
This sentence - which 20.15.8.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a> p7 largely duplicates to
specify requirements on program-defined specializations of
<tt>basic_common_reference</tt> - has two problems:
</p><ol>
<li><p>The grammar term "<i>typedef-name</i>" is overconstraining; there's no
reason to prefer a <i>typedef-name</i> here to an actual type, and</p>
</li>
<li><p>"accessible" and "unambiguous" are not properties of <em>types</em>, they
are properties of names and base classes.</p>
</li>
<li><p>While we're here, we may as well strike the unused name <tt>C</tt> which
both Note B and Note D define for the type denoted by <tt>type</tt>.</p>
</li></ol>

<p><i>[2018-08 Batavia Monday issue prioritization]</i></p>

<p>Priority set to 3</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>

<p>This wording is relative to <a href="https://wg21.link/n4762">N4762</a>.</p>

<ol>
<li><p>Modify 20.15.8.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a> p5 as follows:</p>
<blockquote>
<p>
-5- Note B: Notwithstanding the provisions of 20.15.3 <a href="https://wg21.link/meta.type.synop">[meta.type.synop]</a>,
and pursuant to 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a>, a program may specialize
<tt>common_type&lt;T1, T2&gt;</tt> for types <tt>T1</tt> and <tt>T2</tt> such
that <tt>is_same_v&lt;T1, decay_t&lt;T1&gt;&gt;</tt> and <tt>is_same_v&lt;T2,
decay_t&lt;T2&gt;&gt;</tt> are each true. [<i>Note:</i> &hellip;] Such a
specialization need not have a member named <tt>type</tt>, but if it does,
<del>that member shall be a <i>typedef-name</i> for an accessible and
unambiguous</del> <ins>the <i>qualified-id</i>
<tt>common_type&lt;T1, T2&gt;::type</tt> shall denote a</ins> cv-unqualified
non-reference type <del><tt>C</tt></del> to which each of the types <tt>T1</tt>
and <tt>T2</tt> is explicitly convertible. Moreover, [&hellip;]
</p>
</blockquote>
</li>
<li><p>Modify 20.15.8.7 <a href="https://wg21.link/meta.trans.other">[meta.trans.other]</a> p7 similarly:</p>
<blockquote>
<p>
-7- Note D: Notwithstanding  the provisions of 20.15.3 <a href="https://wg21.link/meta.type.synop">[meta.type.synop]</a>,
and pursuant to 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a>, a program may partially
specialize <tt>basic_common_reference&lt;T, U, TQual, UQual&gt;</tt> for types
<tt>T</tt> and <tt>U</tt> such that <tt>is_same_v&lt;T, decay_t&lt;T&gt;&gt;</tt>
and <tt>is_same_v&lt;U, decay_t&lt;U&gt;&gt;</tt> are each true. [<i>Note:</i>
&hellip;] Such a specialization need not have a member named <tt>type</tt>, but
if it does, <del>that member shall be a <i>typedef-name</i> for an accessible
and unambiguous</del> <ins>the <i>qualified-id</i>
<tt>basic_common_reference&lt;T, U, TQual, UQual&gt;::type</tt> shall denote
a</ins> cv-unqualified non-reference type <del><tt>C</tt></del> to which each of
the types <tt>TQual&lt;T&gt;</tt> and <tt>UQual&lt;U&gt;</tt> is convertible.
Moreover, [&hellip;]
</p>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3293" href="https://cplusplus.github.io/LWG/lwg-active.html#3293">3293</a>. <tt>move_iterator operator+()</tt> has incorrect constraints</h3>
<p><b>Section:</b> 23.5.3.9 <a href="https://wg21.link/move.iter.nonmember">[move.iter.nonmember]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Bo Persson <b>Opened:</b> 2019-09-13 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#move.iter.nonmember">issues</a> in [move.iter.nonmember].</p>
<p><b>Discussion:</b></p>
<p>
Section 23.5.3.9 <a href="https://wg21.link/move.iter.nonmember">[move.iter.nonmember]</a>/2-3 says:
</p>
<blockquote>
<pre>
template&lt;class Iterator&gt;
  constexpr move_iterator&lt;Iterator&gt;
    operator+(iter_difference_t&lt;Iterator&gt; n, const move_iterator&lt;Iterator&gt;&amp; x);
</pre>
<blockquote>
<p>
<i>Constraints:</i> <tt>x + n</tt> is well-formed and has type <tt>Iterator</tt>.
<p/>
<i>Returns:</i> <tt>x + n</tt>.
</p>
</blockquote>
</blockquote>
<p>
However, the return type of this operator is <tt>move_iterator&lt;Iterator&gt;</tt>, so
the expression <tt>x + n</tt> ought to have that type. Also, there is no <tt>operator+</tt> 
that matches the constraints, so it effectively disables the addition.
</p>

<p><i>[2019-10-31 Issue Prioritization]</i></p>

<p>Priority to 3 after reflector discussion.</p>

<strong>Previous resolution [SUPERSEDED]:</strong>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4830">N4830</a>.</p>

<ol>
<li><p>Modify 23.5.3.9 <a href="https://wg21.link/move.iter.nonmember">[move.iter.nonmember]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class Iterator&gt;
  constexpr move_iterator&lt;Iterator&gt;
    operator+(iter_difference_t&lt;Iterator&gt; n, const move_iterator&lt;Iterator&gt;&amp; x);
</pre>
<blockquote>
<p>
-2- <i>Constraints:</i> <tt>x + n</tt> is well-formed and has type <tt><ins>move_iterator&lt;</ins>Iterator<ins>&gt;</ins></tt>.
<p/>
-3- <i>Returns:</i> <tt>x + n</tt>.
</p>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2019-11-04; Casey comments and provides revised wording]</i></p>

<p>
After applying the P/R the <i>Constraint</i> element requires <tt>x + n</tt> to be well-formed (it always is, 
since that operation is unconstrained) and requires <tt>x + n</tt> to have type 
<tt>move_iterator&lt;Iterator&gt;</tt> (which it always does). Consequently, this <i>Constraint</i> 
is always satisfied and it has no normative effect. The intent of the change in 
<a href="https://wg21.link/p0896r4">P0896R4</a> was that this operator be constrained to require 
addition on the base iterator to be well-formed and have type <tt>Iterator</tt>, which ensures that 
the other semantics of this operation are implementable.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4835">N4835</a>.</p>

<ol>
<li><p>Modify 23.5.3.9 <a href="https://wg21.link/move.iter.nonmember">[move.iter.nonmember]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class Iterator&gt;
  constexpr move_iterator&lt;Iterator&gt;
    operator+(iter_difference_t&lt;Iterator&gt; n, const move_iterator&lt;Iterator&gt;&amp; x);
</pre>
<blockquote>
<p>
-2- <i>Constraints:</i> <tt>x<ins>.base()</ins> + n</tt> is well-formed and has type <tt>Iterator</tt>.
<p/>
-3- <i>Returns:</i> <tt>x + n</tt>.
</p>
</blockquote>
</blockquote>

</li>

</ol>




<hr>
<h3><a name="3361" href="https://cplusplus.github.io/LWG/lwg-active.html#3361">3361</a>. <tt>safe_range&lt;<i>SomeRange</i>&amp;></tt> case</h3>
<p><b>Section:</b> 24.4.2 <a href="https://wg21.link/range.range">[range.range]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Johel Ernesto Guerrero Pe&ntilde;a <b>Opened:</b> 2019-12-19 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<p>
24.5.5 <a href="https://wg21.link/range.dangling">[range.dangling]</a> p2 hints at how <tt>safe_range</tt> should allow lvalue ranges to model it.
However, its wording doesn't take into account that case.
</p>

<p><i>[2020-01 Priority set to 3 after review on the reflector.]</i></p>


<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4842">N4842</a>.</p>

<ol>
<li><p>Modify 24.4.2 <a href="https://wg21.link/range.range">[range.range]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T&gt;
  concept safe_range =
    range&lt;T&gt; &amp;&amp;
      (is_lvalue_reference_v&lt;T&gt; || enable_safe_range&lt;remove_cvref_t&lt;T&gt;&gt;);
</pre>
<blockquote>
<p>
-5- <del>Given an expression <tt>E</tt> such that <tt>decltype((E))</tt> is <tt>T</tt>,</del><ins>A type</ins>
<tt>T</tt> models <tt>safe_range</tt> <del>only</del> <ins>if:</ins>
<ol style="list-style-type: none">
<li><p><ins>(5.1) &mdash; <tt>is_lvalue_reference_v&lt;T&gt;</tt> is <tt>true</tt>, or</ins></p></li>
<li><p><ins>(5.2) &mdash; given an expression <tt>E</tt> such that <tt>decltype((E))</tt> is <tt>T</tt>,</ins>
<del>if</del> the validity of iterators obtained from the object denoted by <tt>E</tt> is not tied to the lifetime of
that object.</p></li>
</ol>
<p/>
-6- [<i>Note:</i> <del>Since the validity of iterators is not tied to the lifetime of an object
whose type models <tt>safe_range</tt>, a</del><ins>A</ins> function can accept arguments of <del>such</del> a
type <ins>that models <tt>safe_range</tt></ins> <del>by value</del> and return iterators obtained from it
without danger of dangling. &mdash; <i>end note</i>]
</p>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2021-05-19 Tim updates wording]</i></p>

<p>
The new wording below attempts to keep the "borrowed" property generally
applicable to all models of <tt>borrowed_range</tt>, instead of bluntly carving
out lvalue reference types.
</p>

<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll in June.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.</p>

<ol>
<li><p>Modify 24.4.2 <a href="https://wg21.link/range.range">[range.range]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T&gt;
  concept borrowed_range =
    range&lt;T&gt; &amp;&amp;
      (is_lvalue_reference_v&lt;T&gt; || enable_borrowed_range&lt;remove_cvref_t&lt;T&gt;&gt;);
</pre>
<blockquote>
<p>
-5- <ins>Let <tt>U</tt> be <tt>remove_reference_t&lt;T&gt;</tt> if <tt>T</tt>
is an rvalue reference type, and <tt>T</tt> otherwise.</ins>
Given <del>an expression <tt>E</tt> such that <tt>decltype((E))</tt> is <tt>T</tt></del>
<ins>a variable <tt>u</tt> of type <tt>U</tt></ins>,
<tt>T</tt> models <tt>borrowed_range</tt> only if the validity of iterators
obtained from <del>the object denoted by <tt>E</tt></del> <ins>u</ins> is not tied
to the lifetime of that <del>object</del> <ins>variable</ins>.
<p/>
-6- [<i>Note:</i> Since the validity of iterators is not tied to the lifetime of
<del>an object</del><ins>a variable</ins> whose type models <tt>borrowed_range</tt>,
a function <del>can accept arguments of</del> <ins>with a parameter of</ins>
such a type <del>by value and</del> <ins>can</ins> return iterators
obtained from it without danger of dangling.
&mdash; <i>end note</i>]
</p>
</blockquote>
</blockquote>
</li>
</ol>




<hr>
<h3><a name="3392" href="https://cplusplus.github.io/LWG/lwg-active.html#3392">3392</a>. <tt>ranges::distance()</tt> cannot be used on a move-only iterator with a sized sentinel</h3>
<p><b>Section:</b> 23.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Patrick Palka <b>Opened:</b> 2020-02-07 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<p>
One cannot use <tt>ranges::distance(I, S)</tt> to compute the distance between a
move-only <tt>counted_iterator</tt> and the <tt>default_sentinel</tt>. In other words,
the following is invalid
</p>
<blockquote><pre>
// iter is a counted_iterator with an move-only underlying iterator
ranges::distance(iter, default_sentinel);
</pre></blockquote>
<p>
and yet
</p>
<blockquote><pre>
(default_sentinel - iter);
</pre></blockquote>
<p>
is valid. The first example is invalid because <tt>ranges::distance()</tt> takes
its first argument by value so when invoking it with an iterator lvalue
argument the iterator must be copyable, which a move-only iterator is
not. The second example is valid because <tt>counted_iterator::operator-()</tt>
takes its iterator argument by <tt>const</tt> reference, so it doesn't require
copyability of the <tt>counted_iterator</tt>.
<p/>
This incongruency poses an inconvenience in generic code which uses
<tt>ranges::distance()</tt> to efficiently compute the distance between two
iterators or between an iterator-sentinel pair. Although it's a bit of
an edge case, it would be good if <tt>ranges::distance()</tt> does the right
thing when the iterator is a move-only lvalue with a sized sentinel.
<p/>
If this is worth fixing, one solution might be to define a separate
overload of <tt>ranges::distance(I, S)</tt> that takes its arguments by <tt>const</tt>
reference, as follows.
</p>

<p><i>[2020-02 Prioritized as P3 and LEWG Monday morning in Prague]</i></p>


<p><i>[2020-05-28; LEWG issue reviewing]</i></p>

<p>
LEWG issue processing voted to accept the direction of 3392. Status change to Open.
</p>
<blockquote>
<pre>
Accept the direction of LWG3392

SF F N A SA
14 6 0 0 0
</pre>
</blockquote>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<ol>
<li><p>Modify 23.2 <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</a>, header <tt>&lt;iterator&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
#include &lt;concepts&gt;

namespace std {
  [&hellip;]
  <i>// 23.4.4 <a href="https://wg21.link/range.iter.ops">[range.iter.ops]</a>, range iterator operations</i>
  namespace ranges {
    [&hellip;]
    <i>// 23.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a>, ranges::distance</i>
    template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
      <ins>requires (!sized_sentinel_for&lt;S, I&gt;)</ins>
        constexpr iter_difference_t&lt;I&gt; distance(I first, S last);
    <ins>template&lt;input_or_output_iterator I, sized_sentinel_for&lt;I&gt; S&gt;
      constexpr iter_difference_t&lt;I&gt; distance(const I&amp; first, const S&amp; last);</ins>
    template&lt;range R&gt;
      constexpr range_difference_t&lt;R&gt; distance(R&amp;&amp; r);
    [&hellip;]
  }
  [&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 23.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
  <ins>requires (!sized_sentinel_for&lt;S, I&gt;)</ins>
    constexpr iter_difference_t&lt;I&gt; ranges::distance(I first, S last);
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> <tt>[first, last)</tt> denotes a range<del>, or <tt>[last, first)</tt> denotes a range
and <tt>S</tt> and <tt>I</tt> model <tt>same_as&lt;S, I&gt; &amp;&amp; sized_sentinel_for&lt;S, I&gt;</tt></del>.
<p/>
-2- <i>Effects:</i> <del>If <tt>S</tt> and <tt>I</tt> model <tt>sized_sentinel_for&lt;S, I&gt;</tt>, returns
<tt>(last - first)</tt>; otherwise, r</del><ins>R</ins>eturns the number of increments needed to get from
<tt>first</tt> to <tt>last</tt>.
</p>
</blockquote>
<pre>
<ins>template&lt;input_or_output_iterator I, sized_sentinel_for&lt;I&gt; S&gt;
  constexpr iter_difference_t&lt;I&gt; ranges::distance(const I&amp; first, const S&amp; last);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Preconditions:</i> <tt>S</tt> and <tt>I</tt> model <tt>sized_sentinel_for&lt;S, I&gt;</tt> and either:</ins>
<ol style="list-style-type: none">
<li><p><ins>(?.1) &mdash; <tt>[first, last)</tt> denotes a range, or</ins></p></li>
<li><p><ins>(?.2) &mdash; <tt>[last, first)</tt> denotes a range and <tt>S</tt> and <tt>I</tt> model
<tt>same_as&lt;S, I&gt;</tt>.</ins></p></li>
</ol>
<p/>
<ins>-? <i>Effects:</i> Returns <tt>(last - first)</tt>;</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>
<p><i>[2021-05-19 Tim updates wording]</i></p>

<p>
The wording below removes the explicit precondition on the <tt>sized_sentinel_for</tt>
overload of <tt>distance</tt>, relying instead on the semantic requirements of
that concept and the "Effects: Equivalent to:" word of power. This also removes
the potentially surprising inconsistency that given a non-empty
<tt>std::vector&lt;int&gt; v</tt>,
<tt>ranges::distance(v.begin(), v.cend())</tt> is well-defined but
<tt>ranges::distance(v.cend(), v.begin())</tt> is currently undefined.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.</p>

<ol>
<li><p>Modify 23.2 <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</a>, header <tt>&lt;iterator&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]

namespace std {
  [&hellip;]
  <i>// 23.4.4 <a href="https://wg21.link/range.iter.ops">[range.iter.ops]</a>, range iterator operations</i>
  namespace ranges {
    [&hellip;]
    <i>// 23.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a>, ranges::distance</i>
    template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
      <ins>requires (!sized_sentinel_for&lt;S, I&gt;)</ins>
        constexpr iter_difference_t&lt;I&gt; distance(I first, S last);
    <ins>template&lt;input_or_output_iterator I, sized_sentinel_for&lt;I&gt; S&gt;
      constexpr iter_difference_t&lt;I&gt; distance(const I&amp; first, const S&amp; last);</ins>
    template&lt;range R&gt;
      constexpr range_difference_t&lt;R&gt; distance(R&amp;&amp; r);
    [&hellip;]
  }
  [&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 23.4.4.3 <a href="https://wg21.link/range.iter.op.distance">[range.iter.op.distance]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
  <ins>requires (!sized_sentinel_for&lt;S, I&gt;)</ins>
    constexpr iter_difference_t&lt;I&gt; ranges::distance(I first, S last);
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> <tt>[first, last)</tt> denotes a range<del>, or <tt>[last, first)</tt> denotes a range
and <tt>S</tt> and <tt>I</tt> model <tt>same_as&lt;S, I&gt; &amp;&amp; sized_sentinel_for&lt;S, I&gt;</tt></del>.
<p/>
-2- <del><i>Effects:</i> If <tt>S</tt> and <tt>I</tt> model <tt>sized_sentinel_for&lt;S, I&gt;</tt>, returns
<tt>(last - first)</tt>; otherwise, returns the</del> <ins><i>Returns:</i> The</ins> number of increments needed to get from
<tt>first</tt> to <tt>last</tt>.
</p>
</blockquote>
<pre>
<ins>template&lt;input_or_output_iterator I, sized_sentinel_for&lt;I&gt; S&gt;
  constexpr iter_difference_t&lt;I&gt; ranges::distance(const I&amp; first, const S&amp; last);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return last - first;</tt></ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3407" href="https://cplusplus.github.io/LWG/lwg-active.html#3407">3407</a>. Some problems with the wording changes of <a href="https://wg21.link/p1739r4">P1739R4</a></h3>
<p><b>Section:</b> 24.7.8.1 <a href="https://wg21.link/range.take.overview">[range.take.overview]</a>, 24.6.4 <a href="https://wg21.link/range.iota">[range.iota]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Patrick Palka <b>Opened:</b> 2020-02-21 <b>Last modified:</b> 2021-06-19</p>
<p><b>Priority: </b>2
</p>
<p><b>Discussion:</b></p>
<p>
Section 6.1 of <a href="https://wg21.link/p1739r4">P1739R4</a> changes the specification of
<tt>views::take</tt> as follows:
</p>
<blockquote>
<p>
-2- The name <tt>views::take</tt> denotes a range adaptor object (24.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a>).
<del>Given subexpressions <tt>E</tt> and <tt>F</tt>, the expression <tt>views::take(E, F)</tt> is
expression-equivalent to <tt>take_view{E, F}</tt>.</del>
<ins>Let <tt>E</tt> and <tt>F</tt> be expressions, let <tt>T</tt> be <tt>remove_cvref_t&lt;decltype((E))&gt;</tt>,
and let <tt>D</tt> be <tt>range_difference_t&lt;decltype((E))&gt;</tt>.
If <tt>decltype((F))</tt> does not model <tt>convertible_to&lt;D&gt;</tt>, <tt>views::take(E, F)</tt>
is ill-formed. Otherwise, the expression <tt>views::take(E, F)</tt> is expression-equivalent to:</ins>
</p>
<ol style="list-style-type: none">
<li><p><ins>&mdash; if <tt>T</tt> is a specialization of <tt>ranges::empty_view</tt> (24.6.2.2 <a href="https://wg21.link/range.empty.view">[range.empty.view]</a>),
then <tt>((void) F, <i>decay-copy</i>(E))</tt>;</ins>
</p></li>
<li><p><ins>&mdash; otherwise, if <tt>T</tt> models <tt>random_access_range</tt> and <tt>sized_range</tt> and
is</ins>
</p>
<ol style="list-style-type: none">
<li><p><ins>&mdash; a specialization of <tt>span</tt> (22.7.3 <a href="https://wg21.link/views.span">[views.span]</a>) where
<tt>T::extent == dynamic_extent</tt>,</ins></p></li>
<li><p><ins>&mdash; a specialization of <tt>basic_string_view</tt> (21.4 <a href="https://wg21.link/string.view">[string.view]</a>),</ins></p></li>
<li><p><ins>&mdash; a specialization of <tt>ranges::iota_view</tt> (24.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>), or</ins></p></li>
<li><p><ins>&mdash; a specialization of <tt>ranges::subrange</tt> (24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a>),</ins></p></li>
</ol>
<p><ins>then <tt>T{ranges::begin(E), ranges::begin(E) + min&lt;D&gt;(ranges::size(E), F)}</tt>,
except that <tt>E</tt> is evaluated only once;</ins>
</p></li>
<li><p>
<ins>&mdash; otherwise, <tt>ranges::take_view{E, F}</tt>.</ins>
</p></li>
</ol>
</blockquote>
<p>
Consider the case when <tt>T = subrange&lt;counted_iterator&lt;int&gt;, default_sentinel_t&gt;</tt>.
Then according to the above wording, <tt>views::take(E, F)</tt> is expression-equivalent to
</p>
<blockquote><pre>
T{ranges::begin(E), ranges:begin(E) + min&lt;D&gt;(ranges::size(E), F)};   <i>(*)</i>
</pre></blockquote>
<p>
But this expression is ill-formed for the <tt>T</tt> we chose because
<tt>subrange&lt;counted_iterator&lt;int&gt;, default_sentinel_t&gt;</tt> has no matching
constructor that takes an <tt>iterator-iterator</tt> pair.
<p/>
More generally the above issue applies anytime <tt>T</tt> is a specialization of
<tt>subrange</tt> that does not model <tt>common_range</tt>. But a similar issue also
exists when <tt>T</tt> is a specialization of <tt>iota_view</tt> whose value type differs
from its bound type. In this case yet another issue arises: In order for the expression
<tt><i>(*)</i></tt> to be well-formed when <tt>T</tt> is a specialization of <tt>iota_view</tt>,
we need to be able to construct an <tt>iota_view</tt> out of an <tt>iterator-iterator</tt> pair,
and for that it seems we need to add another constructor to <tt>iota_view</tt>.
</p>

<p><i>[2020-02-24, Casey comments]</i></p>

<p>
Furthermore, the pertinent subrange constructor is only available when <tt>subrange::StoreSize</tt> is
<tt>false</tt> (i.e., when either the <tt>subrange</tt> specialization's third template argument is
not <tt>subrange_kind::sized</tt> or its iterator and sentinel types <tt>I</tt> and <tt>S</tt> model
<tt>sized_sentinel_for&lt;S, I&gt;</tt>).
</p>

<p><i>[2020-03-16, Tomasz comments]</i></p>

<p>
A similar problem occurs for the <tt>views::drop</tt> for the <tt>subrange&lt;I, S, subrange_kind::sized&gt;</tt>,
that explicitly stores size (i.e. <tt>sized_sentinel_for&lt;I, S&gt;</tt> is <tt>false</tt>). In such case,
the <tt>(iterator, sentinel)</tt> constructor that <tt>views::drop</tt> will be expression-equivalent is
not available.
</p>

<p><i>[2020-03-29 Issue Prioritization]</i></p>

<p>Priority to 2 after reflector discussion.</p>

<p><i>[2021-05-18 Tim adds wording]</i></p>

<p>The proposed resolution below is based on the MSVC implementation, with one caveat:
the MSVC implementation uses a SCARY iterator type for <tt>iota_view</tt> and therefore
its <tt>iota_view</tt> case for <tt>take</tt> is able to directly construct the new view
from the iterator type of the original. This is not required to work, so the wording below
constructs the <tt>iota_view</tt> from the result of dereferencing the iterators instead
in this case.
</p>

<p><i>[2021-06-18 Tim syncs wording to the current working draft]</i></p>

<p>The wording below also corrects the size calculation in the presence of
integer-class types.</p>

<p><i>[2021-08-20; LWG telecon]</i></p>

<p>
Set status to Tentatively Ready after telecon review.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/N4892">N4892</a>.</p>
<ol>
<li>
<p>Edit 24.7.8.1 <a href="https://wg21.link/range.take.overview">[range.take.overview]</a> as indicated: </p>
<blockquote>
<p>
-2- The name <tt>views::take</tt> denotes a range adaptor object (24.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a>).
Let <tt>E</tt> and <tt>F</tt> be expressions, let <tt>T</tt> be <tt>remove_cvref_t&lt;decltype((E))&gt;</tt>,
and let <tt>D</tt> be <tt>range_difference_t&lt;decltype((E))&gt;</tt>.
If <tt>decltype((F))</tt> does not model <tt>convertible_to&lt;D&gt;</tt>, <tt>views::take(E, F)</tt>
is ill-formed. Otherwise, the expression <tt>views::take(E, F)</tt> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; if <tt>T</tt> is a specialization of <tt>ranges::empty_view</tt> (24.6.2.2 <a href="https://wg21.link/range.empty.view">[range.empty.view]</a>),
then <tt>((void) F, <i>decay-copy</i>(E))</tt>, except that the evaluations of <tt>E</tt>
and <tt>F</tt> are indeterminately sequenced;
</p></li>
<li><p>(2.2) &mdash; otherwise, if <tt>T</tt> models <tt>random_access_range</tt> and <tt>sized_range</tt>,
and is <ins>a specialization of <tt>span</tt> (22.7.3 <a href="https://wg21.link/views.span">[views.span]</a>), <tt>basic_string_view</tt> (21.4 <a href="https://wg21.link/string.view">[string.view]</a>),
or <tt>ranges::subrange</tt> (24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a>),
then <tt>U(ranges::begin(E), ranges::begin(E) + std::min&lt;D&gt;(ranges::distance(E), F))</tt>,
except that <tt>E</tt> is evaluated only once, where <tt>U</tt> is a type determined as follows:</ins>
</p>
<ol style="list-style-type: none">
<li><p>(2.2.1) &mdash; <ins>if <tt>T</tt> is</ins> a specialization of <tt>span</tt> <del>(22.7.3 <a href="https://wg21.link/views.span">[views.span]</a>) where
<tt>T::extent == dynamic_extent</tt></del>,<ins> then <tt>U</tt> is <tt>span&lt;typename T::element_type&gt;</tt>;</ins></p></li>
<li><p>(2.2.2) &mdash; <ins>otherwise, if <tt>T</tt> is</ins> a specialization of <tt>basic_string_view</tt> <del>(21.4 <a href="https://wg21.link/string.view">[string.view]</a>)</del>, <ins>then <tt>U</tt> is <tt>T</tt>;</ins></p></li>
<li><p><del>(2.2.3) &mdash; a specialization of <tt>ranges::iota_view</tt> (24.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>), or</del></p></li>
<li><p>(2.2.4) &mdash; <ins>otherwise, <tt>T</tt> is</ins> a specialization of <tt>ranges::subrange</tt> <del>(24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a>)</del>,
<ins>and <tt>U</tt> is <tt>ranges::subrange&lt;iterator_t&lt;T&gt;&gt;</tt>;</ins></p></li>
</ol>
<p><del>then <tt>T{ranges::begin(E), ranges::begin(E) + min&lt;D&gt;(ranges::size(E), F)}</tt>,
except that <tt>E</tt> is evaluated only once;</del>
</p></li>
<li><p><ins>(2.?) &mdash; otherwise, if <tt>T</tt> is a specialization of <tt>ranges::iota_view</tt> (24.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>)
that models <tt>random_access_range</tt> and <tt>sized_range</tt>, then
<tt>ranges::iota_view(*ranges::begin(E), *(ranges::begin(E) + std::min&lt;D&gt;(ranges::distance(E), F)))</tt>,
except that <tt>E</tt> and <tt>F</tt> are each evaluated only once;</ins></p></li>
<li><p>(2.3) &mdash; otherwise, <tt>ranges::take_view(E, F)</tt>.
</p></li>
</ol>
</blockquote>
</li>
<li>
<p>Edit 24.7.10.1 <a href="https://wg21.link/range.drop.overview">[range.drop.overview]</a> as indicated: </p>
<blockquote>
<p>
-2- The name <tt>views::drop</tt> denotes a range adaptor object (24.7.2 <a href="https://wg21.link/range.adaptor.object">[range.adaptor.object]</a>).
Let <tt>E</tt> and <tt>F</tt> be expressions, let <tt>T</tt> be <tt>remove_cvref_t&lt;decltype((E))&gt;</tt>,
and let <tt>D</tt> be <tt>range_difference_t&lt;decltype((E))&gt;</tt>.
If <tt>decltype((F))</tt> does not model <tt>convertible_to&lt;D&gt;</tt>, <tt>views::drop(E, F)</tt>
is ill-formed. Otherwise, the expression <tt>views::drop(E, F)</tt> is expression-equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; if <tt>T</tt> is a specialization of <tt>ranges::empty_view</tt> (24.6.2.2 <a href="https://wg21.link/range.empty.view">[range.empty.view]</a>),
then <tt>((void) F, <i>decay-copy</i>(E))</tt>, except that the evaluations of <tt>E</tt>
and <tt>F</tt> are indeterminately sequenced;
</p></li>
<li><p>(2.2) &mdash; otherwise, if <tt>T</tt> models <tt>random_access_range</tt> and <tt>sized_range</tt>,
and is
</p>
<ol style="list-style-type: none">
<li><p>(2.2.1) &mdash;a specialization of <tt>span</tt> (22.7.3 <a href="https://wg21.link/views.span">[views.span]</a>) <del>where
<tt>T::extent == dynamic_extent</tt></del>,</p></li>
<li><p>(2.2.2) &mdash; a specialization of <tt>basic_string_view</tt> (21.4 <a href="https://wg21.link/string.view">[string.view]</a>), </p></li>
<li><p>(2.2.3) &mdash; a specialization of <tt>ranges::iota_view</tt> (24.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>), or</p></li>
<li><p>(2.2.4) &mdash; a specialization of <tt>ranges::subrange</tt> (24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a>)
<ins>where <tt>T::<i>StoreSize</i></tt> is <tt>false</tt></ins>,</p></li>
</ol>
<p>then <tt><del>T</del><ins>U</ins>(ranges::begin(E) + <ins>std::</ins>min&lt;D&gt;(ranges::<del>size</del><ins>distance</ins>(E), F), ranges::end(E))</tt>,
except that <tt>E</tt> is evaluated only once<ins>, where <tt>U</tt> is <tt>span&lt;typename T::element_type&gt;</tt>
if <tt>T</tt> is a specialization of <tt>span</tt> and <tt>T</tt> otherwise</ins>;
</p></li>
<li><p><ins>(2.?) &mdash; otherwise, if <tt>T</tt> is a specialization of <tt>ranges::subrange</tt>
(24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a>) that models <tt>random_access_range</tt> and <tt>sized_range</tt>, then
<tt>T(ranges::begin(E) + std::min&lt;D&gt;(ranges::distance(E), F), ranges::end(E),
<i>to-unsigned-like</i>(ranges::distance(E) - std::min&lt;D&gt;(ranges::distance(E), F)))</tt>,
except that <tt>E</tt> and <tt>F</tt> are each evaluated only once;</ins></p></li>
<li><p>(2.3) &mdash; otherwise, <tt>ranges::drop_view(E, F)</tt>.
</p></li>
</ol>
</blockquote>
</li>
</ol>




<hr>
<h3><a name="3422" href="https://cplusplus.github.io/LWG/lwg-active.html#3422">3422</a>. Issues of <tt>seed_seq</tt>'s constructors</h3>
<p><b>Section:</b> 26.6.8.1 <a href="https://wg21.link/rand.util.seedseq">[rand.util.seedseq]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Jiang An <b>Opened:</b> 2020-03-25 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#rand.util.seedseq">active issues</a> in [rand.util.seedseq].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#rand.util.seedseq">issues</a> in [rand.util.seedseq].</p>
<p><b>Discussion:</b></p>
<p>
26.6.8.1 <a href="https://wg21.link/rand.util.seedseq">[rand.util.seedseq]</a> says that <tt>std::seed_seq</tt> has following 3 constructors:
<p/>
<ol style="list-style-type: none">
<li><p>#1: <tt>seed_seq()</tt></p></li>
<li><p>#2: <tt>template&lt;class T&gt; seed_seq(initializer_list&lt;T&gt; il)</tt></p></li>
<li><p>#3: <tt>template&lt;class InputIterator&gt; seed_seq(InputIterator begin, InputIterator end)</tt></p></li>
</ol>
<p/>
The default constructor (#1) has no precondition and does not throw, and <tt>vector&lt;result_type&gt;</tt>'s default 
constructor is already <tt>noexcept</tt> since C++17, so #1 should also be <tt>noexcept</tt>.
<p/>
Despite that the <tt>vector&lt;result_type&gt;</tt> member is exposition-only, current implementations (at least 
<a href="https://github.com/llvm-mirror/libcxx/blob/master/include/random#L3523">libc++</a>, 
<a href="https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/random.h#L6090">libstdc++</a> and 
<a href="https://github.com/microsoft/STL/blob/master/stl/inc/random#L259">MSVC STL</a>) all hold it as the only 
data member of <tt>seed_seq</tt>, even with different names. And #1 is already <tt>noexcept</tt> in libc++ and libstdc++.
<p/>
These constructors are not constrained, so #3 would never be matched in list-initialization. Consider following code:
</p>
<blockquote><pre>
#include &lt;random&gt;
#include &lt;vector&gt;

int main()
{
  std::vector&lt;int&gt; v(32);
  std::seed_seq{std::begin(v), std::end(v)}; // error: #2 matched and T is not an integer type
  std::seed_seq(std::begin(v), std::end(v)); // OK
}
</pre></blockquote>
<p>
#3 should be made available in list-initialization by changing <i>Mandates</i> in 
26.6.8.1 <a href="https://wg21.link/rand.util.seedseq">[rand.util.seedseq]</a>/3 to <i>Constraints</i> IMO.
</p>

<p><i>[2020-04-18 Issue Prioritization]</i></p>

<p>Priority to 3 after reflector discussion.</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4861">N4861</a>.
</p>

<ol>
<li><p>Modify 26.6.8.1 <a href="https://wg21.link/rand.util.seedseq">[rand.util.seedseq]</a> as indicated:</p>

<blockquote>
<pre>
class seed_seq {
public:
  <i>// types</i>
  using result_type = uint_least32_t;

  <i>// constructors</i>
  seed_seq() <ins>noexcept</ins>;
  [&hellip;]
};
</pre>
</blockquote>
<blockquote>
<pre>
seed_seq() <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-1- <i>Postconditions:</i> <tt>v.empty()</tt> is <tt>true</tt>.
<p/>
<del>-2- <i>Throws:</i> Nothing.</del>
</p>
</blockquote>
<pre>
template&lt;class T&gt;
  seed_seq(initializer_list&lt;T&gt; il);
</pre>
<blockquote>
<p>
-3- <i><ins>Constraints</ins><del>Mandates</del>:</i> <tt>T</tt> is an integer type.
<p/>
-4- <i>Effects:</i> Same as <tt>seed_seq(il.begin(), il.end())</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>




<hr>
<h3><a name="3470" href="https://cplusplus.github.io/LWG/lwg-active.html#3470">3470</a>. <tt><i>convertible-to-non-slicing</i></tt> seems to reject valid case</h3>
<p><b>Section:</b> 24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> S. B. Tam <b>Opened:</b> 2020-07-26 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#range.subrange">active issues</a> in [range.subrange].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.subrange">issues</a> in [range.subrange].</p>
<p><b>Discussion:</b></p>
<p>
Consider
</p>
<blockquote><pre>
#include &lt;ranges&gt;

int main()
{
  int a[3] = { 1, 2, 3 };
  int* b[3] = { &amp;a[2], &amp;a[0], &amp;a[1] };
  auto c = std::ranges::subrange&lt;const int*const*&gt;(b);
}
</pre></blockquote>
<p>
The construction of <tt>c</tt> is ill-formed because <tt><i>convertible-to-non-slicing</i>&lt;int**, const int*const*&gt;</tt>
is <tt>false</tt>, although the conversion does not involve object slicing.
<p/>
I think <tt>subrange</tt> should allow such qualification conversion, just like <tt>unique_ptr&lt;T[]&gt;</tt> already does.
<p/>
(Given that this constraint is useful in more than one context, maybe it deserves a named type trait?)
</p>

<p><i>[2020-08-21; Reflector prioritization]</i></p>

<p>
Set priority to 3 after reflector discussions.
</p>
<p><i>[2021-05-19 Tim adds wording]</i></p>

<p>
The wording below, which has been implemented and tested on top of libstdc++,
uses the same technique we use for <tt>unique_ptr</tt>, <tt>shared_ptr</tt>,
and <tt>span</tt>. It seems especially appropriate to have feature parity between
<tt>subrange</tt> and <tt>span</tt> in this respect.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.</p>

<ol>
<li><p>Modify 24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a> as indicated:</p>

<blockquote>
<pre>
namespace std::ranges {
  <ins>template&lt;class From, class To&gt;
    concept <i>uses-nonqualification-pointer-conversion</i> = <i>// exposition only</i>
      is_pointer_v&lt;From&gt; &amp;&amp; is_pointer_v&lt;To&gt; &amp;&amp;
      !convertible_to&lt;remove_pointer_t&lt;From&gt;(*)[], remove_pointer_t&lt;To&gt;(*)[]&gt;;</ins>

  template&lt;class From, class To&gt;
    concept <i>convertible-to-non-slicing</i> = <i>// exposition only</i>
      convertible_to&lt;From, To&gt; &amp;&amp;
      <ins>!<i>uses-nonqualification-pointer-conversion</i>&lt;decay_t&lt;From&gt;, decay_t&lt;To&gt;&gt;;</ins>
      <del>!(is_pointer_v&lt;decay_t&lt;From&gt;&gt; &amp;&amp;
      is_pointer_v&lt;decay_t&lt;To&gt;&gt; &amp;&amp;
      <i>not-same-as</i>&lt;remove_pointer_t&lt;decay_t&lt;From&gt;&gt;, remove_pointer_t&lt;decay_t&lt;To&gt;&gt;&gt;
      );</del>
  [&hellip;]
}
[&hellip;]
</pre>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3480" href="https://cplusplus.github.io/LWG/lwg-active.html#3480">3480</a>. <tt>directory_iterator</tt> and <tt>recursive_directory_iterator</tt> are not C++20 ranges</h3>
<p><b>Section:</b> 29.12.11 <a href="https://wg21.link/fs.class.directory.iterator">[fs.class.directory.iterator]</a>, 29.12.12 <a href="https://wg21.link/fs.class.rec.dir.itr">[fs.class.rec.dir.itr]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Barry Revzin <b>Opened:</b> 2020-08-27 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#fs.class.directory.iterator">issues</a> in [fs.class.directory.iterator].</p>
<p><b>Discussion:</b></p>
<p>
<tt>std::filesystem::directory_iterator</tt> and <tt>std::filesystem::recursive_directory_iterator</tt> are
intended to be ranges, but both fail to satisfy the concept <tt>std::ranges::range</tt>.
<p/>
They both opt in to being a range the same way, via non-member functions:
</p>
<blockquote><pre>
directory_iterator begin(directory_iterator iter) noexcept;
directory_iterator end(const directory_iterator&amp;) noexcept;

recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
recursive_directory_iterator end(const recursive_directory_iterator&amp;) noexcept;
</pre></blockquote>
<p>
This is good enough for a range-based for statement, but for the <tt>range</tt> concept, non-member
<tt>end</tt> is looked up in a context that includes (24.3.3 <a href="https://wg21.link/range.access.end">[range.access.end]</a>/2.6) the declarations:
</p>
<blockquote><pre>
void end(auto&amp;) = delete;
void end(const auto&amp;) = delete;
</pre></blockquote>
<p>
Which means that non-<tt>const</tt> <tt>directory_iterator</tt> and non-<tt>const</tt>
<tt>recursive_directory_iterator</tt>, the <tt>void end(auto&amp;)</tt> overload ends up being
a better match and thus the CPO <tt>ranges::end</tt> doesn't find a candidate. Which means that
<tt>{recursive_,}directory_iterator</tt> is not a range, even though <tt>const {recursive_,}directory_iterator</tt>
<em>is</em> a range.
<p/>
This could be fixed by having the non-member <tt>end</tt> for both of these types just take by value
(as libstdc++ currently does anyway) or by adding member functions <tt>begin() const</tt> and <tt>end() const</tt>.
<p/>
A broader direction would be to consider removing the poison pill overloads. Their motivation from
<a href="https://wg21.link/p0970">P0970</a> was to support what are now called borrowed ranges &mdash; but
that design now is based on specializing a variable template instead of providing a non-member <tt>begin</tt>
that takes an rvalue, so the initial motivation simply no longer exists. And, in this particular case,
causes harm.
</p>

<p><i>[2020-09-06; Reflector prioritization]</i></p>

<p>
Set priority to 3 during reflector discussions.
</p>

<p><i>[2021-02-22, Barry Revzin comments]</i></p>

<p>
When we do make whichever of the alternative adjustments necessary such that
<tt>range&lt;directory_iterator&gt;</tt> is <tt>true</tt>, we should also remember
to specialize <tt>enable_borrowed_range</tt> for both types to be <tt>true</tt> (since
the iterator is the range, this is kind of trivially true).
</p>

<p><i>[2021-05-17, Tim provides wording]</i></p>

<p>
Both MSVC and libstdc++'s <tt>end</tt> already take its argument by value, so
the wording below just does that. Any discussion about changing or removing the
poison pills is probably better suited for a paper.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.</p>
<ol>
<li>
<p>Edit 29.12.4 <a href="https://wg21.link/fs.filesystem.syn">[fs.filesystem.syn]</a>, header <tt>&lt;filesystem&gt;</tt> synopsis, as indicated:</p>
<blockquote>
<pre>
[&hellip;]
namespace std::filesystem {
  [&hellip;]

  // 29.12.11.3 <a href="https://wg21.link/fs.dir.itr.nonmembers">[fs.dir.itr.nonmembers]</a>, range access for directory iterators
  directory_iterator begin(directory_iterator iter) noexcept;
  directory_iterator end(<del>const</del> directory_iterator<del>&amp;</del>) noexcept;

  [&hellip;]

  // 29.12.12.3 <a href="https://wg21.link/fs.rec.dir.itr.nonmembers">[fs.rec.dir.itr.nonmembers]</a>, range access for recursive directory iterators
  recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
  recursive_directory_iterator end(<del>const</del> recursive_directory_iterator<del>&amp;</del>) noexcept;

  [&hellip;]
}

<ins>
namespace std::ranges {
  template&lt;&gt;
  inline constexpr bool enable_borrowed_range&lt;filesystem::directory_iterator&gt; = true;
  template&lt;&gt;
  inline constexpr bool enable_borrowed_range&lt;filesystem::recursive_directory_iterator&gt; = true;

  template&lt;&gt;
  inline constexpr bool enable_view&lt;filesystem::directory_iterator&gt; = true;
  template&lt;&gt;
  inline constexpr bool enable_view&lt;filesystem::recursive_directory_iterator&gt; = true;
}
</ins>
</pre>
</blockquote>
</li>
<li>
<p>Edit 29.12.11.3 <a href="https://wg21.link/fs.dir.itr.nonmembers">[fs.dir.itr.nonmembers]</a> as indicated:</p>
<blockquote>
<p>
-1- These functions enable range access for <tt>directory_iterator</tt>.
</p>
<pre>
directory_iterator begin(directory_iterator iter) noexcept;
</pre>
<blockquote>
<p>
-2- <i>Returns</i>: <tt>iter</tt>.
</p>
</blockquote>
<pre>
directory_iterator end(<del>const</del> directory_iterator<del>&amp;</del>) noexcept;
</pre>
<blockquote>
<p>
-3- <i>Returns</i>: <tt>directory_iterator()</tt>.
</p>
</blockquote>
</blockquote>
</li>
<li>
<p>Edit 29.12.12.3 <a href="https://wg21.link/fs.rec.dir.itr.nonmembers">[fs.rec.dir.itr.nonmembers]</a> as indicated:</p>
<blockquote>
<p>
-1- These functions enable use of <tt>recursive_directory_iterator</tt> with range-based for statements.
</p>
<pre>
recursive_directory_iterator begin(recursive_directory_iterator iter) noexcept;
</pre>
<blockquote>
<p>
-2- <i>Returns</i>: <tt>iter</tt>.
</p>
</blockquote>
<pre>
recursive_directory_iterator end(<del>const</del> recursive_directory_iterator<del>&amp;</del>) noexcept;
</pre>
<blockquote>
<p>
-3- <i>Returns</i>: <tt>recursive_directory_iterator()</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3498" href="https://cplusplus.github.io/LWG/lwg-active.html#3498">3498</a>. Inconsistent <tt>noexcept</tt>-specifiers for <tt>basic_syncbuf</tt></h3>
<p><b>Section:</b> 29.11.2.1 <a href="https://wg21.link/syncstream.syncbuf.overview">[syncstream.syncbuf.overview]</a>, 29.11.2.3 <a href="https://wg21.link/syncstream.syncbuf.assign">[syncstream.syncbuf.assign]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2020-11-10 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#syncstream.syncbuf.overview">issues</a> in [syncstream.syncbuf.overview].</p>
<p><b>Discussion:</b></p>
<p>
The synopsis in 29.11.2.1 <a href="https://wg21.link/syncstream.syncbuf.overview">[syncstream.syncbuf.overview]</a> shows the move assignment operator and
<tt>swap</tt> member as potentially throwing. The detailed descriptions in
29.11.2.3 <a href="https://wg21.link/syncstream.syncbuf.assign">[syncstream.syncbuf.assign]</a> are <tt>noexcept</tt>.
<p/>
Daniel:
<p/>
This mismatch is already present in the originally accepted paper
<a href="https://wg21.link/p0053r7">P0053R7</a>, so this is nothing that could be resolved editorially.
</p>

<p><i>[2020-11-21; Reflector prioritization]</i></p>

<p>
Set priority to 3 during reflector discussions.
</p>

<p><i>[2021-05-22 Tim adds PR]</i></p>

<p>The move assignment is specified to call <tt>emit()</tt> which can throw,
and there's nothing in the wording providing for catching/ignoring the exception,
so it can't be <tt>noexcept</tt>. The <tt>swap</tt> needs
to call <tt>basic_streambuf::swap</tt>, which isn't <tt>noexcept</tt>,
so it shouldn't be <tt>noexcept</tt> either.</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after eight votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 29.11.2.3 <a href="https://wg21.link/syncstream.syncbuf.assign">[syncstream.syncbuf.assign]</a> as indicated:</p>

<blockquote>
<pre>
basic_syncbuf&amp; operator=(basic_syncbuf&amp;&amp; rhs) <del>noexcept</del>;
</pre>
<blockquote>
<p>
-1- <i>Effects</i>: [&hellip;]
<p/>
-2- <i>Postconditions</i>: [&hellip;]
<p/>
-3- <i>Returns</i>: [&hellip;]
<p/>
-4- <i>Remarks</i>: [&hellip;]
</p>
</blockquote>
<pre>
void swap(basic_syncbuf&amp; other) <del>noexcept</del>;
</pre>
<blockquote>
<p>
-5- <i>Preconditions</i>: [&hellip;]
<p/>
-6- <i>Effects</i>: [&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3535" href="https://cplusplus.github.io/LWG/lwg-active.html#3535">3535</a>. <tt>join_view::<i>iterator</i>::iterator_category</tt> and <tt>::iterator_concept</tt> lie</h3>
<p><b>Section:</b> 24.7.12.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2021-03-16 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#range.join.iterator">active issues</a> in [range.join.iterator].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.join.iterator">issues</a> in [range.join.iterator].</p>
<p><b>Discussion:</b></p>
<p>
Per 24.7.12.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a>/1, <tt>join_view::<i>iterator</i>::iterator_concept</tt> denotes 
<tt>bidirectional_iterator_tag</tt> if <tt><i>ref-is-glvalue</i></tt> is <tt>true</tt> and <tt><i>Base</i></tt> and 
<tt>range_reference_t&lt;<i>Base</i>&gt;</tt> each model <tt>bidirectional_range</tt>. Similarly, paragraph 2 says that 
<tt>join_view::<i>iterator</i>::iterator_category</tt> is present if <tt><i>ref-is-glvalue</i></tt> is <tt>true</tt>, 
and denotes <tt>bidirectional_iterator_tag</tt> if the categories of the iterators of both <tt><i>Base</i></tt> and 
<tt>range_reference_t&lt;<i>Base</i>&gt;</tt> derive from <tt>bidirectional_iterator_tag</tt>.
<p/>
However, the constraints on the declarations of <tt>operator--</tt> and <tt>operator--(int)</tt> in the synopsis 
that immediately precedes paragraph 1 disagree. Certainly they also consistently require <tt><i>ref-is-glvalue</i> 
&amp;&amp; bidirectional_range&lt;<i>Base</i>&gt; &amp;&amp; bidirectional_range&lt;range_reference_t&lt;<i>Base</i>&gt;&gt;</tt>, 
but they additionally require <tt>common_range&lt;range_reference_t&lt;<i>Base</i>&gt;&gt;</tt>. So as currently specified, 
this iterator sometimes declares itself to be bidirectional despite not implementing <tt>--</tt>. This is not 
incorrect for iterator_concept &mdash; recall that <tt>iterator_concept</tt> is effectively an upper bound since 
the concepts require substantial syntax &mdash; but slightly misleading. It is, however, very much incorrect for 
<tt>iterator_category</tt> which must not denote a type derived from a tag that corresponds to a stronger category 
than that iterator implements.
<p/>
It's worth pointing out, that LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3313">3313</a> fixed the constraints on <tt>operator--()</tt> and 
<tt>operator--(int)</tt> by adding the <tt>common_range</tt> requirements, but failed to make a consistent change 
to the definitions of <tt>iterator_concept</tt> and <tt>iterator_category</tt>.
</p>

<p><i>[2021-04-04; Daniel comments]</i></p>

<p>
The below proposed wording can be compared as being based on <a href="https://wg21.link/n4885">N4885</a>.
</p>

<p><i>[2021-04-20; Reflector poll]</i></p>

<p>
Priority set to 2.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to the post-2021-February-virtual-meeting working draft.
</p>

<ol>
<li><p>Modify 24.7.12.3 <a href="https://wg21.link/range.join.iterator">[range.join.iterator]</a> as indicated:</p>

<blockquote>
<p>
-1- <tt><i>iterator</i>::iterator_concept</tt> is defined as follows:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <tt><i>ref-is-glvalue</i></tt> is <tt>true</tt><ins>,</ins> <del>and</del> <tt><i>Base</i></tt> 
<del>and <tt>range_reference_t&lt;<i>Base</i>&gt;</tt> each</del> model<ins>s</ins> <tt>bidirectional_range</tt>, 
<ins>and <tt>range_reference_t&lt;<i>Base</i>&gt;</tt> models both <tt>bidirectional_range</tt> and <tt>common_range</tt>,</ins> 
then <tt>iterator_concept</tt> denotes <tt>bidirectional_iterator_tag</tt>.</p></li>
<li><p>[&hellip;]</p></li>
</ol>
<p>
[&hellip;]
<p/>
-2- The member <i>typedef-name</i> <tt>iterator_category</tt> is defined if and only if <tt><i>ref-is-glvalue</i></tt> 
is <tt>true</tt>, <tt><i>Base</i></tt> models <tt>forward_range</tt>, and <tt>range_reference_t&lt;<i>Base</i>&gt;</tt> 
models <tt>forward_range</tt>. In that case, <tt><i>iterator</i>::iterator_category</tt> is defined as follows:
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; Let <tt><i>OUTERC</i></tt> denote <tt>iterator_traits&lt;iterator_t&lt;<i>Base</i>&gt;&gt;::iterator_category</tt>, 
and let <tt><i>INNERC</i></tt> denote <tt>iterator_traits&lt;iterator_t&lt;range_reference_t&lt;<i>Base</i>&gt;&gt;&gt;::iterator_category</tt>.</p></li>
<li><p>(2.2) &mdash; If <tt><i>OUTERC</i></tt> and <tt><i>INNERC</i></tt> each model 
<tt>derived_from&lt;bidirectional_iterator_tag&gt;</tt>, <ins>and <tt>range_reference_t&lt;<i>Base</i>&gt;</tt> models 
<tt>common_range</tt>,</ins> <tt>iterator_category</tt> denotes <tt>bidirectional_iterator_tag</tt>.</p></li>
<li><p>[&hellip;]</p></li>
</ol>
</blockquote>
</li>

</ol>






<hr>
<h3><a name="3554" href="https://cplusplus.github.io/LWG/lwg-active.html#3554">3554</a>. <tt>chrono::parse</tt> needs <tt>const charT*</tt> and <tt>basic_string_view&lt;charT&gt;</tt> overloads</h3>
<p><b>Section:</b> 27.13 <a href="https://wg21.link/time.parse">[time.parse]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Howard Hinnant <b>Opened:</b> 2021-05-22 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#time.parse">issues</a> in [time.parse].</p>
<p><b>Discussion:</b></p>
<p>
The <tt>chrono::parse</tt> functions take <tt>const basic_string&lt;charT, traits, Alloc&gt;&amp;</tt> parameters
to specify the format strings for the parse. Due to an oversight on my part in the proposal, overloads taking
<tt>const charT*</tt> and <tt>basic_string_view&lt;charT, traits&gt;</tt> were omitted. These are necessary when
the supplied arguments is a string literal or <tt>string_view</tt> respectively:
</p>
<blockquote><pre>
in &gt;&gt; parse("%F %T", tp);
</pre></blockquote>
<p>
These overloads have been implemented in the <a href="https://github.com/HowardHinnant/date">example implementation</a>.
</p>

<p><i>[2021-05-26; Reflector poll]</i></p>

<p>
Set priority to 2 after reflector poll.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 27.2 <a href="https://wg21.link/time.syn">[time.syn]</a>, header <tt>&lt;chrono&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
namespace chrono {
  <i>// 27.13 <a href="https://wg21.link/time.parse">[time.parse]</a>, parsing</i>
  <ins>template&lt;class charT, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp);

  template&lt;class charT, class traits, class Parsable&gt;
    <i>unspecified</i>
      parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);

  template&lt;class charT, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp, minutes&amp; offset);

  template&lt;class charT, class traits, class Parsable&gt;
    <i>unspecified</i>
      parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp, minutes&amp; offset);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);</ins>

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp,
            minutes&amp; offset);

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);

  [&hellip;]
}
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 27.13 <a href="https://wg21.link/time.parse">[time.parse]</a> as indicated:</p>

<blockquote>
<pre>
<ins>template&lt;class charT, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT&gt;&amp;&gt;(), fmt, tp)</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT&gt;{fmt}, tp);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Parsable&gt;
  <i>unspecified</i>
    parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.data(), tp)</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT, traits&gt;{fmt}, tp);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt, tp, addressof(abbrev))</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT, traits, Alloc&gt;{fmt}, tp, abbrev);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.data(), tp, addressof(abbrev))</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT, traits, Alloc&gt;{fmt}, tp, abbrev);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp, minutes&amp; offset);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT&gt;&amp;&gt;(), fmt, tp,
            declval&lt;basic_string&lt;charT&gt;*&gt;(),
            &amp;offset)</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT&gt;{fmt}, tp, offset);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Parsable&gt;
  <i>unspecified</i>
    parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp, minutes&amp; offset);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.data(), tp,
            declval&lt;basic_string&lt;charT, traits&gt;*&gt;(),
            &amp;offset)</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT, traits&gt;{fmt}, tp, offset);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
<i>unspecified</i>
  parse(const charT* fmt, Parsable&amp; tp,
        basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt, tp, addressof(abbrev), &amp;offset)</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT, traits, Alloc&gt;{fmt}, tp, abbrev, offset);</tt></ins>
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(basic_string_view&lt;charT, traits&gt; fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);</ins>
</pre>
<blockquote>
<p>
<ins>-?- <i>Constraints:</i> The expression</ins>
</p>
<blockquote><pre>
<ins>from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.data(), tp, addressof(abbrev), &amp;offset)</ins>
</pre></blockquote>
<p>
<ins>is well-formed when treated as an unevaluated operand.</ins>
<p/>
<ins>-?- <i>Effects:</i> Equivalent to <tt>return parse(basic_string&lt;charT, traits, Alloc&gt;{fmt}, tp, abbrev, offset);</tt></ins>
</p>
</blockquote><pre>
template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; format, Parsable&amp; tp);
</pre>
<blockquote>
<p>
-2- <i>Constraints:</i> The expression
</p>
<blockquote><pre>
from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), fmt.c_str(), tp)
</pre></blockquote>
<p>
is well-formed when treated as an unevaluated operand.
<p/>
-3- <i>Returns:</i> A manipulator such that the expression <tt>is &gt;&gt; parse(fmt, tp)</tt> has type <tt>I</tt>,
has value <tt>is</tt>, and calls <tt>from_stream(is, fmt.c_str(), tp)</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2021-06-02 Tim comments and provides updated wording]</i></p>

<p>
The current specification suggests that <tt>parse</tt> takes a reference to
the format string (stream extraction on the resulting manipulator is specified
to call <tt>from_stream</tt> on <tt>fmt.c_str()</tt>, not some copy), so we
can't call it with a temporary string.
<p/>
Additionally, since the underlying API (<tt>from_stream</tt>) requires a
null-terminated string, the usual practice is to avoid providing a
<tt>string_view</tt> overload (see, e.g., LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3430">3430</a>). The wording
below therefore only provides <tt>const charT*</tt> overloads. It does not use
"Equivalent to" to avoid requiring that the <tt>basic_string</tt> overload
and the <tt>const charT*</tt> overload return the same type. As the manipulator
is intended to be immediately consumed, the wording also adds normative
encouragement to make misuse more difficult.
</p>


<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 27.2 <a href="https://wg21.link/time.syn">[time.syn]</a>, header <tt>&lt;chrono&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
namespace chrono {
  <i>// 27.13 <a href="https://wg21.link/time.parse">[time.parse]</a>, parsing</i>
  <ins>template&lt;class charT, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp);</ins>

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; <del>format</del><ins>fmt</ins>, Parsable&amp; tp);

  <ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);</ins>

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; <del>format</del><ins>fmt</ins>, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);

  <ins>template&lt;class charT, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp, minutes&amp; offset);</ins>

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; <del>format</del><ins>fmt</ins>, Parsable&amp; tp,
            minutes&amp; offset);

  <ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const charT* fmt, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);</ins>

  template&lt;class charT, class traits, class Alloc, class Parsable&gt;
    <i>unspecified</i>
      parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; <del>format</del><ins>fmt</ins>, Parsable&amp; tp,
            basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);

  [&hellip;]
}
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 27.13 <a href="https://wg21.link/time.parse">[time.parse]</a> as indicated:</p>
<p>
-1- Each <tt>parse</tt> overload specified in this subclause calls
<tt>from_­stream</tt> unqualified, so as to enable argument dependent lookup
(6.5.4 <a href="https://wg21.link/basic.lookup.argdep">[basic.lookup.argdep]</a>). In the following paragraphs,
let <tt>is</tt> denote an object of type <tt>basic_­istream&lt;charT, traits&gt;</tt>
and let <tt>I</tt> be <tt>basic_­istream&lt;charT, traits&gt;&amp;</tt>,
where <tt>charT</tt> and <tt>traits</tt> are template parameters in that context.
<p/>
<ins>-?- <i>Recommended practice:</i> Implementations should make it difficult to
accidentally store or use a manipulator that may contain a dangling reference to a
format string, for example by making the manipulators produced by <tt>parse</tt>
immovable and preventing stream extraction into an lvalue of such a manipulator
type.</ins>
</p>
<blockquote>
<pre>
<ins>template&lt;class charT, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp);</ins>
template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp);
</pre>
<blockquote>
<p>
<ins>-?- Let <i>F</i> be <tt>fmt</tt> for the first overload and <tt>fmt.c_str()</tt> for the second overload.
Let <tt>traits</tt> be <tt>char_traits&lt;charT&gt;</tt> for the first overload.</ins>
<p/>
-2- <i>Constraints:</i> The expression
</p>
<blockquote><pre>
from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), <del>fmt.c_str()</del><ins><i>F</i></ins>, tp)
</pre></blockquote>
<p>
is well-formed when treated as an unevaluated operand.
<p/>
-3- <i>Returns:</i> A manipulator such that the expression <tt>is &gt;&gt; parse(fmt, tp)</tt>
has type <tt>I</tt>, has value <tt>is</tt>, and calls <tt>from_­stream(is, <del>fmt.c_str()</del><ins><i>F</i></ins>, tp)</tt>.
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);</ins>
template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev);
</pre>
<blockquote>
<p>
<ins>-?- Let <i>F</i> be <tt>fmt</tt> for the first overload and <tt>fmt.c_str()</tt> for the second overload.</ins>
<p/>
-4- <i>Constraints:</i> The expression
</p>
<blockquote><pre>
from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(), <del>fmt.c_str()</del><ins><i>F</i></ins>, tp, addressof(abbrev))
</pre></blockquote>
<p>
is well-formed when treated as an unevaluated operand.
<p/>
-5- <i>Returns:</i> A manipulator such that the expression <tt>is &gt;&gt; parse(fmt, tp, abbrev)</tt>
has type <tt>I</tt>, has value <tt>is</tt>, and calls <tt>from_­stream(is, <del>fmt.c_str()</del><ins><i>F</i></ins>, tp, addressof(abbrev))</tt>.
</p>
</blockquote>
<pre>
<ins>template&lt;class charT, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp, minutes&amp; offset);</ins>

template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp,
          minutes&amp; offset);
</pre>
<blockquote>
<p>
<ins>-?- Let <i>F</i> be <tt>fmt</tt> for the first overload and <tt>fmt.c_str()</tt> for the second overload.
Let <tt>traits</tt> be <tt>char_traits&lt;charT&gt;</tt> and <tt>Alloc</tt> be <tt>allocator&lt;charT&gt;</tt>
for the first overload.</ins>
<p/>
-6- <i>Constraints:</i> The expression
</p>
<blockquote><pre>
from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(),
            <del>fmt.c_str()</del><ins><i>F</i></ins>, tp,
            declval&lt;basic_string&lt;charT, traits, Alloc&gt;*&gt;(),
            &amp;offset)
</pre></blockquote>
<p>
is well-formed when treated as an unevaluated operand.
<p/>
-7- <i>Returns:</i> A manipulator such that the expression <tt>is &gt;&gt; parse(fmt, tp, offset)</tt>
has type <tt>I</tt>, has value <tt>is</tt>, and calls:
</p>
<blockquote><pre>
from_stream(is,
            <del>fmt.c_str()</del><ins><i>F</i></ins>, tp,
            static_cast&lt;basic_string&lt;charT, traits, Alloc&gt;*&gt;(nullptr),
            &amp;offset)
</pre></blockquote>
</blockquote>
<pre>
<ins>template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const charT* fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);</ins>

template&lt;class charT, class traits, class Alloc, class Parsable&gt;
  <i>unspecified</i>
    parse(const basic_string&lt;charT, traits, Alloc&gt;&amp; fmt, Parsable&amp; tp,
          basic_string&lt;charT, traits, Alloc&gt;&amp; abbrev, minutes&amp; offset);
</pre>
<blockquote>
<p>
<ins>-?- Let <i>F</i> be <tt>fmt</tt> for the first overload and <tt>fmt.c_str()</tt> for the second overload.</ins>
<p/>
-8- <i>Constraints:</i> The expression
</p>
<blockquote><pre>
from_stream(declval&lt;basic_istream&lt;charT, traits&gt;&amp;&gt;(),
            <del>fmt.c_str()</del><ins><i>F</i></ins>, tp, addressof(abbrev), &amp;offset)
</pre></blockquote>
<p>
is well-formed when treated as an unevaluated operand.
<p/>
-9- <i>Returns:</i> A manipulator such that the expression <tt>is &gt;&gt; parse(fmt, tp, abbrev, offset)</tt>
has type <tt>I</tt>, has value <tt>is</tt>, and calls
<tt>from_­stream(is, <del>fmt.c_str()</del><ins><i>F</i></ins>, tp, addressof(abbrev), &amp;offset)</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3557" href="https://cplusplus.github.io/LWG/lwg-active.html#3557">3557</a>. The <tt>static_cast</tt> expression in <tt>convertible_to</tt> has the wrong operand</h3>
<p><b>Section:</b> 18.4.4 <a href="https://wg21.link/concept.convertible">[concept.convertible]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-05-26 <b>Last modified:</b> 2021-06-07</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#concept.convertible">active issues</a> in [concept.convertible].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#concept.convertible">issues</a> in [concept.convertible].</p>
<p><b>Discussion:</b></p>
<p>
The specification of <tt>convertible_to</tt> implicitly requires <tt>static_cast&lt;To&gt;(f())</tt> 
to be equality-preserving. Under 18.2 <a href="https://wg21.link/concepts.equality">[concepts.equality]</a> p1, the operand of this expression 
is <tt>f</tt>, but what we really want is for <tt>f()</tt> to be treated as the operand. We should just
use <tt>declval</tt> (which is treated specially by the definition of "operand" for this purpose) instead 
of reinventing the wheel.
</p>

<p><i>[2021-06-07; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after nine votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 18.4.4 <a href="https://wg21.link/concept.convertible">[concept.convertible]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class From, class To&gt;
  concept convertible_to =
    is_convertible_v&lt;From, To&gt; &amp;&amp;
    requires<del>(add_rvalue_reference_t&lt;From&gt; (&amp;f)())</del> {
      static_cast&lt;To&gt;(<del>f</del><ins>declval&lt;From&gt;</ins>());
    };
</pre>
</blockquote>
</li>
</ol>




<hr>
<h3><a name="3559" href="https://cplusplus.github.io/LWG/lwg-active.html#3559">3559</a>. Semantic requirements of <tt>sized_range</tt> is circular</h3>
<p><b>Section:</b> 24.4.3 <a href="https://wg21.link/range.sized">[range.sized]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-06-03 <b>Last modified:</b> 2021-06-14</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.sized">issues</a> in [range.sized].</p>
<p><b>Discussion:</b></p>
<p>
24.4.3 <a href="https://wg21.link/range.sized">[range.sized]</a> p2.1 requires that for a <tt>sized_range t</tt>, <tt>ranges::size(t)</tt>
is equal to <tt>ranges::distance(t)</tt>. But for a <tt>sized_range</tt>, <tt>ranges::distance(t)</tt> 
is simply <tt>ranges::size(t)</tt> cast to the difference type.
<p/>
Presumably what we meant is that <tt>distance(begin, end)</tt> &mdash; the actual distance you get 
from traversing the range &mdash; is equal to what <tt>ranges::size</tt> produces, and not merely that 
casting from the size type to difference type is value-preserving. Otherwise, <tt>sized_range</tt> would
be more or less meaningless.
</p>

<p><i>[2021-06-14; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 24.4.3 <a href="https://wg21.link/range.sized">[range.sized]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T&gt;
  concept sized_range =
    range&lt;T&gt; &amp;&amp;
    requires(T&amp; t) { ranges::size(t); };
</pre>
<blockquote>
<p>
-2- Given an lvalue <tt>t</tt> of type <tt>remove_reference_t&lt;T&gt;</tt>, <tt>T</tt> models <tt>sized_range</tt> only if
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; <tt>ranges::size(t)</tt> is amortized &#x1d4aa;(1), does not modify <tt>t</tt>, and is equal to 
<tt>ranges::distance(<ins>ranges::begin(t), ranges::end(t)</ins><del>t</del>)</tt>, and</p></li>
<li><p>(2.2) &mdash; if <tt>iterator_t&lt;T&gt;</tt> models <tt>forward_iterator</tt>, <tt>ranges::size(t)</tt> is 
well-defined regardless of the evaluation of <tt>ranges::begin(t)</tt>.</p></li>
</ol>
</blockquote>
</blockquote>
</li>
</ol>




<hr>
<h3><a name="3560" href="https://cplusplus.github.io/LWG/lwg-active.html#3560">3560</a>. <tt>ranges::equal</tt> and <tt>ranges::is_permutation</tt> should short-circuit for <tt>sized_ranges</tt></h3>
<p><b>Section:</b> 25.6.11 <a href="https://wg21.link/alg.equal">[alg.equal]</a>, 25.6.12 <a href="https://wg21.link/alg.is.permutation">[alg.is.permutation]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-06-03 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#alg.equal">issues</a> in [alg.equal].</p>
<p><b>Discussion:</b></p>
<p>
<tt>ranges::equal</tt> and <tt>ranges::is_permutation</tt> are currently only required
to short-circuit on different sizes if the iterator and sentinel of the two ranges
pairwise model <tt>sized_sentinel_for</tt>. They should also short-circuit if the ranges are sized.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 25.6.11 <a href="https://wg21.link/alg.equal">[alg.equal]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class InputIterator1, class InputIterator2&gt;
  constexpr bool equal(InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2);
[&hellip;]
template&lt;class InputIterator1, class InputIterator2,
         class BinaryPredicate&gt;
  constexpr bool equal(InputIterator1 first1, InputIterator1 last1,
                       InputIterator2 first2, InputIterator2 last2,
                       BinaryPredicate pred);
[&hellip;]
template&lt;input_iterator I1, sentinel_for&lt;I1&gt; S1, input_iterator I2, sentinel_for&lt;I2&gt; S2,
         class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity&gt;
  requires indirectly_comparable&lt;I1, I2, Pred, Proj1, Proj2&gt;
  constexpr bool ranges::equal(I1 first1, S1 last1, I2 first2, S2 last2,
                               Pred pred = {},
                               Proj1 proj1 = {}, Proj2 proj2 = {});
template&lt;input_range R1, input_range R2, class Pred = ranges::equal_to,
         class Proj1 = identity, class Proj2 = identity&gt;
  requires indirectly_comparable&lt;iterator_t&lt;R1&gt;, iterator_t&lt;R2&gt;, Pred, Proj1, Proj2&gt;
  constexpr bool ranges::equal(R1&amp;&amp; r1, R2&amp;&amp; r2, Pred pred = {},
                               Proj1 proj1 = {}, Proj2 proj2 = {});
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-3- <i>Complexity:</i> If <del>the types of <tt>first1</tt>, <tt>last1</tt>, <tt>first2</tt>, and <tt>last2</tt></del>:
</p>
<ol style="list-style-type: none">
<li><p>(3.1) &mdash; <ins>the types of <tt>first1</tt>, <tt>last1</tt>, <tt>first2</tt>, and <tt>last2</tt></ins> 
meet the <i>Cpp17RandomAccessIterator</i> requirements (23.3.5.7 <a href="https://wg21.link/random.access.iterators">[random.access.iterators]</a>) <ins>and 
<tt>last1 - first1 != last2 - first2</tt></ins> for the overloads in namespace <tt>std</tt>;</p></li>
<li><p>(3.2) &mdash; <ins>the types of <tt>first1</tt>, <tt>last1</tt>, <tt>first2</tt>, and <tt>last2</tt></ins> 
pairwise model <tt>sized_sentinel_for</tt> (23.3.4.8 <a href="https://wg21.link/iterator.concept.sizedsentinel">[iterator.concept.sizedsentinel]</a>) <ins>and 
<tt>last1 - first1 != last2 - first2</tt></ins> for the <ins>first</ins> overload<del>s</del> in namespace 
<tt>ranges</tt>,</p></li>
<li><p><ins>(3.3) &mdash; <tt>R1</tt> and <tt>R2</tt> each model <tt>sized_range</tt> and <tt>ranges::distance(r1)
!= ranges::distance(r2)</tt> for the second overload in namespace <tt>ranges</tt>,</ins></p></li>
</ol>
<p>
<del>and <tt>last1 - first1 != last2 - first2</tt>,</del> then no applications of the corresponding predicate and
each projection; otherwise, [&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 25.6.12 <a href="https://wg21.link/alg.is.permutation">[alg.is.permutation]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;forward_iterator I1, sentinel_for&lt;I1&gt; S1, forward_iterator I2,
         sentinel_for&lt;I2&gt; S2, class Proj1 = identity, class Proj2 = identity,
         indirect_equivalence_relation&lt;projected&lt;I1, Proj1&gt;,
                                       projected&lt;I2, Proj2&gt;&gt; Pred = ranges::equal_to&gt;
  constexpr bool ranges::is_permutation(I1 first1, S1 last1, I2 first2, S2 last2,
                                        Pred pred = {},
                                        Proj1 proj1 = {}, Proj2 proj2 = {});
template&lt;forward_range R1, forward_range R2,
         class Proj1 = identity, class Proj2 = identity,
         indirect_equivalence_relation&lt;projected&lt;iterator_t&lt;R1&gt;, Proj1&gt;,
                                       projected&lt;iterator_t&lt;R2&gt;, Proj2&gt;&gt; Pred = ranges::equal_to&gt;
  constexpr bool ranges::is_permutation(R1&amp;&amp; r1, R2&amp;&amp; r2, Pred pred = {},
                                        Proj1 proj1 = {}, Proj2 proj2 = {});
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-7- <i>Complexity:</i> No applications of the corresponding predicate and projections if:
</p>
<ol style="list-style-type: none">
<li><p><ins>(7.1) &mdash; for the first overload,</ins></p>
<ol style="list-style-type: none">
<li><p>(7.<ins>1.</ins>1) &mdash; <tt>S1</tt> and <tt>I1</tt> model <tt>sized_sentinel_for&lt;S1, I1&gt;</tt>,</p></li>
<li><p>(7.<ins>1.</ins>2) &mdash; <tt>S2</tt> and <tt>I2</tt> model <tt>sized_sentinel_for&lt;S2, I2&gt;</tt>, and</p></li>
<li><p>(7.<ins>1.</ins>3) &mdash; <tt>last1 - first1 != last2 - first2</tt><del>.</del><ins>;</ins></p></li>
</ol>
</li>
<li><p><ins>(7.2) &mdash; for the second overload, <tt>R1</tt> and <tt>R2</tt> each model <tt>sized_range</tt>, 
and <tt>ranges::distance(r1) != ranges::distance(r2)</tt>.</ins></p></li>
</ol>
<p>
Otherwise, exactly <tt>last1 - first1</tt> applications of the corresponding predicate and projections if
<tt>ranges::equal(first1, last1, first2, last2, pred, proj1, proj2)</tt> would return <tt>true</tt>; otherwise,
at worst &#x1d4aa;(<tt><i>N</i><sup>2</sup></tt>), where <tt><i>N</i></tt> has the value <tt>last1 - first1</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>




<hr>
<h3><a name="3561" href="https://cplusplus.github.io/LWG/lwg-active.html#3561">3561</a>. Issue with internal counter in <tt>discard_block_engine</tt></h3>
<p><b>Section:</b> 26.6.5.2 <a href="https://wg21.link/rand.adapt.disc">[rand.adapt.disc]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Ilya Burylov <b>Opened:</b> 2021-06-03 <b>Last modified:</b> 2021-06-14</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#rand.adapt.disc">issues</a> in [rand.adapt.disc].</p>
<p><b>Discussion:</b></p>
<p>
A <tt>discard_block_engine</tt> engine adaptor is described in 26.6.5.2 <a href="https://wg21.link/rand.adapt.disc">[rand.adapt.disc]</a>. It produces 
random numbers from the underlying engine discarding <tt>(p - r)</tt> last values of <tt>p - size</tt> block, 
where <tt>r</tt> and <tt>p</tt> are template parameters of <tt>std::size_t</tt> type:
</p>
<blockquote><pre>
template&lt;class Engine, size_t p, size_t r&gt;
class discard_block_engine;
</pre></blockquote>
<p>
The transition algorithm for <tt>discard_block_engine</tt> is described as follows (paragraph 2):
</p>
<blockquote><p>
The transition algorithm discards all but <tt><i>r</i> &gt; 0</tt> values from each block of <tt><i>p</i> = <i>r</i></tt> 
values delivered by <tt>&escr;</tt>. The state transition is performed as follows: If <tt><i>n</i> = <i>r</i></tt>, 
advance the state of <tt>e</tt> from <tt>e<sub>i</sub></tt> to <tt>e<sub>i</sub>+<i>p</i>-<i>r</i></tt> and set 
<tt><i>n</i></tt> to <tt>0</tt>. In any case, then increment <tt><i>n</i></tt> and advance <tt>e</tt>'s then-current state 
<tt>e<sub>j</sub></tt> to <tt>e<sub>j+1</sub></tt>.
</p></blockquote>
<p>
Where <tt><i>n</i></tt> is of integer type. In the API of discard block engine, <tt><i>n</i></tt> is represented 
in the following way:
</p>
<blockquote><pre>
[&hellip;]
int n; <i>// exposition only</i>
</pre></blockquote>
<p>
In cases where <tt>int</tt> is equal to <tt>int32_t</tt>, overflow is possible for <tt><i>n</i></tt> that leads 
to undefined behavior. Such situation can happen when the <tt>p</tt> and <tt>r</tt> template parameters exceed 
<tt>INT_MAX</tt>.
<p/>
This misleading exposition block leads to differences in implementations:
</p>
<ul>
<li><p>GNU Libstdc++ uses <tt>size_t</tt> for <tt>n</tt> &mdash; in this case no overflow happened even if template 
parameters exceed <tt>INT_MAX</tt></p></li>
<li><p>LLVM Libcxx uses <tt>int</tt> for <tt>n</tt> together with a <tt>static_assert</tt> that is checking that 
<tt>p</tt> and <tt>r</tt> values are <tt>&lt;= INT_MAX</tt></p></li> 
</ul>
<p>
Such difference in implementation makes code not portable and may potentially breaks random number sequence consistency 
between different implementors of C++ std lib.
<p/>
The problematic use case is the following one:
</p>
<blockquote><pre>
#include &lt;iostream&gt;
#include &lt;random&gt;
#include &lt;limits&gt;

int main() {
  std::minstd_rand0 generator;

  constexpr std::size_t skipped_size = static_cast&lt;std::size_t&gt;(std::numeric_limits&lt;int&gt;::max());
  constexpr std::size_t block_size = skipped_size + 5;
  constexpr std::size_t used_block = skipped_size;

  std::cout &lt;&lt; "block_size = " &lt;&lt; block_size &lt;&lt; std::endl;
  std::cout &lt;&lt; "used_block = " &lt;&lt; used_block &lt;&lt; "\n" &lt;&lt; std::endl;

  std::discard_block_engine&lt;std::minstd_rand0, block_size, used_block&gt; discard_generator;

  <i>// Call discard procedures</i>
  discard_generator.discard(used_block);
  generator.discard(block_size);

  <i>// Call generation. Results should be equal</i>
  for (std::int32_t i = 0; i &lt; 10; ++i)
  {
    std::cout &lt;&lt; discard_generator() &lt;&lt; " should be equal " &lt;&lt; generator() &lt;&lt; std::endl;
  }
}
</pre></blockquote> 
<p>
We see no solid reason for <tt>n</tt> to be an <tt>int</tt>, given that the relevant template parameters are 
<tt>std::size_t</tt>. It seems like a perfectly fine use case to generate random numbers in amounts larger than 
<tt>INT_MAX</tt>.
<p/>
The proposal is to change exposition text to <tt>std::size_t</tt>:
</p>
<blockquote><pre>
size_t n; <i>// exposition only</i>
</pre></blockquote>
<p>
It will not mandate the existing libraries to break ABI, but at least guide for better implementation.
</p>

<p><i>[2021-06-14; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 26.6.5.2 <a href="https://wg21.link/rand.adapt.disc">[rand.adapt.disc]</a>, class template <tt>discard_block_engine</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
  [&hellip;]
  <i>// generating functions</i>
  result_type operator()();
  void discard(unsigned long long z);
  
  <i>// property functions</i>
  const Engine&amp; base() const noexcept { return e; };
  
private:
  Engine e; <i>// exposition only</i>
  <del>int</del><ins>size_t</ins> n; <i>// exposition only</i>
};
</pre>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3563" href="https://cplusplus.github.io/LWG/lwg-active.html#3563">3563</a>. <tt>keys_view</tt> example is broken</h3>
<p><b>Section:</b> 24.7.18.1 <a href="https://wg21.link/range.elements.overview">[range.elements.overview]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Barry Revzin <b>Opened:</b> 2021-05-29 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<p>
In 24.7.18.1 <a href="https://wg21.link/range.elements.overview">[range.elements.overview]</a> we have:
</p>
<blockquote><p>
<tt>keys_view</tt> is an alias for <tt>elements_view&lt;views::all_t&lt;R&gt;, 0&gt;</tt>, and
is useful for extracting keys from associative containers.
<p/>
[<i>Example 2:</i>
</p>
<blockquote><pre>
auto names = keys_view{historical_figures};
for (auto&amp;&amp; name : names) {
  cout &lt;&lt; name &lt;&lt; ' ';  <i>// prints Babbage Hamilton Lovelace Turing</i>
}
</pre></blockquote>
<p>
&mdash; <i>end example</i>]
</p>
</blockquote>
<p>
Where <tt>keys_view</tt> is defined as:
</p>
<blockquote><pre>
template&lt;class R&gt;
  using keys_view = elements_view&lt;views::all_t&lt;R&gt;, 0&gt;;
</pre></blockquote>
<p>
There's a similar example for <tt>values_view</tt>.
<p/>
But class template argument deduction cannot work here, <tt>keys_view(r)</tt> cannot deduce <tt>R</tt> &mdash;
it's a non-deduced context. At the very least, the example is wrong and should be rewritten as
<tt>views::keys(historical_figures)</tt>. Or, I guess, as
<tt>keys_view&lt;decltype(historical_figures)&gt;(historical_figures)&gt;</tt> (but really, not).
</p>

<p><i>[2021-05-29 Tim comments and provides wording]</i></p>

<p>
I have some ideas about making CTAD work for <tt>keys_view</tt> and
<tt>values_view</tt>, but current implementations of alias template CTAD are
not yet in a shape to permit those ideas to be tested.
What <em>is</em> clear, though, is that the current definitions of <tt>keys_view</tt>
and <tt>values_view</tt> can't possibly ever work for CTAD, because <tt>R</tt> is only
used in a non-deduced context and so they can never meet the "deducible" constraint in
12.2.2.9 <a href="https://wg21.link/over.match.class.deduct">[over.match.class.deduct]</a> p2.3.
<p/>
The proposed resolution below removes the <tt>views::all_t</tt> transformation
in those alias templates. This makes these aliases transparent enough to support CTAD out
of the box when a view is used, and any questions about deduction guides on
<tt>elements_view</tt> can be addressed later once the implementations become more mature.
This also makes them consistent with all the other views: you can't write
<tt>elements_view&lt;map&lt;int, int&gt;&amp;, 0&gt;</tt> or
<tt>reverse_view&lt;map&lt;int, int&gt;&amp;&gt;</tt>, so why do we allow
<tt>keys_view&lt;map&lt;int, int&gt;&amp;&gt;</tt>? It is, however, a breaking change,
so it is important that we get this in sooner rather than later.
<p/>
The proposed resolution has been implemented and tested.
</p>

<p><i>[2021-06-14; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll in August.
Partially addressed by an
<a href="https://github.com/cplusplus/draft/pull/4659">editorial change</a>.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 24.2 <a href="https://wg21.link/ranges.syn">[ranges.syn]</a>, header <tt>&lt;ranges&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
namespace std::ranges {
[&hellip;]

  <i>// 24.7.18 <a href="https://wg21.link/range.elements">[range.elements]</a>, elements view</i>
  template&lt;input_range V, size_t N&gt;
    requires <i>see below</i>
  class elements_view;

  template&lt;class T, size_t N&gt;
    inline constexpr bool enable_borrowed_range&lt;elements_view&lt;T, N&gt;&gt; = enable_borrowed_range&lt;T&gt;;

  template&lt;class R&gt;
    using keys_view = elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 0&gt;;
  template&lt;class R&gt;
    using values_view = elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 1&gt;;

[&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 24.7.18.1 <a href="https://wg21.link/range.elements.overview">[range.elements.overview]</a> as indicated:</p>

<blockquote>
<p>
-3- <tt>keys_view</tt> is an alias for <tt>elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 0&gt;</tt>,
and is useful for extracting keys from associative containers.
<p/>
[<i>Example 2</i>:
</p>
<blockquote>
<pre>
auto names = keys_view{<ins>views::all(</ins>historical_figures<ins>)</ins>};
for (auto&amp;&amp; name : names) {
  cout &lt;&lt; name &lt;&lt; ' '; <i>// prints Babbage Hamilton Lovelace Turing</i>
}
</pre>
</blockquote>
<p>
&mdash; <i>end example</i>]
<p/>
-4- <tt>values_view</tt> is an alias for <tt>elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 1&gt;</tt>,
and is useful for extracting values from associative containers.
<p/>
[<i>Example 3</i>:
</p>
<blockquote>
<pre>
auto is_even = [](const auto x) { return x % 2 == 0; };
cout &lt;&lt; ranges::count_if(values_view{<ins>views::all(</ins>historical_figures<ins>)</ins>}, is_even); <i>// prints 2</i>
</pre>
</blockquote>
<p>
&mdash; <i>end example</i>]
</p>
</blockquote>
</li>

</ol>
</blockquote>
<p><i>[2021-06-18 Tim syncs wording to latest working draft]</i></p>

<p>
The examples have been editorially corrected, so the new wording simply changes the
definition of <tt>keys_view</tt> and <tt>values_view</tt>.
</p>

<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.2 <a href="https://wg21.link/ranges.syn">[ranges.syn]</a>, header <tt>&lt;ranges&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
namespace std::ranges {
[&hellip;]

  <i>// 24.7.18 <a href="https://wg21.link/range.elements">[range.elements]</a>, elements view</i>
  template&lt;input_range V, size_t N&gt;
    requires <i>see below</i>
  class elements_view;

  template&lt;class T, size_t N&gt;
    inline constexpr bool enable_borrowed_range&lt;elements_view&lt;T, N&gt;&gt; = enable_borrowed_range&lt;T&gt;;

  template&lt;class R&gt;
    using keys_view = elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 0&gt;;
  template&lt;class R&gt;
    using values_view = elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 1&gt;;

[&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 24.7.18.1 <a href="https://wg21.link/range.elements.overview">[range.elements.overview]</a> as indicated:</p>

<blockquote>
<p>
-3- <tt>keys_view</tt> is an alias for <tt>elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 0&gt;</tt>,
and is useful for extracting keys from associative containers.
<p/>
[<i>Example 2</i>: &hellip; &mdash; <i>end example</i>]
<p/>
-4- <tt>values_view</tt> is an alias for <tt>elements_view&lt;<del>views::all_t&lt;</del>R<del>&gt;</del>, 1&gt;</tt>,
and is useful for extracting values from associative containers.
<p/>
[<i>Example 3</i>: &hellip; &mdash; <i>end example</i>]
</p>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3566" href="https://cplusplus.github.io/LWG/lwg-active.html#3566">3566</a>. Constraint recursion for <tt>operator&lt;=&gt;(optional&lt;T&gt;, U)</tt></h3>
<p><b>Section:</b> 20.6.8 <a href="https://wg21.link/optional.comp.with.t">[optional.comp.with.t]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2021-06-07 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#optional.comp.with.t">issues</a> in [optional.comp.with.t].</p>
<p><b>Discussion:</b></p>
<p>
The three-way-comparison operator for optionals and non-optionals is defined in [optional.comp.with.t] paragraph 25:
</p>
<blockquote><pre>
template&lt;class T, three_way_comparable_with&lt;T&gt; U&gt;
  constexpr compare_three_way_result_t&lt;T, U&gt;
    operator&lt;=&gt;(const optional&lt;T&gt;&amp; x, const U&amp; v);
</pre>
<blockquote><p>
-25- <i>Effects:</i> Equivalent to: <tt>return bool(x) ? *x &lt;=&gt; v : strong_ordering::less;</tt>
</p></blockquote>
</blockquote>
<p>
Checking <tt>three_way_comparable_with</tt> in particular requires checking that <tt>x &lt; v</tt> is well-formed 
for an lvalue <tt>const optional&lt;T&gt;</tt> and lvalue <tt>const U</tt>. <tt>x &lt; v</tt> can be rewritten as 
<tt>(v &lt;=&gt; x) &gt; 0</tt>. If <tt>U</tt> is a specialization of <tt>optional</tt>, this overload could be used for 
<tt>v &lt;=&gt; x</tt>, but first we must check the constraints&hellip;
</p>
<p>
The straightforward fix for this recursion seems to be to refuse to check <tt>three_way_comparable_with&lt;T&gt;</tt> 
when <tt>U</tt> is a specialization of <tt>optional</tt>. MSVC has been shipping such a fix; our initial tests for 
this new operator triggered the recursion.
</p>

<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 20.6.2 <a href="https://wg21.link/optional.syn">[optional.syn]</a>, header <tt>&lt;optional&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
<i>// 20.6.8 <a href="https://wg21.link/optional.comp.with.t">[optional.comp.with.t]</a>, comparison with T</i>
[&hellip;]
template&lt;class T, class U&gt; constexpr bool operator>=(const optional&lt;T&gt;&amp;, const U&amp;);
template&lt;class T, class U&gt; constexpr bool operator>=(const T&amp;, const optional&lt;U&gt;&amp;);
template&lt;class T, <del>three_way_comparable_with&lt;T&gt;</del><ins>class</ins> U&gt;
  <ins>requires <i>see below</i></ins>
    constexpr compare_three_way_result_t&lt;T, U&gt;
      operator&lt;=&gt;(const optional&lt;T&gt;&amp;, const U&amp;);

[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 20.6.8 <a href="https://wg21.link/optional.comp.with.t">[optional.comp.with.t]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, <del>three_way_comparable_with&lt;T&gt;</del><ins>class</ins> U&gt;
  <ins>requires (!<i>is-specialization-of</i>&lt;U, optional&gt;) &amp;&amp; three_way_comparable_with&lt;T, U&gt;</ins>
    constexpr compare_three_way_result_t&lt;T, U&gt;
      operator&lt;=&gt;(const optional&lt;T&gt;&amp;, const U&amp;);
</pre>
<blockquote>
<p>
<ins>-?- The exposition-only trait template <tt><i>is-specialization-of</i>&lt;A, B&gt;</tt> is a constant expression 
with value <tt>true</tt> when <tt>A</tt> denotes a specialization of the class template <tt>B</tt>, and <tt>false</tt> 
otherwise.</ins>
<p/>
-25- <i>Effects:</i> Equivalent to: <tt>return bool(x) ? *x &lt;=&gt; v : strong_ordering::less;</tt>
</p>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2021-06-14; Improved proposed wording based on reflector discussion]</i></p>


<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 20.6.2 <a href="https://wg21.link/optional.syn">[optional.syn]</a>, header <tt>&lt;optional&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
<i>// 20.6.3 <a href="https://wg21.link/optional.optional">[optional.optional]</a>, class template optional</i>
template&lt;class T&gt;
class optional;

<ins>template&lt;class T&gt; 
  constexpr bool <i>is-optional</i> = false;               <i>// exposition only</i></ins>
<ins>template&lt;class T&gt; 
  constexpr bool <i>is-optional</i>&lt;optional&lt;T&gt;&gt; = true;   <i>// exposition only</i></ins>

[&hellip;]
<i>// 20.6.8 <a href="https://wg21.link/optional.comp.with.t">[optional.comp.with.t]</a>, comparison with T</i>
[&hellip;]
template&lt;class T, class U&gt; constexpr bool operator>=(const optional&lt;T&gt;&amp;, const U&amp;);
template&lt;class T, class U&gt; constexpr bool operator>=(const T&amp;, const optional&lt;U&gt;&amp;);
template&lt;class T, <del>three_way_comparable_with&lt;T&gt;</del><ins>class</ins> U&gt;
  <ins>requires (!<i>is-optional</i>&lt;U&gt;) &amp;&amp; three_way_comparable_with&lt;T, U&gt;</ins>
    constexpr compare_three_way_result_t&lt;T, U&gt;
      operator&lt;=&gt;(const optional&lt;T&gt;&amp;, const U&amp;);

[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 20.6.8 <a href="https://wg21.link/optional.comp.with.t">[optional.comp.with.t]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, <del>three_way_comparable_with&lt;T&gt;</del><ins>class</ins> U&gt;
  <ins>requires (!<i>is-optional</i>&lt;U&gt;) &amp;&amp; three_way_comparable_with&lt;T, U&gt;</ins>
    constexpr compare_three_way_result_t&lt;T, U&gt;
      operator&lt;=&gt;(const optional&lt;T&gt;&amp; x, const U&amp; v);
</pre>
<blockquote>
<p>
-25- <i>Effects:</i> Equivalent to: <tt>return bool(x) ? *x &lt;=&gt; v : strong_ordering::less;</tt>
</p>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3567" href="https://cplusplus.github.io/LWG/lwg-active.html#3567">3567</a>. Formatting move-only iterators take two</h3>
<p><b>Section:</b> 20.20.6.4 <a href="https://wg21.link/format.context">[format.context]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2021-06-08 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3539">3539</a> fixed copies of potentially-move-only iterators in the <tt>format_to</tt> and 
<tt>vformat_to</tt> overloads, but missed the fact that member functions of <tt>basic_format_context</tt> 
are specified to copy iterators as well. In particular, 20.20.6.4 <a href="https://wg21.link/format.context">[format.context]</a> states:
</p>
<blockquote>
<pre>
iterator out();
</pre>
<blockquote><p>
-7- <i>Returns:</i> <tt>out_</tt>.
</p></blockquote>
<pre>
void advance_to(iterator it);
</pre>
<blockquote><p>
-8- <i>Effects:</i> Equivalent to: <tt>out_ = it;</tt>
</p></blockquote>
</blockquote>
<p>
both of which appear to require copyability.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 20.20.6.4 <a href="https://wg21.link/format.context">[format.context]</a> as indicated:</p>

<blockquote>
<pre>
iterator out();
</pre>
<blockquote>
<p>
-7- <del><i>Returns:</i> <tt>out_</tt>.</del><ins><i>Effects:</i> Equivalent to: <tt>return std::move(out_);</tt></ins>
</p>
</blockquote>
<pre>
void advance_to(iterator it);
</pre>
<blockquote>
<p>
-8- <i>Effects:</i> Equivalent to: <tt>out_ = <ins>std::move(</ins>it<ins>)</ins>;</tt>
</p>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3568" href="https://cplusplus.github.io/LWG/lwg-active.html#3568">3568</a>. <tt>basic_istream_view</tt> needs to initialize <tt><i>value_</i></tt></h3>
<p><b>Section:</b> 24.6.5.2 <a href="https://wg21.link/range.istream.view">[range.istream.view]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2021-06-15 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
<a href="https://wg21.link/P2325R3">P2325R3</a> removes the default member initializers for <tt>basic_istream_view</tt>'s exposition-only 
<tt><i>stream_</i></tt> and <tt><i>value_</i></tt> members. Consequently, copying a <tt>basic_istream_view</tt> 
before the first call to <tt>begin</tt> may produce undefined behavior since doing so necessarily copies the 
uninitialized <tt><i>value_</i></tt>. We should restore <tt><i>value_</i></tt>'s default member initializer and 
remove this particular footgun.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
Wording relative to the <a href="https://github.com/cplusplus/draft/releases/download/n4892/n4892.pdf">post-202106 
working draft</a> (as near as possible). This PR is currently being implemented in MSVC.
</p>

<ol>
<li><p>Modify 24.6.5.2 <a href="https://wg21.link/range.istream.view">[range.istream.view]</a> as indicated:</p>

<blockquote>
<pre>
namespace std::ranges {
  [&hellip;]
  template&lt;movable Val, class CharT, class Traits>
    requires default_initializable&lt;Val&gt; &amp;&amp;
             <i>stream-extractable</i>&lt;Val, CharT, Traits&gt;
  class basic_istream_view : public view_interface&lt;basic_istream_view&lt;Val, CharT, Traits&gt;&gt; {
    [&hellip;]
    Val <i>value_</i> <ins>= Val()</ins>; <i>// exposition only</i>
  };
}
</pre>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3570" href="https://cplusplus.github.io/LWG/lwg-active.html#3570">3570</a>. <tt>basic_osyncstream::emit</tt> should be an unformatted output function</h3>
<p><b>Section:</b> 29.11.3.3 <a href="https://wg21.link/syncstream.osyncstream.members">[syncstream.osyncstream.members]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-06-19 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
<tt>basic_osyncstream::emit</tt> seems rather similar to <tt>basic_ostream::flush</tt> &mdash;
both are "flushing" operations that forward to member functions of the
<tt>streambuf</tt> and set <tt>badbit</tt> if those functions fail. But the former isn't
currently specified as an unformatted output function, so it a) doesn't construct or check a 
<tt>sentry</tt> and b) doesn't set <tt>badbit</tt> if <tt>emit</tt> exits via an exception. At 
least the latter appears to be clearly desirable &mdash; a <tt>streambuf</tt> operation that throws 
ordinarily results in <tt>badbit</tt> being set.
<p/>
The reference implementation in <a href="https://wg21.link/P0053R7">P0053R7</a> constructs a <tt>sentry</tt> and only
calls <tt>emit</tt> on the <tt>streambuf</tt> if the <tt>sentry</tt> converts to <tt>true</tt>, 
so this seems to be an accidental omission in the wording.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 29.11.3.3 <a href="https://wg21.link/syncstream.osyncstream.members">[syncstream.osyncstream.members]</a> as indicated:</p>

<blockquote>
<pre>
void emit();
</pre>
<blockquote>
<p>
-1- <i>Effects:</i> <ins>Behaves as an unformatted output function (29.7.5.4 <a href="https://wg21.link/ostream.unformatted">[ostream.unformatted]</a>). 
After constructing a <tt>sentry</tt> object, c</ins><del>C</del>alls <tt>sb.emit()</tt>. If that call 
returns <tt>false</tt>, calls <tt>setstate(ios_base::badbit)</tt>.
</p>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3571" href="https://cplusplus.github.io/LWG/lwg-active.html#3571">3571</a>. <tt>flush_emit</tt> should set <tt>badbit</tt> if the <tt>emit</tt> call fails</h3>
<p><b>Section:</b> 29.7.5.5 <a href="https://wg21.link/ostream.manip">[ostream.manip]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-06-19 <b>Last modified:</b> 2021-06-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#ostream.manip">active issues</a> in [ostream.manip].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#ostream.manip">issues</a> in [ostream.manip].</p>
<p><b>Discussion:</b></p>
<p>
<tt>basic_osyncstream::emit</tt> is specified to set <tt>badbit</tt> if it fails
(29.11.3.3 <a href="https://wg21.link/syncstream.osyncstream.members">[syncstream.osyncstream.members]</a> p1), but the <tt>emit</tt> part of the
<tt>flush_emit</tt> manipulator isn't, even though the <tt>flush</tt> part does set
<tt>badbit</tt> if it fails.
<p/>
More generally, given an <tt>osyncstream s</tt>, <tt>s &lt;&lt; flush_emit;</tt> should
probably have the same behavior as <tt>s.flush(); s.emit()</tt>.
<p/>
The reference implementation linked in <a href="https://wg21.link/P0753R2">P0753R2</a> does set <tt>badbit</tt> on
failure, so at least this part appears to be an oversight. As
discussed in LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3570">3570</a>, <tt>basic_osyncstream::emit</tt> should probably be an
unformatted output function, so the <tt>emit</tt> part of <tt>flush_emit</tt> should do so too.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4885">N4885</a>.
</p>

<ol>
<li><p>Modify 29.7.5.5 <a href="https://wg21.link/ostream.manip">[ostream.manip]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class charT, class traits&gt;
  basic_ostream&lt;charT, traits&gt;&amp; flush_emit(basic_ostream&lt;charT, traits&gt;&amp; os);
</pre>
<blockquote>
<p>
-12- <i>Effects:</i> Calls <tt>os.flush()</tt>. Then, if <tt>os.rdbuf()</tt> is a 
<tt>basic_syncbuf&lt;charT, traits, Allocator&gt;*</tt>, called <tt>buf</tt> for the purpose of exposition, 
<ins>behaves as an unformatted output function (29.7.5.4 <a href="https://wg21.link/ostream.unformatted">[ostream.unformatted]</a>) of <tt>os</tt>. After 
constructing a <tt>sentry</tt> object,</ins> calls <tt>buf-&gt;emit()</tt>. <ins>If that call returns 
<tt>false</tt>, calls <tt>os.setstate(ios_base::badbit)</tt>.</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3572" href="https://cplusplus.github.io/LWG/lwg-active.html#3572">3572</a>. <tt><i>copyable-box</i></tt> should be fully <tt>constexpr</tt></h3>
<p><b>Section:</b> 24.7.3 <a href="https://wg21.link/range.copy.wrap">[range.copy.wrap]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-06-19 <b>Last modified:</b> 2021-07-17</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
<a href="https://wg21.link/P2231R1">P2231R1</a> made <tt>optional</tt> fully <tt>constexpr</tt>, but missed its cousin
<tt><i>semiregular-box</i></tt> (which was renamed to <tt><i>copyable-box</i></tt> by 
<a href="https://wg21.link/P2325R3">P2325R3</a>). Most operations of <tt><i>copyable-box</i></tt> are already 
<tt>constexpr</tt> simply because <tt><i>copyable-box</i></tt> is specified in terms of <tt>optional</tt>;
the only missing ones are the assignment operators layered on top when the wrapped type
isn't assignable itself.
</p>

<p><i>[2021-06-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after eight votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.7.3 <a href="https://wg21.link/range.copy.wrap">[range.copy.wrap]</a> as indicated:</p>

<blockquote>
<p>
-1- Many types in this subclause are specified in terms of an exposition-only class template <tt><i>copyable-box</i></tt>.
<tt><i>copyable-box</i>&lt;T&gt;</tt> behaves exactly like <tt>optional&lt;T&gt;</tt> with the following differences:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>(1.2) &mdash; [&hellip;]</p></li>
<li><p>(1.3) &mdash; If <tt>copyable&lt;T&gt;</tt> is not modeled, the copy assignment operator is equivalent to:</p>
<blockquote>
<pre>
<ins>constexpr</ins> <i>copyable-box</i>&amp; operator=(const <i>copyable-box</i>&amp; that)
  noexcept(is_nothrow_copy_constructible_v&lt;T&gt;) {
  if (this != addressof(that)) {
    if (that) emplace(*that);
    else reset();
  }
  return *this;
}
</pre>
</blockquote>
</li>
<li><p>(1.4) &mdash; If <tt>movable&lt;T&gt;</tt> is not modeled, the move assignment operator is equivalent to:</p>
<blockquote>
<pre>
<ins>constexpr</ins> <i>copyable-box</i>&amp; operator=(<i>copyable-box</i>&amp;&amp; that)
  noexcept(is_nothrow_move_constructible_v&lt;T&gt;) {
  if (this != addressof(that)) {
    if (that) emplace(std::move(*that));
    else reset();
  }
  return *this;
}
</pre>
</blockquote>
</li>
</ol>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3573" href="https://cplusplus.github.io/LWG/lwg-active.html#3573">3573</a>. Missing <i>Throws</i> element for <tt>basic_string_view(It begin, End end)</tt></h3>
<p><b>Section:</b> 21.4.3.2 <a href="https://wg21.link/string.view.cons">[string.view.cons]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2021-07-13 <b>Last modified:</b> 2021-07-17</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#string.view.cons">active issues</a> in [string.view.cons].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#string.view.cons">issues</a> in [string.view.cons].</p>
<p><b>Discussion:</b></p>
<p>
The standard does not specify the exceptions of this constructor, but since <tt>std::to_address</tt> is a 
<tt>noexcept</tt> function, this constructor throws if and only when <tt>end - begin</tt> throws, we should 
add a <i>Throws</i> element for it.
</p>


<p><i>[2021-08-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after eight votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 21.4.3.2 <a href="https://wg21.link/string.view.cons">[string.view.cons]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class It, class End&gt;
  constexpr basic_string_view(It begin, End end);
</pre>
<blockquote>
<p>
-7- <i>Constraints:</i> 
<p/>
[&hellip;]
<p/>
-8- <i>Preconditions:</i> 
<p/>
[&hellip;]
<p/>
-9- <i>Effects:</i> Initializes <tt>data_</tt> with <tt>to_address(begin)</tt> and initializes <tt>size_</tt> 
with <tt>end - begin</tt>.
<p/>
<ins>-?- <i>Throws:</i> When and what <tt>end - begin</tt> throws.</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3574" href="https://cplusplus.github.io/LWG/lwg-active.html#3574">3574</a>. <tt>common_iterator</tt> should be completely <tt>constexpr</tt>-able</h3>
<p><b>Section:</b> 23.5.4.1 <a href="https://wg21.link/common.iterator">[common.iterator]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2021-07-21 <b>Last modified:</b> 2021-08-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#common.iterator">issues</a> in [common.iterator].</p>
<p><b>Discussion:</b></p>
<p>
After <a href="https://wg21.link/P2231R1">P2231R1</a>, <tt>variant</tt> becomes completely <tt>constexpr</tt>-able, which means that 
<tt>common_iterator</tt> can also be completely <tt>constexpr</tt>-able.
</p>


<p><i>[2021-08-20; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>


<p><i>[2021-08-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 23.5.4.1 <a href="https://wg21.link/common.iterator">[common.iterator]</a>, class template <tt>common_iterator</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
namespace std {
  template&lt;input_or_output_iterator I, sentinel_for&lt;I&gt; S&gt;
    requires (!same_as&lt;I, S&gt; &amp;&amp; copyable&lt;I&gt;)
  class common_iterator {
  public:
    constexpr common_iterator() requires default_initializable&lt;I&gt; = default;
    constexpr common_iterator(I i);
    constexpr common_iterator(S s);
    template&lt;class I2, class S2&gt;
      requires convertible_to&lt;const I2&amp;, I&gt; &amp;&amp; convertible_to&lt;const S2&amp;, S&gt;
        constexpr common_iterator(const common_iterator&lt;I2, S2&gt;&amp; x);
        
    template&lt;class I2, class S2&gt;
      requires convertible_to&lt;const I2&amp;, I&gt; &amp;&amp; convertible_to&lt;const S2&amp;, S&gt; &amp;&amp;
               assignable_from&lt;I&amp;, const I2&amp;&gt; &amp;&amp; assignable_from&lt;S&amp;, const S2&amp;&gt;
      <ins>constexpr</ins> common_iterator&amp; operator=(const common_iterator&lt;I2, S2&gt;&amp; x);

    <ins>constexpr</ins> decltype(auto) operator*();
    <ins>constexpr</ins> decltype(auto) operator*() const
      requires <i>dereferenceable</i>&lt;const I&gt;;
    <ins>constexpr</ins> decltype(auto) operator-&gt;() const
      requires <i>see below</i>;
 
    <ins>constexpr</ins> common_iterator&amp; operator++();
    <ins>constexpr</ins> decltype(auto) operator++(int);

    template&lt;class I2, sentinel_for&lt;I&gt; S2&gt;
      requires sentinel_for&lt;S, I2&gt;
    friend <ins>constexpr</ins> bool operator==(
      const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y);
    template&lt;class I2, sentinel_for&lt;I&gt; S2&gt;
      requires sentinel_for&lt;S, I2&gt; &amp;&amp; equality_comparable_with&lt;I, I2&gt;
    friend <ins>constexpr</ins> bool operator==(
      const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y);

    template&lt;sized_sentinel_for&lt;I&gt; I2, sized_sentinel_for&lt;I&gt; S2&gt;
      requires sized_sentinel_for&lt;S, I2&gt;
    friend <ins>constexpr</ins> iter_difference_t&lt;I2&gt; operator-(
      const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y);

    friend <ins>constexpr</ins> iter_rvalue_reference_t&lt;I&gt; iter_move(const common_iterator&amp; i)
      noexcept(noexcept(ranges::iter_move(declval&lt;const I&amp;&gt;())))
        requires input_iterator&lt;I&gt;;
    template&lt;indirectly_swappable&lt;I&gt; I2, class S2&gt;
      friend <ins>constexpr</ins> void iter_swap(const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y)
        noexcept(noexcept(ranges::iter_swap(declval&lt;const I&amp;&gt;(), declval&lt;const I2&amp;&gt;())));

  private:
    variant&lt;I, S&gt; v_; <i>// exposition only</i>
  };
  [&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 23.5.4.3 <a href="https://wg21.link/common.iter.const">[common.iter.const]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class I2, class S2&gt;
  requires convertible_to&lt;const I2&amp;, I&gt; &amp;&amp; convertible_to&lt;const S2&amp;, S&gt; &amp;&amp;
           assignable_from&lt;I&amp;, const I2&amp;&gt; &amp;&amp; assignable_from&lt;S&amp;, const S2&amp;&gt;
    <ins>constexpr</ins> common_iterator&amp; operator=(const common_iterator&lt;I2, S2&gt;&amp; x);
</pre>
<blockquote>
<p>
-5- <i>Preconditions:</i> <tt>x.v_.valueless_by_exception()</tt> is <tt>false</tt>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.5.4.4 <a href="https://wg21.link/common.iter.access">[common.iter.access]</a> as indicated:</p>

<blockquote>
<pre>
<ins>constexpr</ins> decltype(auto) operator*();
<ins>constexpr</ins> decltype(auto) operator*() const
  requires <i>dereferenceable</i>&lt;const I&gt;;
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> <tt>holds_alternative&lt;I&gt;(v_)</tt> is <tt>true</tt>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
<ins>constexpr</ins> decltype(auto) operator-&gt;() const
  requires <i>see below</i>;
</pre>
<blockquote>
<p>
-3- The expression in the <i>requires-clause</i> is equivalent to:
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.5.4.5 <a href="https://wg21.link/common.iter.nav">[common.iter.nav]</a> as indicated:</p>

<blockquote>
<pre>
<ins>constexpr</ins> common_iterator&amp; operator++();
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> <tt>holds_alternative&lt;I&gt;(v_)</tt> is <tt>true</tt>.
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
<ins>constexpr</ins> decltype(auto) operator++(int);
</pre>
<blockquote>
<p>
-4- <i>Preconditions:</i> <tt>holds_alternative&lt;I&gt;(v_)</tt> is <tt>true</tt>.
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.5.4.6 <a href="https://wg21.link/common.iter.cmp">[common.iter.cmp]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class I2, sentinel_for&lt;I&gt; S2&gt;
  requires sentinel_for&lt;S, I2&gt;
friend <ins>constexpr</ins> bool operator==(
  const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y);
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> [&hellip;]
</p>
</blockquote>
<pre>
template&lt;class I2, sentinel_for&lt;I&gt; S2&gt;
  requires sentinel_for&lt;S, I2&gt; &amp;&amp; equality_comparable_with&lt;I, I2&gt;
friend <ins>constexpr</ins> bool operator==(
  const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y);
</pre>
<blockquote>
<p>
-3- <i>Preconditions:</i> [&hellip;]
</p>
</blockquote>
<pre>
template&lt;sized_sentinel_for&lt;I&gt; I2, sized_sentinel_for&lt;I&gt; S2&gt;
  requires sized_sentinel_for&lt;S, I2&gt;
friend <ins>constexpr</ins> iter_difference_t&lt;I2&gt; operator-(
  const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y);
</pre>
<blockquote>
<p>
-5- <i>Preconditions:</i> [&hellip;]
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.5.4.7 <a href="https://wg21.link/common.iter.cust">[common.iter.cust]</a> as indicated:</p>

<blockquote>
<pre>
friend <ins>constexpr</ins> iter_rvalue_reference_t&lt;I&gt; iter_move(const common_iterator&amp; i)
  noexcept(noexcept(ranges::iter_move(declval&lt;const I&amp;&gt;())))
    requires input_iterator&lt;I&gt;;
</pre>
<blockquote>
<p>
-1- <i>Preconditions:</i> [&hellip;]
</p>
</blockquote>
<pre>
template&lt;indirectly_swappable&lt;I&gt; I2, class S2&gt;
  friend <ins>constexpr</ins> void iter_swap(const common_iterator&amp; x, const common_iterator&lt;I2, S2&gt;&amp; y)
    noexcept(noexcept(ranges::iter_swap(declval&lt;const I&amp;&gt;(), declval&lt;const I2&amp;&gt;())));
</pre>
<blockquote>
<p>
-3- <i>Preconditions:</i> [&hellip;]
</p>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3580" href="https://cplusplus.github.io/LWG/lwg-active.html#3580">3580</a>. <tt>iota_view's iterator</tt>'s binary <tt>operator+</tt> should be improved</h3>
<p><b>Section:</b> 24.6.4.3 <a href="https://wg21.link/range.iota.iterator">[range.iota.iterator]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Zoe Carver <b>Opened:</b> 2021-08-14 <b>Last modified:</b> 2021-08-20</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.iota.iterator">issues</a> in [range.iota.iterator].</p>
<p><b>Discussion:</b></p>
<p>
<tt>iota_view</tt>'s iterator's <tt>operator+</tt> could avoid a copy construct by doing 
"<tt>i += n; return i</tt>" rather than "<tt>return i += n;</tt>" as seen in 24.6.4.3 <a href="https://wg21.link/range.iota.iterator">[range.iota.iterator]</a>.
<p/>
This is what libc++ has implemented and shipped, even though it may not technically be conforming 
(if a program asserted the number of copies, for example). 
<p/>
It might be good to update this operator and the minus operator accordingly. 
</p>

<p><i>[2021-08-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.6.4.3 <a href="https://wg21.link/range.iota.iterator">[range.iota.iterator]</a> as indicated:</p>

<blockquote>
<pre>
friend constexpr <i>iterator</i> operator+(<i>iterator</i> i, difference_type n)
  requires <i>advanceable</i>&lt;W&gt;;
</pre>
<blockquote>
<p>
-20- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
<del>return</del> i += n; 
<ins>return i;</ins>
</pre></blockquote>
</blockquote>
<pre>
friend constexpr <i>iterator</i> operator+(difference_type n, <i>iterator</i> i)
  requires <i>advanceable</i>&lt;W&gt;;
</pre>
<blockquote>
<p>
-21- <i>Effects:</i> Equivalent to: <tt>return i + n;</tt>
</p>
</blockquote>
<pre>
friend constexpr <i>iterator</i> operator-(<i>iterator</i> i, difference_type n)
  requires <i>advanceable</i>&lt;W&gt;;
</pre>
<blockquote>
<p>
-22- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
<del>return</del> i -= n;
<ins>return i;</ins>
</pre></blockquote>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3581" href="https://cplusplus.github.io/LWG/lwg-active.html#3581">3581</a>. The range constructor makes <tt>basic_string_view</tt> not trivially move constructible</h3>
<p><b>Section:</b> 21.4.3.2 <a href="https://wg21.link/string.view.cons">[string.view.cons]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Jiang An, Casey Carter <b>Opened:</b> 2021-08-16 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#string.view.cons">active issues</a> in [string.view.cons].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#string.view.cons">issues</a> in [string.view.cons].</p>
<p><b>Discussion:</b></p>
<p>
<b>Jiang An</b>:
</p>
<p>
 The issue is found in <a href="https://github.com/microsoft/STL/pull/2128">this Microsoft STL pull request</a>.
<p/>
I think an additional constraint should be added to 21.4.3.2 <a href="https://wg21.link/string.view.cons">[string.view.cons]</a>/11 (a similar constraint is 
already present for <tt>reference_wrapper</tt>):
</p>
<blockquote><p>
<ins>(11.?) &mdash; <tt>is_same_v&lt;remove_cvref_t&lt;R&gt;, basic_string_view&gt;</tt> is <tt>false</tt>.</ins>
</p></blockquote>
<p>
<b>Casey Carter</b>:
</p>
<p>
<a href="https://wg21.link/p1989R2">P1989R2</a> "Range constructor for <tt>std::string_view</tt> 2: Constrain Harder" 
added a converting constructor to <tt>basic_string_view</tt> that accepts (by forwarding reference) any sized 
contiguous range with a compatible element type. This constructor unfortunately intercepts attempts at move 
construction which previously would have resulted in a call to the copy constructor. (I suspect the authors of 
P1989 were under the mistaken impression that <tt>basic_string_view</tt> had a defaulted move constructor, which 
would sidestep this issue by being chosen by overload resolution via the "non-template vs. template" tiebreaker.)
<p/>
The resulting inefficiency could be corrected by adding a defaulted move constructor and move assignment operator 
to <tt>basic_string_view</tt>, but it would be awkward to add text to specify that these moves always leave the 
source intact. Presumably this is why the move operations were omitted in the first place. We therefore recommend 
constraining the conversion constructor template to reject arguments whose decayed type is <tt>basic_string_view</tt> 
(which we should probably do for all conversion constructor templates in the Standard Library).
<p/>
Implementation experience: MSVC STL is in the process of implementing this fix. Per Jonathan Wakely, libstdc++ has a 
similar constraint.
</p>

<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after nine votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 21.4.3.2 <a href="https://wg21.link/string.view.cons">[string.view.cons]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class R&gt;
  constexpr basic_string_view(R&amp;&amp; r);
</pre>
<blockquote>
<p>
-10- Let <tt>d</tt> be an lvalue of type <tt>remove_cvref_t&lt;R&gt;</tt>.
<p/>
-11- <i>Constraints</i>:
</p>
<ol style="list-style-type: none">
<li><p><ins>(11.?) &mdash; <tt>remove_cvref_t&lt;R&gt;</tt> is not the same type as <tt>basic_string_view</tt>,</ins></p></li>
<li><p>(11.1) &mdash; <tt>R</tt> models <tt>ranges::contiguous_range</tt> and <tt>ranges::sized_range</tt>,</p></li>
<li><p>(11.2) &mdash; <tt>is_same_v&lt;ranges::range_value_t&lt;R&gt;, charT&gt;</tt> is <tt>true</tt>,</p></li>
<li><p>[&hellip;]</p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol>




<hr>
<h3><a name="3585" href="https://cplusplus.github.io/LWG/lwg-active.html#3585">3585</a>. Variant converting assignment with immovable alternative</h3>
<p><b>Section:</b> 20.7.3.4 <a href="https://wg21.link/variant.assign">[variant.assign]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Barry Revzin <b>Opened:</b> 2021-09-01 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#variant.assign">active issues</a> in [variant.assign].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#variant.assign">issues</a> in [variant.assign].</p>
<p><b>Discussion:</b></p>
<p>
Example originally from <a href="https://stackoverflow.com/q/68998153/2069064">StackOverflow</a> but with a more reasonable example from Tim Song:
</p>
<blockquote><pre>
#include &lt;variant&gt;
#include &lt;string&gt;

struct A {
  A() = default;
  A(A&amp;&amp;) = delete;
};

int main() {
  std::variant&lt;A, std::string&gt; v;
  v = "hello";
}
</pre></blockquote>
<p>
There is implementation divergence here: libstdc++ rejects, libc++ and msvc accept.
<p/>
20.7.3.4 <a href="https://wg21.link/variant.assign">[variant.assign]</a> bullet (13.3) says that if we're changing the alternative in assignment 
and it is not the case that the converting construction won't throw (as in the above), then "Otherwise, 
equivalent to <tt>operator=(variant(std::forward&lt;T&gt;(t)))</tt>." That is, we defer to move assignment.
<p/>
<tt>variant&lt;A, string&gt;</tt> isn't move-assignable (because <tt>A</tt> isn't move constructible). Per 
the wording in the standard, we have to reject this. libstdc++ follows the wording of the standard.
<p/>
But we don't actually have to do a full move assignment here, since we know the situation we're in is 
changing the alternative, so the fact that <tt>A</tt> isn't move-assignable shouldn't matter. libc++ and 
msvc instead do something more direct, allowing the above program.
</p>

<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 20.7.3.4 <a href="https://wg21.link/variant.assign">[variant.assign]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> This should cover the case that we want to cover: that if construction of <tt>T<sub><i>j</i></sub></tt> 
from <tt>T</tt> throws, we haven't yet changed any state in the variant.]
</p>
</blockquote>

<blockquote>
<pre>
template&lt;class T&gt; constexpr variant&amp; operator=(T&amp;&amp; t) noexcept(<i>see below</i>);
</pre>
<blockquote>
<p>
-11- Let <tt>T<sub><i>j</i></sub></tt> be a type that is determined as follows: build an imaginary function 
<tt><i>FUN</i>(T<sub><i>i</i></sub>)</tt> for each alternative type <tt>T<sub><i>i</i></sub></tt> for which 
<tt>T<sub><i>i</i></sub> x[] = {std::forward&lt;T&gt;(t)};</tt> is well-formed for some invented variable 
<tt>x</tt>. The overload <tt><i>FUN</i>(T<sub><i>j</i></sub>)</tt> selected by overload resolution for the 
expression <tt><i>FUN</i>(std::forward&lt;T&gt;(t))</tt> defines the alternative <tt>T<sub><i>j</i></sub></tt> 
which is the type of the contained value after assignment.
<p/>
-12- <i>Constraints:</i> [&hellip;]
<p/>
-13- <i>Effects:</i>
</p>
<ol style="list-style-type: none">
<li><p>(13.1) &mdash; If <tt>*this</tt> holds a <tt>T<sub><i>j</i></sub></tt>, assigns <tt>std::forward&lt;T&gt;(t)</tt> 
to the value contained in <tt>*this</tt>.</p></li>
<li><p>(13.2) &mdash; Otherwise, if <tt>is_nothrow_constructible_v&lt;T<sub><i>j</i></sub>, T&gt; || 
!is_nothrow_move_constructible_v&lt;T<sub><i>j</i></sub>&gt;</tt> is <tt>true</tt>, equivalent to 
<tt>emplace&lt;<i>j</i>&gt;(std::forward&lt;T&gt;(t))</tt>.</p></li>
<li><p>(13.3) &mdash; Otherwise, equivalent to 
<tt><del>operator=(variant(std::forward&lt;T&gt;(t)))</del><ins>emplace&lt;<i>j</i>&gt;(T<sub><i>j</i></sub>(std::forward&lt;T&gt;(t)))</ins></tt>.</p></li>
</ol>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3589" href="https://cplusplus.github.io/LWG/lwg-active.html#3589">3589</a>. The <tt>const</tt> lvalue reference overload of <tt>get</tt> for <tt>subrange</tt> 
does not constrain <tt>I</tt> to be <tt>copyable</tt> when <tt>N == 0</tt></h3>
<p><b>Section:</b> 24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2021-09-08 <b>Last modified:</b> 2021-09-20</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#range.subrange">active issues</a> in [range.subrange].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.subrange">issues</a> in [range.subrange].</p>
<p><b>Discussion:</b></p>
<p>
The <tt>const</tt> lvalue reference overload of <tt>get</tt> used for <tt>subrange</tt> 
only constraint that <tt>N &lt; 2</tt>, this will cause the "discards qualifiers" error 
inside the function body when applying <tt>get</tt> to the lvalue <tt>subrange</tt> that 
stores a non-<tt>copyable</tt> iterator since its <tt>begin()</tt> is non-<tt>const</tt> 
qualified, we probably need to add a constraint for it.
</p>

<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>


<p><i>[2021-09-20; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.5.4 <a href="https://wg21.link/range.subrange">[range.subrange]</a> as indicated:</p>

<blockquote>
<pre>
namespace std::ranges {
  [&hellip;]
  template&lt;size_t N, class I, class S, subrange_kind K&gt;
    requires <ins>(</ins>(N <del>&lt; 2</del><ins>== 0 &amp;&amp; copyable&lt;I&gt;) || N == 1</ins>)
    constexpr auto get(const subrange&lt;I, S, K&gt;&amp; r);

  template&lt;size_t N, class I, class S, subrange_kind K&gt;
    requires (N &lt; 2)
    constexpr auto get(subrange&lt;I, S, K&gt;&amp;&amp; r);
}
</pre>
</blockquote>
</li>

<li><p>Modify 24.5.4.3 <a href="https://wg21.link/range.subrange.access">[range.subrange.access]</a> as indicated:</p>

<blockquote>
<pre>
  [&hellip;]
  template&lt;size_t N, class I, class S, subrange_kind K&gt;
    requires <ins>(</ins>(N <del>&lt; 2</del><ins>== 0 &amp;&amp; copyable&lt;I&gt;) || N == 1</ins>)
    constexpr auto get(const subrange&lt;I, S, K&gt;&amp; r);
  template&lt;size_t N, class I, class S, subrange_kind K&gt;
    requires (N &lt; 2)
    constexpr auto get(subrange&lt;I, S, K&gt;&amp;&amp; r);
</pre>
<blockquote>
<p>
-10- <i>Effects</i>: Equivalent to:
</p>
<pre>
if constexpr (N == 0)
  return r.begin();
else
  return r.end();
</pre>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3590" href="https://cplusplus.github.io/LWG/lwg-active.html#3590">3590</a>. <tt>split_view::base() const &amp;</tt> is overconstrained</h3>
<p><b>Section:</b> 24.7.14.2 <a href="https://wg21.link/range.split.view">[range.split.view]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-09-13 <b>Last modified:</b> 2021-09-24</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
Unlike every other range adaptor, <tt>split_view::base() const &amp;</tt> is
constrained on <tt>copyable&lt;V&gt;</tt> instead of <tt>copy_constructible&lt;V&gt;</tt>.
<p/>
Since this function just performs a copy construction, there is no
reason to require all of <tt>copyable</tt> &mdash; <tt>copy_constructible</tt> is sufficient.
</p>

<p><i>[2021-09-24; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after eight votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.7.14.2 <a href="https://wg21.link/range.split.view">[range.split.view]</a>, class template <tt>split_view</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
namespace std::ranges {
  template&lt;forward_range V, forward_range Pattern&gt;
    requires view&lt;V&gt; &amp;&amp; view&lt;Pattern&gt; &amp;&amp;
             indirectly_comparable&lt;iterator_t&lt;V&gt;, iterator_t&lt;Pattern&gt;, ranges::equal_to&gt;
  class split_view : public view_interface&lt;split_view&lt;V, Pattern&gt;&gt; {
  private:
    [&hellip;]
  public:
    [&hellip;]

    constexpr V base() const&amp; requires <del>copyable</del><ins>copy_constructible</ins>&lt;V&gt; { return <i>base_</i>; }
    constexpr V base() &amp;&amp; { return std::move(<i>base_</i>); }

    [&hellip;]
  };
</pre>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3591" href="https://cplusplus.github.io/LWG/lwg-active.html#3591">3591</a>. <tt>lazy_split_view&lt;input_view&gt;::<i>inner-iterator</i>::base() &amp;&amp;</tt> invalidates outer iterators</h3>
<p><b>Section:</b> 24.7.13.5 <a href="https://wg21.link/range.lazy.split.inner">[range.lazy.split.inner]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-09-13 <b>Last modified:</b> 2021-09-24</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
The <tt>base() &amp;&amp;</tt> members of iterator adaptors (and iterators of range
adaptors) invalidate the adaptor itself by moving from the contained iterator. This 
is generally unobjectionable &mdash; since you are calling <tt>base()</tt> on an rvalue, 
it is expected that you won't be using it afterwards.
<p/>
But <tt>lazy_split_view&lt;input_view&gt;::<i>inner-iterator</i>::base() &amp;&amp;</tt> 
is special: the iterator being moved from is stored in the <tt>lazy_split_view</tt> itself
and shared between the inner and outer iterators, so the operation invalidates not just the 
<tt><i>inner-iterator</i></tt> on which it is called, but also the <tt><i>outer-iterator</i></tt> 
from which the <tt><i>inner-iterator</i></tt> was obtained.
This spooky-action-at-a-distance behavior can be surprising, and the value category of the 
inner iterator seems to be too subtle to base it upon.
<p/>
The PR below constrains this overload to forward ranges. Forward iterators are copyable anyway, 
but moving could potentially be more efficient.

</p>

<p><i>[2021-09-24; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.7.13.5 <a href="https://wg21.link/range.lazy.split.inner">[range.lazy.split.inner]</a> as indicated:</p>

<blockquote style="note">
<p>
[<i>Drafting note:</i> The constraint uses <tt>forward_range&lt;V&gt;</tt> since that's the condition for 
caching in <tt>lazy_split_view</tt>.]
</p>
</blockquote>

<blockquote>
<blockquote>
<pre>
namespace std::ranges {
  template&lt;input_range V, forward_range Pattern&gt;
    requires view&lt;V&gt; &amp;&amp; view&lt;Pattern&gt; &amp;&amp;
             indirectly_comparable&lt;iterator_t&lt;V&gt;, iterator_t&lt;Pattern&gt;, ranges::equal_to&gt; &amp;&amp;
             (forward_range&lt;V&gt; || <i>tiny-range</i>&lt;Pattern&gt;)
  template&lt;bool Const&gt;
  struct lazy_split_view&lt;V, Pattern&gt;::<i>inner-iterator</i> {
  private:
    [&hellip;]
  public:
    [&hellip;]

    constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const &amp;;
    constexpr iterator_t&lt;<i>Base</i>&gt; base() &amp;&amp; <ins>requires forward_range&lt;V&gt;</ins>;

    [&hellip;]
  };
</pre>
</blockquote>
[&hellip;]
<pre>
constexpr iterator_t&lt;<i>Base</i>&gt; base() &amp;&amp; <ins>requires forward_range&lt;V&gt;</ins>;
</pre>
<blockquote>
<p>
-4- <i>Effects:</i> Equivalent to: <tt>return std::move(<i>i_.current</i>);</tt>
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3592" href="https://cplusplus.github.io/LWG/lwg-active.html#3592">3592</a>. <tt>lazy_split_view</tt> needs to check the simpleness of <tt>Pattern</tt></h3>
<p><b>Section:</b> 24.7.13.2 <a href="https://wg21.link/range.lazy.split.view">[range.lazy.split.view]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2021-09-15 <b>Last modified:</b> 2021-09-24</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#range.lazy.split.view">active issues</a> in [range.lazy.split.view].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.lazy.split.view">issues</a> in [range.lazy.split.view].</p>
<p><b>Discussion:</b></p>
<p>
For forward ranges, the non-<tt>const</tt> versions of <tt>lazy_split_view::begin()</tt>
and <tt>lazy_split_view::end()</tt> returns an <tt><i>outer-iterator</i>&lt;<i>simple-view</i>&lt;V&gt;&gt;</tt>,
promoting to <tt>const</tt> if <tt>V</tt> models <tt><i>simple-view</i></tt>. However, this failed to
take <tt>Pattern</tt> into account, even though that will also be accessed as <tt>const</tt> if 
<tt>const</tt>-promotion takes place. There is no requirement that <tt>const Pattern</tt> is a range, 
however.
</p>

<p><i>[2021-09-24; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 24.7.13.2 <a href="https://wg21.link/range.lazy.split.view">[range.lazy.split.view]</a>, class template <tt>lazy_split_view</tt> synopsis, as indicated:</p>

<blockquote>
<blockquote>
<pre>
namespace std::ranges {

  [&hellip;]

  template&lt;input_range V, forward_range Pattern&gt;
    requires view&lt;V&gt; &amp;&amp; view&lt;Pattern&gt; &amp;&amp;
             indirectly_comparable&lt;iterator_t&lt;V&gt;, iterator_t&lt;Pattern&gt;, ranges::equal_to&gt; &amp;&amp;
            (forward_range&lt;V&gt; || <i>tiny-range</i>&lt;Pattern&gt;)
  class lazy_split_view : public view_interface&lt;lazy_split_view&lt;V, Pattern&gt;&gt; {
  private:
    [&hellip;]
  public:
    [&hellip;]

    constexpr auto begin() {
      if constexpr (forward_range&lt;V&gt;)
        return <i>outer-iterator</i>&lt;<i>simple-view</i>&lt;V&gt;<ins> &amp;&amp;
          <i>simple-view</i>&lt;Pattern&gt;</ins>&gt;{*this, ranges::begin(<i>base_</i>)};
      else {
        <i>current_</i> = ranges::begin(<i>base_</i>);
        return <i>outer-iterator</i>&lt;false&gt;{*this};
      }
    }
    
    [&hellip;]
    
    constexpr auto end() requires forward_range&lt;V&gt; &amp;&amp; common_range&lt;V&gt; {
      return <i>outer-iterator</i>&lt;<i>simple-view</i>&lt;V&gt;<ins> &amp;&amp;
        <i>simple-view</i>&lt;Pattern&gt;</ins>&gt;{*this, ranges::end(<i>base_</i>)};
    }

    [&hellip;]
  };
  
  [&hellip;]
  
}
</pre>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3593" href="https://cplusplus.github.io/LWG/lwg-active.html#3593">3593</a>. Several iterators' <tt>base() const &amp;</tt> and <tt>lazy_split_view::<i>outer-iterator</i>::value_type::end()</tt> missing <tt>noexcept</tt></h3>
<p><b>Section:</b> 23.5.3 <a href="https://wg21.link/move.iterators">[move.iterators]</a>, 23.5.6 <a href="https://wg21.link/iterators.counted">[iterators.counted]</a>, 24.7.6.3 <a href="https://wg21.link/range.filter.iterator">[range.filter.iterator]</a>, 24.7.7.3 <a href="https://wg21.link/range.transform.iterator">[range.transform.iterator]</a>, 24.7.13.4 <a href="https://wg21.link/range.lazy.split.outer.value">[range.lazy.split.outer.value]</a>, 24.7.13.5 <a href="https://wg21.link/range.lazy.split.inner">[range.lazy.split.inner]</a>, 24.7.18.3 <a href="https://wg21.link/range.elements.iterator">[range.elements.iterator]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2021-09-14 <b>Last modified:</b> 2021-09-24</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#move.iterators">issues</a> in [move.iterators].</p>
<p><b>Discussion:</b></p>
<p>
LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3391">3391</a> and <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3533">3533</a> changed some iterators' <tt>base() const &amp;</tt> from returning value to 
returning <tt>const</tt> reference, which also prevents them from throwing exceptions, we should add <tt>noexcept</tt> for them. 
Also, <tt>lazy_split_view::<i>outer-iterator</i>::value_type::end()</tt> can be <tt>noexcept</tt> since it only returns 
<tt>default_sentinel</tt>.
</p>

<p><i>[2021-09-24; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 23.5.3 <a href="https://wg21.link/move.iterators">[move.iterators]</a>, class template <tt>move_iterator</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
constexpr const iterator_type&amp; base() const &amp; <ins>noexcept</ins>;
constexpr iterator_type base() &amp;&amp;;
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 23.5.3.5 <a href="https://wg21.link/move.iter.op.conv">[move.iter.op.conv]</a> as indicated:</p>

<blockquote>
<pre>
constexpr const Iterator&amp; base() const &amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-1- <i>Returns:</i> <tt>current</tt>.
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.5.6.1 <a href="https://wg21.link/counted.iterator">[counted.iterator]</a>, class template <tt>counted_iterator</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
constexpr const I&amp; base() const &amp; <ins>noexcept</ins>;
constexpr I base() &amp;&amp;;
[&hellip;]
</pre>
</blockquote>
</li>

<li><p>Modify 23.5.6.3 <a href="https://wg21.link/counted.iter.access">[counted.iter.access]</a> as indicated:</p>

<blockquote>
<pre>
constexpr const I&amp; base() const &amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-1- <i>Effects:</i> Equivalent to: <tt>return current;</tt>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.7.6.3 <a href="https://wg21.link/range.filter.iterator">[range.filter.iterator]</a> as indicated:</p>

<blockquote>
<blockquote>
<pre>
[&hellip;]
constexpr const iterator_t&lt;V&gt;&amp; base() const &amp; <ins>noexcept</ins>;
constexpr iterator_t&lt;V&gt; base() &amp;&amp;;
[&hellip;]
</pre>
</blockquote>
[&hellip;]
<pre>
constexpr const iterator_t&lt;V&gt;&amp; base() const &amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-5- <i>Effects:</i> Equivalent to: <tt>return <i>current_</i>;</tt>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.7.7.3 <a href="https://wg21.link/range.transform.iterator">[range.transform.iterator]</a> as indicated:</p>

<blockquote>
<blockquote>
<pre>
[&hellip;]
constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const &amp; <ins>noexcept</ins>;
constexpr iterator_t&lt;<i>Base</i>&gt; base() &amp;&amp;;
[&hellip;]
</pre>
</blockquote>
[&hellip;]
<pre>
constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const &amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-5- <i>Effects:</i> Equivalent to: <tt>return <i>current_</i>;</tt>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.7.13.4 <a href="https://wg21.link/range.lazy.split.outer.value">[range.lazy.split.outer.value]</a> as indicated:</p>

<blockquote>
<blockquote>
<pre>
[&hellip;]
constexpr <i>inner-iterator</i>&lt;Const&gt; begin() const;
constexpr default_sentinel_t end() const <ins>noexcept</ins>;
[&hellip;]
</pre>
</blockquote>
[&hellip;]
<pre>
constexpr default_sentinel_t end() const <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-3- <i>Effects:</i> Equivalent to: <tt>return default_sentinel;</tt>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.7.13.5 <a href="https://wg21.link/range.lazy.split.inner">[range.lazy.split.inner]</a> as indicated:</p>

<blockquote>
<blockquote>
<pre>
[&hellip;]
constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const &amp; <ins>noexcept</ins>;
constexpr iterator_t&lt;<i>Base</i>&gt; base() &amp;&amp;;
[&hellip;]
</pre>
</blockquote>
[&hellip;]
<pre>
constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const &amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-3- <i>Effects:</i> Equivalent to: <tt>return <i>i_</i>.<i>current</i>;</tt>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 24.7.18.3 <a href="https://wg21.link/range.elements.iterator">[range.elements.iterator]</a> as indicated:</p>

<blockquote>
<blockquote>
<pre>
[&hellip;]
constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const&amp; <ins>noexcept</ins>;
constexpr iterator_t&lt;<i>Base</i>&gt; base() &amp;&amp;;
[&hellip;]
</pre>
</blockquote>
[&hellip;]
<pre>
constexpr const iterator_t&lt;<i>Base</i>&gt;&amp; base() const&amp; <ins>noexcept</ins>;
</pre>
<blockquote>
<p>
-6- <i>Effects:</i> Equivalent to: <tt>return <i>current_</i>;</tt>
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3595" href="https://cplusplus.github.io/LWG/lwg-active.html#3595">3595</a>. Exposition-only classes <tt><i>proxy</i></tt> and <tt><i>postfix-proxy</i></tt> for <tt>common_iterator</tt> 
should be fully <tt>constexpr</tt></h3>
<p><b>Section:</b> 23.5.4.4 <a href="https://wg21.link/common.iter.access">[common.iter.access]</a>, 23.5.4.5 <a href="https://wg21.link/common.iter.nav">[common.iter.nav]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2021-09-18 <b>Last modified:</b> 2021-09-24</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3574">3574</a> added <tt>constexpr</tt> to all member functions and friends of <tt>common_iterator</tt> to make it 
fully <tt>constexpr</tt>, but accidentally omitted the exposition-only classes <tt><i>proxy</i></tt> and 
<tt><i>postfix-proxy</i></tt> defined for some member functions. We should make these two classes fully <tt>constexpr</tt>, too.
</p>

<p><i>[2021-09-24; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after seven votes in favour during reflector poll.
</p>



<p><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 23.5.4.4 <a href="https://wg21.link/common.iter.access">[common.iter.access]</a> as indicated:</p>

<blockquote>
<pre>
decltype(auto) operator-&gt;() const
  requires <i>see below</i>;
</pre>
<blockquote>
<p>
-3- [&hellip;]
<p/>
-4- [&hellip;]
<p/>
-5- <i>Effects:</i>
</p>
<ol style="list-style-type: none">
<li><p>(5.1) &mdash; [&hellip;]</p></li>
<li><p>(5.2) &mdash; [&hellip;]</p></li>
<li><p>(5.3) &mdash; Otherwise, equivalent to: <tt>return <i>proxy</i>(*get&lt;I&gt;(<i>v_</i>));</tt> 
where <tt><i>proxy</i></tt> is the exposition-only class:</p>
<blockquote><pre>
class <i>proxy</i> {
  iter_value_t&lt;I&gt; keep_;
  <ins>constexpr</ins> <i>proxy</i>(iter_reference_t&lt;I&gt;&amp;&amp; x)
    : keep_(std::move(x)) {}
public:
  <ins>constexpr</ins> const iter_value_t&lt;I&gt;* operator-&gt;() const <ins>noexcept</ins> {
    return addressof(keep_);
  }
};
</pre></blockquote>
</li>
</ol>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.5.4.5 <a href="https://wg21.link/common.iter.nav">[common.iter.nav]</a> as indicated:</p>

<blockquote>
<pre>
decltype(auto) operator++(int);
</pre>
<blockquote>
<p>
-4- [&hellip;]
<p/>
-5- <i>Effects:</i> If I models forward_iterator, equivalent to:
<p/>
[&hellip;]
<p/>
Otherwise, if [&hellip;]
<p/>
[&hellip;]
<p/>
Otherwise, equivalent to:
</p>
<blockquote><pre>
<i>postfix-proxy</i> p(**this);
++*this;
return p;
</pre></blockquote>
<p>
where <tt><i>postfix-proxy</i></tt> is the exposition-only class:
</p>
<blockquote><pre>
class <i>postfix-proxy</i> {
  iter_value_t&lt;I&gt; keep_;
  <ins>constexpr</ins> <i>postfix-proxy</i>(iter_reference_t&lt;I&gt;&amp;&amp; x)
    : keep_(std::forward&lt;iter_reference_t&lt;I&gt;&gt;(x)) {}
public:
  <ins>constexpr</ins> const iter_value_t&lt;I&gt;&amp; operator*() const <ins>noexcept</ins> {
    return keep_;
  }
};
</pre></blockquote>
</blockquote>
</blockquote>
</li>

</ol>





</body>
</html>
