<!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 Kona</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 Kona</h1>
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">P2703R0</td>
</tr>
<tr>
<td align="left">Date:</td>
<td align="left"><p>2022-11-07</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="#ready">Ready Issues</a></li>
<li><a href="#tentatively_ready">Tentatively Ready Issues</a></li>
</ul>
<h2 id="ready">Ready Issues</h2>
<hr>
<h3><a name="3118" href="https://cplusplus.github.io/LWG/lwg-active.html#3118">3118</a>. <tt>fpos</tt> equality comparison unspecified</h3>
<p><b>Section:</b> 31.5.3.2 <a href="https://wg21.link/fpos.operations">[fpos.operations]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2018-06-04 <b>Last modified:</b> 2022-11-02</p>
<p><b>Priority: </b>4
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#fpos.operations">issues</a> in [fpos.operations].</p>
<p><b>Discussion:</b></p>
<p>
The <tt>fpos</tt> requirements do not give any idea what is compared by <tt>operator==</tt> (even after Daniel's 
<a href="https://wg21.link/p0759r1">P0759R1</a> paper). I'd like something to make it clear that <tt>return true;</tt> 
is not a valid implementation of <tt>operator==(const fpos&lt;T&gt;&amp;, const fpos&lt;T&gt;&amp;)</tt>. Maybe in the 
<tt>P(o)</tt> row state that "<tt>p == P(o)</tt>" and "<tt>p != P(o + 1)</tt>", i.e. two <tt>fpos</tt> objects 
constructed from the same <tt>streamoff</tt> values are equal, and two <tt>fpos</tt> objects constructed from two 
different <tt>streamoff</tt> values are not equal.
</p>

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

<p>Priority set to 4</p>

<p><i>[2022-05-01; Daniel comments and provides wording]</i></p>

<p>
The proposed wording does intentionally not use a form involving addition or subtraction to prevent the need
for extra wording that ensures that this computed value is well-defined. According to 31.2.2 <a href="https://wg21.link/stream.types">[stream.types]</a>,
<tt>streamoff</tt> is a signed basic integral type, so we know what equality means for such values.
</p>

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

<li><p>Modify in 31.5.3.2 <a href="https://wg21.link/fpos.operations">[fpos.operations]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> The return type specification of <tt>operator==</tt> should be resolved in
sync with <a href="https://isocpp.org/files/papers/D2167R2.html">D2167R2</a>; see also LWG
<a href="https://cplusplus.github.io/LWG/lwg-active.html#2114">2114</a>.]
</p>
</blockquote>

<blockquote>

<ol style="list-style-type:none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>(1.5) &mdash; <tt>o</tt> <ins>and <tt>o2</tt></ins> refer<del>s</del> to <del>a</del> value<ins>s</ins> 
of type <tt>streamoff</tt> or <tt>const streamoff</tt>.</p></li>
</ol>
<table border="1">
<caption>Table 119: Position type requirements [tab:fpos.operations]</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion/note<br/>pre-/post-condition</th>
</tr>

<tr>
<td colspan="4" style="text-align:center;">&hellip;</td> 
</tr>

<tr>
<td><tt>P p(o);<br/>
P p = o;</tt></td>
<td></td>
<td></td>
<td><i>Effects:</i> Value-initializes the<br/>
state object.<br/>
<i>Postconditions:</i> <tt>p == P(o)</tt> <ins>is <tt>true</tt>.</ins></td>
</tr>

<tr>
<td colspan="4" style="text-align:center;">&hellip;</td> 
</tr>

<tr>
<td><tt>O(p)</tt></td>
<td><tt>streamoff</tt></td>
<td>converts to <tt>offset</tt></td>
<td><tt>P(O(p)) == p</tt></td>
</tr>

<tr>
<td><ins><tt>p == q</tt></ins></td>
<td><ins>convertible to <tt>bool</tt></ins></td>
<td></td>
<td><ins><i>Remarks:</i> For any two values <tt>o</tt> and <tt>o2</tt>, if<br/> 
<tt>p</tt> is obtained from <tt>o</tt> converted to <tt>P</tt> or from a copy<br/> 
of such <tt>P</tt> value and if <tt>q</tt> is obtained from <tt>o2</tt><br/> 
converted to <tt>P</tt> or from a copy of such <tt>P</tt> value, then<br/> 
<tt>bool(p == q)</tt> is <tt>true</tt> only if <tt>o == o2</tt> is <tt>true</tt>.</ins></td>
</tr>

<tr>
<td><tt>p != q</tt></td>
<td>convertible to <tt>bool</tt></td>
<td><tt>!(p == q)</tt></td>
<td></td>
</tr>

<tr>
<td colspan="4" style="text-align:center;">&hellip;</td> 
</tr>

</table>
</blockquote>
</li>
</blockquote>

<p><i>[2022-11-02; Daniel  comments and improves wording]</i></p>

<p>
<a href="https://wiki.edg.com/bin/view/Wg21telecons2022/P2167-20220921">LWG discussion</a> of <a href="https://wg21.link/P2167R2">P2167R2</a>
has shown preference to require that the equality operations of <tt>fpos</tt> should be specified to have type
<tt>bool</tt> instead of being specified as "convertible to <tt>bool</tt>". This has been reflected in the most recent
paper revision <a href="https://isocpp.org/files/papers/P2167R3.html">P2167R3</a>. The below wording changes
follow that direction to reduce the wording mismatch to a minimum.
</p>

<p><i>[2022-11-02; LWG telecon]</i></p>

<p>Moved to Ready. For: 6, Against: 0, Neutral: 0</p>



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

<li><p>Modify in 31.5.3.2 <a href="https://wg21.link/fpos.operations">[fpos.operations]</a> as indicated:</p>

<blockquote>

<ol style="list-style-type:none">
<li><p>(1.1) &mdash; [&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>(1.5) &mdash; <tt>o</tt> <ins>and <tt>o2</tt></ins> refer<del>s</del> to <del>a</del> value<ins>s</ins> 
of type <tt>streamoff</tt> or <tt>const streamoff</tt>.</p></li>
</ol>
<table border="1">
<caption>Table 124: Position type requirements [tab:fpos.operations]</caption>

<tr>
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion/note<br/>pre-/post-condition</th>
</tr>

<tr>
<td colspan="4" style="text-align:center;">&hellip;</td> 
</tr>

<tr>
<td><tt>P p(o);<br/>
P p = o;</tt></td>
<td></td>
<td></td>
<td><i>Effects:</i> Value-initializes the<br/>
state object.<br/>
<i>Postconditions:</i> <tt>p == P(o)</tt> <ins>is <tt>true</tt>.</ins></td>
</tr>

<tr>
<td colspan="4" style="text-align:center;">&hellip;</td> 
</tr>

<tr>
<td><tt>O(p)</tt></td>
<td><tt>streamoff</tt></td>
<td>converts to <tt>offset</tt></td>
<td><tt>P(O(p)) == p</tt></td>
</tr>

<tr>
<td><ins><tt>p == q</tt></ins></td>
<td><ins><tt>bool</tt></ins></td>
<td></td>
<td><ins><i>Remarks:</i> For any two values <tt>o</tt> and <tt>o2</tt>, if<br/> 
<tt>p</tt> is obtained from <tt>o</tt> converted to <tt>P</tt> or from a copy<br/> 
of such <tt>P</tt> value and if <tt>q</tt> is obtained from <tt>o2</tt><br/> 
converted to <tt>P</tt> or from a copy of such <tt>P</tt> value, then<br/> 
<tt>p == q</tt> is <tt>true</tt> only if <tt>o == o2</tt> is <tt>true</tt>.</ins></td>
</tr>

<tr>
<td><tt>p != q</tt></td>
<td><del>convertible to</del> <tt>bool</tt></td>
<td><tt>!(p == q)</tt></td>
<td></td>
</tr>

<tr>
<td colspan="4" style="text-align:center;">&hellip;</td> 
</tr>

</table>
</blockquote>
</li>





<hr>
<h3><a name="3594" href="https://cplusplus.github.io/LWG/lwg-active.html#3594">3594</a>. <tt>inout_ptr</tt> &mdash; inconsistent <tt>release()</tt> in destructor</h3>
<p><b>Section:</b> 20.3.4.3 <a href="https://wg21.link/inout.ptr.t">[inout.ptr.t]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> JeanHeyd Meneide <b>Opened:</b> 2021-09-16 <b>Last modified:</b> 2022-08-24</p>
<p><b>Priority: </b>1
</p>
<p><b>Discussion:</b></p>
<p>
More succinctly, the model for <tt>std::out_ptr_t</tt> and <tt>std::inout_ptr_t</tt>
both have a conditional release in their destructors as part of their
specification (20.3.4.1 <a href="https://wg21.link/out.ptr.t">[out.ptr.t]</a> p8) (Option #2 below).
But, if the wording is followed, they have an unconditional release in
their constructor (Option #1 below). This is not exactly correct and
can cause issues with double-free in <tt>inout_ptr</tt> in particular.
<p/>
Consider a function <tt>MyFunc</tt> that sets <tt>rawPtr</tt> to <tt>nullptr</tt> when freeing
an old value and deciding not to produce a new value, as shown below:
</p>
<blockquote><pre>
// Option #1:
auto uptr = std::make_unique&lt;BYTE[]&gt;(25);
auto rawPtr = uptr.get();
uptr.release(); // UNCONDITIONAL
MyFunc(&amp;rawPtr);
If (rawPtr)
{
  uptr.reset(rawPtr);
}

// Option #2:
auto uptr = std::make_unique&lt;BYTE[]&gt;(25);
auto rawPtr = uptr.get();
MyFunc(&amp;rawPtr);
If (rawPtr)
{
  uptr.release(); // CONDITIONAL
  uptr.reset(rawPtr);
}
</pre></blockquote>
<p>
This is no problem if the implementation selected Option #1 (release
in the constructor), but results in double-free if the implementation
selected option #2 (release in the destructor).
<p/>
As the paper author and after conferring with others, the intent was
that the behavior was identical and whether a choice between the
constructor or destructor is made. The reset should be unconditional,
at least for <tt>inout_ptr_t</tt>. Suggested change for the <tt>~inout_ptr_t</tt>
destructor text is to remove the "<tt>if (p) { ... }</tt>" wrapper from around
the code in 20.3.4.3 <a href="https://wg21.link/inout.ptr.t">[inout.ptr.t]</a> p11.
</p>

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

<p>
Set priority to 1 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/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify 20.3.4.3 <a href="https://wg21.link/inout.ptr.t">[inout.ptr.t]</a> as indicated:</p>

<blockquote>
<pre>
~inout_ptr_t();
</pre>
<blockquote>
<p>
-9- Let <tt>SP</tt> be <tt><i>POINTER_OF_OR</i>(Smart, Pointer)</tt> (20.2.1 <a href="https://wg21.link/memory.general">[memory.general]</a>).
<p/>
-10- Let <tt><i>release-statement</i></tt> be <tt>s.release()</tt>; if an implementation does not call <tt>s.release()</tt> in the
constructor. Otherwise, it is empty.
<p/>
-11- <i>Effects:</i> Equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(11.1) &mdash; </p>
<blockquote><pre>
<del>if (p) {</del>
  apply([&amp;](auto&amp;&amp;... args) {
  s = Smart( static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...); }, std::move(a));
<del>}</del>
</pre></blockquote>
<p>
if <tt>is_pointer_v&lt;Smart&gt;</tt> is <tt>true</tt>;
</p></li>
<li><p>(11.2) &mdash; otherwise,</p>
<blockquote><pre>
<del>if (p) {</del>
  apply([&amp;](auto&amp;&amp;... args) {
  <i>release-statement</i>;
  s.reset(static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...); }, std::move(a));
<del>}</del>
</pre></blockquote>
<p>
if the expression <tt>s.reset(static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...)</tt> is well-formed;
</p>
</li>
<li><p>(11.3) &mdash; otherwise,</p>
<blockquote><pre>
<del>if (p) {</del>
  apply([&amp;](auto&amp;&amp;... args) {
  <i>release-statement</i>;
  s = Smart(static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...); }, std::move(a));
<del>}</del>
</pre></blockquote>
<p>
if <tt>is_constructible_v&lt;Smart, SP, Args...&gt;</tt> is <tt>true</tt>;
</p>
</li>
<li><p>(11.4) &mdash; otherwise, the program is ill-formed.</p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2021-10-28; JeanHeyd Meneide provides improved wording]</i></p>


<p><i>[2022-08-24 Approved unanimously in LWG telecon.]</i></p>




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

<ol>
<li><p>Modify 20.3.4.3 <a href="https://wg21.link/inout.ptr.t">[inout.ptr.t]</a> as indicated:</p>

<blockquote>
<pre>
~inout_ptr_t();
</pre>
<blockquote>
<p>
-9- Let <tt>SP</tt> be <tt><i>POINTER_OF_OR</i>(Smart, Pointer)</tt> (20.2.1 <a href="https://wg21.link/memory.general">[memory.general]</a>).
<p/>
-10- Let <tt><i>release-statement</i></tt> be <tt>s.release()</tt>; if an implementation does not call <tt>s.release()</tt> in the
constructor. Otherwise, it is empty.
<p/>
-11- <i>Effects:</i> Equivalent to:
</p>
<ol style="list-style-type: none">
<li><p>(11.1) &mdash; </p>
<blockquote><pre>
if (p) {
  apply([&amp;](auto&amp;&amp;... args) {
  s = Smart( static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...); }, std::move(a));
}
</pre></blockquote>
<p>
if <tt>is_pointer_v&lt;Smart&gt;</tt> is <tt>true</tt>;
</p></li>
<li><p>(11.2) &mdash; otherwise,</p>
<blockquote><pre>
<ins><i>release-statement</i>;</ins>
if (p) {
  apply([&amp;](auto&amp;&amp;... args) {
  <del><i>release-statement</i>;</del>
  s.reset(static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...); }, std::move(a));
}
</pre></blockquote>
<p>
if the expression <tt>s.reset(static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...)</tt> is well-formed;
</p>
</li>
<li><p>(11.3) &mdash; otherwise,</p>
<blockquote><pre>
<ins><i>release-statement</i>;</ins>
if (p) {
  apply([&amp;](auto&amp;&amp;... args) {
  <del><i>release-statement</i>;</del>
  s = Smart(static_cast&lt;SP&gt;(p), std::forward&lt;Args&gt;(args)...); }, std::move(a));
}
</pre></blockquote>
<p>
if <tt>is_constructible_v&lt;Smart, SP, Args...&gt;</tt> is <tt>true</tt>;
</p>
</li>
<li><p>(11.4) &mdash; otherwise, the program is ill-formed.</p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3636" href="https://cplusplus.github.io/LWG/lwg-active.html#3636">3636</a>. <tt>formatter&lt;T&gt;::format</tt> should be <tt>const</tt>-qualified</h3>
<p><b>Section:</b> 22.14.6.1 <a href="https://wg21.link/formatter.requirements">[formatter.requirements]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Arthur O'Dwyer <b>Opened:</b> 2021-11-11 <b>Last modified:</b> 2022-08-24</p>
<p><b>Priority: </b>1
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#formatter.requirements">active issues</a> in [formatter.requirements].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#formatter.requirements">issues</a> in [formatter.requirements].</p>
<p><b>Discussion:</b></p>
<p>
In <a href="https://reviews.llvm.org/D112017">libc++ review</a>, we've noticed that we don't understand 
the implications of 22.14.6.1 <a href="https://wg21.link/formatter.requirements">[formatter.requirements]</a> bullet 3.1 and Table [tab:formatter.basic]: 
(emphasize mine):
</p>
<blockquote>
<p>
(3.1) &mdash; <tt>f</tt> is a <b>value</b> of type <tt>F</tt>,
<p/>
[&hellip;]
<p/>
Table 70: <i>BasicFormatter</i> requirements [tab:formatter.basic]
<p/>
[&hellip;]
<p/>
<tt>f.parse(pc)</tt> [<em>must compile</em>] [&hellip;]
<p/>
<tt>f.format(u, fc)</tt> [<em>must compile</em>] [&hellip;]
</p>
</blockquote>
<p>
According to Victor Zverovich, his intent was that <tt>f.parse(pc)</tt> should modify the 
state of <tt>f</tt>, but <tt>f.format(u, fc)</tt> should merely read <tt>f</tt>'s state to 
support format string compilation where formatter objects are immutable and therefore the 
<tt>format</tt> function must be <tt>const</tt>-qualified. 
<p/>
That is, a typical formatter should look something like this (modulo errors introduced by me):
</p>
<blockquote>
<pre>
struct WidgetFormatter {
  auto parse(std::format_parse_context&amp;) -&gt; std::format_parse_context::iterator;
  auto format(const Widget&amp;, std::format_context&amp;) const -&gt; std::format_context::iterator;
};
</pre>
</blockquote>
<p>
However, this is not reflected in the wording, which treats <tt>parse</tt> and <tt>format</tt> symmetrically.
Also, there is at least one example that shows a non-const <tt>format</tt> method:
</p>
<blockquote>
<pre>
template&lt;&gt; struct std::formatter&lt;color&gt; : std::formatter&lt;const char*&gt; {
  auto format(color c, format_context&amp; ctx) {
    return formatter&lt;const char*&gt;::format(color_names[c], ctx);
  }
};
</pre>
</blockquote>
<p>
Victor writes:
</p>
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;">
<p>
Maybe we should [&hellip;] open an LWG issue clarifying that all standard formatters have a 
<tt>const</tt> format function.
</p>
</blockquote>
<p>
I'd like to be even more assertive: Let's open an LWG issue clarifying that all formatters must have a 
<tt>const</tt> format function!
</p>

<p><i>[2022-01-30; Reflector poll]</i></p>

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

<p><i>[2022-08-24 Approved unanimously in LWG telecon.]</i></p>




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

<ol>

<li><p>Modify 22.14.6.1 <a href="https://wg21.link/formatter.requirements">[formatter.requirements]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> It might also be reasonable to do a drive-by clarification that when the Table 70 says 
"Stores the parsed format specifiers in <tt>*this</tt>," what it actually means is "Stores the parsed format 
specifiers in <tt>g</tt>." (But I don't think anyone's seriously confused by that wording.)
</p>
</blockquote>

<blockquote>
<p>
-3- Given character type <tt>charT</tt>, output iterator type <tt>Out</tt>, and formatting argument type <tt>T</tt>, 
in Table 70 and Table 71:
</p>
<ol style="list-style-type:none">
<li><p>(3.1) &mdash; <tt>f</tt> is a value of type <ins>(possibly <tt>const</tt>)</ins> <tt>F</tt>,</p></li>
<li><p><ins>(3.?) &mdash; <tt>g</tt> is an lvalue of type <tt>F</tt>,</ins></p></li>
<li><p>(3.2) &mdash; <tt>u</tt> is an lvalue of type <tt>T</tt>,</p></li>
<li><p>(3.3) &mdash; <tt>t</tt> is a value of a type convertible to (possibly <tt>const</tt>) <tt>T</tt>,</p></li>
<li><p>[&hellip;]</p></li>
</ol>
<p>
[&hellip;]
</p>
<blockquote>
<table border="1">
<caption>Table 70: <i>Formatter</i> requirements [tab:formatter]</caption>
<tr>
<th align="center">Expression</th>
<th align="center">Return type</th>
<th align="center">Requirement</th>
</tr>

<tr>
<td>
<tt><del>f</del><ins>g</ins>.parse(pc)</tt>
</td>
<td>
<tt>PC::iterator</tt>
</td>
<td>
[&hellip;]<br/>
Stores the parsed format specifiers in <tt>*this</tt> and
returns an iterator past the end of the parsed range.
</td>
</tr>

<tr>
<td colspan="3" align="center">
<tt>&hellip;</tt>
</td>
</tr>
</table>
</blockquote>
</blockquote>

</li>

<li><p>Modify 22.14.6.3 <a href="https://wg21.link/format.formatter.spec">[format.formatter.spec]</a> as indicated:</p>

<blockquote>
<p>
-6- An enabled specialization <tt>formatter&lt;T, charT&gt;</tt> meets the <i>BasicFormatter</i> requirements 
(22.14.6.1 <a href="https://wg21.link/formatter.requirements">[formatter.requirements]</a>).
<p/>
[<i>Example 1</i>:
</p>
<blockquote>
<pre>
#include &lt;format&gt;

enum color { red, green, blue };
const char* color_names[] = { "red", "green", "blue" };

template&lt;&gt; struct std::formatter&lt;color&gt; : std::formatter&lt;const char*&gt; {
  auto format(color c, format_context&amp; ctx) <ins>const</ins> {
    return formatter&lt;const char*&gt;::format(color_names[c], ctx);
  }
};

[&hellip;]
</pre>
</blockquote>
<p>
&mdash; <i>end example</i>]
</p>
</blockquote>
</li>

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

<blockquote>
<pre>
void advance_to(iterator it);
</pre>
<blockquote>
<p>
-8- <i>Effects:</i> Equivalent to: <tt>out_ = std::move(it);</tt>
<p/>
[<i>Example 1</i>:
</p>
<blockquote>
<pre>
struct S { int value; };

template&lt;&gt; struct std::formatter&lt;S&gt; {
  size_t width_arg_id = 0;
  
  <i>// Parses a width argument id in the format { digit }.</i>
  constexpr auto parse(format_parse_context&amp; ctx) {
    [&hellip;]
  }
  
  <i>// Formats an S with width given by the argument width_arg_id.</i>
  auto format(S s, format_context&amp; ctx) <ins>const</ins> {
    int width = visit_format_arg([](auto value) -&gt; int {
      if constexpr (!is_integral_v&lt;decltype(value)&gt;)
        throw format_error("width is not integral");
      else if (value &lt; 0 || value &gt; numeric_limits&lt;int&gt;::max())
        throw format_error("invalid width");
      else
        return value;
      }, ctx.arg(width_arg_id));
    return format_to(ctx.out(), "{0:x&lt;{1}}", s.value, width);
  }
};

[&hellip;]
</pre>
</blockquote>
<p>
&mdash; <i>end example</i>]
</p>
</blockquote>
</blockquote>
</li>

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

<blockquote>
<pre>
template&lt;class Duration, class charT&gt;
struct formatter&lt;chrono::<i>local-time-format-t</i>&lt;Duration&gt;, charT&gt;;
</pre>
<blockquote>
<p>
-15- Let <tt>f</tt> be [&hellip;]
<p/>
-16- <i>Remarks:</i> [&hellip;]
</p>
</blockquote>
<blockquote>
<pre>
template&lt;class Duration, class TimeZonePtr, class charT&gt;
struct formatter&lt;chrono::zoned_time&lt;Duration, TimeZonePtr&gt;, charT&gt;
  : formatter&lt;chrono::<i>local-time-format-t</i>&lt;Duration&gt;, charT&gt; {
  template&lt;class FormatContext&gt;
    typename FormatContext::iterator
      format(const chrono::zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp, FormatContext&amp; ctx) <ins>const</ins>;
};
</pre>
</blockquote>
<pre>
template&lt;class FormatContext&gt;
  typename FormatContext::iterator
    format(const chrono::zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp, FormatContext&amp; ctx) <ins>const</ins>;
</pre>
<blockquote>
<p>
-17- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
sys_info info = tp.get_info();
return formatter&lt;chrono::<i>local-time-format-t</i>&lt;Duration&gt;, charT&gt;::
         format({tp.get_local_time(), &amp;info.abbrev, &amp;info.offset}, ctx);
</pre></blockquote>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3754" href="https://cplusplus.github.io/LWG/lwg-active.html#3754">3754</a>. Class template <code>expected</code> synopsis contains declarations that do not match the detailed description</h3>
<p><b>Section:</b> 22.8.6.1 <a href="https://wg21.link/expected.object.general">[expected.object.general]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> S. B. Tam <b>Opened:</b> 2022-08-23 <b>Last modified:</b> 2022-09-07</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
22.8.6.1 <a href="https://wg21.link/expected.object.general">[expected.object.general]</a> declares the following constructors:
</p>

<blockquote><pre>
template&lt;class G&gt;
  constexpr expected(const unexpected&lt;G&gt;&amp;);
template&lt;class G&gt;
  constexpr expected(unexpected&lt;G&gt;&amp;&amp;);
</pre></blockquote>

<p>
But in 22.8.6.2 <a href="https://wg21.link/expected.object.ctor">[expected.object.ctor]</a>, these constructors are declared as:
</p>

<blockquote><pre>
template&lt;class G&gt;
  constexpr explicit(!is_convertible_v&lt;const G&amp;, E&gt;) expected(const unexpected&lt;G&gt;&amp; e);
template&lt;class G&gt;
  constexpr explicit(!is_convertible_v&lt;G, E&gt;) expected(unexpected&lt;G&gt;&amp;&amp; e);
</pre></blockquote>

<p>
Note that they have no explicit-specifiers in 22.8.6.1 <a href="https://wg21.link/expected.object.general">[expected.object.general]</a>,
but are conditionally explicit in 22.8.6.2 <a href="https://wg21.link/expected.object.ctor">[expected.object.ctor]</a>.
</p>

<p>
I presume that 22.8.6.1 <a href="https://wg21.link/expected.object.general">[expected.object.general]</a>
is missing a few <code>explicit(<i>see below</i>)</code>.
</p>

<p>
The same inconsistency exists in 22.8.7 <a href="https://wg21.link/expected.void">[expected.void]</a>.
</p>

<p><i>[2022-09-05; Jonathan Wakely provides wording]</i></p>


<p>
In <a href="https://wg21.link/N4910">N4910</a> the <tt>expected</tt> synopses had
<tt>explicit(<i>see below</i>)</tt> on the copy and move constructors.
That was fixed editorially, but this other inconsistency was not noticed.
</p>

<p><i>[2022-09-07; Moved to "Ready" at LWG telecon]</i></p>




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

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

<ol>
<li><p>Change 22.8.6.1 <a href="https://wg21.link/expected.object.general">[expected.object.general]</a> as indicated:</p>

<blockquote><pre>
<i>// 22.8.6.2, constructors</i>
constexpr expected();
constexpr expected(const expected&amp;);
constexpr expected(expected&amp;&amp;) noexcept(<i>see below</i>);
template&lt;class U, class G&gt;
  constexpr explicit(<i>see below</i>) expected(const expected&lt;U, G&gt;&amp;);
template&lt;class U, class G&gt;
  constexpr explicit(<i>see below</i>) expected(expected&lt;U, G&gt;&amp;&amp;);

template&lt;class U = T&gt;
  constexpr explicit(<i>see below</i>) expected(U&amp;&amp; v);

template&lt;class G&gt;
  constexpr <ins>explicit(<i>see below</i>)</ins> expected(const unexpected&lt;G&gt;&amp;);
template&lt;class G&gt;
  constexpr <ins>explicit(<i>see below</i>)</ins> expected(unexpected&lt;G&gt;&amp;&amp;);

template&lt;class... Args&gt;
  constexpr explicit expected(in_place_t, Args&amp;&amp;...);
</pre> </blockquote>
</li>

<li><p>Change 22.8.7.1 <a href="https://wg21.link/expected.void.general">[expected.void.general]</a> as indicated:</p>

<blockquote><pre>
<i>// 22.8.7.2, constructors</i>
constexpr expected() noexcept;
constexpr expected(const expected&);
constexpr expected(expected&amp;&amp;) noexcept(<i>see below</i>);
template&lt;class U, class G&gt;
  constexpr explicit(<i>see below</i>) expected(const expected&lt;U, G&gt;&amp;&amp;);

template&lt;class G&gt;
  constexpr <ins>explicit(<i>see below</i>)</ins> expected(const unexpected&lt;G&gt;&amp;);
template&lt;class G&gt;
  constexpr <ins>explicit(<i>see below</i>)</ins> expected(unexpected&lt;G&gt;&amp;&amp;);

constexpr explicit expected(in_place_t) noexcept;
</pre> </blockquote>

</li>

</ol>






<h2 id="tentatively_ready">Tentatively Ready Issues</h2>
<hr>
<h3><a name="3028" href="https://cplusplus.github.io/LWG/lwg-active.html#3028">3028</a>. Container requirements tables should distinguish <tt>const</tt> and non-<tt>const</tt> variables</h3>
<p><b>Section:</b> 24.2.2.1 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</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> 2017-10-17 <b>Last modified:</b> 2022-09-05</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#container.requirements.general">active issues</a> in [container.requirements.general].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#container.requirements.general">issues</a> in [container.requirements.general].</p>
<p><b>Discussion:</b></p>
<p>
[container.requirements.general] p4 says:
</p>
<blockquote>
<p>
In Tables 83, 84, and 85 <tt>X</tt> denotes a container class containing
objects of type <tt>T</tt>, <tt>a</tt> and <tt>b</tt> denote values of type <tt>X</tt>, <tt>u</tt> denotes an
identifier, <tt>r</tt> denotes a non-<tt>const</tt> value of type <tt>X</tt>, and <tt>rv</tt> denotes a
non-<tt>const</tt> rvalue of type <tt>X</tt>.
</p>
</blockquote>
<p>
This doesn't say anything about whether <tt>a</tt> and <tt>b</tt> are allowed to be
<tt>const</tt>, or must be non-<tt>const</tt>. In fact Table 83 uses them
inconsistently, e.g. the rows for "<tt>a = rv</tt>" and "<tt>a.swap(b)</tt>" most
certainly require them to be non-<tt>const</tt>, but all other uses are valid
for either <tt>const</tt> or non-<tt>const X</tt>.
</p>

<p><i>[2017-11 Albuquerque Wednesday night issues processing]</i></p>

<p>Priority set to 3; Jonathan to provide updated wording.</p>
<p>Wording needs adjustment - could use "possibly const values of type X"</p>
<p>Will distinguish between lvalue/rvalue </p>

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

<ol>
<li><p>Change 24.2.2.1 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> p4 as indicated:</p>

<blockquote>
<p>
-4- In Tables 83, 84, and 85 <tt>X</tt> denotes a container class containing objects of type <tt>T</tt>, 
<tt>a</tt> and <tt>b</tt> denote values of type <tt>X</tt>, <tt>u</tt> denotes an identifier, <tt>r</tt> 
<ins>and s</ins> denote<del>s a</del> non-<tt>const</tt> value<ins>s</ins> of type <tt>X</tt>, and 
<tt>rv</tt> denotes a non-<tt>const</tt> rvalue of type <tt>X</tt>.
</p>
</blockquote>
</li>

<li><p>Change 24.2.2.1 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a>, Table 83 "Container requirements", as indicated:</p>

<blockquote>
<table border="1">
<caption>Table 83 &mdash; Container requirements</caption>
<tr style="text-align:center">
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion/note<br/>pre/post-condition</th>
<th>Complexity</th>
</tr>
<tr>
<td colspan="5" align="center">
<tt>[&hellip;]</tt>
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>r</ins> = rv</tt>
</td>
<td>
<tt>X&amp;</tt>
</td>
<td>
All existing elements<br/>
of <tt><del>a</del><ins>r</ins></tt> are either move<br/>
assigned to or<br/>
destroyed
</td>
<td>
<tt><del>a</del><ins>r</ins></tt> shall be equal to<br/>
the value that <tt>rv</tt> had<br/>
before this<br/>
assignment
</td>
<td>
linear
</td>
</tr>
<tr>
<td colspan="5" align="center">
<tt>[&hellip;]</tt>
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>r</ins>.swap(<del>b</del><ins>s</ins>)</tt>
</td>
<td>
<tt>void</tt>
</td>
<td>
</td>
<td>
exchanges the<br/>
contents of <tt><del>a</del><ins>r</ins></tt> and <tt><del>b</del><ins>s</ins></tt>
</td>
<td>
(Note A)
</td>
</tr>
<tr>
<td colspan="5" align="center">
<tt>[&hellip;]</tt>
</td>
</tr>
<tr>
<td>
<tt>swap(<del>a</del><ins>r</ins>, <del>b</del><ins>s</ins>)</tt>
</td>
<td>
<tt>void</tt>
</td>
<td>
<tt><del>a</del><ins>r</ins>.swap(<del>b</del><ins>s</ins>)</tt>
</td>
<td>
</td>
<td>
(Note A)
</td>
</tr>
</table>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2020-05-03; Daniel provides alternative wording]</i></p>


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

<ol>
<li><p>Change 24.2.2.1 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> as indicated:</p>

<blockquote class="note"><p>
[<i>Drafting note:</i>
</p>
<ul>
<li><p>The following presentation also transforms the current list 
into a bullet list as we already have in 24.2.8 <a href="https://wg21.link/unord.req">[unord.req]</a> p11</p></li>
<li><p>It has been decided to replace the symbol <tt>r</tt> by <tt>s</tt>, because it is
easy to confuse with <tt>rv</tt> but means an lvalue instead, and the other container
tables use it rarely and for something completely different (iterator value)</p></li>
<li><p>A separate symbol <tt>v</tt> is introduced to unambigiously distinguish the
counterpart of a non-<tt>const</tt> rvalue (See 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>)</p></li>
<li><p>Two separate symbols <tt>b</tt> and <tt>c</tt> represent now "(possibly <tt>const</tt>)
values, while the existing symbol <tt>a</tt> represents an unspecified value, whose
meaning becomes defined when context is provided, e.g. for overloads like <tt>begin()</tt>
and <tt>end</tt></p></li>
</ul>
</blockquote>

<blockquote>
<p>
-4- In Tables 73, 74, and 75<ins>:</ins> 
</p>
<ol style="list-style-type: none">
<li><p>(4.1) &mdash; <tt>X</tt> denotes a container class containing objects of type <tt>T</tt>,</p></li>
<li><p>(4.2) &mdash; <tt>a</tt> <del>and <tt>b</tt></del> denote<ins>s a</ins> value<del>s</del> of type <tt>X</tt>,</p></li>
<li><p><ins>(4.2) &mdash; <tt>b</tt> and <tt>c</tt> denote (possibly <tt>const</tt>) values of type <tt>X</tt>,</ins></p></li>
<li><p>(4.3) &mdash; <tt>i</tt> and <tt>j</tt> denote values of type (possibly <tt>const</tt>) <tt>X::iterator</tt>,</p></li>
<li><p>(4.4) &mdash; <tt>u</tt> denotes an identifier,</p></li>
<li><p><ins>(?.?) &mdash; <tt>v</tt> denotes an lvalue of type (possibly <tt>const</tt>) <tt>X</tt> or an
rvalue of type <tt>const X</tt>,</ins></p></li>
<li><p>(4.5) &mdash; <del><tt>r</tt></del><ins><tt>s</tt> and <tt>t</tt></ins> denote<del>s a</del> non-<tt>const</tt> 
<del>value</del><ins>lvalues</ins> of type <tt>X</tt>, and</p></li>
<li><p>(4.6) &mdash; <tt>rv</tt> denotes a non-<tt>const</tt> rvalue of type <tt>X</tt>.</p></li>
</ol>
</blockquote>
</li>

<li><p>Change 24.2.2.1 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a>, Table 73 "Container requirements" [tab:container.req], 
as indicated:</p>

<blockquote class="note"><p>
[<i>Drafting note:</i> The following presentation also moves the copy-assignment expression just before
the move-assignment expression]
</p></blockquote>

<blockquote>
<table border="1">
<caption>Table 73: &mdash; Container requirements [tab:container.req]</caption>
<tr style="text-align:center">
<th>Expression</th>
<th>Return type</th>
<th>Operational<br/>semantics</th>
<th>Assertion/note<br/>pre/post-condition</th>
<th>Complexity</th>
</tr>
<tr>
<td colspan="5" align="center">
<tt>[&hellip;]</tt>
</td>
</tr>

<tr>
<td>
<tt>X(<del>a</del><ins>v</ins>)</tt>
</td>
<td>
</td>
<td>
</td>
<td>
<i>Preconditions:</i> <tt>T</tt> is <i>Cpp17CopyInsertable</i><br/>
into <tt>X</tt> (see below).<br/>
<i>Postconditions:</i> <tt><del>a</del><ins>v</ins> == X(<del>a</del><ins>v</ins>)</tt>.
</td>
<td>
linear
</td>
</tr>
<tr>
<td>
<tt>X u(<del>a</del><ins>v</ins>);<br/>
X u = <del>a</del><ins>v</ins>;</tt>
</td>
<td>
</td>
<td>
</td>
<td>
<i>Preconditions:</i> <tt>T</tt> is <i>Cpp17CopyInsertable</i><br/>
into <tt>X</tt> (see below).<br/>
<i>Postconditions:</i> <tt>u == <del>a</del><ins>v</ins></tt>.
</td>
<td>
linear
</td>
</tr>
<tr>
<td>
<tt>X u(rv);<br/>
X u = rv;</tt>
</td>
<td>
</td>
<td>
</td>
<td>
<i>Postconditions:</i> <tt>u</tt> is equal to the value<br/>
that <tt>rv</tt> had before this construction
</td>
<td>
(Note B)
</td>
</tr>
<tr>
<td>
<ins><tt>t = v</tt></ins>
</td>
<td>
<ins><tt>X&amp;</tt></ins>
</td>
<td>
</td>
<td>
<ins><i>Postconditions:</i> <tt>t == v</tt>.</ins>
</td>
<td>
<ins>linear</ins>
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>t</ins> = rv</tt>
</td>
<td>
<tt>X&amp;</tt>
</td>
<td>
All existing elements<br/>
of <tt><del>a</del><ins>t</ins></tt> are either move<br/>
assigned to or<br/>
destroyed
</td>
<td>
<tt><del>a</del><ins>t</ins></tt> shall be equal to<br/>
the value that <tt>rv</tt> had<br/>
before this<br/>
assignment
</td>
<td>
linear
</td>
</tr>
<tr>
<td colspan="5" align="center">
<tt>[&hellip;]</tt>
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>c</ins> == b</tt>
</td>
<td>
convertible to <tt>bool</tt>
</td>
<td>
<tt>==</tt> is an equivalence relation.<br/>
<tt>equal(<del>a</del><ins>c</ins>.begin(),<br/>
<del>a</del><ins>c</ins>.end(),<br/>
b.begin(),<br/>
b.end())</tt>
</td>
<td>
<i>Preconditions:</i> <tt>T</tt> meets the<br/> 
<i>Cpp17EqualityComparable</i> requirements
</td>
<td>
Constant if <tt><del>a</del><ins>c</ins>.size() != b.size()</tt>,<br/>
linear otherwise
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>c</ins> != b</tt>
</td>
<td>
convertible to <tt>bool</tt>
</td>
<td>
Equivalent to <tt>!(<del>a</del><ins>c</ins> == b)</tt>
</td>
<td>
</td>
<td>
linear
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>t</ins>.swap(<del>b</del><ins>s</ins>)</tt>
</td>
<td>
<tt>void</tt>
</td>
<td>
</td>
<td>
exchanges the<br/>
contents of <tt><del>a</del><ins>t</ins></tt> and <tt><del>b</del><ins>s</ins></tt>
</td>
<td>
(Note A)
</td>
</tr>
<tr>
<td>
<tt>swap(<del>a</del><ins>t</ins>, <del>b</del><ins>s</ins>)</tt>
</td>
<td>
<tt>void</tt>
</td>
<td>
<tt><del>a</del><ins>t</ins>.swap(<del>b</del><ins>s</ins>)</tt>
</td>
<td>
</td>
<td>
(Note A)
</td>
</tr>
<tr>
<td>
<del><tt>r = a</tt></del>
</td>
<td>
<del><tt>X&amp;</tt></del>
</td>
<td>
</td>
<td>
<del><i>Postconditions:</i> <tt>r == a</tt>.</del>
</td>
<td>
<del>linear</del>
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>c</ins>.size()</tt>
</td>
<td>
<tt>size_type</tt>
</td>
<td>
<tt>distance(<del>a</del><ins>c</ins>.begin(), <del>a</del><ins>c</ins>.end())</tt>
</td>
<td>
</td>
<td>
constant
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>c</ins>.max_size()</tt>
</td>
<td>
<tt>size_type</tt>
</td>
<td>
<tt>distance(begin(), end())</tt> for the largest<br/>
possible container
</td>
<td>
</td>
<td>
constant
</td>
</tr>
<tr>
<td>
<tt><del>a</del><ins>c</ins>.empty()</tt>
</td>
<td>
convertible to <tt>bool</tt>
</td>
<td>
<tt><del>a</del><ins>c</ins>.begin() == <del>a</del><ins>c</ins>.end()</tt>
</td>
<td>
</td>
<td>
constant
</td>
</tr>
</table>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-04-20; Jonathan rebases the wording on the latest draft]</i></p>



<p><i>[2022-09-05; Reflector poll]</i></p>

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



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

<ol>
<li><p>Change 24.2.2.1 <a href="https://wg21.link/container.requirements.general">[container.requirements.general]</a> as indicated:</p>

<blockquote class="note"><p>
[<i>Drafting note:</i>
</p>
<ul>
<li><p>It has been decided to replace the symbol <tt>r</tt> by <tt>s</tt>, because it is
easy to confuse with <tt>rv</tt> but means an lvalue instead, and the other container
tables use it rarely and for something completely different (iterator value)</p></li>
<li><p>A separate symbol <tt>v</tt> is introduced to unambigiously distinguish the
counterpart of a non-<tt>const</tt> rvalue (See 16.4.4.2 <a href="https://wg21.link/utility.arg.requirements">[utility.arg.requirements]</a>)</p></li>
<li><p>Two separate symbols <tt>b</tt> and <tt>c</tt> represent now "(possibly <tt>const</tt>)
values, while the existing symbol <tt>a</tt> represents an unspecified value, whose
meaning becomes defined when context is provided, e.g. for overloads like <tt>begin()</tt>
and <tt>end</tt></p></li>
</ul>
</blockquote>

<blockquote>
<p>
-1- In subclause 24.2.2 <a href="https://wg21.link/container.gen.reqmts">[container.gen.reqmts]</a>,
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; <tt>X</tt> denotes a container class containing objects of type <tt>T</tt>,</p></li>
<li><p>(1.2) &mdash; <tt>a</tt> <del>and <tt>b</tt> denote values</del> <ins>denotes a value</ins> of type <tt>X</tt>,</p></li>
<li><p><ins>(?.?) &mdash; <tt>b</tt> and <tt>c</tt> denote values of type (possibly <tt>const</tt>) <tt>X</tt>,</ins></p></li>
<li><p>(1.3) &mdash; <tt>i</tt> and <tt>j</tt> denote values of type (possibly <tt>const</tt>) <tt>X::iterator</tt>,</p></li>
<li><p>(1.4) &mdash; <tt>u</tt> denotes an identifier,</p></li>
<li><p><ins>(?.?) &mdash; <tt>v</tt> denotes an lvalue of type (possibly <tt>const</tt>) <tt>X</tt> or an
rvalue of type <tt>const X</tt>,</ins></p></li>
<li><p>(1.5) &mdash; <del><tt>r</tt> denotes a</del><ins><tt>s</tt> and <tt>t</tt> denote</ins> non-<tt>const</tt> 
<del>value</del><ins>lvalues</ins> of type <tt>X</tt>, and</p></li>
<li><p>(1.6) &mdash; <tt>rv</tt> denotes a non-<tt>const</tt> rvalue of type <tt>X</tt>.</p></li>
</ol>
</blockquote>
</li>

<li><p>Change 24.2.2.2 <a href="https://wg21.link/container.reqmts">[container.reqmts]</a> as indicated:</p>

<blockquote class="note"><p>
[<i>Drafting note:</i> The following presentation also moves the copy-assignment expression just before
the move-assignment expression]
</p></blockquote>

<blockquote>
<pre>
  X u(<del>a</del><ins>v</ins>);
  X u = <del>a</del><ins>v</ins>;
</pre>
<p>-12- <i>Preconditions:</i>
<tt>T</tt> is <i>Cpp17CopyInsertable</i> into <tt>X</tt> (see below).
</p>
<p>-13- <i>Postconditions:</i>
<tt>u == <del>a</del><ins>v</ins></tt>.
</p>
<p>-14- <i>Complexity:</i> Linear.  </p>


<pre>
  X u(rv);
  X u = rv;
</pre>
<p>-15- <i>Postconditions:</i>
<tt>u</tt> is equal to the value
that <tt>rv</tt> had before this construction.
</p>
<p>-14- <i>Complexity:</i>
Linear for <tt>array</tt> and constant for all other standard containers.
</p>

<pre>
  <ins>t = v</ins>
</pre>
<p><ins>-?- <i>Result:</i> <tt>X&amp;</tt>.</ins> </p>
<p><ins>-?- <i>Postconditions:</i> <tt>t == v</tt>.</ins> </p>
<p><ins>-?- <i>Complexity:</i> Linear.</ins>  </p>

<pre>
  <del>a</del><ins>t</ins> = rv
</pre>
<p>-17- <i>Result:</i> <tt>X&amp;</tt>. </p>
<p>-18- <i>Effects:</i>
All existing elements of
<tt><del>a</del><ins>t</ins></tt>
are either move assigned to or destroyed.
</p>
<p>-19- <i>Postconditions:</i>
<tt><del>a</del><ins>t</ins></tt>
shall be equal to the value that <tt>rv</tt> had
before this assignment.
</p>
<p>-20- <i>Complexity:</i> Linear.  </p>

<p>[&hellip;]</p>

<pre>
  <del>a</del><ins>b</ins>.begin()
</pre>
<p>-24- <i>Result:</i> <tt>iterator</tt>; <tt>const_iterator</tt> for constant <del>a</del><ins>b</ins>. </p>
<p>-25- <i>Returns:</i>
An iterator referring to the first element in the container.
</p>
<p>-26- <i>Complexity:</i> Constant. </p>

<pre>
  <del>a</del><ins>b</ins>.end()
</pre>
<p>-27- <i>Result:</i> <tt>iterator</tt>; <tt>const_iterator</tt> for constant <del>a</del><ins>b</ins>. </p>
<p>-28- <i>Returns:</i>
An iterator which is the past-the-end value for the container.
</p>
<p>-29- <i>Complexity:</i> Constant. </p>

<pre>
  <del>a</del><ins>b</ins>.cbegin()
</pre>
<p>-30- <i>Result:</i> <tt>const_iterator</tt>. </p>
<p>-31- <i>Returns:</i>
<tt>const_cast&lt;X const&amp;>(<del>a</del><ins>b</ins>).begin()</tt>
</p>
<p>-32- <i>Complexity:</i> Constant. </p>

<pre>
  <del>a</del><ins>b</ins>.cend()
</pre>
<p>-33- <i>Result:</i> <tt>const_iterator</tt>. </p>
<p>-34- <i>Returns:</i>
<tt>const_cast&lt;X const&amp;>(<del>a</del><ins>b</ins>).end()</tt>
</p>
<p>-35- <i>Complexity:</i> Constant. </p>



<p>[&hellip;]</p>

<pre>
  <del>a</del><ins>c</ins> == b
</pre>
<p>-39- <i>Preconditions:</i>
<tt>T</tt> meets the <i>Cpp17EqualityComparable</i> requirements.
</p>
<p>-40- <i>Result:</i> Convertible to <tt>bool</tt>. </p>
<p>-41- <i>Returns:</i>
<tt>equal(<del>a</del><ins>c</ins>.begin(),
<del>a</del><ins>c</ins>.end(),
b.begin(),
b.end())</tt>.
</p>
<p> &nbsp; &nbsp; &nbsp; &nbsp; [<i>Note 1:</i>
The algorithm <tt>equal</tt> is defined in 27.6.13 <a href="https://wg21.link/alg.equal">[alg.equal]</a>.
<i>&mdash; end note</i>] </p>
<p>-42- <i>Complexity:</i>
Constant if <tt><del>a</del><ins>c</ins>.size() != b.size()</tt>,
linear otherwise.
</p>
<p>-43- <i>Remarks:</i>
<tt>==</tt> is an equivalence relation.</p>

<pre>
  <del>a</del><ins>c</ins> != b
</pre>
<p>-44- <i>Effects:</i> Equivalent to <tt>!(<del>a</del><ins>c</ins> == b)</tt>. </p>

<pre>
  <del>a</del><ins>t</ins>.swap(<del>b</del><ins>s</ins>)
</pre>
<p>-45- <i>Result:</i> <tt>void</tt>. </p>
<p>-46- <i>Effects:</i>
Exchanges the contents of
<tt><del>a</del><ins>t</ins></tt> and <tt><del>b</del><ins>s</ins></tt>.
</p>
<p>-47- <i>Complexity:</i>
Linear for <tt>array</tt> and constant for all other standard containers.
</p>

<pre>
  swap(<del>a</del><ins>t</ins>, <del>b</del><ins>s</ins>)
</pre>
<p>-48- <i>Effects:</i> Equivalent to
<tt><del>a</del><ins>t</ins>.swap(<del>b</del><ins>s</ins>)</tt>
</p>

<pre>
  <del>r = a</del>
</pre>
<p><del>-49- <i>Result:</i> <tt>X&amp;</tt>.</del> </p>
<p><del>-50- <i>Postconditions:</i> <tt>r == a</tt>.</del> </p>
<p><del>-51- <i>Complexity:</i> Linear.</del> </p>

<pre>
  <del>a</del><ins>c</ins>.size()
</pre>
<p>-52- <i>Result:</i> <tt>size_type</tt>. </p>
<p>-53- <i>Returns:</i>
<tt>distance(<del>a</del><ins>c</ins>.begin(), <del>a</del><ins>c</ins>.end())</tt>,
i.e. the number of elements in the container.
</p>
<p>-54- <i>Complexity:</i> Constant. </p>
<p>-55- <i>Remarks:</i>
The number of elements is defined by the rules of constructors, inserts, and erases.
</p>

<pre>
  <del>a</del><ins>c</ins>.max_size()
</pre>
<p>-56- <i>Result:</i> <tt>size_type</tt>. </p>
<p>-57- <i>Returns:</i>
<tt>distance(begin(), end())</tt> for the largest possible container.
</p>
<p>-58- <i>Complexity:</i> Constant. </p>

<pre>
  <del>a</del><ins>c</ins>.empty()
</pre>
<p>-59- <i>Result:</i> Convertible to <tt>bool</tt>. </p>
<p>-60- <i>Returns:</i>
<tt><del>a</del><ins>c</ins>.begin() == <del>a</del><ins>c</ins>.end())</tt>
</p>
<p>-61- <i>Complexity:</i> Constant. </p>
<p>-62- <i>Remarks:</i>
If the container is empty, then
<tt><del>a</del><ins>c</ins>.empty()</tt>
is <tt>true</tt>.
</p>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3177" href="https://cplusplus.github.io/LWG/lwg-active.html#3177">3177</a>. Limit permission to specialize variable templates to program-defined types</h3>
<p><b>Section:</b> 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</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-12-11 <b>Last modified:</b> 2022-09-29</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#namespace.std">active issues</a> in [namespace.std].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#namespace.std">issues</a> in [namespace.std].</p>
<p><b>Discussion:</b></p>
<p>
The permission denoted by [namespace.std]/3 should be limited to program-defined types.
</p>

<p><i>[2018-12-21 Reflector prioritization]</i></p>

<p>Set Priority to 3</p>
<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">
<p>This wording is relative to <a href="https://wg21.link/n4791">N4791</a>.</p>

<ol>
<li><p>Change 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> as indicated:</p>
<blockquote>
<p>
-2- Unless explicitly prohibited, a program may add a template specialization for any standard library class
template to namespace <tt>std</tt> provided that (a) the added declaration depends on at least one program-defined
type and (b) the specialization meets the standard library requirements for the original template.(footnote 174)
<p/>
-3- The behavior of a C++ program is undefined if it declares an explicit or partial specialization of any standard
library variable template, except where explicitly permitted by the specification of that variable 
template<ins>, provided that the added declaration depends on at least one program-defined type</ins>.
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-08-24; LWG telecon]</i></p>

<p>Each variable template that grants permission to specialize already
states requirements more precisely than proposed here anyway.
For example, <code>disable_sized_range</code> only allows it for
cv-unqualified program-defined types.
Adding less precise wording here wouldn't be an improvement.
Add a note to make it clear we didn't just forget to say something here,
and to remind us to state requirements for each variable template in future.
</p>
<p><i>[2022-08-25; Jonathan Wakely provides improved wording]</i></p>



<p><i>[2022-09-28; 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/N4910">N4910</a>.</p>

<ul>
<li><p>Change 16.4.5.2.1 <a href="https://wg21.link/namespace.std">[namespace.std]</a> as indicated:</p>
<blockquote>
<p>
-2- Unless explicitly prohibited, a program may add a template specialization for any standard library class
template to namespace <tt>std</tt> provided that (a) the added declaration depends on at least one program-defined
type and (b) the specialization meets the standard library requirements for the original template.(footnote 163)
</p>
<p>
-3- The behavior of a C++ program is undefined if it declares an explicit or partial specialization of any standard
library variable template, except where explicitly permitted by the specification of that variable 
template.
</p>

<p>
<ins>
[<i>Note 1</i>:
The requirements on an explicit or partial specialization are stated
by each variable template that grants such permission.
&mdash; <i>end note</i>]
</ins>
</p>

</blockquote>
</li>
</ul>






<hr>
<h3><a name="3545" href="https://cplusplus.github.io/LWG/lwg-active.html#3545">3545</a>. <tt>std::pointer_traits</tt> should be SFINAE-friendly</h3>
<p><b>Section:</b> 20.2.3 <a href="https://wg21.link/pointer.traits">[pointer.traits]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Glen Joseph Fernandes <b>Opened:</b> 2021-04-20 <b>Last modified:</b> 2022-10-19</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#pointer.traits">active issues</a> in [pointer.traits].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#pointer.traits">issues</a> in [pointer.traits].</p>
<p><b>Discussion:</b></p>
<p>
<a href="https://wg21.link/p1474r1">P1474R1</a> chose to use <tt>std::to_address</tt> 
(a mechanism of converting pointer-like types to raw pointers) for contiguous iterators.
<tt>std::to_address</tt> provides an optional customization point via an optional member in 
<tt>std::pointer_traits</tt>. However all iterators are not pointers, and the primary 
template of <tt>std::pointer_traits&lt;Ptr&gt;</tt> requires that either 
<tt>Ptr::element_type</tt> is valid or <tt>Ptr</tt> is of the form 
<tt>template&lt;T, Args...&gt;</tt> or the <tt>pointer_traits</tt> specialization is
ill-formed. This requires specializing <tt>pointer_traits</tt> for those contiguous iterator 
types which is inconvenient for users. <a href="https://wg21.link/p1474">P1474</a>
should have also made <tt>pointer_traits</tt> SFINAE friendly.
</p>

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

<p>
Priority set to 2. Send to LEWG.
Daniel: "there is no similar treatment for the <code>rebind</code> member
template and I think it should be clarified whether <code>pointer_to</code>'s
signature should exist and in which form in the offending case."
</p>

<p><i>[2022-01-29; Daniel comments]</i></p>

<p>
This issue has some overlap with LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3665">3665</a> in regard to the question how we should handle
the <tt>rebind_alloc</tt> member template of the <tt>allocator_traits</tt> template as specified by 
20.2.9.2 <a href="https://wg21.link/allocator.traits.types">[allocator.traits.types]</a>/11. It would seem preferable to decide for the same approach in both 
cases.
</p>

<p><i>[2022-02-22 LEWG telecon; Status changed: LEWG &rarr; Open]</i></p>

<p>
No objection to unanimous consent for Jonathan's suggestion to make
<code>pointer_traits</code> an empty class when there is no
<code>element_type</code>. Jonathan to provide a paper.
</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.2.3.2 <a href="https://wg21.link/pointer.traits.types">[pointer.traits.types]</a> as indicated:</p>

<blockquote class="note">
<p>
As additional drive-by fix the improper usage of the term "instantiation"
has been corrected.
</p>
</blockquote>

<blockquote>
<pre>
using element_type = <i>see below</i>;
</pre>
<blockquote>
<p>
-1- <i>Type:</i> <tt>Ptr::element_type</tt> if the <i>qualified-id</i> <tt>Ptr::element_type</tt> 
is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>); otherwise, <tt>T</tt> if <tt>Ptr</tt> 
is a class template <del>instantiation</del><ins>specialization</ins> of the form 
<tt>SomePointer&lt;T, Args&gt;</tt>, where <tt>Args</tt> is zero or more type arguments; otherwise, 
<del>the specialization is ill-formed</del><ins><tt>pointer_traits</tt> has no member <tt>element_type</tt></ins>.
</p>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-09-27; Jonathan provides new wording]</i></p>


<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">

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

<ol>
<li>
<p>Modify 20.2.3.1 <a href="https://wg21.link/pointer.traits.general">[pointer.traits.general]</a> as indicated:</p>

<blockquote>
<p>-1-
The class template <tt>pointer_traits</tt> supplies a uniform interface to
certain attributes of pointer-like types.
</p>

<blockquote><pre>
namespace std {
  template&lt;class Ptr&gt; struct pointer_traits {
    <del>using pointer         = Ptr;</del>
    <del>using element_type    = <i>see below</i>;</del>
    <del>using difference_type = <i>see below</i>;</del>

    <del>template&lt;class U&gt; using rebind = <i>see below</i>;</del>
    <del>static pointer pointer_to(<i>see below</i> r);</del>

    <ins><i>see below</i></ins>;
  };

  template&lt;class T&gt; struct pointer_traits&lt;T*&gt; {
    using pointer         = T*;
    using element_type    = T;
    using difference_type = ptrdiff_t;

    template&lt;class U&gt; using rebind = U*;
    static constexpr pointer pointer_to(<i>see below</i> r) noexcept;
  };
}
</pre></blockquote>

</blockquote>
</li>

<li>
<p>Modify 20.2.3.2 <a href="https://wg21.link/pointer.traits.types">[pointer.traits.types]</a> as indicated:</p>

<blockquote>

<p><ins>-?-
The definitions in this subclause make use of the following
exposition-only class template and concept:
</ins></p>
<blockquote><pre><ins>
template&lt;class T&gt;
struct <i>ptr-traits-elem</i> <i>// exposition only</i>
{ };

template&lt;class T&gt; requires requires { typename T::element_type; }
struct <i>ptr-traits-elem</i>&lt;T&gt;
{ using type = typename T::element_type; };

template&lt;template&lt;class...&gt; class SomePointer, class T, class... Args&gt;
requires (!requires { typename SomePointer&lt;T, Args...&gt;::element_type; })
struct <i>ptr-traits-elem</i>&lt;SomePointer&lt;T, Args...&gt;&gt;
{ using type = T; };

template&lt;class Ptr&gt;
  concept <i>has-elem-type</i> = <i>// exposition only</i>
    requires { typename <i>ptr-traits-elem</i>&lt;Ptr&gt;::type; }
</ins></pre></blockquote>

<p><ins>-?-
If <tt>Ptr</tt> satisfies <tt><i>has-elem-type</i></tt>,
a specialization <tt>pointer_traits&lt;Ptr&gt;</tt> generated from the
<tt>pointer_traits</tt> primary template has the members described in
20.2.3.2 <a href="https://wg21.link/pointer.traits.types">[pointer.traits.types]</a> and 20.2.3.3 <a href="https://wg21.link/pointer.traits.functions">[pointer.traits.functions]</a>;
otherwise, such a specialization has no members by any of the names described
in those subclauses or in 20.2.3.4 <a href="https://wg21.link/pointer.traits.optmem">[pointer.traits.optmem]</a>.
</ins></p>

<pre><ins>using pointer = Ptr;</ins>
</pre>

<pre>using element_type = <del><i>see below</i></del> <ins>typename <i>ptr-traits-elem</i>&lt;Ptr&gt;::type</ins>;</pre>
<blockquote>
<p><del>-1- <i>Type</i>: <tt>Ptr::element_type</tt> if the <i>qualified-id</i>
<tt>Ptr::element_type</tt> is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>);
otherwise, <tt>T</tt> if <tt>Ptr</tt> is a class template instantiation of the
form <tt>SomePointer&lt;T, Args&gt;</tt>, where <tt>Args</tt> is zero or more
type arguments; otherwise, the
specialization is ill-formed.</del>
</p>
</blockquote>
<pre>using difference_type = <i>see below</i>;</pre>
<blockquote>
<p>-2-
<i>Type</i>: <tt>Ptr::difference_type</tt> if the <i>qualified-id</i>
<tt>Ptr::difference_type</tt> is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>);
otherwise, <tt>ptrdiff_t</tt>.
</p>
</blockquote>
<pre>template&lt;class U&gt; using rebind = <i>see below</i>;</pre>
<blockquote>
<p>-3-
<i>Alias template</i>: <tt>Ptr::rebind&lt;U&gt;</tt> if the <i>qualified-id</i>
<tt>Ptr::rebind&lt;U&gt;</tt> is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>);
otherwise, <tt>SomePointer&lt;U, Args&gt;</tt> if <tt>Ptr</tt> is a class template instantiation of the
form <tt>SomePointer&lt;T, Args&gt;</tt>, where <tt>Args</tt> is zero or more
type arguments; otherwise, the instantiation of <tt>rebind</tt> is ill-formed.
</p>
</blockquote>
</blockquote>
</li>
</ol>


</blockquote>

<p><i>[2022-10-11; Jonathan provides improved wording]</i></p>


<p><i>[2022-10-19; Reflector poll]</i></p>

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



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

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

<ol>
<li>
<p>Modify 20.2.3.1 <a href="https://wg21.link/pointer.traits.general">[pointer.traits.general]</a> as indicated:</p>

<blockquote>
<p>-1-
The class template <tt>pointer_traits</tt> supplies a uniform interface to
certain attributes of pointer-like types.
</p>

<blockquote><pre>
namespace std {
  template&lt;class Ptr&gt; struct pointer_traits {
    <del>using pointer         = Ptr;</del>
    <del>using element_type    = <i>see below</i>;</del>
    <del>using difference_type = <i>see below</i>;</del>

    <del>template&lt;class U&gt; using rebind = <i>see below</i>;</del>
    <del>static pointer pointer_to(<i>see below</i> r);</del>

    <ins><i>see below</i></ins>;
  };

  template&lt;class T&gt; struct pointer_traits&lt;T*&gt; {
    using pointer         = T*;
    using element_type    = T;
    using difference_type = ptrdiff_t;

    template&lt;class U&gt; using rebind = U*;
    static constexpr pointer pointer_to(<i>see below</i> r) noexcept;
  };
}
</pre></blockquote>

</blockquote>
</li>

<li>
<p>Modify 20.2.3.2 <a href="https://wg21.link/pointer.traits.types">[pointer.traits.types]</a> as indicated:</p>

<blockquote>

<p><ins>-?-
The definitions in this subclause make use of the following
exposition-only class template and concept:
</ins></p>
<blockquote><pre><ins>
template&lt;class T&gt;
struct <i>ptr-traits-elem</i> <i>// exposition only</i>
{ };

template&lt;class T&gt; requires requires { typename T::element_type; }
struct <i>ptr-traits-elem</i>&lt;T&gt;
{ using type = typename T::element_type; };

template&lt;template&lt;class...&gt; class SomePointer, class T, class... Args&gt;
requires (!requires { typename SomePointer&lt;T, Args...&gt;::element_type; })
struct <i>ptr-traits-elem</i>&lt;SomePointer&lt;T, Args...&gt;&gt;
{ using type = T; };

template&lt;class Ptr&gt;
  concept <i>has-elem-type</i> = <i>// exposition only</i>
    requires { typename <i>ptr-traits-elem</i>&lt;Ptr&gt;::type; }
</ins></pre></blockquote>

<p><ins>-?-
If <tt>Ptr</tt> satisfies <tt><i>has-elem-type</i></tt>,
a specialization <tt>pointer_traits&lt;Ptr&gt;</tt> generated from the
<tt>pointer_traits</tt> primary template has the following members
as well as those described in 20.2.3.3 <a href="https://wg21.link/pointer.traits.functions">[pointer.traits.functions]</a>;
otherwise, such a specialization has no members by any of those names.
</ins></p>

<pre><ins>using pointer = <i>see below</i>;</ins></pre>
<blockquote>
<p><ins>-?-
<i>Type</i>: <tt>Ptr</tt>.
</ins></p>
</blockquote>

<pre>using element_type = <i>see below</i>;</pre>
<blockquote>
<p>-1- <i>Type</i>:
<ins><tt>typename <i>ptr-traits-elem</i>&lt;Ptr&gt;::type</tt>.</ins>
<del><tt>Ptr::element_type</tt> if the <i>qualified-id</i>
<tt>Ptr::element_type</tt> is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>);
otherwise, <tt>T</tt> if <tt>Ptr</tt> is a class template instantiation of the
form <tt>SomePointer&lt;T, Args&gt;</tt>, where <tt>Args</tt> is zero or more
type arguments; otherwise, the
specialization is ill-formed.</del>
</p>
</blockquote>
<pre>using difference_type = <i>see below</i>;</pre>
<blockquote>
<p>-2-
<i>Type</i>: <tt>Ptr::difference_type</tt> if the <i>qualified-id</i>
<tt>Ptr::difference_type</tt> is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>);
otherwise, <tt>ptrdiff_t</tt>.
</p>
</blockquote>
<pre>template&lt;class U&gt; using rebind = <i>see below</i>;</pre>
<blockquote>
<p>-3-
<i>Alias template</i>: <tt>Ptr::rebind&lt;U&gt;</tt> if the <i>qualified-id</i>
<tt>Ptr::rebind&lt;U&gt;</tt> is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>);
otherwise, <tt>SomePointer&lt;U, Args&gt;</tt> if <tt>Ptr</tt> is a class template instantiation of the
form <tt>SomePointer&lt;T, Args&gt;</tt>, where <tt>Args</tt> is zero or more
type arguments; otherwise, the instantiation of <tt>rebind</tt> is ill-formed.
</p>
</blockquote>
</blockquote>
</li>

<li>
<p>Modify 20.2.3.4 <a href="https://wg21.link/pointer.traits.optmem">[pointer.traits.optmem]</a> as indicated:</p>

<blockquote>
<p>-1-
Specializations of <tt>pointer_traits</tt> may define the member declared
in this subclause to customize the behavior of the standard library.
<ins>
A specialization generated from the <tt>pointer_traits</tt> primary template
has no member by this name.
</ins>
</p>
<pre>static element_type* to_address(pointer p) noexcept;</pre>
<blockquote>
<p>-1- <i>Returns</i>:
A pointer of type <tt>element_type*</tt> that references the same location
as the argument <tt>p</tt>.
</p>
</blockquote>
</blockquote>

</li>
</ol>






<hr>
<h3><a name="3597" href="https://cplusplus.github.io/LWG/lwg-active.html#3597">3597</a>. Unsigned integer types don't model <tt><i>advanceable</i></tt></h3>
<p><b>Section:</b> 26.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</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> 2021-09-23 <b>Last modified:</b> 2022-10-19</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#range.iota.view">active issues</a> in [range.iota.view].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.iota.view">issues</a> in [range.iota.view].</p>
<p><b>Discussion:</b></p>
<p>
Unsigned integer types satisfy <tt><i>advanceable</i></tt>, but don't model it, since
</p>
<blockquote><p>
every two values of an unsigned integer type are reachable from each other, and
modular arithmetic is performed on unsigned integer types,
</p></blockquote>
<p>
which makes the last three bullets of the semantic requirements of <tt><i>advanceable</i></tt> 
(26.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>/5) can't be satisfied, and some (if not all) uses of 
<tt>iota_view</tt>s of unsigned integer types ill-formed, no diagnostic required.
<p/>
Some operations that are likely to expect the semantic requirements of <tt><i>advanceable</i></tt> 
behave incorrectly for unsigned integer types. E.g. according to 26.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>/6 
and 26.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>/16, <tt>std::ranges::iota_view&lt;std::uint8_t, std::uint8_t&gt;(std::uint8_t(1)).size()</tt> 
is well-defined IMO, because
</p>
<blockquote><p>
<tt>Bound()</tt> is <tt>std::uint8_t(0)</tt>, which is reachable from <tt>std::uint8_t(1)</tt>, and
not modeling <tt><i>advanceable</i></tt> shouldn't affect the validity, as both <tt>W</tt> and 
<tt>Bound</tt> are integer types.
</p></blockquote>
<p>
However, it returns <tt>unsigned(-1)</tt> on common implementations (where <tt>sizeof(int) &gt; sizeof(std::uint8_t))</tt>, 
which is wrong.
<p/>
Perhaps the semantic requirements of <tt><i>advanceable</i></tt> should be adjusted, 
and a refined definition of reachability in 26.6.4 <a href="https://wg21.link/range.iota">[range.iota]</a> is needed to avoid reaching 
<tt>a</tt> from <tt>b</tt> when <tt>a &gt; b</tt> (the iterator type is also affected).
</p>

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

<p>
Set priority to 3 after reflector poll.
</p>
<p><i>[Tim Song commented:]</i></p>

<p>
The advanceable part of the issue is NAD.
This is no different from NaN and <code>totally_ordered</code>,
see 16.3.2.3 <a href="https://wg21.link/structure.requirements">[structure.requirements]</a>/8.
</p>
<p>
The part about <code>iota_view&lt;uint8_t, uint8_t&gt;(1)</code> is simply this:
when we added "When <code>W</code> and <code>Bound</code> model ..." to
26.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a>/8,
we forgot to add its equivalent to the single-argument constructor.
We should do that.
</p>

<p><i>[2022-10-12; Jonathan provides wording]</i></p>


<p><i>[2022-10-19; Reflector poll]</i></p>

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



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

<ol>
<li>
<p>Modify 26.6.4.2 <a href="https://wg21.link/range.iota.view">[range.iota.view]</a> as indicated:</p>
<blockquote>
<pre>constexpr explicit iota_view(W value);</pre>
<blockquote>
<p>-6-
<i>Preconditions</i>: <tt>Bound</tt> denotes <tt>unreachable_sentinel_t</tt>
or <tt>Bound()</tt> is reachable from <tt>value</tt>.
<ins>
When <tt>W</tt> and <tt>Bound</tt> model <tt>totally_ordered_with</tt>,
then <tt>bool(value &lt;= Bound())</tt> is <tt>true</tt>.
</ins>
</p>
<p>-7-
<i>Effects</i>: Initializes <tt><i>value_</i></tt> with <tt>value</tt>.
</p>
</blockquote>

<pre>constexpr iota_view(type_identity_t&lt;W&gt; value, type_identity_t&lt;Bound&gt; bound);</pre>
<blockquote>
<p>-8-
<i>Preconditions</i>: <tt>Bound</tt> denotes <tt>unreachable_sentinel_t</tt>
or <tt>bound</tt> is reachable from <tt>value</tt>.
When <tt>W</tt> and <tt>Bound</tt> model <tt>totally_ordered_with</tt>,
then <tt>bool(value &lt;= bound)</tt> is <tt>true</tt>.
</p>
<p>-9-
<i>Effects</i>: Initializes <tt><i>value_</i></tt> with <tt>value</tt>
and <tt><i>bound_</i></tt> with <tt>bound</tt>.
</p>
</blockquote>

</blockquote>
</li>

</ol>






<hr>
<h3><a name="3600" href="https://cplusplus.github.io/LWG/lwg-active.html#3600">3600</a>. Making <tt>istream_iterator</tt> copy constructor trivial is an ABI break</h3>
<p><b>Section:</b> 25.6.2.2 <a href="https://wg21.link/istream.iterator.cons">[istream.iterator.cons]</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> 2021-09-23 <b>Last modified:</b> 2022-11-07</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#istream.iterator.cons">issues</a> in [istream.iterator.cons].</p>
<p><b>Discussion:</b></p>
<p>
Libstdc++ never implemented this change made between C++03 and C++11 (by <a href="https://wg21.link/n2994">N2994</a>):
</p>
24.6.1.1 [istream.iterator.cons] p3:
<blockquote>
<pre>
istream_iterator(const istream_iterator&lt;T,charT,traits,Distance&gt;&amp; x) = default;
</pre>
<blockquote>
<p>
-3- <i>Effects:</i> Constructs a copy of <tt>x</tt>. If <tt>T</tt> is a literal type, then this constructor shall 
be a trivial copy constructor.
</p>
</blockquote>
</blockquote>
<p>
This breaks our ABI, as it changes the argument passing convention for the type, meaning this function segfaults 
if compiled with today's libstdc++ and called from one that makes the triviality change:
</p>
<blockquote><pre>
#include &lt;iterator&gt;
#include &lt;istream&gt;

int f(std::istream_iterator&lt;int&gt; i)
{
  return *i++;
}
</pre></blockquote>
<p>
As a result, it's likely that libstdc++ will never implement the change.
<p/>
There is no reason to require this constructor to be trivial. It was required for C++0x at one point, so the type 
could be literal, but that is not true in the current language. We should strike the requirement, to reflect reality. 
MSVC and libc++ are free to continue to define it as defaulted (and so trivial when appropriate) but we should not 
require it from libstdc++. The cost of an ABI break is not worth the negligible benefit from making it trivial.
</p>

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

<ol>
<li><p>Modify 25.6.2.2 <a href="https://wg21.link/istream.iterator.cons">[istream.iterator.cons]</a> as indicated:</p>

<blockquote>
<pre>
istream_iterator(const istream_iterator&amp; x) = default;
</pre>
<blockquote>
<p>
-5- <i>Postconditions:</i> <tt>in_stream == x.in_stream</tt> is <tt>true</tt>.
<p/>
<del>-6- <i>Remarks:</i> If <tt>is_trivially_copy_constructible_v&lt;T&gt;</tt> is <tt>true</tt>, 
then this constructor is trivial.</del>
</p>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2021-09-30; Jonathan revises wording after reflector discussion]</i></p>

<p>
A benefit of triviality is that it is constexpr, want to preserve that.
</p>

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

<p>
Set priority to 3 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/n4892">N4892</a>.
</p>

<ol>
<li><p>Modify the class synopsis in 25.6.2.1 <a href="https://wg21.link/istream.iterator.general">[istream.iterator.general]</a>
as indicated:</p>
<blockquote>
<pre>
constexpr istream_iterator();
constexpr istream_iterator(default_sentinel_t);
istream_iterator(istream_type&amp; s);
<ins>constexpr</ins> istream_iterator(const istream_iterator&amp; x)<del> = default</del>;
~istream_iterator() = default;
istream_iterator&amp; operator=(const istream_iterator&amp;) = default;
</pre>
</blockquote>
</li>

<li><p>Modify 25.6.2.2 <a href="https://wg21.link/istream.iterator.cons">[istream.iterator.cons]</a> as indicated:</p>

<blockquote>
<pre>
  <ins>constexpr</ins> istream_iterator(const istream_iterator&amp; x)<del> = default</del>;
</pre>
<blockquote>
<p>
-5- <i>Postconditions:</i> <tt>in_stream == x.in_stream</tt> is <tt>true</tt>.
</p>
<p>
-6- <i>Remarks:</i> <del>If <tt>is_trivially_copy_constructible_v&lt;T&gt;</tt> is <tt>true</tt>, 
then this constructor is trivial.</del>
<ins>If the initializer <tt>T(x.value)</tt> in the declaration
<tt>auto val = T(x.value);</tt>
is a constant initializer ([expr.const]),
  then this constructor is a constexpr constructor.</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2022-10-12; Jonathan provides improved wording]</i></p>

<p>
Discussed on the reflector September 2021.
</p>

<p><i>[2022-10-13; Jonathan revises wording to add a noexcept-specifier]</i></p>



<p><i>[2022-11-07; 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/N4917">N4917</a>.
</p>

<ol>
<li><p>Modify the class synopsis in 25.6.2.1 <a href="https://wg21.link/istream.iterator.general">[istream.iterator.general]</a>
as indicated:</p>
<blockquote>
<pre>
constexpr istream_iterator();
constexpr istream_iterator(default_sentinel_t);
istream_iterator(istream_type&amp; s);
<ins>constexpr</ins> istream_iterator(const istream_iterator&amp; x) <ins>noexcept(<i>see below</i>)</ins><del> = default</del>;
~istream_iterator() = default;
istream_iterator&amp; operator=(const istream_iterator&amp;) = default;
</pre>
</blockquote>
</li>

<li><p>Modify 25.6.2.2 <a href="https://wg21.link/istream.iterator.cons">[istream.iterator.cons]</a> as indicated:</p>

<blockquote>
<pre>
  <ins>constexpr</ins> istream_iterator(const istream_iterator&amp; x) <ins>noexcept(<i>see below</i>)</ins><del> = default</del>;
</pre>
<blockquote>
<p>
<del>
-5- <i>Postconditions:</i> <tt>in_stream == x.in_stream</tt> is <tt>true</tt>.
</del>
</p>
<p>
<ins>
-?- <i>Effects:</i> Initializes <tt>in_stream</tt> with <tt>x.in_stream</tt>
and initializes <tt>value</tt> with <tt>x.value</tt>.
</ins>
</p>
<p>
-6- <i>Remarks:</i> <del>If <tt>is_trivially_copy_constructible_v&lt;T&gt;</tt> is <tt>true</tt>,
then this constructor is trivial.</del>
<ins>
An invocation of this constructor may be used in a core constant expression
if and only if the initialization of <tt>value</tt> from <tt>x.value</tt>
is a constant subexpression ([defns.const.subexpr]).
The exception specification is equivalent to
<tt>is_nothrow_copy_constructible_v&lt;T&gt;</tt>.
</ins>
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3629" href="https://cplusplus.github.io/LWG/lwg-active.html#3629">3629</a>. <code>make_error_code</code> and <code>make_error_condition</code> are customization points</h3>
<p><b>Section:</b> 19.5 <a href="https://wg21.link/syserr">[syserr]</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> 2021-10-31 <b>Last modified:</b> 2022-09-23</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#syserr">issues</a> in [syserr].</p>
<p><b>Discussion:</b></p>
<p>
The rule in 16.4.2.2 <a href="https://wg21.link/contents">[contents]</a> means that the calls to
<code>make_error_code</code> in 19.5.4.2 <a href="https://wg21.link/syserr.errcode.constructors">[syserr.errcode.constructors]</a>
and 19.5.4.3 <a href="https://wg21.link/syserr.errcode.modifiers">[syserr.errcode.modifiers]</a> are required to call
<code>std::make_error_code</code>,
which means program-defined error codes do not work.
The same applies to the <code>make_error_condition</code> calls in
19.5.5.2 <a href="https://wg21.link/syserr.errcondition.constructors">[syserr.errcondition.constructors]</a> and
19.5.5.3 <a href="https://wg21.link/syserr.errcondition.modifiers">[syserr.errcondition.modifiers]</a>.
</p>

<p>
They need to use ADL.
This is what all known implementations (including Boost.System) do.
</p>

<p><i>[2022-01-29; 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/n4901">N4901</a>.
</p>

<ol>
<li><p>Modify 19.5.2 <a href="https://wg21.link/system.error.syn">[system.error.syn]</a> as indicated:</p>

<blockquote>
<p>
-1-
The value of each <code>enum errc</code> constant shall be the same as the
value of the <code>&lt;cerrno&gt;</code> macro shown in the above synopsis.
Whether or not the <code>&lt;system_error&gt;</code> implementation exposes
the <code>&lt;cerrno&gt;</code> macros is unspecified.
</p>

<p>
<ins>
-?-
Invocations of <code>make_error_code</code> and
<code>make_error_condition</code> shown in subclause 19.5 <a href="https://wg21.link/syserr">[syserr]</a>
select a function to call via overload resolution (12.2 <a href="https://wg21.link/over.match">[over.match]</a>)
on a candidate set that includes the lookup set found by
argument dependent lookup (6.5.4 <a href="https://wg21.link/basic.lookup.argdep">[basic.lookup.argdep]</a>).
</ins>
</p>

<p>
-2-
The <code>is_error_code_enum</code> and <code>is_error_condition_enum</code>
templates may be specialized for program-defined types to indicate that such
types are eligible for <code>class error_code</code> and
<code>class error_condition</code> implicit conversions, respectively.
</p>

<p>
<ins>
<em>[Note 1:</em>
Conversions from such types are done by program-defined overloads of
<code>make_error_code</code> and <code>make_error_condition</code>,
found by ADL. <em>&mdash;end note]</em>
</ins>
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2022-08-25; Jonathan Wakely provides improved wording]</i></p>

<p>
Discussed in LWG telecon and decided on new direction:
<ul>
<li>Add <code>make_error_code</code> and <code>make_error_condition</code>
to 16.4.2.2 <a href="https://wg21.link/contents">[contents]</a> as done for <code>swap</code>.
Describe form of lookup used for them.</li>
<li>Respecify <code>error_code</code> and <code>error_condition</code>
constructors in terms of "<i>Effects</i>: Equivalent to" so that the
requirements on program-defined overloads found by ADL are implied by those
effects.</li>
</ul>
</p>

<p><i>[2022-09-07; Jonathan Wakely revises wording]</i></p>


<p>
Discussed in LWG telecon. Decided to change "established as-if by performing
unqualified name lookup and argument-dependent lookup"
to simply "established as-if by performing argument-dependent lookup".
</p>
<p>
This resolves the question of whether <tt>std::make_error_code(errc)</tt>,
<tt>std::make_error_code(io_errc)</tt>, etc. should be visible to the
unqualified name lookup. This affects whether a program-defined type that
specializes <tt>is_error_code_enum</tt> but doesn't provide an overload of
<tt>make_error_code</tt> should find the overloads in namespace <tt>std</tt>
and consider them for overload resolution, via implicit conversion to
<tt>std::errc</tt>, <tt>std::io_errc</tt>, etc.
</p>

<p><i>[2022-09-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/N4910">N4910</a>.
</p>

<ul>
<li><p>Modify 16.4.2.2 <a href="https://wg21.link/contents">[contents]</a> as indicated:</p>

<blockquote>
<p>-3-
Whenever an unqualified name other than <code>swap</code><ins>,
<code>make_error_code</code>, or <code>make_error_condition</code></ins>
is used in the specification of a declaration <code>D</code> in
17 <a href="https://wg21.link/support">[support]</a> through 33 <a href="https://wg21.link/thread">[thread]</a> or D <a href="https://wg21.link/depr">[depr]</a>,
its meaning is established as-if by performing unqualified name lookup
(6.5.3 <a href="https://wg21.link/basic.lookup.unqual">[basic.lookup.unqual]</a>) in the context of <code>D</code>.
</p>

<p>
[<i>Note 1</i>:
Argument-dependent lookup is not performed.
&mdash; <i>end note</i>]
</p>

<p>
Similarly, the meaning of a <i>qualified-id</i> is established as-if by
performing qualified name lookup (6.5.5 <a href="https://wg21.link/basic.lookup.qual">[basic.lookup.qual]</a>)
in the context of <code>D</code>.
</p>

<p>
[<i>Example 1</i>:
The reference to <code>is_array_v</code> in the specification of
<code>std::to_array</code> (24.3.7.6 <a href="https://wg21.link/array.creation">[array.creation]</a>)
refers to <code>::std::is_array_v</code>.
&mdash; <i>end example</i>]
</p>

<p>
[<i>Note 2</i>:
Operators in expressions (12.2.2.3 <a href="https://wg21.link/over.match.oper">[over.match.oper]</a>)
are not so constrained; see 16.4.6.4 <a href="https://wg21.link/global.functions">[global.functions]</a>.
&mdash; <i>end note</i>]
</p>

<p>
The meaning of the unqualified name <code>swap</code> is established
in an overload resolution context for swappable values
(16.4.4.3 <a href="https://wg21.link/swappable.requirements">[swappable.requirements]</a>).
<ins>
The meanings of the unqualified names
<code>make_error_code</code> and <code>make_error_condition</code>
are established as-if by performing
argument-dependent lookup (6.5.4 <a href="https://wg21.link/basic.lookup.argdep">[basic.lookup.argdep]</a>).
</ins>
</p>

</blockquote>
</li>

<li><p>Modify 19.5.4.2 <a href="https://wg21.link/syserr.errcode.constructors">[syserr.errcode.constructors]</a> as indicated:</p>

<blockquote>
<pre>error_code() noexcept;</pre>
<p>
<del>
-1- <i>Postconditions</i>:
<code>val_ == 0</code> and <code>cat_ == &amp;system_category()</code>.
</del>
<br/>
<ins>
-1- <i>Effects</i>:
Initializes <code>val_</code> with <code>0</code>
and <code>cat_</code> with <code>&amp;system_category()</code>.
</ins>
</p>

<pre>error_code(int val, const error_category&amp; cat) noexcept;</pre>
<p>
<del>
-2- <i>Postconditions</i>:
<code>val_ == val</code> and <code>cat_ == &amp;cat</code>.
</del>
<br/>
<ins>
-2- <i>Effects</i>:
Initializes <code>val_</code> with <code>val</code>
and <code>cat_</code> with <code>&amp;cat</code>.
</ins>
</p>

<pre>template&lt;class ErrorCodeEnum&gt;
  error_code(ErrorCodeEnum e) noexcept;</pre>
<p>-3- <i>Constraints</i>:
<code>is_error_code_enum_v&lt;ErrorCodeEnum&gt;</code> is <code>true</code>.
</p>
<p>
<del>
-4- <i>Postconditions</i>:
<code>*this == make_error_code(e)</code>.
</del>
<br/>
<ins>
-4- <i>Effects</i>: Equivalent to:
</ins>
<blockquote><pre><ins>error_code ec = make_error_code(e);
assign(ec.value(), ec.category());
</ins></pre></blockquote>
</p>
</blockquote>
</li>

<li><p>Modify 19.5.4.3 <a href="https://wg21.link/syserr.errcode.modifiers">[syserr.errcode.modifiers]</a> as indicated:</p>

<blockquote>
<pre>template&lt;class ErrorCodeEnum&gt;
  error_code&amp; operator=(ErrorCodeEnum e) noexcept;</pre>
<p>-2- <i>Constraints</i>:
<code>is_error_code_enum_v&lt;ErrorCodeEnum&gt;</code> is <code>true</code>.
</p>
<p>
<del>
-3- <i>Postconditions</i>:
<code>*this == make_error_code(e)</code>.
</del>
<br/>
<ins>
-3- <i>Effects</i>: Equivalent to:
</ins>
<blockquote><pre><ins>error_code ec = make_error_code(e);
assign(ec.value(), ec.category());
</ins></pre></blockquote>
</p>
<p>
-4- <i>Returns</i>: <code>*this</code>.
</p>
</blockquote>

</li>

<li><p>Modify 19.5.5.2 <a href="https://wg21.link/syserr.errcondition.constructors">[syserr.errcondition.constructors]</a> as indicated:</p>

<blockquote>
<pre>error_condition() noexcept;</pre>
<p>
<del>
-1- <i>Postconditions</i>:
<code>val_ == 0</code> and <code>cat_ == &amp;generic_category()</code>.
</del>
<br/>
<ins>
-1- <i>Effects</i>:
Initializes <code>val_</code> with <code>0</code>
and <code>cat_</code> with <code>&amp;generic_category()</code>.
</ins>
</p>

<pre>error_condition(int val, const error_category&amp; cat) noexcept;</pre>
<p>
<del>
-2- <i>Postconditions</i>:
<code>val_ == val</code> and <code>cat_ == &amp;cat</code>.
</del>
<br/>
<ins>
-2- <i>Effects</i>:
Initializes <code>val_</code> with <code>val</code>
and <code>cat_</code> with <code>&amp;cat</code>.
</ins>
</p>

<pre>template&lt;class ErrorConditionEnum&gt;
  error_condition(ErrorConditionEnum e) noexcept;</pre>
<p>-3- <i>Constraints</i>:
<code>is_error_condition_enum_v&lt;ErrorConditionEnum&gt;</code> is <code>true</code>.
</p>
<p>
<del>
-4- <i>Postconditions</i>:
<code>*this == make_error_condition(e)</code>.
</del>
<br/>
<ins>
-4- <i>Effects</i>: Equivalent to:
</ins>
<blockquote><pre><ins>error_condition ec = make_error_condition(e);
assign(ec.value(), ec.category());
</ins></pre></blockquote>
</p>
</blockquote>
</li>

<li><p>Modify 19.5.5.3 <a href="https://wg21.link/syserr.errcondition.modifiers">[syserr.errcondition.modifiers]</a> as indicated:</p>

<blockquote>
<pre>template&lt;class ErrorConditionEnum&gt;
  error_condition&amp; operator=(ErrorConditionEnum e) noexcept;</pre>
<p>-2- <i>Constraints</i>:
<code>is_error_condition_enum_v&lt;ErrorConditionEnum&gt;</code> is <code>true</code>.
</p>
<p>
<del>
-3- <i>Postconditions</i>:
<code>*this == make_error_condition(e)</code>.
</del>
<br/>
<ins>
-3- <i>Effects</i>: Equivalent to:
</ins>
<blockquote><pre><ins>error_condition ec = make_error_condition(e);
assign(ec.value(), ec.category());
</ins></pre></blockquote>
</p>
<p>
-4- <i>Returns</i>: <code>*this</code>.
</p>
</blockquote>

</li>

</ul>






<hr>
<h3><a name="3646" href="https://cplusplus.github.io/LWG/lwg-active.html#3646">3646</a>. <tt>std::ranges::view_interface::size</tt> returns a signed type</h3>
<p><b>Section:</b> 26.5.3.1 <a href="https://wg21.link/view.interface.general">[view.interface.general]</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> 2021-11-29 <b>Last modified:</b> 2022-09-23</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#view.interface.general">active issues</a> in [view.interface.general].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#view.interface.general">issues</a> in [view.interface.general].</p>
<p><b>Discussion:</b></p>
<p>
According to 26.5.3.1 <a href="https://wg21.link/view.interface.general">[view.interface.general]</a>, <tt>view_interface::size</tt> returns 
the difference between the sentinel and the beginning iterator, which always has a 
signed-integer-like type. However, IIUC the decision that a <tt>size</tt> member function 
should return an unsigned type by default was made when adopting <a href="https://wg21.link/P1227R2">P1227R2</a>, 
and the relative changes of the ranges library were done in <a href="https://wg21.link/P1523R1">P1523R1</a>. 
I don't know why <tt>view_interface::size</tt> was unchanged, while <tt>ranges::size</tt> 
returns an unsigned type in similar situations (26.3.10 <a href="https://wg21.link/range.prim.size">[range.prim.size]</a> (2.5)).
<p/>
If we want to change <tt>views_interface::size</tt> to return an unsigned type, the both 
overloads should be changed as below:
</p>
<blockquote><pre>
constexpr auto size() requires forward_range&lt;D&gt; &amp;&amp;
  sized_sentinel_for&lt;sentinel_t&lt;D&gt;, iterator_t&lt;D&gt;&gt; {
    return <i>to-unsigned-like</i>(ranges::end(<i>derived</i>()) - ranges::begin(<i>derived</i>()));
  }
constexpr auto size() const requires forward_range&lt;const D&gt; &amp;&amp;
  sized_sentinel_for&lt;sentinel_t&lt;const D&gt;, iterator_t&lt;const D&gt;&gt; {
    return <i>to-unsigned-like</i>(ranges::end(<i>derived</i>()) - ranges::begin(<i>derived</i>()));
  }
</pre></blockquote>

<p><i>[2022-01-30; Reflector poll]</i></p>

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

<p><i>[2022-06-22; Reflector poll]</i></p>

<p>
LEWG poll approved the proposed resolution
</p>

<p><i>[2022-09-23; Reflector poll]</i></p>

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



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

<ol>

<li><p>Modify 26.5.3.1 <a href="https://wg21.link/view.interface.general">[view.interface.general]</a>, class template <tt>view_interface</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
[&hellip;]
constexpr auto size() requires forward_range&lt;D&gt; &amp;&amp;
  sized_sentinel_for&lt;sentinel_t&lt;D&gt;, iterator_t&lt;D&gt;&gt; {
    return <ins><i>to-unsigned-like</i>(</ins>ranges::end(<i>derived</i>()) - ranges::begin(<i>derived</i>())<ins>)</ins>;
  }
constexpr auto size() const requires forward_range&lt;const D&gt; &amp;&amp;
  sized_sentinel_for&lt;sentinel_t&lt;const D&gt;, iterator_t&lt;const D&gt;&gt; {
    return <ins><i>to-unsigned-like</i>(</ins>ranges::end(<i>derived</i>()) - ranges::begin(<i>derived</i>())<ins>)</ins>;
  }
[&hellip;]
</pre>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3677" href="https://cplusplus.github.io/LWG/lwg-active.html#3677">3677</a>. Is a <i>cv</i>-qualified <tt>pair</tt> specially handled in uses-allocator construction?</h3>
<p><b>Section:</b> 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</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> 2022-02-16 <b>Last modified:</b> 2022-10-06</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#allocator.uses.construction">active issues</a> in [allocator.uses.construction].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#allocator.uses.construction">issues</a> in [allocator.uses.construction].</p>
<p><b>Discussion:</b></p>
<p>
It seems unclear whether <i>cv</i>-qualified <tt>pair</tt> specializations are considered as 
specializations of <tt>pair</tt> in 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a>.
<p/>
Currently MSVC STL only considered <i>cv</i>-unqualified pair types as such specializations, 
while libstdc++ accept both <i>cv</i>-unqualified and <tt>const</tt>-qualified pair types as 
such specializations. The resolution of LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3525">3525</a> uses <tt>remove_cv_t</tt>,
which possibly imply that the specialization of pair may be <i>cv</i>-qualified.
<p/>
The difference can be observed via the following program:
</p>
<blockquote><pre>
#include &lt;utility&gt;
#include &lt;memory&gt;
#include &lt;vector&gt;
#include &lt;cassert&gt; 

template&lt;class T&gt;
class payload_ator {

  int payload{};
    
public:
  payload_ator() = default;

  constexpr explicit payload_ator(int n) noexcept : payload{n} {}

  template&lt;class U&gt;
  constexpr explicit payload_ator(payload_ator&lt;U&gt; a) noexcept : payload{a.payload} {}   

  friend bool operator==(payload_ator, payload_ator) = default;

  template&lt;class U&gt;
  friend constexpr bool operator==(payload_ator x, payload_ator&lt;U&gt; y) noexcept
  {
    return x.payload == y.payload;
  }   

  using value_type = T;

  constexpr T* allocate(std::size_t n) { return std::allocator&lt;T&gt;{}.allocate(n); }

  constexpr void deallocate(T* p, std::size_t n) { return std::allocator&lt;T&gt;{}.deallocate(p, n); }   

  constexpr int get_payload() const noexcept { return payload; }
};

bool test()
{
  constexpr int in_v = 42;
  using my_pair_t = std::pair&lt;int, std::vector&lt;int, payload_ator&lt;int&gt;&gt;&gt;;
  auto out_v = std::make_obj_using_allocator&lt;const my_pair_t&gt;(payload_ator&lt;int&gt;{in_v}).second.get_allocator().get_payload();
  return in_v == out_v;
}

int main()
{
  assert(test()); // <span style="color:red;font-weight:bolder">passes only if a const-qualified pair specialization is considered as a pair specialization</span>
}
</pre></blockquote>

<p><i>[2022-03-04; Reflector poll]</i></p>

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

<p><i>[2022-08-24; LWG telecon]</i></p>

<p>Change every <code>T</code> to <code>remove_cv_t&lt;T&gt;</code>.</p>

<p><i>[2022-08-25; Jonathan Wakely provides wording]</i></p>


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

<ul>
<li><p>Modify 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a> as indicated,
using <code>remove_cv_t</code> in every <i>Constraints</i>: element:</p>

<blockquote>
<p><i>Constraints</i>:
<code><ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins></code> [is|is not]
a specialization of <code>pair</code>
</p>
</blockquote>
</li>
</ul>

</blockquote>

<p><i>[2022-09-23; Jonathan provides improved wording]</i></p>


<p><i>[2022-09-30; moved to Tentatively Ready after seven votes in reflector poll]</i></p>




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

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

<ol>
<li><p>Modify 20.2.8.2 <a href="https://wg21.link/allocator.uses.construction">[allocator.uses.construction]</a> as indicated,
using <code>remove_cv_t</code> in every <i>Constraints</i>: element (paragraphs 4, 6, 8, 10, 12, 14, 17):</p>

<blockquote>
<p><i>Constraints</i>:
<code><ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins></code> [is|is not]
a specialization of <code>pair</code>
</p>
</blockquote>
</li>

<li>
<p>Add <tt>remove_cv_t</tt> in paragraph 5:</p>

<blockquote>
<p>-5- <i>Returns</i>: A <code>tuple</code> value determined as follows: </p>
<p>(5.1) &mdash; If
<code>uses_allocator_v&lt;<ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>, Alloc&gt;</code>
is <code>false</code> and  <code>is_constructible_v&lt;T, Args...&gt;</code>
is <code>true</code>,
return <code>forward_as_tuple(std::forward&lt;Args&gt;(args)...)</code>.
</p>
<p>(5.2) &mdash;
Otherwise, if <code>uses_allocator_v&lt;<ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>, Alloc&gt;</code> is <code>true</code>
and <code>is_constructible_v&lt;T, allocator_arg_t, const Alloc&amp;, Args...&gt;</code> is <code>true</code>, return
</p>
<pre><code>tuple&lt;allocator_arg_t, const Alloc&amp;, Args&amp;&amp;...&gt;(
  allocator_arg, alloc, std::forward&lt;Args&gt;(args)...)</code></pre>

<p>(5.3) &mdash;
Otherwise, if <code>uses_allocator_v&lt;<ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>, Alloc&gt;</code> is <code>true</code>
and <code>is_constructible_v&lt;T, Args..., const Alloc&amp;&gt;</code> is <code>true</code>, return <code>forward_as_tuple(std::forward&lt;Args&gt;(args)..., alloc)</code>.
</p>
<p>(5.4) &mdash; Otherwise, the program is ill-formed. </p>
</blockquote>
</li>

<li>
<p>Rephrase paragraph 7 in terms of the pair member types:</p>

<blockquote>
<p>
<ins> -?-
Let <code>T1</code> be <code>T::first_type</code>.
Let <code>T2</code> be <code>T::second_type</code>.
</ins>
</p>

<p>-6- <i>Constraints</i>:
<code><ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins></code> is
a specialization of <code>pair</code>
</p>
<p>-7- <i>Effects:</i>:
<del>
For <code>T</code> specified as <code>pair&lt;T1, T2&gt;</code>, equivalent
</del>
<ins>Equivalent</ins>
to:
</p>
</blockquote>
</li>

</ol>






<hr>
<h3><a name="3732" href="https://cplusplus.github.io/LWG/lwg-active.html#3732">3732</a>. <tt>prepend_range</tt> and <tt>append_range</tt> can't be amortized constant time</h3>
<p><b>Section:</b> 24.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</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> 2022-07-06 <b>Last modified:</b> 2022-08-31</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#sequence.reqmts">active issues</a> in [sequence.reqmts].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p>
<p><b>Discussion:</b></p>
<p>
24.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a>/69 says "An implementation shall implement them so as to take amortized constant time." 
followed by a list of operations that includes the newly added <tt>append_range</tt> and <tt>prepend_range</tt>. 
Obviously these operations cannot be implemented in amortized constant time.
<p/>
Because the actual complexity of these operations are already specified in the concrete container specification, 
we can just exclude them here.
</p>

<p><i>[2022-08-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/N4910">N4910</a>.
</p>

<ol>

<li><p>Modify 24.2.4 <a href="https://wg21.link/sequence.reqmts">[sequence.reqmts]</a> as indicated:</p>

<blockquote>
<p>
-69- The following operations are provided for some types of sequence containers but not others. <del>An implementation
shall implement them</del><ins>Operations other than <tt>prepend_range</tt> and <tt>append_range</tt> are implemented</ins> 
so as to take amortized constant time.
</p>
</blockquote>
</li>


</ol>





<hr>
<h3><a name="3736" href="https://cplusplus.github.io/LWG/lwg-active.html#3736">3736</a>. <tt>move_iterator</tt> missing <tt>disable_sized_sentinel_for</tt> specialization</h3>
<p><b>Section:</b> 25.2 <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</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> 2022-07-14 <b>Last modified:</b> 2022-07-16</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#iterator.synopsis">active issues</a> in [iterator.synopsis].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#iterator.synopsis">issues</a> in [iterator.synopsis].</p>
<p><b>Discussion:</b></p>
<p>
Since <tt>reverse_iterator::operator-</tt> is not constrained, the standard adds a 
<tt>disable_sized_sentinel_for</tt> specialization for it to avoid situations where the 
underlying iterator can be subtracted making <tt>reverse_iterator</tt> accidentally model 
<tt>sized_sentinel_for</tt>.
<p/>
However, given that <tt>move_iterator::operator-</tt> is also unconstrained and the standard 
does not have the <tt>disable_sized_sentinel_for</tt> specialization for it, this makes 
<tt>subrange&lt;move_iterator&lt;I&gt;, move_iterator&lt;I&gt;&gt;</tt> unexpectedly satisfy 
<tt>sized_range</tt> and incorrectly use <tt>I::operator-</tt> to get size when <tt>I</tt> 
can be subtracted but not modeled <tt>sized_sentinel_for&lt;I&gt;</tt>.
<p/>
In addition, since <a href="https://wg21.link/P2520">P2520</a> makes <tt>move_iterator</tt> no longer just <tt>input_iterator</tt>, 
<tt>ranges::size</tt> can get the size of the range by subtracting two <tt>move_iterator</tt> pairs,
this also makes <tt>r | views::as_rvalue</tt> may satisfy <tt>sized_range</tt> when neither <tt>r</tt> nor 
<tt>r | views::reverse</tt> is <tt>sized_range</tt>.
<p/>
We should add a <tt>move_iterator</tt> version of the <tt>disable_sized_sentinel_for</tt> 
specialization to the standard to avoid the above situation.
</p>

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

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>
<p>
"but I don't think the issue text is quite right - both
<code>move_iterator</code> and <code>reverse_iterator</code>'s
<code>operator-</code> are constrained on <code>x.base() - y.base()</code>
being valid."
</p>
<p>
Does anyone remember why we did this for <code>reverse_iterator</code>
and not <code>move_iterator</code>?
</p>



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

<ol>

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

<blockquote>
<pre>
namespace std::ranges {
  [&hellip;]
  template&lt;class Iterator&gt;
    constexpr move_iterator&lt;Iterator&gt; make_move_iterator(Iterator i);

  <ins>template&lt;class Iterator1, class Iterator2&gt;
      requires (!sized_sentinel_for&lt;Iterator1, Iterator2&gt;)
    inline constexpr bool disable_sized_sentinel_for&lt;move_iterator&lt;Iterator1&gt;,
                                                     move_iterator&lt;Iterator2&gt;&gt; = true;</ins>

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





<hr>
<h3><a name="3738" href="https://cplusplus.github.io/LWG/lwg-active.html#3738">3738</a>. Missing preconditions for <tt>take_view</tt> constructor</h3>
<p><b>Section:</b> 26.7.10.2 <a href="https://wg21.link/range.take.view">[range.take.view]</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> 2022-07-15 <b>Last modified:</b> 2022-07-16</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.take.view">issues</a> in [range.take.view].</p>
<p><b>Discussion:</b></p>
<p>
When <tt>V</tt> does not model <tt>sized_range</tt>, <tt>take_view::begin</tt> returns 
<tt>counted_iterator(ranges::begin(<i>base_</i>), <i>count_</i>)</tt>. Since the 
<tt>counted_iterator</tt> constructor (25.5.7.2 <a href="https://wg21.link/counted.iter.const">[counted.iter.const]</a>) already has 
a precondition that <tt>n &gt;= 0</tt>, we should add this to <tt>take_view</tt> as well,
which is consistent with <tt>drop_view</tt>.
</p>

<p><i>[2022-08-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/N4910">N4910</a>.
</p>

<ol>

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

<blockquote>
<pre>
constexpr take_view(V base, range_difference_t&lt;V&gt; count);
</pre>
<blockquote>
<p>
<ins>-?- <i>Preconditions</i>: <tt>count &gt;= 0</tt> is <tt>true</tt>.</ins>
</p>
<p>
-1- <i>Effects</i>: Initializes <tt><i>base_</i></tt> with <tt>std::move(base)</tt> and 
<tt><i>count_</i></tt> with <tt>count</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3743" href="https://cplusplus.github.io/LWG/lwg-active.html#3743">3743</a>. <tt>ranges::to</tt>'s <tt>reserve</tt> may be ill-formed</h3>
<p><b>Section:</b> 26.5.7.2 <a href="https://wg21.link/range.utility.conv.to">[range.utility.conv.to]</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> 2022-07-21 <b>Last modified:</b> 2022-07-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.utility.conv.to">active issues</a> in [range.utility.conv.to].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.utility.conv.to">issues</a> in [range.utility.conv.to].</p>
<p><b>Discussion:</b></p>
<p>
When the "reserve" branch is satisfied, <tt>ranges::to</tt> directly passes the 
result of <tt>ranges::size(r)</tt> into the <tt>reserve</tt> call. However, given 
that the standard only guarantees that integer-class type can be explicitly converted 
to any integer-like type (25.3.4.4 <a href="https://wg21.link/iterator.concept.winc">[iterator.concept.winc]</a> p6), this makes 
the call potentially ill-formed, since <tt>ranges::size(r)</tt> may return an 
integer-class type:
</p>
<blockquote><pre>
#include &lt;ranges&gt;
#include &lt;vector&gt;

int main() {
  auto r = std::ranges::subrange(std::views::iota(0ULL) | std::views::take(5), 5);
  auto v = r | std::ranges::to&lt;std::vector&lt;std::size_t&gt;&gt;(0); // <span style="color:red;font-weight:bolder">cannot implicitly convert _Unsigned128 to size_t in MSVC-STL</span>
}
</pre></blockquote>
<p>
We should do an explicit cast before calling <tt>reserve</tt>.
</p>

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

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>
<p>
Are we all happy that the result of conversion to the container's size type
may be less than the length of the source range, so the reservation is too small
but we don't realize until pushing the max_size() + 1st element fails?
I think it's acceptable that converting pathologically large ranges to
containers fails kind of messily, but I could imagine throwing
if the range length is greater than container's max_size().
</p>



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

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

<blockquote>
<pre>
template&lt;class C, input_range R, class... Args&gt; requires (!view&lt;C&gt;)
  constexpr C to(R&amp;&amp; r, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
-1- <i>Returns</i>: An object of type <tt>C</tt> constructed from the elements of <tt>r</tt> in the following manner:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <tt>convertible_to&lt;range_reference_t&lt;R&gt;, range_value_t&lt;C&gt;&gt;</tt> is <tt>true</tt>:</p></li>
<ol style="list-style-type: none">
<li><p>(1.1.1) &mdash; If <tt>constructible_from&lt;C, R, Args...&gt;</tt> is <tt>true</tt>:</p></li>
<blockquote><tt>C(std::forward&lt;R&gt;(r), std::forward&lt;Args&gt;(args)...)</tt></blockquote>
<li><p>(1.1.2) &mdash; Otherwise, if <tt>constructible_from&lt;C, from_range_t, R, Args...&gt;</tt> is <tt>true</tt>:</p></li>
<blockquote><tt>C(from_range, std::forward&lt;R&gt;(r), std::forward&lt;Args&gt;(args)...)</tt></blockquote>
<li><p>(1.1.3) &mdash; Otherwise, if</p></li>
<ol style="list-style-type: none">
<li><p>(1.1.3.1) &mdash; <tt>common_range&lt;R&gt;</tt> is <tt>true</tt>,</p></li>
<li><p>(1.1.3.2) &mdash; <tt><i>cpp17-input-iterator</i>&lt;iterator_t&lt;R&gt;&gt;</tt> is <tt>true</tt>, and</p></li>
<li><p>(1.1.3.3) &mdash; <tt>constructible_from&lt;C, iterator_t&lt;R&gt;, sentinel_t&lt;R&gt;, Args...&gt;</tt> is <tt>true</tt>:</p></li>
<blockquote><tt>C(ranges::begin(r), ranges::end(r), std::forward&lt;Args&gt;(args)...)</tt></blockquote>
</ol>
<li><p>(1.1.4) &mdash; Otherwise, if</p></li>
<ol style="list-style-type: none">
<li><p>(1.1.4.1) &mdash; <tt>constructible_from&lt;C, Args...&gt;</tt> is <tt>true</tt>, and</p></li>
<li><p>(1.1.4.2) &mdash; <tt><i>container-insertable</i>&lt;C, range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>:</p>
<blockquote><pre>
C c(std::forward&lt;Args&gt;(args)...);
if constexpr (sized_range&lt;R&gt; &amp;&amp; <i>reservable-container</i>&lt;C&gt;)
  c.reserve(<ins>static_cast&lt;range_size_t&lt;C&gt;&gt;(</ins>ranges::size(r)<ins>)</ins>);
ranges::copy(r, <i>container-inserter</i>&lt;range_reference_t&lt;R&gt;&gt;(c));
</pre></blockquote></li>
</ol>
</ol>
<li><p>(1.2) &mdash; Otherwise, if <tt>input_range&lt;range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>:</p>
<blockquote><pre>
to&lt;C&gt;(r | views::transform([](auto&amp;&amp; elem) {
  return to&lt;range_value_t&lt;C&gt;&gt;(std::forward&lt;decltype(elem)&gt;(elem));
}), std::forward&lt;Args&gt;(args)...);
</pre></blockquote></li>
<li><p>(1.3) &mdash; Otherwise, the program is ill-formed.</p></li>
</ol>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3745" href="https://cplusplus.github.io/LWG/lwg-active.html#3745">3745</a>. <tt>std::atomic_wait</tt> and its friends lack <tt>noexcept</tt></h3>
<p><b>Section:</b> 33.5.2 <a href="https://wg21.link/atomics.syn">[atomics.syn]</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> 2022-07-25 <b>Last modified:</b> 2022-07-30</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#atomics.syn">active issues</a> in [atomics.syn].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#atomics.syn">issues</a> in [atomics.syn].</p>
<p><b>Discussion:</b></p>
<p>
Currently function templates <tt>std::atomic_wait</tt>, <tt>std::atomic_wait_explicit</tt>, 
<tt>std::atomic_notify_one</tt>, and <tt>std::atomic_notify_all</tt> are not <tt>noexcept</tt> 
in the Working Draft, but the equivalent member functions are all <tt>noexcept</tt>. I think 
these function templates should be specified as <tt>noexcept</tt>, in order to be consistent 
with the <tt>std::atomic_flag_*</tt> free functions, the corresponding member functions, and 
other <tt>std::atomic_*</tt> function templates.
<p/>
Mainstream implementations (libc++, libstdc++, and MSVC STL) have already added <tt>noexcept</tt> 
to them.
</p>

<p><i>[2022-07-30; Daniel provides wording]</i></p>


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

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>
<p>
"Technically there's a difference between these and the member functions -
the pointer can be null - but we don't seem to have let that stop us
from adding noexcept to the rest of these functions."
</p>



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

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

<blockquote>
<pre>
[&hellip;]
template&lt;class T&gt;
  void atomic_wait(const volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_wait(const atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_wait_explicit(const volatile atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type,
                            memory_order) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_wait_explicit(const atomic&lt;T&gt;*, typename atomic&lt;T&gt;::value_type,
                            memory_order) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_notify_one(volatile atomic&lt;T&gt;*) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_notify_one(atomic&lt;T&gt;*) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_notify_all(volatile atomic&lt;T&gt;*) <ins>noexcept</ins>;
template&lt;class T&gt;
  void atomic_notify_all(atomic&lt;T&gt;*) <ins>noexcept</ins>;
[&hellip;]
</pre>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3746" href="https://cplusplus.github.io/LWG/lwg-active.html#3746">3746</a>. <tt>optional</tt>'s spaceship with <tt>U</tt> with a type derived from <tt>optional</tt> 
causes infinite constraint meta-recursion</h3>
<p><b>Section:</b> 22.5.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> Ville Voutilainen <b>Opened:</b> 2022-07-25 <b>Last modified:</b> 2022-08-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>
What ends up happening is that the constraints of 
<tt>operator&lt;=&gt;(const optional&lt;T&gt;&amp;, const U&amp;)</tt> end up 
in <tt>three_way_comparable_with</tt>, and then in <tt><i>partially-ordered-with</i></tt>, 
and the expressions there end up performing a conversion from <tt>U</tt> to an 
<tt>optional</tt>, and we end up instantiating the same <tt>operator&lt;=&gt;</tt>
again, evaluating its constraints again, until the compiler bails out.
<p/>
See an <a href="https://godbolt.org/z/T7f4sr8jv">online example here</a>.
<p/>
All implementations end up with infinite meta-recursion.
<p/>
The solution to the problem is to stop the meta-recursion by constraining
the spaceship with <tt>U</tt> so that <tt>U</tt> is not publicly and unambiguously derived
from a specialization of optional, SFINAEing that candidate out, and letting 
22.5.6 <a href="https://wg21.link/optional.relops">[optional.relops]</a>/20 perform the comparison instead.
</p>

<p><i>[2022-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/N4910">N4910</a>.
</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> This proposed wording removes the only use of <tt><i>is-optional</i></tt>. ]
</p>
</blockquote>

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

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

  <del>template&lt;class T&gt;
    constexpr bool <i>is-optional</i> = false; <i>// exposition only</i>
  template&lt;class T&gt;
    constexpr bool <i>is-optional</i>&lt;optional&lt;T&gt;&gt; = true; <i>// exposition only</i></del>
  <ins>template&lt;class T&gt;
    concept <i>is-derived-from-optional</i> = requires(const T&amp; t) { <i>// exposition only</i>
      []&lt;class U&gt;(const optional&lt;U&gt;&amp;){ }(t);
    };</ins>
  [&hellip;]
  <i>// 22.5.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&gt;=(const T&amp;, const optional&lt;U&gt;&amp;);
  template&lt;class T, class U&gt; requires (!<i>is-<ins>derived-from-</ins>optional</i>&lt;U&gt;) &amp;&amp; three_way_comparable_with&lt;T, U&gt;
    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 22.5.8 <a href="https://wg21.link/optional.comp.with.t">[optional.comp.with.t]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, class U&gt; requires (!<i>is-<ins>derived-from-</ins>optional</i>&lt;U&gt;) &amp;&amp; three_way_comparable_with&lt;T, U&gt;
  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>
-25- <i>Effects:</i> Equivalent to: <tt>return x.has_value() ? *x &lt;=&gt; v : strong_ordering::less;</tt>
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3747" href="https://cplusplus.github.io/LWG/lwg-active.html#3747">3747</a>. <tt>ranges::uninitialized_copy_n</tt>, <tt>ranges::uninitialized_move_n</tt>, and 
<tt>ranges::destroy_n</tt> should use <tt>std::move</tt></h3>
<p><b>Section:</b> 27.11.5 <a href="https://wg21.link/uninitialized.copy">[uninitialized.copy]</a>, 27.11.6 <a href="https://wg21.link/uninitialized.move">[uninitialized.move]</a>, 27.11.9 <a href="https://wg21.link/specialized.destroy">[specialized.destroy]</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> 2022-07-28 <b>Last modified:</b> 2022-08-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#uninitialized.copy">issues</a> in [uninitialized.copy].</p>
<p><b>Discussion:</b></p>
<p>
Currently, <tt>ranges::uninitialized_copy_n</tt> has the following equivalent <i>Effects</i>:
</p>
<blockquote><pre>
auto t = uninitialized_copy(counted_iterator(ifirst, n),
                            default_sentinel, ofirst, olast);
return {std::move(t.in).base(), t.out};
</pre></blockquote>
<p>
Given that <tt>ifirst</tt> is just an <tt>input_iterator</tt> which is not guaranteed to be <tt>copyable</tt>, 
we should move it into <tt>counted_iterator</tt>. The same goes for <tt>ranges::uninitialized_move_n</tt> 
and <tt>ranges::destroy_n</tt>.
</p>

<p><i>[2022-08-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/N4910">N4910</a>.
</p>

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

<blockquote>
<pre>
namespace ranges {
  template&lt;input_iterator I, <i>nothrow-forward-iterator</i> O, <i>nothrow-sentinel-for</i>&lt;O&gt; S&gt;
    requires constructible_from&lt;iter_value_t&lt;O&gt;, iter_reference_t&lt;I&gt;&gt;
    uninitialized_copy_n_result&lt;I, O&gt;
      uninitialized_copy_n(I ifirst, iter_difference_t&lt;I&gt; n, O ofirst, S olast);
}
</pre>
<blockquote>
<p>
-9- <i>Preconditions</i>: [<tt>ofirst, olast</tt>) does not overlap with <tt>ifirst +</tt> [<tt>0, n</tt>) .
</p>
<p>
-10- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
auto t = uninitialized_copy(counted_iterator(<ins>std::move(</ins>ifirst<ins>)</ins>, n),
                            default_sentinel, ofirst, olast);
return {std::move(t.in).base(), t.out};
</pre></blockquote>
</blockquote>
</blockquote>
</li>

<li><p>Modify 27.11.6 <a href="https://wg21.link/uninitialized.move">[uninitialized.move]</a> as indicated:</p>

<blockquote>
<pre>
namespace ranges {
  template&lt;input_iterator I, <i>nothrow-forward-iterator</i> O, <i>nothrow-sentinel-for</i>&lt;O&gt; S&gt;
    requires constructible_from&lt;iter_value_t&lt;O&gt;, iter_rvalue_reference_t&lt;I&gt;&gt;
    uninitialized_move_n_result&lt;I, O&gt;
      uninitialized_move_n(I ifirst, iter_difference_t&lt;I&gt; n, O ofirst, S olast);
}
</pre>
<blockquote>
<p>
-8- <i>Preconditions</i>: [<tt>ofirst, olast</tt>) does not overlap with <tt>ifirst +</tt> [<tt>0, n</tt>) .
</p>
<p>
-9- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
auto t = uninitialized_move(counted_iterator(<ins>std::move(</ins>ifirst<ins>)</ins>, n),
                            default_sentinel, ofirst, olast);
return {std::move(t.in).base(), t.out};
</pre></blockquote>
</blockquote>
</blockquote>
</li>

<li><p>Modify 27.11.9 <a href="https://wg21.link/specialized.destroy">[specialized.destroy]</a> as indicated:</p>

<blockquote>
<pre>
namespace ranges {
  template&lt;<i>nothrow-input-iterator</i> I&gt;
    requires destructible&lt;iter_value_t&lt;I&gt;&gt;
    constexpr I destroy_n(I first, iter_difference_t&lt;I&gt; n) noexcept;
}
</pre>
<blockquote>
<p>
-5- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
return destroy(counted_iterator(<ins>std::move(</ins>first<ins>)</ins>, n), default_sentinel).base();
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3750" href="https://cplusplus.github.io/LWG/lwg-active.html#3750">3750</a>. Too many papers bump <tt>__cpp_lib_format</tt></h3>
<p><b>Section:</b> 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</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> 2022-08-04 <b>Last modified:</b> 2022-08-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#version.syn">active issues</a> in [version.syn].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#version.syn">issues</a> in [version.syn].</p>
<p><b>Discussion:</b></p>
<p>
As pointed out by <a href="https://lists.isocpp.org/sg10/2022/07/0829.php">Casey Carter</a>, 
four papers approved at the recent July 2022 plenary:
</p>
<ul>
<li><p><a href="https://wg21.link/P2419R2">P2419R2</a> "Clarify handling of encodings in localized formatting of chrono
types"</p></li>
<li><p><a href="https://wg21.link/P2508R1">P2508R1</a> "Expose <tt>std::basic-format-string&lt;charT, Args...&gt;</tt>"</p></li>
<li><p><a href="https://wg21.link/P2286R8">P2286R8</a> "Formatting Ranges"</p></li>
<li><p><a href="https://wg21.link/P2585R1">P2585R1</a> "Improve container default formatting"</p></li>
</ul>
<p>
all bump the value of <tt>__cpp_lib_format</tt>. We never accounted for all of these papers 
being moved at the same time, and these papers have fairly different implementation complexities. 
<p/>
<a href="https://lists.isocpp.org/sg10/2022/07/0832.php">Victor Zverovich</a> suggests that we 
instead add <tt>__cpp_lib_format_ranges</tt> (with value <tt>202207L</tt>) for the two formatting 
ranges papers (<a href="https://wg21.link/P2286">P2286</a> and <a href="https://wg21.link/P2585">P2585</a>, which should probably be implemented 
concurrently anyway, since the latter modifies the former) and <tt>bump __cpp_lib_format</tt> for 
the other two, which are both minor changes.
<p/>
We should do that.
</p>

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

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



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

<li><p>Modify 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a> as indicated:</p>

<blockquote>
<pre>
#define __cpp_lib_format          202207L <i>// also in &lt;format&gt;</i>
<ins>#define __cpp_lib_format_ranges   202207L <i>// also in &lt;format&gt;</i></ins>

</pre>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3751" href="https://cplusplus.github.io/LWG/lwg-active.html#3751">3751</a>. Missing feature macro for <tt>flat_set</tt></h3>
<p><b>Section:</b> 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</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> 2022-08-04 <b>Last modified:</b> 2022-08-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#version.syn">active issues</a> in [version.syn].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#version.syn">issues</a> in [version.syn].</p>
<p><b>Discussion:</b></p>
<p>
As pointed out by <a href="https://lists.isocpp.org/sg10/2022/07/0834.php">Casey Carter</a>, 
while there is a feature macro for <tt>flat_map</tt> in <a href="https://wg21.link/P0429">P0429</a>, there is 
no corresponding macro for flat_set in <a href="https://wg21.link/P1222">P1222</a>. We should add one.
</p>

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

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



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

<li><p>Modify 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a> as indicated:</p>

<blockquote>
<pre>
#define __cpp_lib_flat_map  202207L <i>// also in &lt;flat_map&gt;</i>
<ins>#define __cpp_lib_flat_set  202207L <i>// also in &lt;flat_set&gt;</i></ins>
</pre>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3755" href="https://cplusplus.github.io/LWG/lwg-active.html#3755">3755</a>. <tt><i>tuple-for-each</i></tt> can call user-defined <tt>operator,</tt></h3>
<p><b>Section:</b> 26.7.23.2 <a href="https://wg21.link/range.zip.view">[range.zip.view]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Nicole Mazzuca  <b>Opened:</b> 2022-08-26 <b>Last modified:</b> 2022-09-25</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.zip.view">active issues</a> in [range.zip.view].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.zip.view">issues</a> in [range.zip.view].</p>
<p><b>Discussion:</b></p>
<p>
The specification for <tt><i>tuple-for-each</i></tt> is:
</p>

<blockquote><pre>
template&lt;class F, class Tuple&gt;
constexpr auto <i>tuple-for-each</i>(F&amp;&amp; f, Tuple&amp;&amp; t) { <i>// exposition only</i>
  apply([&amp;]&lt;class... Ts&gt;(Ts&amp;&amp;... elements) {
    (invoke(f, std::forward&lt;Ts&gt;(elements)), ...);
  }, std::forward&lt;Tuple&gt;(t));
}
</pre></blockquote>

<p>Given</p>

<blockquote><pre>
struct Evil {
  void operator,(Evil) {
        abort();
    }
};
</pre></blockquote>

<p>
and <tt>tuple&lt;int, int&gt; t</tt>, then
<tt><i>tuple-for-each</i>([](int) { return Evil{}; }, t)</tt>,
the program will (unintentionally) abort.
</p>

<p>
It seems likely that our <tt>Evil</tt>'s <tt>operator,</tt>
should not be called.
</p>


<p><i>[2022-09-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after nine votes in favour during reflector poll.
</p>
<p>
Feedback from reviewers:
</p>
<blockquote>
<p>
"NAD. This exposition-only facility is only used with things that return <tt>void</tt>. 
As far as I know, users can't define <tt>operator,</tt> for <tt>void</tt>."
"If I see the <tt>void</tt> cast, I don't need to audit the uses or be concerned that 
we'll add a broken use in the future."
</p>
</blockquote>



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

<p> This wording is relative to the forthcoming C++23 CD. </p>

<ul>
<li>
<p>
Modify 26.7.5 <a href="https://wg21.link/range.adaptor.tuple">[range.adaptor.tuple]</a> as indicated:
</p>

<blockquote><pre>
template&lt;class F, class Tuple&gt;
constexpr auto <i>tuple-for-each</i>(F&amp;&amp; f, Tuple&amp;&amp; t) { <i>// exposition only</i>
  apply([&amp;]&lt;class... Ts&gt;(Ts&amp;&amp;... elements) {
    (<ins>static_cast&lt;void&gt;(</ins>invoke(f, std::forward&lt;Ts&gt;(elements))<ins>)</ins>, ...);
  }, std::forward&lt;Tuple&gt;(t));
}
</pre></blockquote>

</li>
</ul>






<hr>
<h3><a name="3757" href="https://cplusplus.github.io/LWG/lwg-active.html#3757">3757</a>. What's the effect of <tt>std::forward_like&lt;void&gt;(x)</tt>?</h3>
<p><b>Section:</b> 22.2.4 <a href="https://wg21.link/forward">[forward]</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> 2022-08-24 <b>Last modified:</b> 2022-09-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#forward">issues</a> in [forward].</p>
<p><b>Discussion:</b></p>
<p>
Currently the return type of <tt>std::forward_like</tt> is specified by the following bullet:
</p>
<blockquote>
<p>
&mdash; Let <tt>V</tt> be
</p>
<blockquote><pre>
<i>OVERRIDE_REF</i>(T&amp;&amp;, <i>COPY_CONST</i>(remove_reference_t&lt;T&gt;, remove_reference_t&lt;U&gt;))
</pre></blockquote>
</blockquote>
<p>
where <tt>T&amp;&amp;</tt> is not always valid, e.g. it's invalid when <tt>T</tt> is <tt>void</tt>.
<p/>
A strait forward reading may suggest that there is a hard error when <tt>T</tt> is not referenceable 
(which is currently implemented in MSVC STL), but this seems not clarified. It is unclear to me whether 
the intent is that hard error, substitution failure, or no error is caused when <tt>T&amp;&amp;</tt> is invalid.
</p>

<p><i>[2022-09-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/N4917">N4917</a>.
</p>

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

<blockquote>
<pre>
template&lt;class T, class U&gt;
  [[nodiscard]] constexpr auto forward_like(U&amp;&amp; x) noexcept -> <i>see below</i>;
</pre>
<blockquote>
<p>
<ins><i>Mandates</i>: <tt>T</tt> is a referenceable type (3.46 <a href="https://wg21.link/defns.referenceable">[defns.referenceable]</a>).</ins>
<p/>
[&hellip;]
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3759" href="https://cplusplus.github.io/LWG/lwg-active.html#3759">3759</a>. <tt>ranges::rotate_copy</tt> should use <tt>std::move</tt></h3>
<p><b>Section:</b> 27.7.11 <a href="https://wg21.link/alg.rotate">[alg.rotate]</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> 2022-08-25 <b>Last modified:</b> 2022-09-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.rotate">issues</a> in [alg.rotate].</p>
<p><b>Discussion:</b></p>
<p>
The range version of <tt>ranges::rotate_copy</tt> directly passes the <tt>result</tt> to the 
iterator-pair version. Since the type of <tt>result</tt> only models <tt>weakly_incrementable</tt> 
and may not be copied, we should use <tt>std::move</tt> here.
</p>


<p><i>[2022-09-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/N4910">N4910</a>.
</p>

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

<blockquote>
<pre>
template&lt;forward_range R, weakly_incrementable O&gt;
  requires indirectly_copyable&lt;iterator_t&lt;R&gt;, O&gt;
  constexpr ranges::rotate_copy_result&lt;borrowed_iterator_t&lt;R&gt;, O&gt;
    ranges::rotate_copy(R&amp;&amp; r, iterator_t&lt;R&gt; middle, O result);
</pre>
<blockquote>
<p>
-11- <i>Effects</i>: Equivalent to:
<blockquote><pre>
return ranges::rotate_copy(ranges::begin(r), middle, ranges::end(r), <ins>std::move(</ins>result<ins>)</ins>);
</pre></blockquote>
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3760" href="https://cplusplus.github.io/LWG/lwg-active.html#3760">3760</a>. <tt>cartesian_product_view::<i>iterator</i></tt>'s <tt><i>parent_</i></tt> is never valid</h3>
<p><b>Section:</b> 26.7.31 <a href="https://wg21.link/range.cartesian">[range.cartesian]</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> 2022-08-27 <b>Last modified:</b> 2022-09-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
<tt>cartesian_product_view::<i>iterator</i></tt> has a pointer member <tt><i>parent_</i></tt> that points 
to <tt>cartesian_product_view</tt>, but its constructor only accepts a <tt>tuple</tt> of iterators, which 
makes <tt><i>parent_</i></tt> always default-initialized to <tt>nullptr</tt>.
<p/>
The proposed resolution is to add an aliased <tt><i>Parent</i></tt> parameter to the constructor and 
initialize <tt><i>parent_</i></tt> with <tt>addressof</tt>, as we usually do.
</p>

<p><i>[2022-09-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/N4917">N4917</a>.
</p>

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

<blockquote>
<pre>
constexpr <i>iterator</i>&lt;false&gt; begin()
  requires (!<i>simple-view</i>&lt;First&gt; || ... || !<i>simple-view</i>&lt;Vs&gt;);
</pre>
<blockquote>
<p>
-2- <i>Effects</i>: Equivalent to: <tt>return <i>iterator</i>&lt;false&gt;(<ins>*this,</ins> <i>tuple-transform</i>(ranges::begin, 
<i>bases_</i>));</tt>
</p>
</blockquote>  
<pre>
constexpr <i>iterator</i>&lt;true&gt; begin() const
  requires (range&lt;const First&gt; &amp;&amp; ... &amp;&amp; range&lt;const Vs&gt;);
</pre>
<blockquote>
<p>
-3- <i>Effects</i>: Equivalent to: <tt>return <i>iterator</i>&lt;true&gt;(<ins>*this,</ins> <i>tuple-transform</i>(ranges::begin, 
<i>bases_</i>));</tt>
</p>
</blockquote>
<pre>
constexpr <i>iterator</i>&lt;false&gt; end()
  requires ((!<i>simple-view</i>&lt;First&gt; || ... || !<i>simple-view</i>&lt;Vs&gt;)
    &amp;&amp; <i>cartesian-product-is-common</i>&lt;First, Vs...&gt;);
constexpr <i>iterator</i>&lt;true&gt; end() const
  requires <i>cartesian-product-is-common</i>&lt;const First, const Vs...&gt;;
</pre>
<blockquote>
<p>
-4- Let:
</p>
<ol style="list-style-type: none">
<li><p>(4.1) &mdash; <tt><i>is-const</i></tt> be <tt>true</tt> for the const-qualified overload, and <tt>false</tt> otherwise;</p></li>
<li><p>(4.2) &mdash; <tt><i>is-empty</i></tt> be <tt>true</tt> if the expression <tt>ranges::empty(rng)</tt> is <tt>true</tt> 
for any <tt>rng</tt> among the underlying ranges except the first one and <tt>false</tt> otherwise; and</p></li>
<li><p>(4.3) &mdash; <tt><i>begin-or-first-end</i>(rng)</tt> be expression-equivalent to 
<tt><i>is-empty</i> ? ranges::begin(rng) : <i>cartesian-common-arg-end</i>(rng)</tt> if <tt>rng</tt> is the first underlying range 
and <tt>ranges::begin(rng)</tt> otherwise.</p></li>
</ol>
<p>
-5- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
<i>iterator</i>&lt;<i>is-const</i>&gt; it(<ins>*this,</ins> <i>tuple-transform</i>(
  [](auto&amp; rng){ return <i>begin-or-first-end</i>(rng); }, <i>bases_</i>));
return it;
</pre></blockquote>
</blockquote>
</blockquote>
</li>

<li><p>Modify 26.7.31.3 <a href="https://wg21.link/ranges.cartesian.iterator">[ranges.cartesian.iterator]</a> as indicated:</p>
<blockquote>
<blockquote>
<pre>
namespace std::ranges {
  template&lt;input_range First, forward_range... Vs&gt;
    requires (view&lt;First&gt; &amp;&amp; ... &amp;&amp; view&lt;Vs&gt;)
  template&lt;bool Const&gt;
  class cartesian_product_view&lt;First, Vs...&gt;::<i>iterator</i> {
  public:
    [&hellip;]

  private:
    <ins>using <i>Parent</i> = <i>maybe-const</i>&lt;Const, cartesian_product_view&gt;;           <i>// exposition only</i></ins>
    <ins><i>Parent</i></ins><del><i>maybe-const</i>&lt;Const, cartesian_product_view&gt;</del>* <i>parent_</i> = nullptr; <i>// exposition only</i>
    tuple&lt;iterator_t&lt;<i>maybe-const</i>&lt;Const, First&gt;&gt;,
      iterator_t&lt;<i>maybe-const</i>&lt;Const, Vs&gt;&gt;...&gt; <i>current_</i>;                   <i>// exposition only</i>
    
    template&lt;size_t N = sizeof...(Vs)&gt;
      constexpr void <i>next</i>();                                             <i>// exposition only</i>
    
    template&lt;size_t N = sizeof...(Vs)&gt;
      constexpr void <i>prev</i>();                                             <i>// exposition only</i>
    
    template&lt;class Tuple>
      constexpr difference_type <i>distance-from</i>(Tuple t);                  <i>// exposition only</i>
    
    constexpr <del>explicit</del> <i>iterator</i>(<ins><i>Parent</i>&amp; parent,</ins> tuple&lt;iterator_t&lt;<i>maybe-const</i>&lt;Const, First&gt;&gt;,
      iterator_t&lt;<i>maybe-const</i>&lt;Const, Vs&gt;&gt;...&gt; current);                   <i>// exposition only</i>
  };
}
</pre>
</blockquote>
<p>
[&hellip;]
</p>
<pre>
constexpr <del>explicit</del> <i>iterator</i>(<ins><i>Parent</i>&amp; parent,</ins> tuple&lt;iterator_t&lt;<i>maybe-const</i>&lt;Const, First&gt;&gt;,
  iterator_t&lt;<i>maybe-const</i>&lt;Const, Vs&gt;&gt;...&gt; current);
</pre>
<blockquote>
<p>
-10- <i>Effects</i>:  Initializes <ins><tt><i>parent_</i></tt> with <tt>addressof(parent)</tt> and</ins> 
<tt><i>current_</i></tt> with <tt>std::move(current)</tt>.
</p>
</blockquote>
<pre>
constexpr <i>iterator</i>(<i>iterator</i>&lt;!Const&gt; i) requires Const &amp;&amp;
  (convertible_to&lt;iterator_t&lt;First&gt;, iterator_t&lt;const First&gt;&gt; &amp;&amp;
    ... &amp;&amp; convertible_to&lt;iterator_t&lt;Vs&gt;, iterator_t&lt;const Vs&gt;&gt;);
</pre>
<blockquote>
<p>
-11- <i>Effects</i>: Initializes <ins><tt><i>parent_</i></tt> with <tt>i.<i>parent_</i></tt> and</ins> 
<tt><i>current_</i></tt> with <tt>std::move(i.<i>current_</i>)</tt>.
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3761" href="https://cplusplus.github.io/LWG/lwg-active.html#3761">3761</a>. <tt>cartesian_product_view::<i>iterator</i>::operator-</tt> should pass by reference</h3>
<p><b>Section:</b> 26.7.31.3 <a href="https://wg21.link/ranges.cartesian.iterator">[ranges.cartesian.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> 2022-08-27 <b>Last modified:</b> 2022-09-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#ranges.cartesian.iterator">active issues</a> in [ranges.cartesian.iterator].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#ranges.cartesian.iterator">issues</a> in [ranges.cartesian.iterator].</p>
<p><b>Discussion:</b></p>
<p>
There are two problems with <tt>cartesian_product_view::<i>iterator</i>::operator-</tt>.
<p/>
First, <tt><i>distance-from</i></tt> is not <tt>const</tt>-qualified, which would cause 
the common version of <tt>operator-</tt> to produce a hard error inside the function body 
since it invokes <tt><i>distance-from</i></tt> on a const <tt><i>iterator</i></tt> object.
<p/>
Second, the non-common version of <tt>operator-</tt> passes <tt><i>iterator</i></tt> by value,
which unnecessarily prohibits subtracting <tt>default_sentinel</tt> from an lvalue 
<tt><i>iterator</i></tt> whose first underlying iterator is non-<tt>copyable</tt>.
Even if we <tt>std::move</tt> it into <tt>operator-</tt>, the other overload will still be ill-formed
since it returns <tt>-(i - s)</tt> which will calls <tt>i</tt>'s deleted copy constructor.
<p/>
The proposed resolution is to add <tt>const</tt> qualification to <tt><i>distance-from</i></tt> 
and make the non-common version of <tt><i>iterator</i>::operator-</tt> pass by const reference. 
Although the <tt>Tuple</tt> parameter of <tt><i>distance-from</i></tt> is guaranteed to be 
<tt>copyable</tt>, I think it would be more appropriate to pass it by reference.
</p>

<p><i>[2022-09-08]</i></p>

<p>
As suggested by Tim Song, the originally submitted proposed wording has been refined to use
<tt>const Tuple&amp;</tt> instead of <tt>Tuple&amp;</tt>.
</p>

<p><i>[2022-09-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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 26.7.31.3 <a href="https://wg21.link/ranges.cartesian.iterator">[ranges.cartesian.iterator]</a> as indicated:</p>
<blockquote>
<blockquote>
<pre>
namespace std::ranges {
  template&lt;input_range First, forward_range... Vs&gt;
    requires (view&lt;First&gt; &amp;&amp; ... &amp;&amp; view&lt;Vs&gt;)
  template&lt;bool Const&gt;
  class cartesian_product_view&lt;First, Vs...&gt;::<i>iterator</i> {
  public:
    [&hellip;]

    friend constexpr difference_type operator-(<ins>const</ins> <i>iterator</i><ins>&amp;</ins> i, default_sentinel_t)
      requires <i>cartesian-is-sized-sentinel</i>&lt;Const, sentinel_t, First, Vs...&gt;;
    friend constexpr difference_type operator-(default_sentinel_t, <ins>const</ins> <i>iterator</i><ins>&amp;</ins> i)
      requires <i>cartesian-is-sized-sentinel</i>&lt;Const, sentinel_t, First, Vs...&gt;;

    [&hellip;]
  private:
    [&hellip;]
    
    template&lt;class Tuple&gt;
      constexpr difference_type <i>distance-from</i>(<ins>const</ins> Tuple<ins>&amp;</ins> t) <ins>const</ins>;            <i>// exposition only</i>
      
    [&hellip;]
  };
}
</pre>
</blockquote>
<p>
[&hellip;]
</p>
<pre>
template&lt;class Tuple&gt;
  constexpr difference_type <i>distance-from</i>(<ins>const</ins> Tuple<ins>&amp;</ins> t) <ins>const</ins>;
</pre>
<blockquote>
<p>
-7- Let:
</p>
<ol style="list-style-type: none">
<li><p>(7.1) &mdash; <tt><i>scaled-size</i>(<i>N</i>)</tt> be the product of 
<tt>static_cast&lt;difference_type&gt;(ranges::size(std::get&lt;<i>N</i>&gt;(<i>parent_</i>-&gt;<i>bases_</i>)))</tt> and 
<tt><i>scaled-size</i>(<i>N</i> + 1)</tt> if <tt><i>N</i> &lt; sizeof...(Vs)</tt>, otherwise 
<tt>static_cast&lt;difference_type&gt;(1)</tt>;</p></li>
<li><p>(7.2) &mdash; <tt><i>scaled-distance</i>(<i>N</i>)</tt> be the product of 
<tt>static_cast&lt;difference_type&gt;(std::get&lt;<i>N</i>&gt;(<i>current_</i>) - std::get&lt;<i>N</i>&gt;(t))</tt> and 
<tt><i>scaled-size</i>(<i>N</i> + 1)</tt>; and</p></li>
<li><p>(7.3) &mdash; <tt><i>scaled-sum</i></tt> be the sum of <tt><i>scaled-distance</i>(<i>N</i>)</tt> for every integer 
<tt>0 &le; <i>N</i> &le; sizeof...(Vs)</tt>.</p></li>
</ol>
<p>
-8- <i>Preconditions</i>: <tt><i>scaled-sum</i></tt> can be represented by <tt>difference_type</tt>.
</p>
<p>
-9- <i>Returns</i>: <tt><i>scaled-sum</i></tt>.
</p>
</blockquote>
<p>
[&hellip;]
</p>
<pre>
friend constexpr difference_type operator-(<ins>const</ins> <i>iterator</i><ins>&amp;</ins> i, default_sentinel_t)
  requires <i>cartesian-is-sized-sentinel</i>&lt;Const, sentinel_t, First, Vs...&gt;;
</pre>
<blockquote>
<p>
-32- Let <tt><i>end-tuple</i></tt> be an object of a type that is a specialization of <tt>tuple</tt>, such that:
</p>
<ol style="list-style-type: none">
<li><p>(32.1) &mdash; <tt>std::get&lt;0&gt;(<i>end-tuple</i>)</tt> has the same value as 
<tt>ranges::end(std::get&lt;0&gt;(i.<i>parent_</i>-&gt;<i>bases_</i>))</tt>;</p></li>
<li><p>(32.2) &mdash; <tt>std::get&lt;<i>N</i>&gt;(<i>end-tuple</i>)</tt> has the 
same value as <tt>ranges::begin(std::get&lt;<i>N</i>&gt;(i.<i>parent_</i>-&gt;<i>bases_</i>))</tt> 
for every integer <tt>1 &le; <i>N</i> &le; sizeof...(Vs)</tt>.</p></li>
</ol>
<p>
-33- <i>Effects</i>: Equivalent to: <tt>return i.<i>distance-from</i>(<i>end-tuple</i>);</tt>
</p>
</blockquote>
<pre>
friend constexpr difference_type operator-(default_sentinel_t, <ins>const</ins> <i>iterator</i><ins>&amp;</ins> i)
  requires <i>cartesian-is-sized-sentinel</i>&lt;Const, sentinel_t, First, Vs...&gt;;
</pre>
<blockquote>
<p>
-34- <i>Effects</i>: Equivalent to: <tt>return -(i - s);</tt>
</p>
</blockquote>
</blockquote>

</li>

</ol>





<hr>
<h3><a name="3762" href="https://cplusplus.github.io/LWG/lwg-active.html#3762">3762</a>. <tt>generator::<i>iterator</i>::operator==</tt> should pass by reference</h3>
<p><b>Section:</b> 26.8.6 <a href="https://wg21.link/coro.generator.iterator">[coro.generator.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> 2022-08-27 <b>Last modified:</b> 2022-09-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
Currently, <tt>generator::<i>iterator</i>::operator==</tt> passes <tt><i>iterator</i></tt> by value.
Given that <tt><i>iterator</i></tt> is a move-only type, this makes it impossible for 
<tt>generator</tt> to model <tt>range</tt>, since <tt>default_sentinel</tt> cannot be compared 
to the <tt><i>iterator</i></tt> of <tt>const</tt> lvalue and is not eligible to be its sentinel.
</p>

<p><i>[2022-09-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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 26.8.6 <a href="https://wg21.link/coro.generator.iterator">[coro.generator.iterator]</a> as indicated:</p>
<blockquote>
<blockquote>
<pre>
namespace std {
  template&lt;class Ref, class V, class Allocator&gt;
  class generator&lt;Ref, V, Allocator&gt;::<i>iterator</i> {
  public:
    using value_type = <i>value</i>;
    using difference_type = ptrdiff_t;

    <i>iterator</i>(<i>iterator</i>&amp;&amp; other) noexcept;
    <i>iterator</i>&amp; operator=(<i>iterator</i>&amp;&amp; other) noexcept;
    
    <i>reference</i> operator*() const noexcept(is_nothrow_copy_constructible_v&lt;<i>reference</i>&gt;);
    <i>iterator</i>&amp; operator++();
    void operator++(int);

    friend bool operator==(<ins>const</ins> <i>iterator</i><ins>&amp;</ins> i, default_sentinel_t);

  private:
    coroutine_handle&lt;promise_type&gt; <i>coroutine_</i>; <i>// exposition only</i>
  };
}
</pre>
</blockquote>
<p>
[&hellip;]
</p>
<pre>
friend bool operator==(<ins>const</ins> <i>iterator</i><ins>&amp;</ins> i, default_sentinel_t);
</pre>
<blockquote>
<p>
-10- <i>Effects</i>: Equivalent to: <tt>return i.<i>coroutine_</i>.done();</tt>
</p>
</blockquote>
</blockquote>

</li>

</ol>





<hr>
<h3><a name="3764" href="https://cplusplus.github.io/LWG/lwg-active.html#3764">3764</a>. <tt>reference_wrapper::operator()</tt> should propagate <tt>noexcept</tt></h3>
<p><b>Section:</b> 22.10.6.5 <a href="https://wg21.link/refwrap.invoke">[refwrap.invoke]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Zhihao Yuan <b>Opened:</b> 2022-08-31 <b>Last modified:</b> 2022-09-25</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#refwrap.invoke">issues</a> in [refwrap.invoke].</p>
<p><b>Discussion:</b></p>
<p>
The following assertion does not hold, making
the type less capable than the function pointers.
</p>
<blockquote><pre>
void f() noexcept;

std::reference_wrapper fn = f;
static_assert(std::is_nothrow_invocable_v&lt;decltype(fn)&gt;);
</pre></blockquote>

<p><i>[2022-09-23; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after six votes in favour during reflector poll.
</p>
<p>
Already implemented in MSVC and libstdc++.
</p>



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

<ol>

<li><p>Modify 22.10.6.1 <a href="https://wg21.link/refwrap.general">[refwrap.general]</a>, class template <tt>reference_wrapper</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
<i>// 22.10.6.5 <a href="https://wg21.link/refwrap.invoke">[refwrap.invoke]</a>, invocation</i>
template&lt;class... ArgTypes&gt;
  constexpr invoke_result_t&lt;T&amp;, ArgTypes...&gt; operator()(ArgTypes&amp;&amp;...) const 
    <ins>noexcept(is_nothrow_invocable_v&lt;T&amp;, ArgTypes...&gt;)</ins>;
</pre>
</blockquote>
</li>

<li><p>Modify 22.10.6.5 <a href="https://wg21.link/refwrap.invoke">[refwrap.invoke]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class... ArgTypes&gt;
  constexpr invoke_result_t&lt;T&amp;, ArgTypes...&gt;
    operator()(ArgTypes&amp;&amp;... args) const <ins>noexcept(is_nothrow_invocable_v&lt;T&amp;, ArgTypes...&gt;)</ins>;
</pre>
<blockquote>
<p>
-1- <i>Mandates</i>: <tt>T</tt> is a complete type.
<p/>
-2- <i>Returns</i>: <tt><i>INVOKE</i>(get(), std::forward&lt;ArgTypes&gt;(args)...)</tt>. (22.10.4 <a href="https://wg21.link/func.require">[func.require]</a>)
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3765" href="https://cplusplus.github.io/LWG/lwg-active.html#3765">3765</a>. <tt>const_sentinel</tt> should be constrained</h3>
<p><b>Section:</b> 25.2 <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</a>, 25.5.3.2 <a href="https://wg21.link/const.iterators.alias">[const.iterators.alias]</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> 2022-09-03 <b>Last modified:</b> 2022-09-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#iterator.synopsis">active issues</a> in [iterator.synopsis].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#iterator.synopsis">issues</a> in [iterator.synopsis].</p>
<p><b>Discussion:</b></p>
<p>
The current standard does not have any constraints on <tt>const_sentinel</tt> template parameters, 
which makes it possible to pass almost any type of object to <tt>make_const_sentinel</tt>.
It would be more appropriate to constrain the type to meet the minimum requirements of the 
sentinel type such as <tt>semiregular</tt> as <tt>move_sentinel</tt> does.
</p>

<p><i>[2022-09-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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 25.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;compare&gt;              <i>// see 17.12.1 <a href="https://wg21.link/compare.syn">[compare.syn]</a></i>
#include &lt;concepts&gt;             <i>// see 18.3 <a href="https://wg21.link/concepts.syn">[concepts.syn]</a></i>

namespace std {
  [&hellip;]
  
  <i>// 25.5.3 <a href="https://wg21.link/const.iterators">[const.iterators]</a>, constant iterators and sentinels</i>
  <i>// 25.5.3.2 <a href="https://wg21.link/const.iterators.alias">[const.iterators.alias]</a>, alias templates</i>
  [&hellip;]
  template&lt;input_iterator I&gt;
    using const_iterator = <i>see below</i>;                                               // <i>freestanding</i>
  template&lt;<ins>semiregular</ins><del>class</del> S&gt;
    using const_sentinel = <i>see below</i>;                                               // <i>freestanding</i>

  [&hellip;]
  template&lt;input_iterator I&gt;
    constexpr const_iterator&lt;I&gt; make_const_iterator(I it) { return it; }            // <i>freestanding</i>

  template&lt;<ins>semiregular</ins><del>class</del> S&gt;
    constexpr const_sentinel&lt;S&gt; make_const_sentinel(S s) { return s; }              // <i>freestanding</i>
  [&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 25.5.3.2 <a href="https://wg21.link/const.iterators.alias">[const.iterators.alias]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;<ins>semiregular</ins><del>class</del> S&gt;
  using const_sentinel = <i>see below</i>;
</pre>
<blockquote>
<p>
-2- <i>Result</i>: If <tt>S</tt> models <tt>input_iterator</tt>, <tt>const_iterator&lt;S&gt;</tt>. Otherwise, <tt>S</tt>.
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3770" href="https://cplusplus.github.io/LWG/lwg-active.html#3770">3770</a>. <tt>const_sentinel_t</tt> is missing</h3>
<p><b>Section:</b> 26.2 <a href="https://wg21.link/ranges.syn">[ranges.syn]</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> 2022-09-05 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#ranges.syn">active issues</a> in [ranges.syn].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#ranges.syn">issues</a> in [ranges.syn].</p>
<p><b>Discussion:</b></p>
<p>
The type alias pair <tt>const_iterator</tt> and <tt>const_sentinel</tt> 
and the factory function pair <tt>make_const_iterator</tt> and 
<tt>make_const_sentinel</tt> are defined in <tt>&lt;iterator&gt;</tt>, 
however, only <tt>const_iterator_t</tt> exists in <tt>&lt;ranges&gt;</tt>, 
which lacks <tt>const_sentinel_t</tt>, we should add it to ensure consistency.
<p/>
The proposed resolution also lifts the type constraint of <tt>const_iterator_t</tt> 
to <tt>input_range</tt> to make it consistent with <tt>const_iterator</tt>, 
which already requires that its template parameter must model 
<tt>input_iterator</tt>.
</p>

<p><i>[2022-09-23; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
<p/>
Comment from a reviewer:
</p>
<blockquote><p>
"I don't see why we should redundantly constrain <tt>const_iterator_t</tt>
with <tt>input_range</tt>; it's not as if we can make it more ill-formed
or more SFINAE-friendly than it is now."
</p></blockquote>

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

<ol>

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

<blockquote>
<pre>
#include &lt;compare&gt;              // <i>see 17.12.1 <a href="https://wg21.link/compare.syn">[compare.syn]</a></i>
#include &lt;initializer_list&gt;     // <i>see 17.11.2 <a href="https://wg21.link/initializer.list.syn">[initializer.list.syn]</a></i>
#include &lt;iterator&gt;             // <i>see 25.2 <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</a></i>

namespace std::ranges {
  [&hellip;]
  template&lt;class T&gt;
    using iterator_t = decltype(ranges::begin(declval&lt;T&amp;&gt;()));                      // freestanding
  template&lt;range R&gt;
    using sentinel_t = decltype(ranges::end(declval&lt;R&amp;&gt;()));                        // freestanding
  template&lt;<ins>input_</ins>range R&gt;
    using const_iterator_t = const_iterator&lt;iterator_t&lt;R&gt;&gt;;                         // freestanding
  <ins>template&lt;range R&gt;
    using const_sentinel_t = const_sentinel&lt;sentinel_t&lt;R&gt;&gt;;                         // freestanding</ins>
  [&hellip;]
}
</pre>
</blockquote>
</li>

</ol>
</blockquote>

<p><i>[2022-09-25; Daniel and Hewill provide alternative wording]</i></p>

<p>
The alternative solution solely adds the suggested <tt>const_sentinel_t</tt> alias template
and doesn't touch the <tt>const_iterator_t</tt> constraints.
</p>

<p><i>[2022-10-12; Reflector poll]</i></p>

<p>Set status to "Tentatively Ready" after seven votes in favour.</p>



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

<ol>

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

<blockquote>
<pre>
#include &lt;compare&gt;              // <i>see 17.12.1 <a href="https://wg21.link/compare.syn">[compare.syn]</a></i>
#include &lt;initializer_list&gt;     // <i>see 17.11.2 <a href="https://wg21.link/initializer.list.syn">[initializer.list.syn]</a></i>
#include &lt;iterator&gt;             // <i>see 25.2 <a href="https://wg21.link/iterator.synopsis">[iterator.synopsis]</a></i>

namespace std::ranges {
  [&hellip;]
  template&lt;class T&gt;
    using iterator_t = decltype(ranges::begin(declval&lt;T&amp;&gt;()));                      // freestanding
  template&lt;range R&gt;
    using sentinel_t = decltype(ranges::end(declval&lt;R&amp;&gt;()));                        // freestanding
  template&lt;range R&gt;
    using const_iterator_t = const_iterator&lt;iterator_t&lt;R&gt;&gt;;                         // freestanding
  <ins>template&lt;range R&gt;
    using const_sentinel_t = const_sentinel&lt;sentinel_t&lt;R&gt;&gt;;                         // freestanding</ins>
  [&hellip;]
}
</pre>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3773" href="https://cplusplus.github.io/LWG/lwg-active.html#3773">3773</a>. <tt>views::zip_transform</tt> still requires <tt>F</tt> to be <tt>copy_constructible</tt> when empty pack</h3>
<p><b>Section:</b> 26.7.24.1 <a href="https://wg21.link/range.zip.transform.overview">[range.zip.transform.overview]</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> 2022-09-12 <b>Last modified:</b> 2022-09-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
After <a href="https://wg21.link/P2494R2">P2494R2</a>, range adaptors only require callable to be
<tt>move_constructible</tt>, however, for <tt>views::zip_transform</tt>,
when empty pack, it still requires callable to be <tt>copy_constructible</tt>.
We should relax this requirement, too.
</p>

<p><i>[2022-09-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/N4910">N4910</a>.
</p>

<ol>
<li>
<p>Modify 26.7.24.1 <a href="https://wg21.link/range.zip.transform.overview">[range.zip.transform.overview]</a> as indicated:</p>
<blockquote>
<p>
-2- The name <tt>views::zip_transform</tt> denotes a customization point object
(16.3.3.3.6 <a href="https://wg21.link/customization.point.object">[customization.point.object]</a>). 
Let <tt>F</tt> be a subexpression,
and let <tt>Es...</tt> be a pack of subexpressions.
</p>
<ol style="list-style-type:none">
<li><p>(2.1) — If <tt>Es</tt> is an empty pack, let <tt>FD</tt> be <tt>decay_t&lt;decltype((F))&gt;</tt>.</p></li>
<ol style="list-style-type:none">
<li><p>(2.1.1) — If <tt><ins>move_constructible</ins><del>copy_constructible</del>&lt;FD&gt; &amp;&amp; regular_invocable&lt;FD&amp;&gt;</tt> is <tt>false</tt>, or if <tt>decay_t&lt;invoke_result_t&lt;FD&amp;&gt;&gt;</tt> is not an object type, <tt>views::zip_transform(F, Es...)</tt> is ill-formed.</p></li>
<li><p>(2.1.2) — Otherwise, the expression <tt>views::zip_transform(F, Es...)</tt> is expression-equivalent to</p>
<pre>
      ((void)F, auto(views::empty&lt;decay_t&lt;invoke_result_t&lt;FD&amp;&gt;&gt;&gt;))</pre>
</li>
</ol>
<li><p>(2.2) — Otherwise, the expression <tt>views::zip_transform(F, Es...)</tt> is expression-equivalent to <tt>zip_transform_view(F, Es...)</tt>.</p></li>
</ol>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3774" href="https://cplusplus.github.io/LWG/lwg-active.html#3774">3774</a>. <tt>&lt;flat_set&gt;</tt> should include <tt>&lt;compare&gt;</tt></h3>
<p><b>Section:</b> 24.6.5 <a href="https://wg21.link/flat.set.syn">[flat.set.syn]</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> 2022-09-12 <b>Last modified:</b> 2022-09-23</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
This was originally
<a href="https://github.com/cplusplus/draft/pull/5789">editorial PR #5789</a>
which is considered not-editorial.
</p>
 
<p>
<code>std::flat_set</code> and <code>std::flat_multiset</code>
have <code>operator&lt;=&gt;</code>
so <code>&lt;compare&gt;</code> should be included in the corresponding header,
in the spirit of LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3330">3330</a>.
<code>#include &lt;compare&gt;</code> is also missing in the adopted paper
<a href="https://wg21.link/P1222R4">P1222R4</a>.
</p>

<p><i>[2022-09-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/N4917">N4917</a>.</p>

<ol>
<li>
<p>Modify the synopsis in 24.6.5 <a href="https://wg21.link/flat.set.syn">[flat.set.syn]</a> as indicated:</p>

<blockquote><pre>
<ins>#include &lt;compare&gt;              <i>// see 17.12.1 <a href="https://wg21.link/compare.syn">[compare.syn]</a></i></ins>
#include &lt;initializer_list&gt;     <i>// see 17.11.2 <a href="https://wg21.link/initializer.list.syn">[initializer.list.syn]</a></i>
</pre></blockquote>
</li>
</ol>





<hr>
<h3><a name="3775" href="https://cplusplus.github.io/LWG/lwg-active.html#3775">3775</a>. Broken dependencies in the <i>Cpp17Allocator</i> requirements</h3>
<p><b>Section:</b> 16.4.4.6.1 <a href="https://wg21.link/allocator.requirements.general">[allocator.requirements.general]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2022-09-22 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#allocator.requirements.general">active issues</a> in [allocator.requirements.general].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#allocator.requirements.general">issues</a> in [allocator.requirements.general].</p>
<p><b>Discussion:</b></p>
<p>
This issue is extracted from <a href="https://wg21.link/P0177R2">P0177R2</a> as
that paper stalled on the author's ability to update in time for C++17.  While
the issue was recorded and going to be resolved in the paper, we did not file
an issue for the list when work on that paper stopped.
<p/>
Many of the types and expressions in the <i>Cpp17Allocator</i> requirements are
optional, and as such a default is provided that is exposed through
<code>std::allocator_traits</code>.  However, some types and operations are
specified directly in terms of the allocator member, when really they should be
specified allowing for reliance on the default, obtained through
<code>std::allocator_traits</code>.  For example, <code>X::pointer</code> is
an optional type and not required to exist; <code>XX::pointer</code> is either
<code>X::pointer</code> when it is present, or the default formula otherwise,
and so is guaranteed to always exist, and the intended interface for user code.
Observe that bullet list in p2, which acts as the key to the names in the
<i>Cpp17Allocator</i> requirements, gets this right, unlike most of the text
that follows.
<p/>
This change corresponds to the known implementations, which meet the intended
contract rather than that currently specified.  For example,
<code>std::allocator</code> does not provide any of the <code>pointer</code>
related typedef members, so many of the default semantics indicated today would
be ill-formed if implementations were not already implementing the fix.
<p/>
An alternative resolution might be to add wording around p1-3 to state that if
a name lookup fails then the default formula is used.  However, it is simply
clearer to write the constraints as intended, in the form of code that users
can write, rather than hide behind a layer of indirect semantics that may be
interpreted as requiring another layer of SFINAE metaprogramming.
</p>

<p><i>[2022-10-12; 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/N4917">N4917</a>.</p>

<ol>
<li>
<p>Modify 16.4.4.6.1 <a href="https://wg21.link/allocator.requirements.general">[allocator.requirements.general]</a> as indicated:</p>

<blockquote>
<pre>
typename X::pointer
</pre>
<blockquote>
<p>
-4- <i>Remarks</i>: Default: <tt>T*</tt>
</p>
</blockquote>
<pre>
typename X::const_pointer
</pre>
<blockquote>
<p>
-5- <i>Mandates</i>: <tt>X<ins>X</ins>::pointer</tt> is convertible to <tt>X<ins>X</ins>::const_pointer</tt>.
<p/>
-6- <i>Remarks</i>: Default: <tt>pointer_traits&lt;X<ins>X</ins>::pointer&gt;::rebind&lt;const T&gt;</tt>
</p>
</blockquote>
<pre>
typename X::void_pointer
typename Y::void_pointer
</pre>
<blockquote>
<p>
-7- <i>Mandates</i>: <tt>X<ins>X</ins>::pointer</tt> is convertible to <tt>X<ins>X</ins>::void_pointer</tt>. 
<tt>X<ins>X</ins>::void_pointer</tt> and <tt>Y<ins>Y</ins>::void_pointer</tt> are the same type.
<p/>
-8- <i>Remarks</i>: Default: <tt>pointer_traits&lt;X<ins>X</ins>::pointer&gt;::rebind&lt;void&gt;</tt>
</p>
</blockquote>
<pre>
typename X::const_void_pointer
typename Y::const_void_pointer
</pre>
<blockquote>
<p>
-9- <i>Mandates</i>: <tt>X<ins>X</ins>::pointer</tt>, <tt>X<ins>X</ins>::const_pointer</tt>, and 
<tt>X<ins>X</ins>::void_pointer</tt> are convertible to <tt>X<ins>X</ins>::const_void_pointer</tt>. 
<tt>X<ins>X</ins>::const_void_pointer</tt> and <tt>Y<ins>Y</ins>::const_void_pointer</tt> are the same type.
<p/>
-10- <i>Remarks</i>: Default: <tt>pointer_traits&lt;X<ins>X</ins>::pointer&gt;::rebind&lt;const void&gt;</tt>
</p>
</blockquote>
<pre>
typename X::value_type
</pre>
<blockquote>
<p>
-11- <i>Result</i>: Identical to <tt>T</tt>.
</p>
</blockquote>
<pre>
typename X::size_type
</pre>
<blockquote>
<p>
-12- <i>Result</i>: An unsigned integer type that can represent the size of the largest object 
in the allocation model.
<p/>
-13- <i>Remarks</i>: Default: <tt>make_unsigned_t&lt;X<ins>X</ins>::difference_type&gt;</tt>
</p>
</blockquote>
<pre>
typename X::difference_type
</pre>
<blockquote>
<p>
-14- <i>Result</i>: A signed integer type that can represent the difference between any two pointers 
in the allocation model.
<p/>
-15- <i>Remarks</i>: Default: <tt>pointer_traits&lt;X<ins>X</ins>::pointer&gt;::difference_type</tt>
</p>
</blockquote>
<pre>
typename X::template rebind&lt;U&gt;::other
</pre>
<blockquote>
<p>
-16- <i>Result</i>: <tt>Y</tt>
<p/>
-17- <i>Postconditions</i>: For all <tt>U</tt> (including <tt>T</tt>), 
<tt>Y<ins>Y</ins>::<del>template rebind</del><ins>rebind_alloc</ins>&lt;T&gt;<del>::other</del></tt> 
is <tt>X</tt>.
<p/>
-18- <i>Remarks</i>: If <tt>Allocator</tt> is a class template instantiation of the form 
<tt>SomeAllocator&lt;T, Args&gt;</tt>, where <tt>Args</tt> is zero or more type arguments, and 
<tt>Allocator</tt> does not supply a <tt>rebind</tt> member template, the standard 
<tt>allocator_traits</tt> template uses <tt>SomeAllocator&lt;U, Args&gt;</tt> in place of 
<tt>Allocator::rebind&lt;U&gt;::other</tt> by default. For allocator types that are not template 
instantiations of the above form, no default is provided.
<p/>
-19- [<i>Note 1</i>: The member class template <tt>rebind</tt> of <tt>X</tt> is effectively a 
typedef template. In general, if the name <tt>Allocator</tt> is bound to <tt>SomeAllocator&lt;T&gt;</tt>, 
then <tt>Allocator::rebind&lt;U&gt;::other</tt> is the same type as <tt>SomeAllocator&lt;U&gt;</tt>, where 
<tt>SomeAllocator&lt;T&gt;::value_type</tt> is <tt>T</tt> and <tt>SomeAllocator&lt;U&gt;::value_type</tt> 
is <tt>U</tt>. &mdash; <i>end note</i>]
</p>
</blockquote>
<p>
[&hellip;]
</p>
<pre>
static_cast&lt;X<ins>X</ins>::pointer&gt;(w)
</pre>
<blockquote>
<p>
-29- <i>Result</i>: <tt>X<ins>X</ins>::pointer</tt>
<p/>
-30- <i>Postconditions</i>: <tt>static_cast&lt;X<ins>X</ins>::pointer&gt;(w) == p</tt>.
</p>
</blockquote>
<pre>
static_cast&lt;X<ins>X</ins>::const_pointer&gt;(x)
</pre>
<blockquote>
<p>
-31- <i>Result</i>: <tt>X<ins>X</ins>::const_pointer</tt>
<p/>
-32- <i>Postconditions</i>: <tt>static_cast&lt;X<ins>X</ins>::const_pointer&gt;(x) == q</tt>.
</p>
</blockquote>
<pre>
pointer_traits&lt;X<ins>X</ins>::pointer&gt;::pointer_to(r)
</pre>
<blockquote>
<p>
-33- <i>Result</i>: <tt>X<ins>X</ins>::pointer</tt>
<p/>
-34- <i>Postconditions</i>: Same as <tt>p</tt>.
</p>
</blockquote>
<pre>
a.allocate(n)
</pre>
<blockquote>
<p>
-35- <i>Result</i>: <tt>X<ins>X</ins>::pointer</tt>
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
a.allocate(n, y)
</pre>
<blockquote>
<p>
-40- <i>Result</i>: <tt>X<ins>X</ins>::pointer</tt>
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
a.allocate_at_least(n)
</pre>
<blockquote>
<p>
-43- <i>Result</i>: <tt>allocation_result&lt;X<ins>X</ins>::pointer&gt;</tt>
<p/>
-44- <i>Returns</i>: <tt>allocation_result&lt;X<ins>X</ins>::pointer&gt;{ptr, count}</tt> where 
<tt>ptr</tt> is memory allocated for an array of count <tt>T</tt> and such an object 
is created but array elements are not constructed, such that <tt>count = n</tt>.
If <tt>n == 0</tt>, the return value is unspecified.
<p/>
[&hellip;]
</p>
</blockquote>
[&hellip;]
<pre>
a.max_size()
</pre>
<blockquote>
<p>
-50- <i>Result</i>: <tt>X<ins>X</ins>::size_type</tt>
<p/>
-51- <i>Returns</i>: The largest value <ins><tt>n</tt></ins> that can meaningfully be passed to 
<tt><del>X::</del><ins>a.</ins>allocate(<ins>n</ins>)</tt>.
<p/>
-52- <i>Remarks</i>: Default: <tt>numeric_limits&lt;size_type&gt;::max() / sizeof(value_type)</tt>
</p>
</blockquote>
[&hellip;]
<pre>
a == b
</pre>
<blockquote>
<p>
-59- <i>Result</i>: <tt>bool</tt>
<p/>
-60- <i>Returns</i>: <tt>a == Y<ins>Y</ins>::rebind<ins>_alloc</ins>&lt;T&gt;<del>::other</del>(b)</tt>.
</p>
</blockquote>
[&hellip;]
<p>
-92- An allocator type <tt>X</tt> shall meet the <i>Cpp17CopyConstructible</i> requirements (Table 33). 
The <tt>X<ins>X</ins>::pointer</tt>, <tt>X<ins>X</ins>::const_pointer</tt>, <tt>X<ins>X</ins>::void_pointer</tt>, 
and <tt>X<ins>X</ins>::const_void_pointer</tt> types shall meet the <i>Cpp17NullablePointer</i> requirements 
(Table 37). No constructor, comparison operator function, copy operation, move operation, or swap operation 
on these pointer types shall exit via an exception. <tt>X<ins>X</ins>::pointer</tt> and 
<tt>X<ins>X</ins>::const_pointer</tt> shall also meet the requirements for a <i>Cpp17RandomAccessIterator</i> 
(25.3.5.7) and the additional requirement that, when <tt><del>a</del><ins>p</ins></tt> and 
<tt>(<del>a</del><ins>p</ins> + n)</tt> are dereferenceable pointer values for some integral value <tt>n</tt>, 
<tt>addressof(*(<del>a</del><ins>p</ins> + n)) == addressof(*<del>a</del><ins>p</ins>) + n</tt> is <tt>true</tt>.
<p/>
-93- Let <tt>x1</tt> and <tt>x2</tt> denote objects of (possibly different) types <tt>X<ins>X</ins>::void_pointer</tt>, 
<tt>X<ins>X</ins>::const_void_pointer</tt>, <tt>X<ins>X</ins>::pointer</tt>, or <tt>X<ins>X</ins>::const_pointer</tt>. 
Then, <tt>x1</tt> and <tt>x2</tt> are equivalently-valued pointer values, if and only if both <tt>x1</tt> and 
<tt>x2</tt> can be explicitly converted to the two corresponding objects <tt>px1</tt> and <tt>px2</tt> of type 
<tt>X<ins>X</ins>::const_pointer</tt>, using a sequence of <tt>static_cast</tt>s using only these four types, and the 
expression <tt>px1 == px2</tt> evaluates to <tt>true</tt>.
<p/>
-94- Let <tt>w1</tt> and <tt>w2</tt> denote objects of type <tt>X<ins>X</ins>::void_pointer</tt>. Then for the expressions
</p>
<blockquote><pre>
w1 == w2
w1 != w2
</pre></blockquote>
<p>
either or both objects may be replaced by an equivalently-valued object of type 
<tt>X<ins>X</ins>::const_void_pointer</tt> with no change in semantics.
<p/>
-95- Let <tt>p1</tt> and <tt>p2</tt> denote objects of type <tt>X<ins>X</ins>::pointer</tt>. Then for the expressions
</p>
<blockquote><pre>
p1 == p2
p1 != p2
p1 &lt; p2
p1 &lt;= p2
p1 &gt;= p2
p1 &gt; p2
p1 - p2
</pre></blockquote>
<p>
either or both objects may be replaced by an equivalently-valued object of type <tt>X<ins>X</ins>::const_pointer</tt> 
with no change in semantics.
</p>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3778" href="https://cplusplus.github.io/LWG/lwg-active.html#3778">3778</a>. <tt>vector&lt;bool&gt;</tt> missing exception specifications</h3>
<p><b>Section:</b> 24.3.12.1 <a href="https://wg21.link/vector.bool.pspc">[vector.bool.pspc]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Alisdair Meredith <b>Opened:</b> 2022-09-13 <b>Last modified:</b> 2022-09-29</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
As noted back in <a href="https://wg21.link/P0177R2">P0177R2</a>, the primary template for <tt>vector</tt> has picked 
up some exception specification, but the partial specialization for <tt>vector&lt;bool&gt;</tt> 
has not been so updated.
<p/>
Several other changes have been made to <tt>vector</tt> in the intervening years, but these 
particular exception specifications have still not been updated. Note that the free-function 
<tt>swap</tt> in the header synopsis will automatically pick up this update once applied.
</p>

<p><i>[2022-09-28; 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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 24.3.12.1 <a href="https://wg21.link/vector.bool.pspc">[vector.bool.pspc]</a>, partial class template 
<tt>vector&lt;bool, Allocator&gt;</tt> synopsis, as indicated:</p>

<blockquote>
<pre>
namespace std {
  template&lt;class Allocator&gt;
  class vector&lt;bool, Allocator&gt; {
  public:
    [&hellip;]
    // <i>construct/copy/destroy</i>
    constexpr vector() <ins>noexcept(noexcept(Allocator()))</ins> : vector(Allocator()) { }
    constexpr explicit vector(const Allocator&amp;) <ins>noexcept</ins>;
    constexpr explicit vector(size_type n, const Allocator&amp; = Allocator());
    constexpr vector(size_type n, const bool&amp; value, const Allocator&amp; = Allocator());
    template&lt;class InputIterator&gt;
      constexpr vector(InputIterator first, InputIterator last, const Allocator&amp; = Allocator());
    template&lt;container-compatible-range &lt;bool&gt; R&gt;
      constexpr vector(from_range_t, R&amp;&amp; rg, const Allocator&amp; = Allocator());
    constexpr vector(const vector&amp; x);
    constexpr vector(vector&amp;&amp; x) <ins>noexcept</ins>;
    constexpr vector(const vector&amp;, const type_identity_t&lt;Allocator&gt;&amp;);
    constexpr vector(vector&amp;&amp;, const type_identity_t&lt;Allocator&gt;&amp;);
    constexpr vector(initializer_list&lt;bool&gt;, const Allocator&amp; = Allocator());
    constexpr ~vector();
    constexpr vector&amp; operator=(const vector&amp; x);
    constexpr vector&amp; operator=(vector&amp;&amp; x)
      <ins>noexcept(allocator_traits&lt;Allocator&gt;::propagate_on_container_move_assignment::value ||</ins>
               <ins>allocator_traits&lt;Allocator&gt;::is_always_equal::value)</ins>;
    constexpr vector&amp; operator=(initializer_list&lt;bool&gt;);
    template&lt;class InputIterator&gt;
      constexpr void assign(InputIterator first, InputIterator last);
    template&lt;container-compatible-range &lt;bool&gt; R&gt;
      constexpr void assign_range(R&amp;&amp; rg);
    constexpr void assign(size_type n, const bool&amp; t);
    constexpr void assign(initializer_list&lt;bool&gt;);
    constexpr allocator_type get_allocator() const noexcept;
  
    [&hellip;]
    constexpr iterator erase(const_iterator position);
    constexpr iterator erase(const_iterator first, const_iterator last);
    constexpr void swap(vector&amp;)
      <ins>noexcept(allocator_traits&lt;Allocator&gt;::propagate_on_container_swap::value ||</ins>
               <ins>allocator_traits&lt;Allocator&gt;::is_always_equal::value)</ins>;
    constexpr static void swap(reference x, reference y) noexcept;
    constexpr void flip() noexcept; // <i>flips all bits</i>
    constexpr void clear() noexcept;
  };
}
</pre>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3781" href="https://cplusplus.github.io/LWG/lwg-active.html#3781">3781</a>. The exposition-only alias templates <tt><i>cont-key-type</i></tt> and  <tt><i>cont-mapped-type</i></tt> should be removed</h3>
<p><b>Section:</b> 24.6.1 <a href="https://wg21.link/container.adaptors.general">[container.adaptors.general]</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> 2022-09-16 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
<a href="https://wg21.link/P0429R9">P0429R9</a> removed the <tt>flat_map</tt>'s single-range argument constructor and uses C++23-compatible 
<tt>from_range_t</tt> version constructor with alias templates <tt><i>range-key-type</i></tt> and 
<tt><i>range-mapped-type</i></tt> to simplify the deduction guide.
<p/>
This makes <tt><i>cont-key-type</i></tt> and <tt><i>cont-mapped-type</i></tt> no longer useful, we should remove them.
</p>

<p><i>[2022-10-12; 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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 24.6.1 <a href="https://wg21.link/container.adaptors.general">[container.adaptors.general]</a> as indicated:</p>

<blockquote>
<p>
-7- The exposition-only alias template <tt><i>iter-value-type</i></tt> defined in 
24.3.1 <a href="https://wg21.link/sequences.general">[sequences.general]</a> and the exposition-only alias templates 
<tt><i>iter-key-type</i></tt> and <tt><i>iter-mapped-type</i></tt> defined in 
24.4.1 <a href="https://wg21.link/associative.general">[associative.general]</a> may appear in deduction guides for container adaptors.
</p>
<p>
<del>-8- The following exposition-only alias templates may appear in deduction guides for container adaptors:</del>
</p>
<blockquote><pre><del>
template&lt;class Container&gt;
  using <i>cont-key-type</i> =                                // <i>exposition only</i>
    remove_const_t&lt;typename Container::value_type::first_type&gt;;
template&lt;class Container&gt;
  using <i>cont-mapped-type</i> =                             // <i>exposition only</i>
    typename Container::value_type::second_type;
</del></pre></blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3782" href="https://cplusplus.github.io/LWG/lwg-active.html#3782">3782</a>. Should <tt>&lt;math.h&gt;</tt> declare <tt>::lerp</tt>?</h3>
<p><b>Section:</b> 17.15.7 <a href="https://wg21.link/support.c.headers.other">[support.c.headers.other]</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> 2022-09-17 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#support.c.headers.other">active issues</a> in [support.c.headers.other].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#support.c.headers.other">issues</a> in [support.c.headers.other].</p>
<p><b>Discussion:</b></p>
<p>
According to 17.15.7 <a href="https://wg21.link/support.c.headers.other">[support.c.headers.other]</a>/1, <tt>&lt;math.h&gt;</tt> is required to 
provide <tt>::lerp</tt>, despite that it is a C++-only component. In <a href="https://wg21.link/P0811R3">P0811R3</a>, neither 
<tt>&lt;math.h&gt;</tt> nor C compatibility is mentioned, so it seems unintended not to list 
<tt>lerp</tt> as an exception in 17.15.7 <a href="https://wg21.link/support.c.headers.other">[support.c.headers.other]</a>.
<p/>
Currently there is implementation divergence: libstdc++ provide <tt>::lerp</tt> in 
<tt>&lt;math.h&gt;</tt> but not in <tt>&lt;cmath&gt;</tt>, while MSVC STL and libc++ don't provide 
<tt>::lerp</tt> in <tt>&lt;math.h&gt;</tt> or <tt>&lt;cmath&gt;</tt> at all.
<p/>
I'm not sure whether this should be considered together with LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3484">3484</a>. 
Since <tt>nullptr_t</tt> has become a part of the C standard library as of C23 
(see <a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3042.htm">WG14-N3042</a> and 
<a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3048.htm">WG14-N3048</a>), 
I believe we should keep providing <tt>::nullptr_t</tt> in <tt>&lt;stddef.h&gt;</tt>.
</p>

<p><i>[2022-10-12; 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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 17.15.7 <a href="https://wg21.link/support.c.headers.other">[support.c.headers.other]</a> as indicated:</p>

<blockquote>
<p>
-1- Every C header other than <tt>&lt;complex.h&gt;</tt> (17.15.2 <a href="https://wg21.link/complex.h.syn">[complex.h.syn]</a>), 
<tt>&lt;iso646.h&gt;</tt> (17.15.3 <a href="https://wg21.link/iso646.h.syn">[iso646.h.syn]</a>), 
<tt>&lt;stdalign.h&gt;</tt> (17.15.4 <a href="https://wg21.link/stdalign.h.syn">[stdalign.h.syn]</a>),
<tt>&lt;stdatomic.h&gt;</tt> (33.5.12 <a href="https://wg21.link/stdatomic.h.syn">[stdatomic.h.syn]</a>), 
<tt>&lt;stdbool.h&gt;</tt> (17.15.5 <a href="https://wg21.link/stdbool.h.syn">[stdbool.h.syn]</a>), 
and <tt>&lt;tgmath.h&gt;</tt> (17.15.6 <a href="https://wg21.link/tgmath.h.syn">[tgmath.h.syn]</a>), each of which has a name of
the form <tt>&lt;<i>name</i>.h&gt;</tt>, behaves as if each name placed in 
the standard library namespace by the corresponding <tt>&lt;c<i>name</i>&gt;</tt> 
header is placed within the global namespace scope, except for the functions 
described in 28.7.6 <a href="https://wg21.link/sf.cmath">[sf.cmath]</a>, <ins>the <tt>std::lerp</tt> function overloads 
(28.7.4 <a href="https://wg21.link/c.math.lerp">[c.math.lerp]</a>),</ins> the declaration of <tt>std::byte</tt> 
(17.2.1 <a href="https://wg21.link/cstddef.syn">[cstddef.syn]</a>), and the functions and function templates described 
in 17.2.5 <a href="https://wg21.link/support.types.byteops">[support.types.byteops]</a>. [&hellip;]
</p>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3784" href="https://cplusplus.github.io/LWG/lwg-active.html#3784">3784</a>. <tt>std.compat</tt> should not provide <tt>::byte</tt> and its friends</h3>
<p><b>Section:</b> 16.4.2.4 <a href="https://wg21.link/std.modules">[std.modules]</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> 2022-09-19 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
Currently 16.4.2.4 <a href="https://wg21.link/std.modules">[std.modules]</a>/3 seemly requires that the <tt>std.compat</tt> module 
has to provide <tt>byte</tt> (via <tt>&lt;cstddef&gt;</tt>), <tt>beta</tt> (via <tt>&lt;cmath&gt;</tt>) 
etc. in the global namespace, which is defective to me as these components are C++-only, 
and doing so would increase the risk of conflict.
<p/>
I think we should only let <tt>std.compat</tt> provide the same set of global declarations as 
<tt>&lt;xxx.h&gt;</tt> headers.
</p>

<p><i>[2022-10-12; 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/N4917">N4917</a>.
</p>

<ol>

<li><p>Modify 16.4.2.4 <a href="https://wg21.link/std.modules">[std.modules]</a> as indicated:</p>

<blockquote>
<p>
-3- The named module <tt>std.compat</tt> exports the same declarations as the named module <tt>std</tt>, 
and additionally exports declarations in the global namespace corresponding to the declarations in 
namespace <tt>std</tt> that are provided by the C++ headers for C library facilities 
(Table 26)<ins>, except the explicitly excluded declarations described in 17.15.7 <a href="https://wg21.link/support.c.headers.other">[support.c.headers.other]</a></ins>.
</p>
</blockquote>
</li>

</ol>





<hr>
<h3><a name="3785" href="https://cplusplus.github.io/LWG/lwg-active.html#3785">3785</a>. <tt>ranges::to</tt> is over-constrained on the destination type being a range</h3>
<p><b>Section:</b> 26.5.7.2 <a href="https://wg21.link/range.utility.conv.to">[range.utility.conv.to]</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> 2022-09-19 <b>Last modified:</b> 2022-09-28</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.utility.conv.to">active issues</a> in [range.utility.conv.to].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.utility.conv.to">issues</a> in [range.utility.conv.to].</p>
<p><b>Discussion:</b></p>
<p>
The current wording in 26.5.7.2 <a href="https://wg21.link/range.utility.conv.to">[range.utility.conv.to]</a> starts:
</p>
<blockquote><p>
If <tt>convertible_to&lt;range_reference_t&lt;R&gt;, range_value_t&lt;C&gt;&gt;</tt> is <tt>true</tt>
</p></blockquote>
<p>
and then tries to do <tt>C(r, args...)</tt> and then <tt>C(from_range, r, args...)</tt>. The problem 
is that <tt>C</tt> might not be a range &mdash; indeed we explicitly removed that requirement from an 
earlier revision of the paper &mdash; which makes this check ill-formed. One example use-case is using 
<tt>ranges::to</tt> to convert a range of <tt>expected&lt;T, E&gt;</tt> into a 
<tt>expected&lt;vector&lt;T&gt;, E&gt;</tt> &mdash; <tt>expected</tt> isn't any kind of range, but it 
could support this operation, which is quite useful. Unfortunately, the wording explicitly rejects that. 
This change happened between R6 and R7 of the paper and seems to have unintentionally rejected this use-case.
</p>

<p><i>[2022-09-28; Reflector poll]</i></p>

<p>
Set status to Tentatively Ready after five votes in favour during reflector poll.
During telecon review we agreed that supporting non-ranges was an intended
part of the original design, but was inadvertently broken when adding
<code>range_value_t</code> for other reasons.
</p>



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

<ol>

<li><p>Modify 26.5.7.2 <a href="https://wg21.link/range.utility.conv.to">[range.utility.conv.to]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> We need to be careful that this short-circuits, since if <tt>C</tt> does 
not satisfy <tt>input_range</tt>, then <tt>range_value_t&lt;C&gt;</tt> will be ill-formed.]
</p>
</blockquote>

<blockquote>
<pre>
template&lt;class C, input_range R, class... Args&gt; requires (!view&lt;C&gt;)
  constexpr C to(R&amp;&amp; r, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
-1- <i>Returns</i>: An object of type <tt>C</tt> constructed from the elements of <tt>r</tt> in the following manner:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If <ins><tt>C</tt> does not satisfy <tt>input_range</tt> or</ins> 
<tt>convertible_to&lt;range_reference_t&lt;R&gt;, range_value_t&lt;C&gt;&gt;</tt> is <tt>true</tt>:</p></li>
<ol style="list-style-type: none">
<li><p>(1.1.1) &mdash; If <tt>constructible_from&lt;C, R, Args...&gt;</tt> is <tt>true</tt>:</p></li>
<blockquote><tt>C(std::forward&lt;R&gt;(r), std::forward&lt;Args&gt;(args)...)</tt></blockquote>
<li><p>(1.1.2) &mdash; Otherwise, if <tt>constructible_from&lt;C, from_range_t, R, Args...&gt;</tt> is <tt>true</tt>:</p></li>
<blockquote><tt>C(from_range, std::forward&lt;R&gt;(r), std::forward&lt;Args&gt;(args)...)</tt></blockquote>
<li><p>(1.1.3) &mdash; Otherwise, if</p></li>
<ol style="list-style-type: none">
<li><p>(1.1.3.1) &mdash; <tt>common_range&lt;R&gt;</tt> is <tt>true</tt>,</p></li>
<li><p>(1.1.3.2) &mdash; <tt><i>cpp17-input-iterator</i>&lt;iterator_t&lt;R&gt;&gt;</tt> is <tt>true</tt>, and</p></li>
<li><p>(1.1.3.3) &mdash; <tt>constructible_from&lt;C, iterator_t&lt;R&gt;, sentinel_t&lt;R&gt;, Args...&gt;</tt> is <tt>true</tt>:</p></li>
<blockquote><tt>C(ranges::begin(r), ranges::end(r), std::forward&lt;Args&gt;(args)...)</tt></blockquote>
</ol>
<li><p>(1.1.4) &mdash; Otherwise, if</p></li>
<ol style="list-style-type: none">
<li><p>(1.1.4.1) &mdash; <tt>constructible_from&lt;C, Args...&gt;</tt> is <tt>true</tt>, and</p></li>
<li><p>(1.1.4.2) &mdash; <tt><i>container-insertable</i>&lt;C, range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>:</p>
<blockquote><pre>
C c(std::forward&lt;Args&gt;(args)...);
if constexpr (sized_range&lt;R&gt; &amp;&amp; <i>reservable-container</i>&lt;C&gt;)
  c.reserve(ranges::size(r));
ranges::copy(r, <i>container-inserter</i>&lt;range_reference_t&lt;R&gt;&gt;(c));
</pre></blockquote></li>
</ol>
</ol>
<li><p>(1.2) &mdash; Otherwise, if <tt>input_range&lt;range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>:</p>
<blockquote><pre>
to&lt;C&gt;(r | views::transform([](auto&amp;&amp; elem) {
  return to&lt;range_value_t&lt;C&gt;&gt;(std::forward&lt;decltype(elem)&gt;(elem));
}), std::forward&lt;Args&gt;(args)...);
</pre></blockquote></li>
<li><p>(1.3) &mdash; Otherwise, the program is ill-formed.</p></li>
</ol>
</blockquote>
</blockquote>
</li>
</ol>






<hr>
<h3><a name="3788" href="https://cplusplus.github.io/LWG/lwg-active.html#3788">3788</a>. <tt>jthread::operator=(jthread&amp;&amp;)</tt> postconditions are unimplementable under self-assignment</h3>
<p><b>Section:</b> 33.4.4.2 <a href="https://wg21.link/thread.jthread.cons">[thread.jthread.cons]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Nicole Mazzuca <b>Opened:</b> 2022-09-22 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<p>
In the <i>Postconditions</i> element of <tt>jthread&amp; jthread::operator=(jthread&amp;&amp;)</tt> 
(33.4.4.2 <a href="https://wg21.link/thread.jthread.cons">[thread.jthread.cons]</a> p13), we have the following:
</p>
<blockquote><p>
<i>Postconditions</i>: <tt>x.get_id() == id()</tt>, and <tt>get_id()</tt> returns the value of
<tt>x.get_id()</tt> prior to the assignment. <tt>ssource</tt> has the value of <tt>x.ssource</tt> 
prior to the assignment and <tt>x.ssource.stop_possible()</tt> is <tt>false</tt>.
</p></blockquote>
<p>
Assume <tt>j</tt> is a joinable <tt>jthread</tt>. Then, <tt>j = std::move(j);</tt> results in the following post-conditions:
</p>
<ul>
<li><p>Let <tt>old_id = j.get_id()</tt> (and since <tt>j</tt> is joinable, <tt>old_id != id()</tt>)</p></li>
<li><p>Since <tt>x.get_id() == id()</tt>, <tt>j.get_id() == id()</tt></p></li>
<li><p>Since <tt>get_id() == old_id</tt>, <tt>j.get_id() == old_id</tt></p></li>
<li><p>Thus, <tt>id() == j.get_id() == old_id</tt>, and <tt>old_id != id()</tt>, which is a contradiction.</p></li>
</ul>
<p>
One can see that these postconditions are therefore unimplementable.
<p/>
Two standard libraries &ndash; the MSVC STL and libstdc++ &ndash; currently implement <tt>jthread</tt>.
<p/>
The MSVC STL chooses to follow the letter of the <i>Effects</i> element, which results in unfortunate behavior.
It first <tt>request_stop()</tt>s, then <tt>join()</tt>s; then, it assigns the values over. This results in
<tt>j.get_id() == id()</tt> &ndash; this means that <tt>std::swap(j, j)</tt> stops and joins <tt>j</tt>.
<p/>
libstdc++ chooses instead to implement this move assignment operator via the move-swap idiom.
This results in <tt>j.get_id() == old_id</tt>, and <tt>std::swap(j, j)</tt> is a no-op.
<p/>
It is the opinion of the issue writer that libstdc++'s choice is the correct one, and should be
taken into the standard.
</p>

<p><i>[2022-09-28; Reflector poll]</i></p>

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

<p><i>[2022-09-28; Jonathan provides wording]</i></p>


<p><i>[2022-09-29; 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/N4917">N4917</a>.
</p>

<ol>
<li>
<p>Modify 33.4.4.2 <a href="https://wg21.link/thread.jthread.cons">[thread.jthread.cons]</a> as indicated:</p>

<blockquote>
<pre>jthread&amp; operator=(jthread&amp;&amp; x) noexcept;</pre>
<blockquote>
<p>-12- <i>Effects</i>:
If
<ins><tt>&amp;x == this</tt> is <tt>true</tt>, there are no effects.
Otherwise, if</ins>
<tt>joinable()</tt> is <tt>true</tt>, calls <tt>request_stop()</tt>
and then <tt>join()</tt><del>.
Assigns</del><ins>, then assigns</ins>
the state of <tt>x</tt> to <tt>*this</tt>
and sets <tt>x</tt> to a default constructed state.
</p>
<p> -13- <i>Postconditions</i>:
<del><tt>x.get_id() == id()</tt> and</del>
<tt>get_id()</tt> returns the value of <tt>x.get_id()</tt> prior to the assignment.
<tt>ssource</tt> has the value of <tt>x.ssource</tt> prior to the assignment
<del>and <tt>x.ssource.stop_possible()</tt> is <tt>false</tt></del>.
</p>
<p>-14- <i>Returns</i>: <tt>*this</tt>.</p>
</blockquote>
</blockquote>
</li>
</ol>






<hr>
<h3><a name="3792" href="https://cplusplus.github.io/LWG/lwg-active.html#3792">3792</a>. <tt>__cpp_lib_constexpr_algorithms</tt> should also be defined in <tt>&lt;utility&gt;</tt></h3>
<p><b>Section:</b> 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Marc Mutz <b>Opened:</b> 2022-10-05 <b>Last modified:</b> 2022-10-12</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#version.syn">active issues</a> in [version.syn].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#version.syn">issues</a> in [version.syn].</p>
<p><b>Discussion:</b></p>
<p>
17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a> says that <tt>__cpp_lib_constexpr_algorithms</tt> is only defined
in <tt>&lt;version&gt;</tt> and <tt>&lt;algorithm&gt;</tt>, but the macro applies to <tt>std::exchange()</tt>
in <tt>&lt;utility&gt;</tt> as well (via <a href="https://wg21.link/P0202R3">P0202R3</a>), so it should also be available from 
<tt>&lt;utility&gt;</tt>.
</p>

<p><i>[2022-10-12; 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/N4917">N4917</a>.
</p>

<ol>
<li><p>Modify 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a> as indicated (It is suggested to retroactively apply to C++20):</p>

<blockquote>
<pre>
[&hellip;]
#define __cpp_lib_concepts             202207L // <i>also in &lt;concepts&gt;, &lt;compare&gt;</i>
#define __cpp_lib_constexpr_algorithms 201806L // <i>also in &lt;algorithm&gt;<ins>, &lt;utility&gt;</ins></i>
#define __cpp_lib_constexpr_bitset     202202L // <i>also in &lt;bitset&gt;</i>
[&hellip;]
</pre>
</blockquote>
</li>
</ol>





<hr>
<h3><a name="3795" href="https://cplusplus.github.io/LWG/lwg-active.html#3795">3795</a>. Self-move-assignment of <tt>std::future</tt> and <tt>std::shared_future</tt> have unimplementable postconditions</h3>
<p><b>Section:</b> 33.10.7 <a href="https://wg21.link/futures.unique.future">[futures.unique.future]</a>, 33.10.8 <a href="https://wg21.link/futures.shared.future">[futures.shared.future]</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> 2022-10-19 <b>Last modified:</b> 2022-11-07</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#futures.unique.future">issues</a> in [futures.unique.future].</p>
<p><b>Discussion:</b></p>
<p>
The move assignment operators of <tt>std::future</tt> and <tt>std::shared_future</tt> have their postconditions specified as below:
</p>
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;">
<p>
<i>Postconditions</i>:
</p>
<ul>
<li><p><tt>valid()</tt> returns the same value as <tt>rhs.valid()</tt> returned prior to the assignment.</p></li>
<li><p><tt>rhs.valid() == false</tt>.</p></li>
</ul>        
</blockquote>
<p>
It can be found that when <tt>*this</tt> and <tt>rhs</tt> is the same object and <tt>this-&gt;valid()</tt> 
is <tt>true</tt> before the assignment, the postconditions can't be achieved.
<p/>
Mainstream implementations (libc++, libstdc++, msvc stl) currently implement such self-move-assignment as no-op, 
which doesn't meet the requirements in the <i>Effects:</i> element. As discussed in LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3788">3788</a>, I think 
we should say self-move-assignment has no effects for these types.
</p>

<p><i>[2022-11-01; Reflector poll]</i></p>

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

<p><i>[2022-11-01; Jonathan provides wording]</i></p>



<p><i>[2022-11-07; 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/N4917">N4917</a>.
</p>

<ol>
<li><p>Modify 33.10.7 <a href="https://wg21.link/futures.unique.future">[futures.unique.future]</a> as indicated:</p>

<blockquote>
<blockquote><pre>
future&amp; operator=(future&amp;&amp; rhs) noexcept;
</pre></blockquote>
<blockquote>
<p>-11- <i>Effects</i>:
<ins>
If <tt>addressof(rhs) == this</tt> is <tt>true</tt>, there are no effects.
Otherwise:
</ins>
<ol style="list-style-type: none">
<li>(11.1) &mdash; Releases any shared state (33.10.5 <a href="https://wg21.link/futures.state">[futures.state]</a>).</li>
<li>(11.2) &mdash; move assigns the contents of <tt>rhs</tt> to <tt>*this</tt>.</li>
</ol>
</p>
<p> -12- <i>Postconditions</i>:
<ol style="list-style-type: none">
<li>(12.1) &mdash; <tt>valid()</tt> returns the same value as <tt>rhs.valid()</tt> prior to the assignment.</li>
<li>(12.2) &mdash; <ins>If <tt>addressof(rhs) == this</tt> is <tt>false</tt>,</ins> <tt>rhs.valid() == false</tt>.</li>
</ol>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 33.10.8 <a href="https://wg21.link/futures.shared.future">[futures.shared.future]</a> as indicated:</p>

<blockquote>
<blockquote><pre>
shared_future&amp; operator=(shared_future&amp;&amp; rhs) noexcept;
</pre></blockquote>
<blockquote>
<p>-13- <i>Effects</i>:
<ins>
If <tt>addressof(rhs) == this</tt> is <tt>true</tt>, there are no effects.
Otherwise:
</ins>
<ol style="list-style-type: none">
<li>(13.1) &mdash; Releases any shared state (33.10.5 <a href="https://wg21.link/futures.state">[futures.state]</a>).</li>
<li>(13.2) &mdash; move assigns the contents of <tt>rhs</tt> to <tt>*this</tt>.</li>
</ol>
</p>
<p> -14- <i>Postconditions</i>:
<ol style="list-style-type: none">
<li>(14.1) &mdash; <tt>valid()</tt> returns the same value as <tt>rhs.valid()</tt> returned prior to the assignment.</li>
<li>(14.2) &mdash; <ins>If <tt>addressof(rhs) == this</tt> is <tt>false</tt>,</ins> <tt>rhs.valid() == false</tt>.</li>
</ol>
</p>
</blockquote>

<blockquote><pre>
shared_future&amp; operator=(const shared_future&amp; rhs) noexcept;
</pre></blockquote>
<blockquote>
<p>-15- <i>Effects</i>:
<ins>
If <tt>addressof(rhs) == this</tt> is <tt>true</tt>, there are no effects.
Otherwise:
</ins>
<ol style="list-style-type: none">
<li>(15.1) &mdash; Releases any shared state (33.10.5 <a href="https://wg21.link/futures.state">[futures.state]</a>).</li>
<li>(15.2) &mdash; assigns the contents of <tt>rhs</tt> to <tt>*this</tt>.
<p>[<i>Note 3</i>: As a result, <tt>*this</tt> refers to the same shared state
as <tt>rhs</tt> (if any). &mdash; <i>end note</i>]</p>
</li>
</ol>
</p>
<p> -16- <i>Postconditions</i>:
<tt>valid() == rhs.valid()</tt>.
</p>
</blockquote>
</blockquote>
</li>
</ol>






<hr>
<h3><a name="3796" href="https://cplusplus.github.io/LWG/lwg-active.html#3796">3796</a>. <tt><i>movable-box</i></tt> as member should use default-initialization instead of copy-initialization</h3>
<p><b>Section:</b> 26.6.5.2 <a href="https://wg21.link/range.repeat.view">[range.repeat.view]</a>, 26.7.29.2 <a href="https://wg21.link/range.chunk.by.view">[range.chunk.by.view]</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> 2022-10-20 <b>Last modified:</b> 2022-11-01</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.repeat.view">active issues</a> in [range.repeat.view].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#range.repeat.view">issues</a> in [range.repeat.view].</p>
<p><b>Discussion:</b></p>
<p>
Currently, the member variable <tt><i>value_</i></tt> of <tt>repeat_view</tt> is initialized with the following expression:
</p>
<blockquote><pre>
<i>movable-box</i>&lt;W&gt; <i>value_</i> = W();
</pre></blockquote>
<p>
which will result in the following unexpected error in <a href="https://godbolt.org/z/jK7djP6GT">libstdc++</a>:
</p>
<blockquote><pre>
#include &lt;ranges&gt;

int main() {
  std::ranges::repeat_view&lt;int&gt; r; // <span style="color:red;font-weight:bolder">error: could not convert '0' from 'int' to 'std::ranges::__detail::__box&lt;int&gt;'</span>
}
</pre></blockquote>
<p>
This is because the single-argument constructors of the simple version of <tt><i>movable-box</i></tt> in libstdc++ 
are declared as <tt>explicit</tt>, which is different from the conditional <tt>explicit</tt> declared by the 
<tt>optional</tt>'s constructor, resulting in no visible conversion between those two types.
<p/>
For MSVC-STL, the simple version of <tt><i>movable-box</i></tt> does not provide a single-argument constructor, 
so this form of initialization will also produce a hard error.
</p>
<p>
This may be a bug of existing implementations, but we don't need such "copy-initialization", the default-constructed 
<tt><i>movable-box</i></tt> already value-initializes the underlying type.
<p/>
Simply using default initialization, as most other range adaptors do, guarantees consistency, which also 
eliminates extra move construction.
</p>

<p><i>[2022-11-01; 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/N4917">N4917</a>.
</p>

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

<blockquote>
<pre>
namespace std::ranges {
  template&lt;move_constructible W, semiregular Bound = unreachable_sentinel_t&gt;
    requires (is_object_v&lt;W&gt; &amp;&amp; same_as&lt;W, remove_cv_t&lt;W&gt;&gt; &amp;&amp;
              (<i>is-integer-like</i>&lt;Bound&gt; || same_as&lt;Bound, unreachable_sentinel_t&gt;))
   class repeat_view : public view_interface&lt;repeat_view&lt;W, Bound&gt;&gt; {
   private:
     // <i>26.6.5.3 <a href="https://wg21.link/range.repeat.iterator">[range.repeat.iterator]</a>, class repeat_view::<i>iterator</i></i>
     struct <i>iterator</i>;                            // <i>exposition only</i>

     <i>movable-box</i>&lt;W&gt; <i>value_</i><del> = W()</del>;                // <i>exposition only, see 26.7.3 <a href="https://wg21.link/range.move.wrap">[range.move.wrap]</a></i>
     Bound <i>bound_</i> = Bound();                     // <i>exposition only</i>
     [&hellip;]
   };
   [&hellip;]
}
</pre>
</blockquote>
</li>

<li><p>Modify 26.7.29.2 <a href="https://wg21.link/range.chunk.by.view">[range.chunk.by.view]</a> as indicated:</p>

<blockquote>
<pre>
namespace std::ranges {
  template&lt;forward_range V, indirect_binary_predicate&lt;iterator_t&lt;V&gt;, iterator_t&lt;V&gt;&gt; Pred&gt;
    requires view&lt;V&gt; &amp;&amp; is_object_v&lt;Pred&gt;
  class chunk_by_view : public view_interface&lt;chunk_by_view&lt;V, Pred&gt;&gt; {
    V <i>base_</i> = V();                                          // <i>exposition only</i>
    <i>movable-box</i>&lt;Pred&gt; <i>pred_</i><del> = Pred()</del>;                       // <i>exposition only</i>

    // <i>26.7.29.3 <a href="https://wg21.link/range.chunk.by.iter">[range.chunk.by.iter]</a></i>, <i>class</i> chunk_by_view::<i>iterator</i>
    class <i>iterator</i>;                                         // <i>exposition only</i>
    [&hellip;]
  };
  [&hellip;]
}
</pre>
</blockquote>

</li>
</ol>





<hr>
<h3><a name="3798" href="https://cplusplus.github.io/LWG/lwg-active.html#3798">3798</a>. Rvalue reference and <tt>iterator_category</tt></h3>
<p><b>Section:</b> 25.3.2.3 <a href="https://wg21.link/iterator.traits">[iterator.traits]</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> 2022-10-22 <b>Last modified:</b> 2022-11-01</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#iterator.traits">active issues</a> in [iterator.traits].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#iterator.traits">issues</a> in [iterator.traits].</p>
<p><b>Discussion:</b></p>
<p>
Since C++11, a forward iterator may have an rvalue reference as its <tt>reference</tt> type. 
I think this is an intentional change made by <a href="https://wg21.link/N3066">N3066</a>. However, several components 
added (or changed) in C++20/23 recognize an iterator as a <i>Cpp17ForwardIterator</i> (by using 
<tt>forward_iterator_tag</tt> or a stronger iterator category tag type as the <tt>iterator_category</tt> 
type) only if the <tt>reference</tt> type would be an lvalue reference type, which seems a regression.
</p>

<p><i>[2022-11-01; 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/N4917">N4917</a>.
</p>

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

<blockquote>
<p>
-2- The definitions in this subclause make use of the following exposition-only concepts:
</p>
<blockquote><pre>
[&hellip;]
template&lt;class I&gt;
concept <i>cpp17-forward-iterator</i> =
  <i>cpp17-input-iterator</i>&lt;I&gt; &amp;&amp; constructible_from&lt;I&gt; &amp;&amp;
  is_<del>lvalue_</del>reference_v&lt;iter_reference_t&lt;I&gt;&gt; &amp;&amp;
  same_as&lt;remove_cvref_t&lt;iter_reference_t&lt;I&gt;&gt;,
          typename indirectly_readable_traits&lt;I&gt;::value_type&gt; &amp;&amp;
  requires(I i) {
    {  i++ } -&gt; convertible_to&lt;const I&amp;&gt;;
    { *i++ } -&gt; same_as&lt;iter_reference_t&lt;I&gt;&gt;;
  };
[&hellip;]
</pre></blockquote>
</blockquote>
</li>

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

<blockquote>
<p>
-2- The member <i>typedef-name</i> <tt>iterator_category</tt> is defined if and only if <i>Base</i> 
models <tt>forward_range</tt>. In that case, <tt><i>iterator</i>::iterator_category</tt> is defined 
as follows: Let <tt>C</tt> denote the type <tt>iterator_traits&lt;iterator_t&lt;<i>Base</i>&gt;&gt;::iterator_category</tt>.
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; If <tt>is_<del>lvalue_</del>reference_v&lt;invoke_result_t&lt;<i>maybe-const</i>&lt;Const, F&gt;&amp;, 
range_reference_t&lt;<i>Base</i>&gt;&gt;&gt;</tt> is <tt>true</tt>, then</p>
<ol style="list-style-type: none">
<li><p>(2.1.1) &mdash; if <tt>C</tt> models <tt>derived_from&lt;contiguous_iterator_tag&gt;</tt>, 
<tt>iterator_category denotes random_access_iterator_tag</tt>;</p></li>
<li><p>(2.1.2) &mdash; otherwise, <tt>iterator_category</tt> denotes <tt>C</tt>.</p></li>
</ol>
</li>
<li><p>(2.2) &mdash; Otherwise, <tt>iterator_category</tt> denotes <tt>input_iterator_tag</tt>.</p></li>
</ol>
</blockquote>
</li>

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

<blockquote>
<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>, and <tt><i>Base</i></tt> and <tt><i>InnerBase</i></tt> each model <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; [&hellip;]</p></li>
<li><p>(2.2) &mdash; If</p>
<blockquote><pre>
is_<del>lvalue_</del>reference_v&lt;common_reference_t&lt;iter_reference_t&lt;<i>InnerIter</i>&gt;,
                      iter_reference_t&lt;<i>PatternIter</i>&gt;&gt;&gt;
</pre></blockquote>
<p>
is <tt>false</tt>, <tt>iterator_category</tt> denotes <tt>input_iterator_tag</tt>.
</p>
</li>
<li><p>(2.3) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

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

<blockquote>
<p>
-1- The member <i>typedef-name</i> <tt><i>iterator</i>::iterator_category</tt> is defined if and only if 
<tt><i>Base</i></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>(1.1) &mdash; If</p>
<blockquote><pre>
invoke_result_t&lt;<i>maybe-const</i>&lt;Const, F&gt;&amp;, range_reference_t&lt;<i>maybe-const</i>&lt;Const, Views&gt;&gt;...&gt;
</pre></blockquote>
<p>
is not a<del>n lvalue</del> reference, <tt>iterator_category</tt> denotes <tt>input_iterator_tag</tt>.
</p>
</li>
<li><p>(1.2) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

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

<blockquote>
<p>
-1- The member <i>typedef-name</i> <tt><i>iterator</i>::iterator_category</tt> is defined as follows:
</p>
<ol style="list-style-type: none">
<li><p>(1.1) &mdash; If 
<tt>invoke_result_t&lt;<i>maybe-const</i>&lt;Const, F&gt;&amp;, <i>REPEAT</i>(range_reference_t&lt;<i>Base</i>&gt;, N)...&gt;</tt>
is not a<del>n lvalue</del> reference, <tt>iterator_category</tt> denotes <tt>input_iterator_tag</tt>.
</p>
</li>
<li><p>(1.2) &mdash; [&hellip;]</p></li>
</ol>
</blockquote>
</li>

</ol>






<hr>
<h3><a name="3801" href="https://cplusplus.github.io/LWG/lwg-active.html#3801">3801</a>. <tt>cartesian_product_view::<i>iterator</i>::<i>distance-from</i></tt> ignores the size of last underlying range</h3>
<p><b>Section:</b> 26.7.31.3 <a href="https://wg21.link/ranges.cartesian.iterator">[ranges.cartesian.iterator]</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> 2022-10-25 <b>Last modified:</b> 2022-11-04</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#ranges.cartesian.iterator">active issues</a> in [ranges.cartesian.iterator].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#ranges.cartesian.iterator">issues</a> in [ranges.cartesian.iterator].</p>
<p><b>Discussion:</b></p>
<p>
The helper <tt><i>scaled-size</i>(<i>N</i>)</tt> from the wording for <a href="https://wg21.link/P2374R4">P2374R4</a>'s
<tt>cartesian_product_view::<i>iterator</i>::<i>distance-from</i></tt> is recursively 
specified as:
</p>
<blockquote>
<p>
Let <tt><i>scaled-size</i>(<i>N</i>)</tt> be the product of
<tt>static_cast&lt;difference_type&gt;(ranges::size(std::get&lt;<i>N</i>&gt;(<i>parent_</i>-&gt;<i>bases_</i>)))</tt>
and <tt><i>scaled-size</i>(<i>N</i> + 1)</tt> if <tt><i>N</i> &lt; sizeof...(Vs)</tt>, otherwise
<tt>static_cast&lt;difference_type&gt;(1)</tt>;
</p>
</blockquote>
<p>
Intuitively, <tt><i>scaled-size</i>(<i>N</i>)</tt> is the size of the cartesian product of all
but the first <tt><i>N</i></tt> underlying ranges. Thus <tt><i>scaled-size</i>(sizeof...(Vs))</tt> 
ought to just yield the size of the last underlying range (since there are
<tt>1 + sizeof...(Vs)</tt> underlying ranges), but according to this definition it
yields <tt>1</tt>. Similarly at the other extreme, <tt><i>scaled-size</i>(0)</tt> should yield
the product of the sizes of all the underlying ranges, but it instead yields that of all but 
the last underlying range.
<p/>
For <tt>cartesian_product_view</tt>s of two or more underlying ranges, this
causes the relevant <tt>operator-</tt> overloads to compute wrong distances, e.g.
</p>
<blockquote><pre>
int x[] = {1, 2, 3};
auto v = views::cartesian_product(x, x);
auto i = v.begin() + 5;  // *i == {2, 3}
assert(*i == tuple{2, 3});
assert(i - v.begin() == 5); // fails, expects 3, because:
// scaled-sum = scaled-distance(0) + scaled-distance(1)
//            = ((1 - 0) * scaled-size(1)) + ((2 - 0) * scaled-size(2))
//            = 1 + 2 instead of 3 + 2
</pre></blockquote>
<p>
The recursive condition should probably use <tt>&lt;=</tt> instead of <tt>&lt;</tt>.
</p>

<p><i>[2022-11-04; 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/N4917">N4917</a>.
</p>

<ol>
<li><p>Modify 26.7.31.3 <a href="https://wg21.link/ranges.cartesian.iterator">[ranges.cartesian.iterator]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class Tuple&gt;
  constexpr difference_type <i>distance-from</i>(Tuple t);
</pre>
<blockquote>
<p>
-7- Let:
</p>
<ol style="list-style-type: none">
<li><p>(7.1) &mdash; <tt><i>scaled-size</i>(<i>N</i>)</tt> be the product of 
<tt>static_cast&lt;difference_type&gt;(ranges::size(std::get&lt;<i>N</i>&gt;(<i>parent_</i>-&gt;<i>bases_</i>)))</tt> 
and <tt><i>scaled-size</i>(<i>N</i> + 1)</tt> if <tt><i>N</i> <ins>&le;</ins><del>&lt;</del> sizeof...(Vs)</tt>, otherwise 
<tt>static_cast&lt;difference_type&gt;(1)</tt>;</p></li>
<li><p>(7.2) &mdash; <tt><i>scaled-distance</i>(<i>N</i>)</tt> be the product of 
<tt>static_cast&lt;difference_type&gt;(std::get&lt;<i>N</i>&gt;(<i>current_</i>) - std::get&lt;<i>N</i>&gt;(t))</tt> 
and <tt><i>scaled-size</i>(<i>N</i> + 1)</tt>; and</p></li>
<li><p>(7.3) &mdash; <tt><i>scaled-sum</i></tt> be the sum of <tt><i>scaled-distance</i>(<i>N</i>)</tt> for every 
integer <tt>0 &le; N &le; sizeof...(Vs)</tt>.</p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol>





</body>
</html>
