<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>C++ Standard Library Issues to be moved in Wrocław, Nov. 2024</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 Wrocław, Nov. 2024</h1>
<table>
<tr>
<td align="left">Doc. no.</td>
<td align="left">P3504R0</td>
</tr>
<tr>
<td align="left">Date:</td>
<td align="left"><p>2024-11-18</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 id="3436"><a href="https://cplusplus.github.io/LWG/lwg-active.html#3436">3436</a>. <code>std::construct_at</code> should support arrays</h3>
<p><b>Section:</b> 26.11.8 <a href="https://wg21.link/specialized.construct">[specialized.construct]</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> 2020-04-29 <b>Last modified:</b> 2024-06-24</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#specialized.construct">active issues</a> in [specialized.construct].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#specialized.construct">issues</a> in [specialized.construct].</p>
<p><b>Discussion:</b></p>
<p>
<code>std::construct_at</code> is ill-formed for array types, because the type of the <code>new</code>-expression is <code>T</code> 
not <code>T*</code> so it cannot be converted to the return type.
<p/>
In C++17 <code>allocator_traits::construct</code> did work for arrays, because it returns <code>void</code> so there is no 
ill-formed conversion. On the other hand, in C++17 <code>allocator_traits::destroy</code> didn't work for arrays, 
because <code>p-&gt;~T()</code> isn't valid.
<p/>
In C++20 <code>allocator_traits::destroy</code> does work, because <code>std::destroy_at</code> treats arrays specially, 
but <code>allocator_traits::construct</code> no longer works because it uses <code>std::construct_at</code>.
<p/>
It seems unnecessary and/or confusing to remove support for arrays in <code>construct</code> when we're adding it in <code>destroy</code>.
<p/>
I suggest that <code>std::construct_at</code> should also handle arrays. It might be reasonable to restrict that 
support to the case where <code>sizeof...(Args) == 0</code>, if supporting parenthesized aggregate-initialization 
is not desirable in <code>std::construct_at</code>.
</p>

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

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

<p><i>[2021-01-16; Zhihao Yuan 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/N4878" title=" Working Draft, Standard for Programming Language C++">N4878</a>. 
</p>

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

<blockquote>
<pre>
template&lt;class T, class... Args&gt;
  constexpr T* construct_at(T* location, Args&amp;&amp;... args);

namespace ranges {
  template&lt;class T, class... Args&gt;
    constexpr T* construct_at(T* location, Args&amp;&amp;... args);
}
</pre>
<blockquote>
<p>
-1- <i>Constraints:</i> The expression <code>::new (declval&lt;void*&gt;()) T(declval&lt;Args&gt;()...)</code> is well-formed
when treated as an unevaluated operand.
<p/>
-2- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
<del>return</del><ins>auto ptr =</ins> ::new (<i>voidify</i>(*location)) T(std::forward&lt;Args&gt;(args)...);
<ins>if constexpr (is_array_v&lt;T&gt;)
  return launder(location);
else
  return ptr;</ins>
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2021-12-07; Zhihao Yuan comments and provides improved wording]</i></p>

<p>
The previous PR allows constructing arbitrary number of elements when
<code>T</code> is an array of unknown bound:</p>
<blockquote><pre>
extern int a[];
std::construct_at(&amp;a, 0, 1, 2);
</pre></blockquote>
<p>
and leads to a UB.
</p>
<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">

<p>
This wording is relative to <a href="https://wg21.link/N4901" title=" Working Draft, Standard for Programming Language C++">N4901</a>. 
</p>

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

<blockquote>
<pre>
template&lt;class T, class... Args&gt;
  constexpr T* construct_at(T* location, Args&amp;&amp;... args);

namespace ranges {
  template&lt;class T, class... Args&gt;
    constexpr T* construct_at(T* location, Args&amp;&amp;... args);
}
</pre>
<blockquote>
<p>
-1- <i>Constraints:</i> The expression <code>::new (declval&lt;void*&gt;()) T(declval&lt;Args&gt;()...)</code> is well-formed
when treated as an unevaluated operand (7.2.3 <a href="https://wg21.link/expr.context">[expr.context]</a>) <ins>and <code>is_unbounded_array_v&lt;T&gt;</code> is 
<code>false</code></ins>.
<p/>
-2- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
<del>return</del><ins>auto ptr =</ins> ::new (<i>voidify</i>(*location)) T(std::forward&lt;Args&gt;(args)...);
<ins>if constexpr (is_array_v&lt;T&gt;)
  return launder(location);
else
  return ptr;</ins>
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2024-03-18; Jonathan provides new wording]</i></p>

<p>
During Core review in Varna, Hubert suggested creating <code class='backtick'>T[1]</code> for the array case.
</p>

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

<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

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

<blockquote>
<pre>
template&lt;class T, class... Args&gt;
  constexpr T* construct_at(T* location, Args&amp;&amp;... args);

namespace ranges {
  template&lt;class T, class... Args&gt;
    constexpr T* construct_at(T* location, Args&amp;&amp;... args);
}
</pre>
<blockquote>
<p>
-1- <i>Constraints:</i>
<ins><code>is_unbounded_array_v&lt;T&gt;</code> is <code>false</code>.</ins>
The expression <code>::new (declval&lt;void*&gt;()) T(declval&lt;Args&gt;()...)</code> is well-formed
when treated as an unevaluated operand (7.2.3 <a href="https://wg21.link/expr.context">[expr.context]</a>).
<p/>
-2- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
<ins>if constexpr (is_array_v&lt;T&gt;)
  return ::new (<i>voidify</i>(*location)) T[1]{{std::forward&lt;Args&gt;(args)...}};
else</ins>
  return ::new (<i>voidify</i>(*location)) T(std::forward&lt;Args&gt;(args)...);
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[St. Louis 2024-06-24; Jonathan provides improved wording]</i></p>

<p>
Why not support unbounded arrays, deducing the bound from <code class='backtick'>sizeof...(Args)</code>?
<br/>
JW: There's no motivation to support that here in <code class='backtick'>construct_at</code>.
It isn't possible to create unbounded arrays via allocators,
nor via any of the <code class='backtick'>uninitialized_xxx</code> algorithms. Extending <code class='backtick'>construct_at</code>
that way seems like a design change, not restoring support for something
that used to work with allocators and then got broken in C++20.
</p>
<p>
Tim observed that the proposed resolution is ill-formed if <code class='backtick'>T</code> has an
explicit default constructor. Value-initialization would work for that case,
and there seems to be little motivation for supplying arguments to
initialize the array. In C++17 the <code class='backtick'>allocator_traits::construct</code> case only
supported value-initialization.
</p>

<p><i>[St. Louis 2024-06-24; move to Ready.]</i></p>



<p id="res-3436"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

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

<blockquote>
<pre>
template&lt;class T, class... Args&gt;
  constexpr T* construct_at(T* location, Args&amp;&amp;... args);

namespace ranges {
  template&lt;class T, class... Args&gt;
    constexpr T* construct_at(T* location, Args&amp;&amp;... args);
}
</pre>
<blockquote>
<p>
-1- <i>Constraints:</i>
<ins><code>is_unbounded_array_v&lt;T&gt;</code> is <code>false</code>.</ins>
The expression <code>::new (declval&lt;void*&gt;()) T(declval&lt;Args&gt;()...)</code> is well-formed
when treated as an unevaluated operand (7.2.3 <a href="https://wg21.link/expr.context">[expr.context]</a>).
</p>
<p>
<ins>-?- <i>Mandates</i>:
If <code>is_array_v&lt;T&gt;</code> is <code class='backtick'>true</code>, <code class='backtick'>sizeof...(Args)</code> is zero.
</ins>
</p>
<p>
-2- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
<ins>if constexpr (is_array_v&lt;T&gt;)
  return ::new (<i>voidify</i>(*location)) T[1]();
else</ins>
  return ::new (<i>voidify</i>(*location)) T(std::forward&lt;Args&gt;(args)...);
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>




<hr>
<h3 id="3899"><a href="https://cplusplus.github.io/LWG/lwg-active.html#3899">3899</a>. <code>co_yield</code>ing elements of an lvalue <code>generator</code> is unnecessarily inefficient</h3>
<p><b>Section:</b> 25.8.5 <a href="https://wg21.link/coro.generator.promise">[coro.generator.promise]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2023-03-04 <b>Last modified:</b> 2024-06-28</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#coro.generator.promise">active issues</a> in [coro.generator.promise].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#coro.generator.promise">issues</a> in [coro.generator.promise].</p>
<p><b>Discussion:</b></p>
<p>
Consider:
</p>
<blockquote>
<pre>
std::generator&lt;int&gt; f();
std::generator&lt;int&gt; g() {
    auto gen = f();
    auto gen2 = f();
    co_yield std::ranges::elements_of(std::move(gen));   // #1
    co_yield std::ranges::elements_of(gen2);             // #2
    // other stuff
}
</pre>
</blockquote>
<p>
Both #1 and #2 compile. The differences are:
</p>
<ul>
<li>
<p>
#2 is significantly less efficient (it uses the general overload of <code>yield_value</code>,
so it creates a new coroutine frame and doesn't do symmetric transfer into <code>gen2</code>'s coroutine)
</p>
</li>
<li>
<p>
the coroutine frame of <code>gen</code> and <code>gen2</code> are destroyed at different
times: <code>gen</code>'s frame is destroyed at the end of #1, but <code>gen2</code>'s is
not destroyed until the closing brace.
</p>
</li>
</ul>
<p>
But as far as the user is concerned, neither <code>gen</code> nor <code>gen2</code> is
usable after the <code>co_yield</code>. In both cases the only things you can do
with the objects are:
</p>
<ul>
<li><p>destroying them;</p></li>
<li><p>assigning to them;</p></li>
<li><p>call <code>end()</code> on them to get a copy of <code>default_sentinel</code>.</p></li>
</ul>
<p>
We could make #2 ill-formed, but that seems unnecessary: there is no meaningful
difference between <code>generator</code> and any other single-pass input range
(or a <code>generator</code> with a different yielded type that has to go through
the general overload) in this regard. We should just make #2 do the efficient
thing too.
</p>

<p><i>[2023-03-22; Reflector poll]</i></p>

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

<p><i>[St. Louis 2024-06-28; move to Ready]</i></p>




<p id="res-3899"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4928" title=" Working Draft, Standard for Programming Language C++">N4928</a>.
</p>

<ol>

<li><p>Modify 25.8.5 <a href="https://wg21.link/coro.generator.promise">[coro.generator.promise]</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;::promise_type {
  public:
    [&hellip;]
    auto yield_value(const remove_reference_t&lt;yielded&gt;&amp; lval)
      requires is_rvalue_reference_v&lt;yielded&gt; &amp;&amp;
        constructible_from&lt;remove_cvref_t&lt;yielded&gt;, const remove_reference_t&lt;yielded&gt;&amp;&gt;;

    template&lt;class R2, class V2, class Alloc2, class Unused&gt;
      requires same_as&lt;typename generator&lt;R2, V2, Alloc2&gt;::yielded, yielded&gt;
        auto yield_value(ranges::elements_of&lt;generator&lt;R2, V2, Alloc2&gt;&amp;&amp;, Unused&gt; g) noexcept;
<ins>    template&lt;class R2, class V2, class Alloc2, class Unused&gt;
      requires same_as&lt;typename generator&lt;R2, V2, Alloc2&gt;::yielded, yielded&gt;
        auto yield_value(ranges::elements_of&lt;generator&lt;R2, V2, Alloc2&gt;&amp;, Unused&gt; g) noexcept;</ins>

    template&lt;ranges::input_range R, class Alloc&gt;
      requires convertible_to&lt;ranges::range_reference_t&lt;R&gt;, yielded&gt;
        auto yield_value(ranges::elements_of&lt;R, Alloc&gt; r) noexcept;
    [&hellip;]
   };
}
</pre>
</blockquote>
[&hellip;]
<pre>
template&lt;class R2, class V2, class Alloc2, class Unused&gt;
  requires same_as&lt;typename generator&lt;R2, V2, Alloc2&gt;::yielded, yielded&gt;
  auto yield_value(ranges::elements_of&lt;generator&lt;R2, V2, Alloc2&gt;&amp;&amp;, Unused&gt; g) noexcept;
<ins>template&lt;class R2, class V2, class Alloc2, class Unused&gt;
  requires same_as&lt;typename generator&lt;R2, V2, Alloc2&gt;::yielded, yielded&gt;
  auto yield_value(ranges::elements_of&lt;generator&lt;R2, V2, Alloc2&gt;&amp;, Unused&gt; g) noexcept;</ins>
</pre>
<blockquote>
<p>
-10- <i>Preconditions</i>: A handle referring to the coroutine whose promise object
is <code>*this</code> is at the top of <code>*<i>active_</i></code> of some generator
object <code>x</code>. The coroutine referred to by <code>g.range.<i>coroutine_</i></code>
is suspended at its initial suspend point.
<p/>
-11- <i>Returns:</i> An awaitable object of an unspecified type (7.6.2.4 <a href="https://wg21.link/expr.await">[expr.await]</a>)
into which <code>g.range</code> is moved, whose member <code>await_ready</code> returns <code>false</code>,
whose member <code>await_suspend</code> pushes <code>g.range.<i>coroutine_</i></code> into <code>*x.<i>active_</i></code>
and resumes execution of the coroutine referred to by <code>g.range.<i>coroutine_</i></code>,
and whose member <code>await_resume</code> evaluates <code>rethrow_exception(<i>except_</i>)</code>
if <code>bool(<i>except_</i>)</code> is <code>true</code>. If <code>bool(<i>except_</i>)</code> is <code>false</code>,
the <code>await_resume</code> member has no effects.
<p/>
-12- <i>Remarks</i>: A <i>yield-expression</i> that calls
<del>this function</del><ins>one of these functions</ins> has type
<code>void</code> (7.6.17 <a href="https://wg21.link/expr.yield">[expr.yield]</a>).
</p>
</blockquote>
</blockquote>

</li>


</ol>





<hr>
<h3 id="3900"><a href="https://cplusplus.github.io/LWG/lwg-active.html#3900">3900</a>. The <code>allocator_arg_t</code> overloads of <code>generator::promise_type::operator new</code>
should not be constrained</h3>
<p><b>Section:</b> 25.8.5 <a href="https://wg21.link/coro.generator.promise">[coro.generator.promise]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Tim Song <b>Opened:</b> 2023-03-04 <b>Last modified:</b> 2024-06-28</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#coro.generator.promise">active issues</a> in [coro.generator.promise].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#coro.generator.promise">issues</a> in [coro.generator.promise].</p>
<p><b>Discussion:</b></p>
<p>
When the allocator is not type-erased, the <code>allocator_arg_t</code> overloads of
<code>generator::promise_type::operator new</code> are constrained on
<code>convertible_to&lt;const Alloc&amp;, Allocator&gt;</code>. As a result, if the
the allocator is default-constructible (like <code>polymorphic_allocator</code> is)
but the user accidentally provided a wrong type (say, <code>memory_resource&amp;</code>
instead of <code>memory_resource*</code>), their code will silently fall back to
using a default-constructed allocator. It would seem better to take the tag
as definitive evidence of the user's intent to supply an allocator for the coroutine,
and error out if the supplied allocator cannot be used.
<p/>
This change does mean that the user cannot deliberately pass an incompatible
allocator (preceded by an <code>std::allocator_arg_t</code> tag) for their own use
inside the coroutine, but that sort of API seems fragile and confusing at best,
since the usual case is that allocators so passed <i>will</i> be used by
<code>generator</code>.
</p>

<p><i>[2023-03-22; Reflector poll]</i></p>

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

<p><i>[St. Louis 2024-06-28; move to Ready]</i></p>




<p id="res-3900"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4928" title=" Working Draft, Standard for Programming Language C++">N4928</a>.
</p>

<ol>

<li><p>Modify 25.8.5 <a href="https://wg21.link/coro.generator.promise">[coro.generator.promise]</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;::promise_type {
  public:
    [&hellip;]
    void* operator new(size_t size)
      requires same_as&lt;Allocator, void&gt; || default_initializable&lt;Allocator&gt;;

    template&lt;class Alloc, class... Args&gt;
      <del>requires same_as&lt;Allocator, void&gt; || convertible_to&lt;const Alloc&amp;, Allocator&gt;</del>
        void* operator new(size_t size, allocator_arg_t, const Alloc&amp; alloc, const Args&amp;...);

    template&lt;class This, class Alloc, class... Args&gt;
      <del>requires same_as&lt;Allocator, void&gt; || convertible_to&lt;const Alloc&amp;, Allocator&gt;</del>
        void* operator new(size_t size, const This&amp;, allocator_arg_t, const Alloc&amp; alloc,
                           const Args&amp;...);
    [&hellip;]
   };
}
</pre>
</blockquote>
[&hellip;]
<pre>
void* operator new(size_t size)
  requires same_as&lt;Allocator, void&gt; || default_initializable&lt;Allocator&gt;;

template&lt;class Alloc, class... Args&gt;
  <del>requires same_as&lt;Allocator, void&gt; || convertible_to&lt;const Alloc&amp;, Allocator&gt;</del>
  void* operator new(size_t size, allocator_arg_t, const Alloc&amp; alloc, const Args&amp;...);

template&lt;class This, class Alloc, class... Args&gt;
  <del>requires same_as&lt;Allocator, void&gt; || convertible_to&lt;const Alloc&amp;, Allocator&gt;</del>
  void* operator new(size_t size, const This&amp;, allocator_arg_t, const Alloc&amp; alloc,
                     const Args&amp;...);
</pre>
<blockquote>
<p>
-17- Let <code>A</code> be
</p>
<ol style="list-style-type: none">
  <li><p>(17.1) &mdash; <code>Allocator</code>, if it is not <code>void</code>,</p></li>
  <li><p>(17.2) &mdash; <code>Alloc</code> for the overloads with a template parameter <code>Alloc</code>, or</p></li>
  <li><p>(17.3) &mdash; <code>allocator&lt;void&gt;</code> otherwise.</p></li>
</ol>
<p>
Let <code>B</code> be <code>allocator_traits&lt;A&gt;::template rebind_alloc&lt;U&gt;</code>
where <code>U</code> is an unspecified type whose size and alignment are both
<code>__STDCPP_DEFAULT_NEW_ALIGNMENT__</code>.
<p/>
-18- <i>Mandates</i>: <code>allocator_traits&lt;B&gt;::pointer</code> is a pointer type.
<ins>For the overloads with a template parameter <code>Alloc</code>,
<code>same_as&lt;Allocator, void&gt; || convertible_to&lt;const Alloc&amp;, Allocator&gt;</code> is modeled.</ins>
<p/>
-19- <i>Effects</i>: Initializes an allocator <code>b</code> of type <code>B</code> with <code>A(alloc)</code>,
for the overloads with a function parameter <code>alloc</code>, and with <code>A()</code> otherwise.
Uses <code>b</code> to allocate storage for the smallest array of <code>U</code> sufficient
to provide storage for a coroutine state of size <code>size</code>, and unspecified
additional state necessary to ensure that <code>operator delete</code> can later
deallocate this memory block with an allocator equal to <code>b</code>.
<p/>
-20- <i>Returns:</i> A pointer to the allocated storage.
</p>

</blockquote>
</blockquote>


</li>


</ol>





<hr>
<h3 id="3918"><a href="https://cplusplus.github.io/LWG/lwg-active.html#3918">3918</a>. <code>std::uninitialized_move/_n</code> and guaranteed copy elision</h3>
<p><b>Section:</b> 26.11.6 <a href="https://wg21.link/uninitialized.move">[uninitialized.move]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Jiang An <b>Opened:</b> 2023-04-04 <b>Last modified:</b> 2024-06-26</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<p>
Currently <code>std::move</code> is unconditionally used in <code>std::uninitialized_move</code> and <code>std::uninitialized_move_n</code>, 
which may involve unnecessary move construction if dereferencing the input iterator yields a prvalue.
<p/>
The status quo was mentioned in <a href="https://github.com/cplusplus/papers/issues/975#issuecomment-990323753">paper issue #975</a>, 
but no further process is done since then.
</p>

<p><i>[2023-06-01; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll. Send to LEWG.
</p>
<p>
"<a href="https://wg21.link/P2283" title=" constexpr for specialized memory algorithms">P2283</a> wants to remove guaranteed elision here."
"Poorly motivated, not clear anybody is using these algos with proxy iterators."
"Consider using <code>iter_move</code> in the move algos."
</p>

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

<p>
This wording is relative to <a href="https://wg21.link/N4944" title=" Working Draft, Standard for Programming Language C++">N4944</a>.
</p>

<ol>
<li>
<p>Modify 26.11.1 <a href="https://wg21.link/specialized.algorithms.general">[specialized.algorithms.general]</a> as indicated:</p>

<blockquote>
<p>
-3- Some algorithms specified in 26.11 <a href="https://wg21.link/specialized.algorithms">[specialized.algorithms]</a> make use of the <ins>following</ins> exposition-only 
function<ins>s</ins> <del><code><i>voidify</i></code></del>:
</p>
<blockquote><pre>
template&lt;class T&gt;
  constexpr void* <i>voidify</i>(T&amp; obj) noexcept {
    return addressof(obj);
  }
  
<ins>template&lt;class I&gt;
  decltype(auto) <i>deref-move</i>(const I&amp; it) {
    if constexpr (is_lvalue_reference_v&lt;decltype(*it)&gt;)
      return std::move(*it);
    else
      return *it;
  }</ins>
</pre></blockquote>
</blockquote>
</li>

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

<blockquote>
<pre>
template&lt;class InputIterator, class NoThrowForwardIterator&gt;
  NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                            NoThrowForwardIterator result);
</pre>
<blockquote>
<p>
-1- <i>Preconditions</i>: <code>result + [0, (last - first))</code> does not overlap with <code>[first, last)</code>.
<p/>
-2- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
for (; first != last; (void)++result, ++first)
  ::new (<i>voidify</i>(*result))
    typename iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(<del>std::move(*</del><ins><i>deref-move</i>(</ins>first));
return result;
</pre></blockquote>
</blockquote>
[&hellip;]
<pre>
template&lt;class InputIterator, class Size, class NoThrowForwardIterator&gt;
  pair&lt;InputIterator, NoThrowForwardIterator&gt;
    uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result);
</pre>
<blockquote>
<p>
-6- <i>Preconditions</i>: <code>result + [0, n)</code> does not overlap with <code>first + [0, n)</code>.
<p/>
-7- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
for (; n &gt; 0; ++result,(void) ++first, --n)
  ::new (<i>voidify</i>(*result))
    typename iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(<del>std::move(*</del><ins><i>deref-move</i>(</ins>first));
return {first, result};
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2024-03-22; Tokyo: Jonathan updates wording after LEWG review]</i></p>

<p>
LEWG agrees it would be good to do this.
Using <code class='backtick'>iter_move</code> was discussed, but it was noted that the versions of these
algos in the <code class='backtick'>ranges</code> namespace already use it and introducing
<code class='backtick'>ranges::iter_move</code> into the non-ranges versions wasn't desirable.
It was observed that the proposed <em>deref-move</em> has a
<code>const I&amp;</code> parameter which would be ill-formed for any iterator
with a non-const <code class='backtick'>operator*</code> member. Suggested removing the const and
recommended LWG to accept the proposed resolution.
</p>

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

<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

<ol>
<li>
<p>Modify 26.11.1 <a href="https://wg21.link/specialized.algorithms.general">[specialized.algorithms.general]</a> as indicated:</p>

<blockquote>
<p>
-3- Some algorithms specified in 26.11 <a href="https://wg21.link/specialized.algorithms">[specialized.algorithms]</a> make use of the <ins>following</ins> exposition-only 
function<ins>s</ins> <del><code><i>voidify</i></code></del>:
</p>
<blockquote><pre>
template&lt;class T&gt;
  constexpr void* <i>voidify</i>(T&amp; obj) noexcept {
    return addressof(obj);
  }
  
<ins>template&lt;class I&gt;
  decltype(auto) <i>deref-move</i>(I&amp; it) {
    if constexpr (is_lvalue_reference_v&lt;decltype(*it)&gt;)
      return std::move(*it);
    else
      return *it;
  }</ins>
</pre></blockquote>
</blockquote>
</li>

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

<blockquote>
<pre>
template&lt;class InputIterator, class NoThrowForwardIterator&gt;
  NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                            NoThrowForwardIterator result);
</pre>
<blockquote>
<p>
-1- <i>Preconditions</i>: <code>result + [0, (last - first))</code> does not overlap with <code>[first, last)</code>.
<p/>
-2- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
for (; first != last; (void)++result, ++first)
  ::new (<i>voidify</i>(*result))
    typename iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(<del>std::move(*</del><ins><i>deref-move</i>(</ins>first));
return result;
</pre></blockquote>
</blockquote>
[&hellip;]
<pre>
template&lt;class InputIterator, class Size, class NoThrowForwardIterator&gt;
  pair&lt;InputIterator, NoThrowForwardIterator&gt;
    uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result);
</pre>
<blockquote>
<p>
-6- <i>Preconditions</i>: <code>result + [0, n)</code> does not overlap with <code>first + [0, n)</code>.
<p/>
-7- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
for (; n &gt; 0; ++result,(void) ++first, --n)
  ::new (<i>voidify</i>(*result))
    typename iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(<del>std::move(*</del><ins><i>deref-move</i>(</ins>first));
return {first, result};
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[St. Louis 2024-06-24; revert P/R and move to Ready]</i></p>

<p>
Tim observed that the iterator requirements require all iterators to be
const-dereferenceable, so there was no reason to remove the const.
Restore the original resolution and move to Ready.
</p>



<p id="res-3918"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

<ol>
<li>
<p>Modify 26.11.1 <a href="https://wg21.link/specialized.algorithms.general">[specialized.algorithms.general]</a> as indicated:</p>

<blockquote>
<p>
-3- Some algorithms specified in 26.11 <a href="https://wg21.link/specialized.algorithms">[specialized.algorithms]</a> make use of the <ins>following</ins> exposition-only 
function<ins>s</ins> <del><code><i>voidify</i></code></del>:
</p>
<blockquote><pre>
template&lt;class T&gt;
  constexpr void* <i>voidify</i>(T&amp; obj) noexcept {
    return addressof(obj);
  }

<ins>template&lt;class I&gt;
  decltype(auto) <i>deref-move</i>(I&amp; it) {
    if constexpr (is_lvalue_reference_v&lt;decltype(*it)&gt;)
      return std::move(*it);
    else
      return *it;
  }</ins>
</pre></blockquote>
</blockquote>
</li>

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

<blockquote>
<pre>
template&lt;class InputIterator, class NoThrowForwardIterator&gt;
  NoThrowForwardIterator uninitialized_move(InputIterator first, InputIterator last,
                                            NoThrowForwardIterator result);
</pre>
<blockquote>
<p>
-1- <i>Preconditions</i>: <code>result + [0, (last - first))</code> does not overlap with <code>[first, last)</code>.
<p/>
-2- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
for (; first != last; (void)++result, ++first)
  ::new (<i>voidify</i>(*result))
    typename iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(<del>std::move(*</del><ins><i>deref-move</i>(</ins>first));
return result;
</pre></blockquote>
</blockquote>
[&hellip;]
<pre>
template&lt;class InputIterator, class Size, class NoThrowForwardIterator&gt;
  pair&lt;InputIterator, NoThrowForwardIterator&gt;
    uninitialized_move_n(InputIterator first, Size n, NoThrowForwardIterator result);
</pre>
<blockquote>
<p>
-6- <i>Preconditions</i>: <code>result + [0, n)</code> does not overlap with <code>first + [0, n)</code>.
<p/>
-7- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
for (; n &gt; 0; ++result,(void) ++first, --n)
  ::new (<i>voidify</i>(*result))
    typename iterator_traits&lt;NoThrowForwardIterator&gt;::value_type(<del>std::move(*</del><ins><i>deref-move</i>(</ins>first));
return {first, result};
</pre></blockquote>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4014"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4014">4014</a>. LWG 3809 changes behavior of some existing <code>std::subtract_with_carry_engine</code> code</h3>
<p><b>Section:</b> 29.5.4.4 <a href="https://wg21.link/rand.eng.sub">[rand.eng.sub]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Matt Stephanson <b>Opened:</b> 2023-11-15 <b>Last modified:</b> 2024-10-09</p>
<p><b>Priority: </b>2
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#rand.eng.sub">issues</a> in [rand.eng.sub].</p>
<p><b>Discussion:</b></p>
<p>
Issue <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3809" title="Is std::subtract_with_carry_engine&lt;uint16_t&gt; supposed to work? (Status: WP)">3809</a><sup><a href="https://cplusplus.github.io/LWG/issue3809" title="Latest snapshot">(i)</a></sup> pointed out that <code>subtract_with_carry_engine&lt;T&gt;</code> can be seeded with values
from a <code>linear_congruential_engine&lt;T, 40014u, 0u, 2147483563u&gt;</code> object, which results in narrowing
when <code>T</code> is less than 32 bits. Part of the resolution was to modify the LCG seed sequence as follows:
</p>
<blockquote>
<pre>explicit subtract_with_carry_engine(result_type value);</pre>
<p>-7- <i>Effects</i>:
Sets the values of
<math>
  <mrow>
    <msub> <mi>X</mi> <mrow> <mo>-</mo> <mi>r</mi> </mrow> </msub>
    <mo separator="true">,</mo>
    <mo>&hellip;</mo>
    <mo separator="true">,</mo>
    <msub> <mi>X</mi> <mrow> <mo>-</mo> <mn>1</mn> </mrow> </msub>
  </mrow>
</math>,
in that order, as specified below. If
<math>
  <mrow>
    <msub> <mi>X</mi> <mrow> <mo>-</mo> <mn>1</mn> </mrow> </msub>
  </mrow>
</math>
is then <math> <mn>0</mn> </math>,
sets <math> <mi>c</mi> </math> to <math> <mn>1</mn> </math>;
otherwise sets <math> <mi>c</mi> </math> to <math> <mn>0</mn> </math>.
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
To set the values
<math> <mrow> <msub> <mi>X</mi> <mi>k</mi> </msub> </mrow> </math>,
first construct <code>e</code>, a <code>linear_congruential_engine</code> object,
as if by the following definition:
</p>
<blockquote><pre>
linear_congruential_engine&lt;<del>result_type</del><ins>uint_least32_t</ins>,
                           40014u,0u,2147483563u&gt; e(value == 0u ? default_seed : value);
</pre></blockquote>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
Then, to set each
<math> <mrow> <msub> <mi>X</mi> <mi>k</mi> </msub> </mrow> </math>,
obtain new values
<math>
  <mrow>
    <msub> <mi>z</mi> <mn>0</mn> </msub>
    <mo separator="true">,</mo>
    <mo>&hellip;</mo>
    <mo separator="true">,</mo>
    <msub> <mi>z</mi> <mrow> <mi>n</mi> <mo>-</mo> <mn>1</mn> </mrow> </msub>
  </mrow>
</math>
from
<math>
  <mrow>
    <mi>n</mi> <mo>=</mo>
    <mo form="prefix" stretchy="false">&#x2308;</mo>
    <mi>w</mi> <mo lspace="0em" rspace="0em">/</mo> <mn>32</mn>
    <mo form="postfix" stretchy="false">&#x2309;</mo>
  </mrow>
</math>
successive invocations of <code>e</code>.
Set
<math> <mrow> <msub> <mi>X</mi> <mi>k</mi> </msub> </mrow> </math>
to
<math>
  <mrow>
    <mrow>
      <mo fence="true" form="prefix">(</mo>
      <msubsup>
        <mo movablelimits="false">&sum;</mo>
        <mrow> <mi>j</mi> <mo>=</mo> <mn>0</mn> </mrow>
        <mrow> <mi>n</mi> <mo>-</mo> <mn>1</mn> </mrow>
      </msubsup>
      <msub> <mi>z</mi> <mi>j</mi> </msub>
      <mo>&#x2219;</mo>
      <msup> <mn>2</mn> <mrow> <mn>32</mn> <mi>j</mi> </mrow> </msup>
      <mo fence="true" form="postfix">)</mo>
    </mrow>
    <mo lspace="0.2222em" rspace="0.2222em">mod</mo>
    <mi>m</mi>
  </mrow>
</math>.
</p>
</blockquote>
<p>
Inside <code>linear_congruential_engine</code>, the seed is reduced modulo 2147483563, so <code>uint_least32_t</code>
is fine from that point on. This resolution, however, forces <code>value</code>, the user-provided seed, to be
truncated from <code>result_type</code> to <code>uint_least32_t</code> before the reduction, which generally will
change the result. It also breaks the existing behavior that two seeds are equivalent if they're in the same
congruence class modulo the divisor.
</p>

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

<p>
Set priority to 2 after reflector poll.

<p><i>[2024-01-11; Jonathan comments]</i></p>

<p>
More precisely, the resolution forces <code>value</code> to be <i>converted</i>
to <code>uint_least32_t</code>, which doesn't necessarily truncate, and if it
does truncate, it doesn't necessarily change the value.
But it will truncate whenever <code>value_type</code> is wider than
<code>uint_least32_t</code>,
e.g. for 32-bit <code>uint_least32_t</code> you get a different result for
<code>std::ranlux48_base(UINT_MAX + 1LL)()</code>.
The new proposed resolution below restores the old behaviour for that type.
</p>

</p>

<p><i>[2024-10-09; LWG telecon: Move to Ready]</i></p>




<p id="res-4014"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4964" title=" Working Draft, Programming Languages — C++">N4964</a> <em>after the wording changes applied</em> by LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3809" title="Is std::subtract_with_carry_engine&lt;uint16_t&gt; supposed to work? (Status: WP)">3809</a><sup><a href="https://cplusplus.github.io/LWG/issue3809" title="Latest snapshot">(i)</a></sup>,
which had been accepted into the working paper during the Kona 2023-11 meeting.
</p>

<ol>

<li><p>Modify 29.5.4.4 <a href="https://wg21.link/rand.eng.sub">[rand.eng.sub]</a> as indicated:</p>

<blockquote>
<pre>explicit subtract_with_carry_engine(result_type value);</pre>
<p>-7- <i>Effects</i>:
Sets the values of
<math>
  <mrow>
    <msub> <mi>X</mi> <mrow> <mo>-</mo> <mi>r</mi> </mrow> </msub>
    <mo separator="true">,</mo>
    <mo>&hellip;</mo>
    <mo separator="true">,</mo>
    <msub> <mi>X</mi> <mrow> <mo>-</mo> <mn>1</mn> </mrow> </msub>
  </mrow>
</math>,
in that order, as specified below. If
<math>
  <mrow>
    <msub> <mi>X</mi> <mrow> <mo>-</mo> <mn>1</mn> </mrow> </msub>
  </mrow>
</math>
is then <math> <mn>0</mn> </math>,
sets <math> <mi>c</mi> </math> to <math> <mn>1</mn> </math>;
otherwise sets <math> <mi>c</mi> </math> to <math> <mn>0</mn> </math>.
</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
To set the values
<math> <mrow> <msub> <mi>X</mi> <mi>k</mi> </msub> </mrow> </math>,
first construct <code>e</code>, a <code>linear_congruential_engine</code> object,
as if by the following definition:
</p>
<blockquote><pre>
linear_congruential_engine&lt;uint_least32_t,
                           40014u,0u,2147483563u&gt; e(value == 0u ? default_seed :
                           <ins>static_cast&lt;uint_least32_t&gt;(</ins>value<ins> % 2147483563u)</ins>);
</pre></blockquote>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
Then, to set each
<math> <mrow> <msub> <mi>X</mi> <mi>k</mi> </msub> </mrow> </math>,
obtain new values
<math>
  <mrow>
    <msub> <mi>z</mi> <mn>0</mn> </msub>
    <mo separator="true">,</mo>
    <mo>&hellip;</mo>
    <mo separator="true">,</mo>
    <msub> <mi>z</mi> <mrow> <mi>n</mi> <mo>-</mo> <mn>1</mn> </mrow> </msub>
  </mrow>
</math>
from
<math>
  <mrow>
    <mi>n</mi> <mo>=</mo>
    <mo form="prefix" stretchy="false">&#x2308;</mo>
    <mi>w</mi> <mo lspace="0em" rspace="0em">/</mo> <mn>32</mn>
    <mo form="postfix" stretchy="false">&#x2309;</mo>
  </mrow>
</math>
successive invocations of <code>e</code>.
Set
<math> <mrow> <msub> <mi>X</mi> <mi>k</mi> </msub> </mrow> </math>
to
<math>
  <mrow>
    <mrow>
      <mo fence="true" form="prefix">(</mo>
      <msubsup>
        <mo movablelimits="false">&sum;</mo>
        <mrow> <mi>j</mi> <mo>=</mo> <mn>0</mn> </mrow>
        <mrow> <mi>n</mi> <mo>-</mo> <mn>1</mn> </mrow>
      </msubsup>
      <msub> <mi>z</mi> <mi>j</mi> </msub>
      <mo>&#x2219;</mo>
      <msup> <mn>2</mn> <mrow> <mn>32</mn> <mi>j</mi> </mrow> </msup>
      <mo fence="true" form="postfix">)</mo>
    </mrow>
    <mo lspace="0.2222em" rspace="0.2222em">mod</mo>
    <mi>m</mi>
  </mrow>
</math>.
</p>
</blockquote>

</li>

</ol>





<hr>
<h3 id="4024"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4024">4024</a>. Underspecified destruction of objects created in <code>std::make_shared_for_overwrite/std::allocate_shared_for_overwrite</code></h3>
<p><b>Section:</b> 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Jiang An <b>Opened:</b> 2023-12-16 <b>Last modified:</b> 2024-08-21</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#util.smartptr.shared.create">active issues</a> in [util.smartptr.shared.create].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#util.smartptr.shared.create">issues</a> in [util.smartptr.shared.create].</p>
<p><b>Discussion:</b></p>
<p>
Currently, only destructions of non-array (sub)objects created in <code>std::make_shared</code> and <code>std::allocate_shared</code> 
are specified in 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a>. Presumably, objects created in 
<code>std::make_shared_for_overwrite</code> and <code>std::allocate_shared_for_overwrite</code> should be destroyed by plain 
destructor calls.
</p>

<p><i>[2024-03-11; Reflector poll]</i></p>

<p>
Set priority to 2 after reflector poll in December 2023.
</p>
<p>
This was the <a href="https://wg21.link/P1020R1" title=" Smart pointer creation with default initialization">P1020R1</a> author's intent (see LWG reflector mail
in November 2018) but it was never clarified in the wording. This fixes that.
</p>

<p><i>[2024-08-21; Move to Ready at LWG telecon]</i></p>




<p id="res-4024"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4964" title=" Working Draft, Programming Languages — C++">N4964</a>.
</p>

<ol>

<li><p>Modify 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, ...&gt;
  shared_ptr&lt;T&gt; make_shared(<i>args</i>);
template&lt;class T, class A, ...&gt;
  shared_ptr&lt;T&gt; allocate_shared(const A&amp; a, <i>args</i>);
template&lt;class T, ...&gt;
  shared_ptr&lt;T&gt; make_shared_for_overwrite(<i>args</i>);
template&lt;class T, class A, ...&gt;
  shared_ptr&lt;T&gt; allocate_shared_for_overwrite(const A&amp; a, <i>args</i>);
</pre>
<blockquote>
<p>
[&hellip;]
<p/>
-7- <i>Remarks:</i>
</p>
<ol style="list-style-type: none">
<li><p>[&hellip;]</p></li>
<li><p>(7.11) &mdash; When a (sub)object of non-array type <code>U</code> that was initialized by 
<code>make_shared</code><ins>, <code>make_shared_for_overwrite</code>, or <code>allocate_shared_for_overwrite</code></ins> 
is to be destroyed, it is destroyed via the expression <code>pv-&gt;~U()</code> where <code>pv</code> points to that 
object of type <code>U</code>.</p></li>
<li><p>[&hellip;]</p></li>
</ol>
</blockquote>
</blockquote>
</li>

</ol>







<hr>
<h3 id="4027"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4027">4027</a>. <code><i>possibly-const-range</i></code> should prefer returning <code>const R&amp;</code></h3>
<p><b>Section:</b> 25.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">Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2023-12-17 <b>Last modified:</b> 2024-06-28</p>
<p><b>Priority: </b>2
</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>
<code><i>possibly-const-range</i></code> currently only returns <code>const R&amp;</code> when <code>R</code> does not 
satisfy <code>constant_range</code> and <code>const R</code> satisfies <code>constant_range</code>.
<p/>
Although it's not clear why we need the former condition, this does diverge from the legacy <code>std::cbegin</code> 
(<a href="https://godbolt.org/z/636osY7os">demo</a>):
</p>
<blockquote><pre>
#include &lt;ranges&gt;

int main() {
  auto r = std::views::single(0)
        | std::views::transform([](int) { return 0; });
  using C1 = decltype(std::ranges::cbegin(r));
  using C2 = decltype(std::cbegin(r));
  static_assert(std::same_as&lt;C1, C2&gt;); // <span style="color:red;font-weight:bolder">failed</span>
}
</pre></blockquote>
<p>
Since <code>R</code> itself is <code>constant_range</code>, so <code><i>possibly-const-range</i></code>, above just returns 
<code>R&amp;</code> and <code>C1</code> is <code>transform_view::<i>iterator</i>&lt;false&gt;</code>; <code>std::cbegin</code> 
specifies to return <code>as_const(r).begin()</code>, which makes that <code>C2</code> is 
<code>transform_view::<i>iterator</i>&lt;true&gt;</code> which is different from <code>C1</code>.
<p/>
I believe <code>const R&amp;</code> should always be returned if it's a range, regardless of whether <code>const R</code> 
or <code>R</code> is a <code>constant_range</code>, just as <code><i>fmt-maybe-const</i></code> in format ranges always prefers 
<code>const R</code> over <code>R</code>.
<p/>
Although it is theoretically possible for <code>R</code> to satisfy <code>constant_range</code> and that <code>const R</code> 
is a mutable range, such nonsense range type should not be of interest.
<p/>
This relaxation of constraints allows for maximum consistency with <code>std::cbegin</code>, and in some cases can 
preserve constness to the greatest extent (<a href="https://godbolt.org/z/3hYToMq35">demo</a>):
</p>
<blockquote><pre>
#include &lt;ranges&gt;

int main() {
  auto r = std::views::single(0) | std::views::lazy_split(0);
  (*std::ranges::cbegin(r)).front() = 42; // ok
  (*std::cbegin(r)).front() = 42; // <span style="color:red;font-weight:bolder">not ok</span>
}
</pre></blockquote>
<p>
Above, <code>*std::ranges::cbegin</code> returns a range of type <code>const lazy_split_view::<i>outer-iterator</i>&lt;false&gt;::value_type</code>, 
which does not satisfy <code>constant_range</code> because its reference type is <code>int&amp;</code>.
<p/>
However, <code>*std::cbegin(r)</code> returns <code>lazy_split_view::<i>outer-iterator</i>&lt;true&gt;::value_type</code> 
whose reference type is <code>const int&amp;</code> and satisfies <code>constant_range</code>.
</p>

<p><i>[2024-03-11; Reflector poll]</i></p>

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

<p><i>[St. Louis 2024-06-28; LWG and SG9 joint session: move to Ready]</i></p>




<p id="res-4027"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

<ol>

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

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

namespace std::ranges {
  [&hellip;]

  // <i>25.7.22 <a href="https://wg21.link/range.as.const">[range.as.const]</a>, as const view</i>
  template&lt;input_range R&gt;
    constexpr auto&amp; <i>possibly-const-range</i>(R&amp; r) noexcept { // <i>exposition only</i>
      if constexpr (<ins>input</ins><del>constant</del>_range&lt;const R&gt;<del> &amp;&amp; !constant_range&lt;R&gt;</del>) {
        return const_cast&lt;const R&amp;&gt;(r);
      } else {
        return r;
      }
    }

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

</ol>







<hr>
<h3 id="4044"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4044">4044</a>. Confusing requirements for <code>std::print</code> on POSIX platforms</h3>
<p><b>Section:</b> 31.7.10 <a href="https://wg21.link/print.fun">[print.fun]</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> 2024-01-24 <b>Last modified:</b> 2024-06-24</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#print.fun">active issues</a> in [print.fun].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#print.fun">issues</a> in [print.fun].</p>
<p><b>Discussion:</b></p>
<p>
The effects for <code>vprintf_unicode</code> say:
</p>

<blockquote>
<p>
If <code>stream</code> refers to a terminal capable of displaying Unicode,
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
and implementations are encouraged to diagnose it.
Otherwise writes <code>out</code> to <code>stream</code> unchanged.
If the native Unicode API is used, the function flushes <code>stream</code>
before writing <code>out</code>.
</p>
<p>
[<i>Note 1</i>:
On POSIX and Windows, <code>stream</code> referring to a terminal means that,
respectively, <code>isatty(fileno(stream))</code> and
<code>GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)</code>
return nonzero.
&mdash; <i>end note</i>]
</p>
<p>
[<i>Note 2</i>:
On Windows, the native Unicode API is <code>WriteConsoleW</code>.
&mdash; <i>end note</i>]
</p>
<p>-8-
<i>Throws</i>:  [...]
</p>
<p>-9-
<i>Recommended practice</i>:
If invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
</p>
</blockquote>

<p>
The very explicit mention of <code>isatty</code> for POSIX platforms has
confused at least two implementers into thinking that we're supposed to
use <code>isatty</code>, and supposed to do something differently based
on what it returns. That seems consistent with the nearly identical wording
in 28.5.2.2 <a href="https://wg21.link/format.string.std">[format.string.std]</a> paragraph 12, which says
"Implementations should use either UTF-8, UTF-16, or UTF-32,
on platforms <u>capable of displaying Unicode text in a terminal</u>"
and then has a note explicitly saying this is the case for Windows-based and
many POSIX-based operating systems. So it seems clear that POSIX platforms
are supposed to be considered to have "a terminal capable of displaying
Unicode text", and so <code>std::print</code> should use <code>isatty</code>
and then use a native Unicode API, and diagnose invalid code units.
</p>
<p>
This is a problem however, because <code>isatty</code> needs
to make a system call on Linux, adding 500ns to every <code>std::print</code>
call. This results in a 10x slowdown on Linux, where <code>std::print</code>
can take just 60ns without the <code>isatty</code> check.
</p>
<p>
From discussions with Tom Honermann I learned that the "native Unicode API"
wording is only relevant on Windows. This makes sense, because for POSIX
platforms, writing to a terminal is done using the usual stdio functions,
so there's no need to treat a terminal differently to any other file stream.
And substitution of invalid code units with
<span style="font-variant: small-caps">u+fffd</span>
is recommended for Windows because that's what typical modern terminals do on
POSIX platforms, so requiring the implementation to do that on Windows gives
consistent behaviour. But the implementation doesn't need to do anything to
make that happen with a POSIX terminal, it happens anyway.
So the <code>isatty</code> check is unnecessary for POSIX platforms,
and the note mentioning it just causes confusion and has no benefit.
</p>

<p>
Secondly, there initially seems to be a contradiction between the 
"implementations are encouraged to diagnose it" wording and the later
<i>Recommended practice</i>. In fact, there's no contradiction because
the native Unicode API might accept UTF-8 and therefore require no
transcoding, and so the <i>Recommended practice</i> wouldn't apply.
The intention is that diagnosing invalid UTF-8 is still desirable in this case,
but how should it be diagnosed? By writing an error to the terminal alongside
the formatted string?
Or by substituting <span style="font-variant: small-caps">u+fffd</span> maybe?
If the latter is the intention, why is one suggestion in the middle of the
<i>Effects</i>, and one given as <i>Recommended practice</i>?
</p>

<p>
The proposed resolution attempts to clarify that a "native Unicode API"
is only needed if that's how you display Unicode on the terminal.
It also moves the flushing requirement to be adjacent to the other
requirements for systems using a native Unicode API instead of on its own
later in the paragraph.
And the suggestion to diagnose invalid code units is moved into the
<i>Recommended practice</i> and clarified that it's only relevant if
using a native Unicode API. I'm still not entirely happy with encouragement
to diagnose invalid code units without giving any clue as to how that should
be done. What does it mean to diagnose something at runtime? That's novel
for the C++ standard. The way it's currently phrased seems to imply something
other than <span style="font-variant: small-caps">u+fffd</span> substitution
should be done, although that seems the most obvious implementation to me.
</p>


<p><i>[2024-03-12; Reflector poll]</i></p>

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

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

<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

<ol>
<li><p>Modify 31.7.6.3.5 <a href="https://wg21.link/ostream.formatted.print">[ostream.formatted.print]</a> as indicated:</p>
<blockquote>
<pre>
void vprint_unicode(ostream&amp; os, string_view fmt, format_args args);
void vprint_nonunicode(ostream&amp; os, string_view fmt, format_args args);
</pre>
<p>-3-
<i>Effects</i>:
Behaves as a formatted output function
(31.7.6.3.1 <a href="https://wg21.link/ostream.formatted.reqmts">[ostream.formatted.reqmts]</a>)
of <code>os</code>, except that:
<ol style="list-style-type: none">
<li>(3.1) &ndash;
failure to generate output is reported as specified below, and
</li>
<li>(3.2) &ndash;
any exception thrown by the call to <code>vformat</code> is propagated without
regard to the value of <code>os.exceptions()</code> and without turning on
<code>ios_base::badbit</code> in the error state of <code>os</code>.
</li>
</ol>
</p>
<p>
After constructing a <code>sentry</code> object,
the function initializes an automatic variable via
<pre><code>  string out = vformat(os.getloc(), fmt, args); </code></pre>
If the function is <code>vprint_unicode</code>
and <code>os</code> is a stream that
refers to a terminal capable of displaying Unicode
<ins>via a native Unicode API,</ins>
which is determined in an implementation-defined manner,
<ins>flushes <code>os</code> and then</ins>
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
<del>and implementations are encouraged to diagnose it</del>.
<del>
If the native Unicode API is used, the function flushes <code>os</code>
before writing <code>out</code>.
</del>
Otherwise, (if <code>os</code> is not such a stream or the function is
<code>vprint_nonunicode</code>), inserts the character sequence
[<code>out.begin()</code>,<code>out.end()</code>) into <code>os</code>.
If writing to the terminal or inserting into <code>os</code> fails, calls
<code>os.setstate(ios_base::badbit)</code>
(which may throw <code>ios_base::failure</code>).
</p>
<p>-4-
<i>Recommended practice</i>:
For <code>vprint_unicode</code>,
if invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
<ins>
If invoking the native Unicode API  does not require transcoding,
implementations are encouraged to diagnose invalid code units.
</ins>
</p>
</blockquote>
</li>

<li><p>Modify 31.7.10 <a href="https://wg21.link/print.fun">[print.fun]</a> as indicated:</p>

<blockquote>
<pre>
void vprint_unicode(FILE* stream, string_view fmt, format_args args);
</pre>
<p>-6-
<i>Preconditions</i>:
<code>stream</code> is a valid pointer to an output C stream.
</p>
<p>-7-
<i>Effects</i>:
The function initializes an automatic variable via
<pre><code>  string out = vformat(fmt, args); </code></pre>
If <code>stream</code> refers to a terminal capable of displaying Unicode
<ins>via a native Unicode API</ins>,
<ins>flushes <code>stream</code> and then</ins>
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
<del>and implementations are encouraged to diagnose it</del>.
Otherwise writes <code>out</code> to <code>stream</code> unchanged.
<del>
If the native Unicode API is used, the function flushes <code>stream</code>
before writing <code>out</code>.
</del>
</p>
<p>
[<i>Note 1</i>:
On <del>POSIX and</del> Windows<del>,</del>
<ins>the native Unicode API is <code>WriteConsoleW</code> and</ins>
<code>stream</code> referring to a terminal means that<del>,
respectively, <code>isatty(fileno(stream))</code> and</del>
<code>GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)</code>
return nonzero.
&mdash; <i>end note</i>]
</p>
<p>
<del>
[<i>Note 2</i>:
On Windows, the native Unicode API is <code>WriteConsoleW</code>.
&mdash; <i>end note</i>]
</del>
</p>
<p>-8-
<i>Throws</i>:  [...]
</p>
<p>-9-
<i>Recommended practice</i>:
If invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
<ins>
If invoking the native Unicode API  does not require transcoding,
implementations are encouraged to diagnose invalid code units.
</ins>
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2024-03-12; Jonathan updates wording based on SG16 feedback]</i></p>

<p>
SG16 reviewed the issue and approved the proposed resolution with
the wording about diagnosing invalid code units removed.
</p>
<p>
SG16 favors removing the following text (both occurrences) from the proposed
wording. This is motivated by a lack of understanding regarding what it means
to diagnose such invalid code unit sequences given that the input is likely
provided at run-time.

<blockquote>
If invoking the native Unicode API does not require transcoding, implementations are encouraged to diagnose invalid code units.
</blockquote>
</p>

<p>
Some concern was expressed regarding how the current wording is structured.
At present, the wording leads with a Windows centric perspective;
if the stream refers to a terminal ... use the native Unicode API ...
otherwise write code units to the stream.
It might be an improvement to structure the wording such that use of the native
Unicode API is presented as a fallback for implementations that require its use
when writing directly to the stream is not sufficient to produce desired
results. In other words, the wording should permit direct writing to the stream
even when the stream is directed to a terminal and a native Unicode API is
available when the implementation has reason to believe that doing so will
produce the correct results. For example, Microsoft's HoloLens has a Windows
based operating system, but it only supports use of UTF-8 as the system code
page and therefore would not require the native Unicode API bypass;
implementations for it could avoid the overhead of checking to see if the
stream is directed to a console.
</p>

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


<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

<ol>
<li><p>Modify 31.7.6.3.5 <a href="https://wg21.link/ostream.formatted.print">[ostream.formatted.print]</a> as indicated:</p>
<blockquote>
<pre>
void vprint_unicode(ostream&amp; os, string_view fmt, format_args args);
void vprint_nonunicode(ostream&amp; os, string_view fmt, format_args args);
</pre>
<p>-3-
<i>Effects</i>:
Behaves as a formatted output function
(31.7.6.3.1 <a href="https://wg21.link/ostream.formatted.reqmts">[ostream.formatted.reqmts]</a>)
of <code>os</code>, except that:
<ol style="list-style-type: none">
<li>(3.1) &ndash;
failure to generate output is reported as specified below, and
</li>
<li>(3.2) &ndash;
any exception thrown by the call to <code>vformat</code> is propagated without
regard to the value of <code>os.exceptions()</code> and without turning on
<code>ios_base::badbit</code> in the error state of <code>os</code>.
</li>
</ol>
</p>
<p>
After constructing a <code>sentry</code> object,
the function initializes an automatic variable via
<pre><code>  string out = vformat(os.getloc(), fmt, args); </code></pre>
If the function is <code>vprint_unicode</code>
and <code>os</code> is a stream that
refers to a terminal <ins>that is only</ins> capable of displaying Unicode
<ins>via a native Unicode API,</ins>
which is determined in an implementation-defined manner,
<ins>flushes <code>os</code> and then</ins>
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
<del>and implementations are encouraged to diagnose it</del>.
<del>
If the native Unicode API is used, the function flushes <code>os</code>
before writing <code>out</code>.
</del>
Otherwise, (if <code>os</code> is not such a stream or the function is
<code>vprint_nonunicode</code>), inserts the character sequence
[<code>out.begin()</code>,<code>out.end()</code>) into <code>os</code>.
If writing to the terminal or inserting into <code>os</code> fails, calls
<code>os.setstate(ios_base::badbit)</code>
(which may throw <code>ios_base::failure</code>).
</p>
<p>-4-
<i>Recommended practice</i>:
For <code>vprint_unicode</code>,
if invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
</p>
</blockquote>
</li>

<li><p>Modify 31.7.10 <a href="https://wg21.link/print.fun">[print.fun]</a> as indicated:</p>

<blockquote>
<pre>
void vprint_unicode(FILE* stream, string_view fmt, format_args args);
</pre>
<p>-6-
<i>Preconditions</i>:
<code>stream</code> is a valid pointer to an output C stream.
</p>
<p>-7-
<i>Effects</i>:
The function initializes an automatic variable via
<pre><code>  string out = vformat(fmt, args); </code></pre>
If <code>stream</code> refers to a terminal <ins>that is only</ins>
capable of displaying Unicode
<ins>via a native Unicode API</ins>,
<ins>flushes <code>stream</code> and then</ins>
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
<del>and implementations are encouraged to diagnose it</del>.
Otherwise writes <code>out</code> to <code>stream</code> unchanged.
<del>
If the native Unicode API is used, the function flushes <code>stream</code>
before writing <code>out</code>.
</del>
</p>
<p>
[<i>Note 1</i>:
On <del>POSIX and</del> Windows<del>,</del>
<ins>the native Unicode API is <code>WriteConsoleW</code> and</ins>
<code>stream</code> referring to a terminal means that<del>,
respectively, <code>isatty(fileno(stream))</code> and</del>
<code>GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)</code>
return nonzero.
&mdash; <i>end note</i>]
</p>
<p>
<del>
[<i>Note 2</i>:
On Windows, the native Unicode API is <code>WriteConsoleW</code>.
&mdash; <i>end note</i>]
</del>
</p>
<p>-8-
<i>Throws</i>:  [...]
</p>
<p>-9-
<i>Recommended practice</i>:
If invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2024-03-19; Tokyo: Jonathan updates wording after LWG review]</i></p>

<p>
Split the <em>Effects</em>: into separate bullets for the "native Unicode API"
and "otherwise" cases. Remove the now-redundant "if <code class='backtick'>os</code> is not such a stream"
parenthesis.
</p>

<p><i>[St. Louis 2024-06-24; move to Ready.]</i></p>



<p id="res-4044"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

<ol>
<li><p>Modify 31.7.6.3.5 <a href="https://wg21.link/ostream.formatted.print">[ostream.formatted.print]</a> as indicated:</p>
<blockquote>
<pre>
void vprint_unicode(ostream&amp; os, string_view fmt, format_args args);
void vprint_nonunicode(ostream&amp; os, string_view fmt, format_args args);
</pre>
<p>-3-
<i>Effects</i>:
Behaves as a formatted output function
(31.7.6.3.1 <a href="https://wg21.link/ostream.formatted.reqmts">[ostream.formatted.reqmts]</a>)
of <code>os</code>, except that:
<ol style="list-style-type: none">
<li>(3.1) &ndash;
failure to generate output is reported as specified below, and
</li>
<li>(3.2) &ndash;
any exception thrown by the call to <code>vformat</code> is propagated without
regard to the value of <code>os.exceptions()</code> and without turning on
<code>ios_base::badbit</code> in the error state of <code>os</code>.
</li>
</ol>
</p>

<p>
<ins>-?-</ins>
After constructing a <code>sentry</code> object,
the function initializes an automatic variable via
<pre><code>  string out = vformat(os.getloc(), fmt, args); </code></pre>
<ol style="list-style-type: none">
<li><ins>(?.1) &ndash; </ins>
If the function is <code>vprint_unicode</code>
and <code>os</code> is a stream that
refers to a terminal <ins>that is only</ins> capable of displaying Unicode
<ins>via a native Unicode API,</ins>
which is determined in an implementation-defined manner,
<ins>flushes <code>os</code> and then</ins>
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
<del>and implementations are encouraged to diagnose it.</del>
<del>
If the native Unicode API is used, the function flushes <code>os</code>
before writing <code>out</code></del>.
</li>
<li><ins>(?.2) &ndash; </ins>
Otherwise,
<del>
(if <code>os</code> is not such a stream or the function is
<code>vprint_nonunicode</code>),
</del>
inserts the character sequence
[<code>out.begin()</code>,<code>out.end()</code>) into <code>os</code>.
</li>
</ol>
</p>
<p>
<ins>-?-</ins>
If writing to the terminal or inserting into <code>os</code> fails, calls
<code>os.setstate(ios_base::badbit)</code>
(which may throw <code>ios_base::failure</code>).
</p>
<p>-4-
<i>Recommended practice</i>:
For <code>vprint_unicode</code>,
if invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
</p>
</blockquote>
</li>

<li><p>Modify 31.7.10 <a href="https://wg21.link/print.fun">[print.fun]</a> as indicated:</p>

<blockquote>
<pre>
void vprint_unicode(FILE* stream, string_view fmt, format_args args);
</pre>
<p>-6-
<i>Preconditions</i>:
<code>stream</code> is a valid pointer to an output C stream.
</p>
<p>-7-
<i>Effects</i>:
The function initializes an automatic variable via
<pre><code>  string out = vformat(fmt, args); </code></pre>
<ol style="list-style-type: none">
<li><ins>(7.1) &ndash; </ins>
If <code>stream</code> refers to a terminal <ins>that is only</ins>
capable of displaying Unicode
<ins>via a native Unicode API</ins>,
<ins>flushes <code>stream</code> and then</ins>
writes <code>out</code> to the terminal using the native Unicode API;
if <code>out</code> contains invalid code units, the behavior is undefined
<del>and implementations are encouraged to diagnose it</del>.
</li>
<li><ins>(7.2) &ndash; </ins>
Otherwise writes <code>out</code> to <code>stream</code> unchanged.
</li>
</ol>
</p>
<p>
<del>
If the native Unicode API is used, the function flushes <code>stream</code>
before writing <code>out</code>.
</del>
</p>
<p>
[<i>Note 1</i>:
On <del>POSIX and</del> Windows<del>,</del>
<ins>the native Unicode API is <code>WriteConsoleW</code> and</ins>
<code>stream</code> referring to a terminal means that<del>,
respectively, <code>isatty(fileno(stream))</code> and</del>
<code>GetConsoleMode(_get_osfhandle(_fileno(stream)), ...)</code>
return<ins>s</ins> nonzero.
&mdash; <i>end note</i>]
</p>
<p>
<del>
[<i>Note 2</i>:
On Windows, the native Unicode API is <code>WriteConsoleW</code>.
&mdash; <i>end note</i>]
</del>
</p>
<p>-8-
<i>Throws</i>:  [...]
</p>
<p>-9-
<i>Recommended practice</i>:
If invoking the native Unicode API requires transcoding, implementations
should substitute invalid code units with
<span style="font-variant: small-caps">u+fffd replacement character</span>
per the Unicode Standard, Chapter 3.9
<span style="font-variant: small-caps">u+fffd</span> Substitution in Conversion.
</p>
</blockquote>
</li>
</ol>






<hr>
<h3 id="4064"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4064">4064</a>. Clarify that <code>std::launder</code> is not needed when using the result of <code>std::memcpy</code></h3>
<p><b>Section:</b> 27.5.1 <a href="https://wg21.link/cstring.syn">[cstring.syn]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Jan Schultke <b>Opened:</b> 2024-04-05 <b>Last modified:</b> 2024-06-28</p>
<p><b>Priority: </b>3
</p>
<p><b>Discussion:</b></p>
<blockquote><pre>
int x = 0;
alignas(int) std::byte y[sizeof(int)];
int z = *static_cast&lt;int*&gt;(std::memcpy(y, &amp;x, sizeof(int)));
</pre></blockquote>
<p>
This example should be well-defined, even without the use of <code>std::launder</code>.
<code>std::memcpy</code> implicitly creates an <code>int</code> inside <code>y</code>, and 
<a href="https://www.iso-9899.info/n3047.html#7.26.2.1p3">https://www.iso-9899.info/n3047.html#7.26.2.1p3</a> 
states that
</p>
<blockquote style="border-left: 3px solid #ccc;padding-left: 15px;">
<p>
The <code>memcpy</code> function returns the value of [the destination operand].
</p>
</blockquote>
<p>
In conjunction with 27.5.1 <a href="https://wg21.link/cstring.syn">[cstring.syn]</a> p3, this presumably means that <code>std::memcpy</code> 
returns a pointer to the (first) implicitly-created object, and no use of <code>std::launder</code> 
is necessary.
<p/>
The wording should be clarified to clearly support this interpretation or reject it.
</p>

<p><i>[2024-06-24; 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/N4971" title=" Working Draft, Programming Languages — C++">N4971</a>.
</p>

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

<blockquote>
<p>
-3- The functions <code>memcpy</code> and <code>memmove</code> are signal-safe (17.13.5 <a href="https://wg21.link/support.signal">[support.signal]</a>). 
Both functions implicitly create objects (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>) in the destination region of 
storage immediately prior to copying the sequence of characters to the destination. <ins>Both functions 
return a pointer to a suitable created object.</ins>
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[St. Louis 2024-06-26; CWG suggested improved wording]</i></p>

<p><i>[St. Louis 2024-06-28; LWG: move to Ready]</i></p>




<p id="res-4064"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

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

<blockquote>
<p>
-3-
The functions <code>memcpy</code> and <code>memmove</code> are signal-safe
(17.13.5 <a href="https://wg21.link/support.signal">[support.signal]</a>).
<del>Both</del> <ins>Each of these</ins> functions implicitly
<del>create</del> <ins>creates</ins> objects (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>)
in the destination region of storage immediately prior to copying
the sequence of characters to the destination.
<ins>Each of these functions returns a pointer to a suitable created object,
if any, otherwise the value of the first parameter.</ins>
</p>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4072"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4072">4072</a>. <code class='backtick'>std::optional</code> comparisons: constrain harder</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">Ready</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2024-04-19 <b>Last modified:</b> 2024-08-21</p>
<p><b>Priority: </b>1
</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>
<a href="https://wg21.link/P2944R3" title=" Comparisons for reference_wrapper">P2944R3</a> added constraints to <code class='backtick'>std::optional</code>'s comparisons, e.g.
</p>
<blockquote>
<pre><code>
template&lt;class T, class U&gt; constexpr bool operator==(const optional&lt;T&gt;&amp; x, const optional&lt;U&gt;&amp; y);
</code></pre>
-1- <em><del>Mandates</del><ins>Constraints</ins></em>:
The expression <code class='backtick'>*x == *y</code> is well-formed and its result is convertible to <code class='backtick'>bool</code>.
<p> &hellip; </p>
<pre><code>
template&lt;class T, class U&gt; constexpr bool operator==(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
-1- <em><del>Mandates</del><ins>Constraints</ins></em>:
The expression <code class='backtick'>*x == v</code> is well-formed and its result is convertible to <code class='backtick'>bool</code>.
</blockquote>

<p>
But I don't think the constraint on the second one (the "compare with value")
is correct. If we try to compare two optionals that can't be compared,
such as <code>optional&lt;void*&gt;</code> and <code>optional&lt;int&gt;</code>,
then the first overload is not valid due to the new constraints, and so does
not participate in overload resolution.  But that means we now consider the
second overload, but that's ambiguous. We could either use
<code>operator==&lt;void*, optional&lt;int&gt;&gt;</code> or we could use
<code>operator==&lt;optional&lt;void*&gt;, int&gt;</code> with the arguments
reversed (using the C++20 default comparison rules).
We never even get as far as checking the new constraints on those overloads,
because they're simply ambiguous.
</p>
<p>
Before <a href="https://wg21.link/P2944R3" title=" Comparisons for reference_wrapper">P2944R3</a> overload resolution always would have selected
the first overload, for comparing two optionals. But because that is now
constrained away, we consider an overload that should never be used for
comparing two optionals. The solution is to add an additional constraint
to the "compare with value" overloads so that they won't be used when the
"value" is really another optional.
</p>

<p>
A similar change was made to <code class='backtick'>optional</code>'s <code>operator&lt;=&gt;</code> by
LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3566" title="Constraint recursion for operator&lt;=&gt;(optional&lt;T&gt;, U) (Status: C++23)">3566</a><sup><a href="https://cplusplus.github.io/LWG/issue3566" title="Latest snapshot">(i)</a></sup>, and modified by LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3746" title="optional's spaceship with U with a type derived from optional 
causes infinite constraint meta-recursion (Status: C++23)">3746</a><sup><a href="https://cplusplus.github.io/LWG/issue3746" title="Latest snapshot">(i)</a></sup>.
I haven't analyzed whether we need the modification here too.
</p>

<p>
The proposed resolution (without <em><code class='backtick'>is-derived-from-optional</code></em>)
has been implemented and tested in libstdc++.
</p>

<p><i>[2024-06-24; Reflector poll]</i></p>

<p>
Set priority to 1 after reflector poll.
LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3746" title="optional's spaceship with U with a type derived from optional 
causes infinite constraint meta-recursion (Status: C++23)">3746</a><sup><a href="https://cplusplus.github.io/LWG/issue3746" title="Latest snapshot">(i)</a></sup> changes might be needed here too,
i.e, consider types derived from <code class='backtick'>optional</code>, not only <code class='backtick'>optional</code> itself.
</p>

<p><i>[2024-08-21; Move to Ready at LWG telecon]</i></p>




<p id="res-4072"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

<ol>
<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><code>
template&lt;class T, class U&gt; constexpr bool operator==(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
<p>-1-
<em>Constraints</em>:
<ins><code class='backtick'>U</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>*x == v</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator==(const T&amp; v, const optional&lt;U&gt;&amp; x);
</code></pre>
<p>-3-
<em>Constraints</em>:
<ins><code class='backtick'>T</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>v == *x</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator!=(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
<p>-5-
<em>Constraints</em>:
<ins><code class='backtick'>U</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>*x != v</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator!=(const T&amp; v, const optional&lt;U&gt;&amp; x);
</code></pre>
<p>-7-
<em>Constraints</em>:
<ins><code class='backtick'>T</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>v != *x</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&lt;(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
<p>-9-
<em>Constraints</em>:
<ins><code class='backtick'>U</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>*x &lt; v</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&lt;(const T&amp; v, const optional&lt;U&gt;&amp; x);
</code></pre>
<p>-11-
<em>Constraints</em>:
<ins><code class='backtick'>T</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>v &lt; *x</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&gt;(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
<p>-13-
<em>Constraints</em>:
<ins><code class='backtick'>U</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>*x &gt; v</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&gt;(const T&amp; v, const optional&lt;U&gt;&amp; x);
</code></pre>
<p>-15-
<em>Constraints</em>:
<ins><code class='backtick'>T</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>v &gt; *x</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&lt;=(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
<p>-17-
<em>Constraints</em>:
<ins><code class='backtick'>U</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>*x &lt;= v</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&lt;=(const T&amp; v, const optional&lt;U&gt;&amp; x);
</code></pre>
<p>-19-
<em>Constraints</em>:
<ins><code class='backtick'>T</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>v &lt;= *x</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&gt;=(const optional&lt;T&gt;&amp; x, const U&amp; v);
</code></pre>
<p>-21-
<em>Constraints</em>:
<ins><code class='backtick'>U</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code class='backtick'>*x &amp;gt;= v</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>

<pre><code>
template&lt;class T, class U&gt; constexpr bool operator&gt;=(const T&amp; v, const optional&lt;U&gt;&amp; x);
</code></pre>
<p>-23-
<em>Constraints</em>:
<ins><code class='backtick'>T</code> is not a specialization of <code class='backtick'>optional</code>.</ins>
The expression <code>v &gt;= *x</code> is well-formed
and its result is convertible to <code class='backtick'>bool</code>.
</p>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4085"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4085">4085</a>. <code>ranges::generate_random</code>'s helper lambda should specify the return type</h3>
<p><b>Section:</b> 26.12.2 <a href="https://wg21.link/alg.rand.generate">[alg.rand.generate]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2024-04-28 <b>Last modified:</b> 2024-10-09</p>
<p><b>Priority: </b>2
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#alg.rand.generate">active issues</a> in [alg.rand.generate].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#alg.rand.generate">issues</a> in [alg.rand.generate].</p>
<p><b>Discussion:</b></p>
<p>
The non-specialized case of <code>generate_random(r, g, d)</code> would call
<code>ranges::generate(r, [&amp;d, &amp;g] { return invoke(d, g); })</code>.
However, the lambda does not explicitly specify the return type, which leads
to a hard error when <code>invoke</code> returns a reference to the object that is not copyable or
<code>R</code> is not the <code>output_range</code> for <code>decay_t&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt;</code>.
</p>

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

<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

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

<blockquote>
<pre>
template&lt;class R, class G, class D&gt;
  requires output_range&lt;R, invoke_result_t&lt;D&amp;, G&amp;&gt;&gt; &amp;&amp; invocable&lt;D&amp;, G&amp;&gt; &amp;&amp;
           uniform_random_bit_generator&lt;remove_cvref_t&lt;G&gt;&gt;
constexpr borrowed_iterator_t&lt;R&gt; ranges::generate_random(R&amp;&amp; r, G&amp;&amp; g, D&amp;&amp; d);
</pre>
<p>-5- <i>Effects</i>:</p>
<ol style="list-style-type: none">
<li><p>(5.1) &mdash; [&hellip;]</p></li>
<li><p>(5.2) &mdash; [&hellip;]</p></li>
<li><p>(5.3) &mdash; Otherwise, calls:</p>
<blockquote><pre>
ranges::generate(std::forward&lt;R&gt;(r), [&amp;d, &amp;g] <ins>-&gt; decltype(auto)</ins> { return invoke(d, g); });
</pre></blockquote>
</li>
</ol>
<p>-6- <i>Returns</i>: <code>ranges::end(r)</code></p>
<p>-7- <i>Remarks</i>: The effects of <code>generate_random(r, g, d)</code> shall be equivalent to</p>
<blockquote><pre>
ranges::generate(std::forward&lt;R&gt;(r), [&amp;d, &amp;g] <ins>-&gt; decltype(auto)</ins> { return invoke(d, g); })
</pre></blockquote>
</blockquote>

</li>
</ol>
</blockquote>

<p><i>[2024-05-12, Hewill Kang provides improved wording]</i></p>


<p><i>[2024-08-02; Reflector poll]</i></p>

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

<p><i>[2024-10-09; LWG telecon: Move to Ready]</i></p>




<p id="res-4085"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

<ol>
<li><p>Modify 29.5.2 <a href="https://wg21.link/rand.synopsis">[rand.synopsis]</a>, header <code>&lt;random&gt;</code> synopsis, as indicated:</p>

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

namespace std {
  [&hellip;]
  namespace ranges {
    [&hellip;]
    template&lt;class R, class G, class D&gt;
      requires output_range&lt;R, invoke_result_t&lt;D&amp;, G&amp;&gt;&gt; &amp;&amp; invocable&lt;D&amp;, G&amp;&gt; &amp;&amp;
               uniform_random_bit_generator&lt;remove_cvref_t&lt;G&gt;&gt; <ins>&amp;&amp;
               is_arithmetic_v&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt;</ins>
    constexpr borrowed_iterator_t&lt;R&gt; generate_random(R&amp;&amp; r, G&amp;&amp; g, D&amp;&amp; d);

    template&lt;class G, class D, output_iterator&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt; O, sentinel_for&lt;O&gt; S&gt;
      requires invocable&lt;D&amp;, G&amp;&gt; &amp;&amp; uniform_random_bit_generator&lt;remove_cvref_t&lt;G&gt;&gt; <ins>&amp;&amp;
               is_arithmetic_v&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt;</ins>
    constexpr O generate_random(O first, S last, G&amp;&amp; g, D&amp;&amp; d);
  }
  [&hellip;]
}
</pre>
</blockquote>

</li>

<li><p>Modify 26.12.2 <a href="https://wg21.link/alg.rand.generate">[alg.rand.generate]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class R, class G, class D&gt;
  requires output_range&lt;R, invoke_result_t&lt;D&amp;, G&amp;&gt;&gt; &amp;&amp; invocable&lt;D&amp;, G&amp;&gt; &amp;&amp;
           uniform_random_bit_generator&lt;remove_cvref_t&lt;G&gt;&gt; <ins>&amp;&amp;
           is_arithmetic_v&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt;</ins>
constexpr borrowed_iterator_t&lt;R&gt; ranges::generate_random(R&amp;&amp; r, G&amp;&amp; g, D&amp;&amp; d);
</pre>
<blockquote>
<p>
-5- <i>Effects</i>:
</p>
[&hellip;]
</blockquote>
<pre>
template&lt;class G, class D, output_iterator&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt; O, sentinel_for&lt;O&gt; S&gt;
  requires invocable&lt;D&amp;, G&amp;&gt; &amp;&amp; uniform_random_bit_generator&lt;remove_cvref_t&lt;G&gt;&gt; <ins>&amp;&amp;
           is_arithmetic_v&lt;invoke_result_t&lt;D&amp;, G&amp;&gt;&gt;</ins>
constexpr O ranges::generate_random(O first, S last, G&amp;&amp; g, D&amp;&amp; d);
</pre>
<blockquote>
<p>
-8- <i>Effects</i>: Equivalent to:
</p>
[&hellip;]
</blockquote>
</blockquote>

</li>
</ol>






<hr>
<h3 id="4112"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4112">4112</a>. <code><i>has-arrow</i></code> should required <code>operator-&gt;()</code> to be <code>const</code>-qualified</h3>
<p><b>Section:</b> 25.5.2 <a href="https://wg21.link/range.utility.helpers">[range.utility.helpers]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2024-06-22 <b>Last modified:</b> 2024-06-24</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
The helper concept <code><i>has-arrow</i></code> in 25.5.2 <a href="https://wg21.link/range.utility.helpers">[range.utility.helpers]</a> does not 
require that <code>I::operator-&gt;()</code> be <code>const</code>-qualified, which is inconsistent with 
the constraints on <code>reverse_iterator</code> and <code>common_iterator</code>'s <code>operator-&gt;()</code> 
as the latter two both require the underlying iterator has <code>const operator-&gt;()</code> member.
<p/>
We should enhance the semantics of <code><i>has-arrow</i></code> so that
<i>implicit expression variations</i> (18.2 <a href="https://wg21.link/concepts.equality">[concepts.equality]</a>)
prohibit silly games.
</p>

<p><i>[St. Louis 2024-06-24; move to Ready]</i></p>




<p id="res-4112"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

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

<blockquote>
<pre>
[&hellip;]

template&lt;class I&gt;
  concept <i>has-arrow</i> =                                       // <i>exposition only</i>
    input_iterator&lt;I&gt; &amp;&amp; (is_pointer_v&lt;I&gt; || requires(<ins>const</ins> I i) { i.operator-&gt;(); });

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

</li>
</ol>





<hr>
<h3 id="4134"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4134">4134</a>. Issue with Philox algorithm specification</h3>
<p><b>Section:</b> 29.5.4.5 <a href="https://wg21.link/rand.eng.philox">[rand.eng.philox]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Ilya A. Burylov <b>Opened:</b> 2024-08-06 <b>Last modified:</b> 2024-08-21</p>
<p><b>Priority: </b>1
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#rand.eng.philox">active issues</a> in [rand.eng.philox].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#rand.eng.philox">issues</a> in [rand.eng.philox].</p>
<p><b>Discussion:</b></p>
<p>
The <a href="https://wg21.link/P2075R6" title=" Philox as an extension of the C++ RNG engines">P2075R6</a> proposal introduced the Philox engine and described the algorithm closely 
following the <a href="https://www.thesalmons.org/john/random123/papers/random123sc11.pdf">original paper</a> 
(further Random123sc11).
<p/>
Matt Stephanson implemented P2075R6 and the 10000'th number did not match. Further investigation revealed 
several places in Random123sc11 algorithm description, which either deviate from the reference implementation 
written by Random123sc11 authors or loosely defined, which opens the way for different interpretations.
<p/>
All major implementations of the Philox algorithm (NumPy, Intel MKL, Nvidia cuRAND, etc.) match the 
reference implementation written by Random123sc11 authors and we propose to align wording with that.
<p/>
The rationale of proposed changes:
</p>
<ol>
<li><p>Random123sc11 refers to the permutation step as "the inputs are permuted using the Threefish 
N-word P-box", thus the P2075R6 permutation table ([tab:rand.eng.philox.f]) is taken from 
Threefish algorithm. But the permutation for N=4 in this table does not match the reference 
implementations. It's worth noting that while Random123sc11 described the Philox algorithm for N=8 
and N=16, there are no known reference implementations of it either provided by authors or 
implemented by other libraries. We proposed to drop N=8 and N=16 for now and update 
the permutation indices for N=4 to match the reference implementation. Note: the proposed resolution 
allows extending N &gt; 4 cases in the future.</p></li>
<li><p>The original paper describes the S-box update for X values in terms of <code>L'</code> and 
<code>R'</code> but does not clarify their ordering as part of the counter. In order to match Random123sc11 
reference implementation the ordering should be swapped.</p></li>
<li><p>Philox alias templates should be updated, because the current ordering of constants matches the 
specific optimization in the reference Random123sc11 implementation and not the generic algorithm 
description.</p></li>
</ol>
<p>
All proposed modifications below are confirmed by:
</p>
<ul>
<li><p>Philox algorithm coauthor Mark Moraes who is planning to publish errata for the original Random123sc11 
Philox paper.</p></li>
<li><p>Matt Stephanson, who originally found the mismatch in P2075R6</p></li>
<li><p>The <a href="https://github.com/rarutyun/iso_cpp_papers/blob/main/rng/philox/philox.hpp">updated 
reference implementation</a>.</p></li>
</ul>

<p><i>[2024-08-21; Reflector poll]</i></p>

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

<p><i>[2024-08-21; Move to Ready at LWG telecon]</i></p>




<p id="res-4134"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

<ol>
<li><p>Modify 29.5.4.5 <a href="https://wg21.link/rand.eng.philox">[rand.eng.philox]</a>, [tab:rand.eng.philox.f] as indicated (This effectively reduces
16 data columns to 4 data columns and 4 data rows to 2 data rows):</p>

<blockquote>
<table border="1">
<caption>Table 101 &mdash; Values for the word permutation <i>f</i><sub><i>n</i></sub>(<i>j</i>) [tab:rand.eng.philox.f]</caption>
<tr>
  <th rowspan="2" colspan="2"><i>f</i><sub><i>n</i></sub>(<i>j</i>)</th>
  <th colspan="16" align="center"><code><i>j</i></code></th>
</tr>
<tr>
  <th>0</th>
  <th>1</th>
  <th>2</th>
  <th>3</th>
  <th><del>4</del></th>
  <th><del>5</del></th>
  <th><del>6</del></th>
  <th><del>7</del></th>
  <th><del>8</del></th>
  <th><del>9</del></th>
  <th><del>10</del></th>
  <th><del>11</del></th>
  <th><del>12</del></th>
  <th><del>13</del></th>
  <th><del>14</del></th>
  <th><del>15</del></th>
</tr>

<tr>
  <th rowspan="5"><i>n</i></th>
</tr>
<tr>
  <th>2</th>
    <td>0</td>
    <td>1</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
</tr>
<tr>
  <th>4</th>
    <td><ins>2</ins><del>0</del></td>
    <td><ins>1</ins><del>3</del></td>
    <td><ins>0</ins><del>2</del></td>
    <td><ins>3</ins><del>1</del></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
</tr>
<tr>
  <th><del>8</del></th>
    <td><del>2</del></td>
    <td><del>1</del></td>
    <td><del>4</del></td>
    <td><del>7</del></td>
    <td><del>6</del></td>
    <td><del>5</del></td>
    <td><del>0</del></td>
    <td><del>3</del></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
</tr>
<tr>  
  <th><del>16</del></th>
    <td><del>0</del></td>
    <td><del>9</del></td>
    <td><del>2</del></td>
    <td><del>13</del></td>
    <td><del>6</del></td>
    <td><del>11</del></td>
    <td><del>4</del></td>
    <td><del>15</del></td>
    <td><del>10</del></td>
    <td><del>7</del></td>
    <td><del>12</del></td>
    <td><del>3</del></td>
    <td><del>14</del></td>
    <td><del>5</del></td>
    <td><del>8</del></td>
    <td><del>1</del></td>
</tr>
</table> 

</blockquote>
</li>

<li><p>Modify 29.5.4.5 <a href="https://wg21.link/rand.eng.philox">[rand.eng.philox]</a> as indicated:</p>

<blockquote>
<p>
-4- [&hellip;]
</p>
<ol style="list-style-type: none">
<li><p>(4.1) &mdash; [&hellip;]</p></li>
<li><p>(4.2) &mdash; The following computations are applied to the elements of the <i>V</i> sequence:</p>
<blockquote>
<p>
<math><msub><mi>X</mi><mrow><mn>2</mn><mi>k</mi><mo>+</mo><mn>0</mn></mrow></msub></math> = <ins>mulhi</ins><del>mullo</del>(<math><msub><mi>V</mi><mrow><mn>2</mn><mi>k</mi><del><mo>+</mo><mn>1</mn></del></mrow></msub></math>,<math><msub><mi>M</mi><mi>k</mi></msub></math>,<i>w</i>)
<ins>xor <math><msubsup><mi style="font-style: italic">key</mi><mi>k</mi><mi>q</mi></msubsup></math> xor <math><msub><mi>V</mi><mrow><mn>2</mn><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></math></ins>
<p/>
<math><msub><mi>X</mi><mrow><mn>2</mn><mi>k</mi><mo>+</mo><mn>1</mn></mrow></msub></math> = <ins>mullo</ins><del>mulhi</del>(<math><msub><mi>V</mi><mrow><mn>2</mn><mi>k</mi><del><mo>+</mo><mn>1</mn></del></mrow></msub></math>,<math><msub><mi>M</mi><mi>k</mi></msub></math>,<i>w</i>)
 <del>xor <math><msubsup><mi style="font-style: italic">key</mi><mi>k</mi><mi>q</mi></msubsup></math> xor <math><msub><mi>V</mi><mrow><mn>2</mn><mi>k</mi></mrow></msub></math></del>
</p>
</blockquote>
</li>
</ol>
<p>
-5- [&hellip;]
<p/>
-6- <i>Mandates</i>:
</p>
<ol style="list-style-type: none">
<li><p>(6.1) &mdash; [&hellip;]</p></li>
<li><p>(6.2) &mdash; <code>n == 2 || n == 4 <del>|| n == 8 || n == 16</del></code> is <code>true</code>, and</p></li>
<li><p>(6.3) &mdash; [&hellip;]</p></li>
<li><p>(6.4) &mdash; [&hellip;]</p></li>
</ol>

</blockquote>
</li>

<li><p>Modify 29.5.6 <a href="https://wg21.link/rand.predef">[rand.predef]</a> as indicated:</p>

<blockquote>
<pre>
using philox4x32 =
      philox_engine&lt;uint_fast32_t, 32, 4, 10,
       <ins>0xCD9E8D57</ins><del>0xD2511F53</del>, 0x9E3779B9, <ins>0xD2511F53</ins><del>0xCD9E8D57</del>, 0xBB67AE85&gt;;
</pre>
<blockquote>
<p>
-11- <i>Required behavior</i>: The 10000<sup>th</sup> consecutive invocation a default-constructed 
object of type <code>philox4x32</code> produces the value <code>1955073260</code>.
</p>
</blockquote>
<pre>
using philox4x64 =
      philox_engine&lt;uint_fast64_t, 64, 4, 10,
       <ins>0xCA5A826395121157</ins><del>0xD2E7470EE14C6C93</del>, 0x9E3779B97F4A7C15, <ins>0xD2E7470EE14C6C93</ins><del>0xCA5A826395121157</del>, 0xBB67AE8584CAA73B&gt;;
</pre>
<blockquote>
<p>
-12- <i>Required behavior</i>: The 10000<sup>th</sup> consecutive invocation a default-constructed 
object of type <code>philox4x64</code> produces the value 3409172418970261260.
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3 id="4154"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4154">4154</a>. The Mandates for <code>std::packaged_task</code>'s constructor from a callable entity should consider decaying</h3>
<p><b>Section:</b> 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Ready</a>
 <b>Submitter:</b> Jiang An <b>Opened:</b> 2024-09-18 <b>Last modified:</b> 2024-10-09</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#futures.task.members">active issues</a> in [futures.task.members].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#futures.task.members">issues</a> in [futures.task.members].</p>
<p><b>Discussion:</b></p>
<p>
Currently, 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a>/3 states:
<blockquote>
<i>Mandates</i>:
<code>is_invocable_r_v&lt;R, F&amp;, ArgTypes...&gt;</code> is <code class='backtick'>true</code>.
</blockquote>
where <code>F&amp;</code> can be a reference to a cv-qualified function object type.
</p>
<p>
However, in mainstream implementations (libc++, libstdc++, and MSVC STL),
the stored task object always has a cv-unqualified type,
and thus the cv-qualification is unrecognizable in <code class='backtick'>operator()</code>.
</p>
<p>
Since 22.10.17.3.2 <a href="https://wg21.link/func.wrap.func.con">[func.wrap.func.con]</a> uses a decayed type,
perhaps we should also so specify for <code class='backtick'>std::packaged_task</code>.
</p>

<p><i>[2024-10-02; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>
<p>
"Fix preconditions, <code class='backtick'>f</code> doesn't need to be invocable, we only invoke the copy."
</p>

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

<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>
<ol>
<li><p>Modify 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a> as indicated:</p>
<blockquote>
<p>
-3- <i>Mandates</i>:
<code>is_invocable_r_v&lt;R, <del>F</del><ins>decay_t&lt;F&gt;</ins>&amp;, ArgTypes...&gt;</code>
is <code class='backtick'>true</code>.
</p>
[...]
<p>
-5- <i>Effects</i>:
Constructs a new <code class='backtick'>packaged_task</code> object with a shared state and initializes
the object's stored task
<ins>of type <code>decay_t&lt;F&gt;</code></ins>
with <code>std::forward&lt;F&gt;(f)</code>.
</p>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2024-10-02; Jonathan provides improved wording]</i></p>

<p>Drop preconditions as suggested on reflector.</p>

<p><i>[2024-10-02; LWG telecon]</i></p>

<p>
Clarify that "of type <code>decay_t&lt;F&gt;</code>"
is supposed to be specifying the type of the stored task.
</p>

<p><i>[2024-10-09; LWG telecon: Move to Ready]</i></p>




<p id="res-4154"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>
<ol>
<li><p>Modify 32.10.10.2 <a href="https://wg21.link/futures.task.members">[futures.task.members]</a> as indicated:</p>
<blockquote>
<pre><code>template&lt;class F&gt;
  explicit packaged_task(F&amp;&amp; f);</code></pre>
<p>
-2- <i>Constraints</i>:
<code>remove_cvref_t&lt;F&gt;</code> is not the same type as
<code>packaged_task&lt;R(ArgTypes...)&gt;</code>.
</p>
<p>
-3- <i>Mandates</i>:
<code>is_invocable_r_v&lt;R, <del>F</del><ins>decay_t&lt;F&gt;</ins>&amp;, ArgTypes...&gt;</code>
is <code class='backtick'>true</code>.
</p>
<p>
<del>-4- <i>Preconditions</i>:
Invoking a copy of <code class='backtick'>f</code> behaves the same as invoking <code class='backtick'>f</code>.
</del>
</p>
<p>
-5- <i>Effects</i>:
Constructs a new <code class='backtick'>packaged_task</code> object with
<ins>a stored task of type <code>decay_t&lt;F&gt;</code> and</ins>
a shared state
<ins>. Initializes</ins>
<del>and initializes</del>
the object's stored task
with <code>std::forward&lt;F&gt;(f)</code>.
</p>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4164"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4164">4164</a>. Missing guarantees for <code class='backtick'>forward_list</code> modifiers</h3>
<p><b>Section:</b> 23.3.7.5 <a href="https://wg21.link/forward.list.modifiers">[forward.list.modifiers]</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> 2024-10-05 <b>Last modified:</b> 2024-10-09</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#forward.list.modifiers">issues</a> in [forward.list.modifiers].</p>
<p><b>Discussion:</b></p>
<p>
The new <code class='backtick'>std::list</code> members added by <a href="https://wg21.link/P1206R7" title=" Conversions from ranges to containers">P1206R7</a>,
<code>insert_range(const_iterator, R&amp;&amp;)</code>,
<code>prepend_range(R&amp;&amp;)</code>, and
<code>append_range(R&amp;&amp;)</code>,
have the same exception safety guarantee as
<code class='backtick'>std::list::insert(const_iterator, InputIterator, InputIterator)</code>, which is:
<blockquote>
<i>Remarks</i>:
Does not affect the validity of iterators and references.
If an exception is thrown, there are no effects.
</blockquote>
</p>
<p>
This guarantee was achieved for the new <code class='backtick'>list</code> functions simply by placing
them in the same set of declarations as the existing <code class='backtick'>insert</code> overloads,
at the start of 23.3.9.4 <a href="https://wg21.link/list.modifiers">[list.modifiers]</a>.
</p>

<p>
However, the new <code class='backtick'>std::forward_list</code> members,
<code>insert_range_after(const_iterator, R&amp;&amp;)</code> and
<code>prepend_range(R&amp;&amp;)</code>,
do not have the same guarantee as <code class='backtick'>forward_list::insert_after</code>.
This looks like an omission caused by the fact that <code class='backtick'>insert_after</code>'s
exception safety guarantee is given in a separate paragraph at the start
of 23.3.7.5 <a href="https://wg21.link/forward.list.modifiers">[forward.list.modifiers]</a>:
<blockquote>
None of the overloads of <code class='backtick'>insert_after</code>
shall affect the validity of iterators and references,
and <code class='backtick'>erase_after</code> shall invalidate only iterators and references
to the erased elements.
If an exception is thrown during <code class='backtick'>insert_after</code> there shall be no effect.
</blockquote>
</p>

<p>
I think we should give similar guarantees for <code class='backtick'>insert_range_after</code>
and <code class='backtick'>prepend_range</code>.
The change might also be appropriate for <code class='backtick'>emplace_after</code> as well.
A "no effects" guarantee is already given for <code class='backtick'>push_front</code> and <code class='backtick'>emplace_front</code>
in 23.2.2.2 <a href="https://wg21.link/container.reqmts">[container.reqmts]</a> p66, although that doesn't say anything
about iterator invalidation so we might want to add that to
23.3.7.5 <a href="https://wg21.link/forward.list.modifiers">[forward.list.modifiers]</a> too.
For the functions that insert a single element, it's trivial to not modify
the list if allocating a new node of constructing the element throws.
The strong exception safety guarantee for the multi-element insertion functions
is easily achieved by inserting into a temporary <code class='backtick'>forward_list</code> first,
then using <code class='backtick'>splice_after</code> which is non-throwing.
</p>


<p><i>[2024-10-09; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>
<p>It was suggested to change
"If an exception is thrown by any of these member functions
that insert elements there is no effect on the forward_list"
to simply
"If an exception is thrown by any of these member functions
there is no effect on the forward_list"
</p>

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

<p>This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.</p>

<ol>
<li>
<p>Change 23.3.7.5 <a href="https://wg21.link/forward.list.modifiers">[forward.list.modifiers]</a> as indicated:</p>
<blockquote>
None of the <del>overloads of <code class='backtick'>insert_after</code> shall</del>
<ins>member functions in this subclause that insert elements</ins>
affect the validity of iterators and references,
and <code class='backtick'>erase_after</code> <del>shall invalidate</del> <ins>invalidates</ins>
only iterators and references to the erased elements.
If an exception is thrown
<del>during <code class='backtick'>insert_after</code></del>
<ins>by any of these member functions</ins>
there <del>shall be</del> <ins>is</ins> no effect
<ins>on the <code class='backtick'>forward_list</code></ins>.
</blockquote>

</li>
</ol>

</blockquote>

<p><i>[2024-10-09; LWG suggested improved wording]</i></p>

<p>
The proposed resolution potentially mandates a change to <code class='backtick'>resize</code> when
increasing the size, requiring implementations to "roll back" earlier
insertions if a later one throws, so that the size is left unchanged.
It appears that libstdc++ and MSVC already do this, libc++ does not.
</p>

<p><i>[2024-10-09; LWG telecon: Move to Ready]</i></p>




<p id="res-4164"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.</p>

<ol>
<li>
<p>Change 23.3.7.5 <a href="https://wg21.link/forward.list.modifiers">[forward.list.modifiers]</a> as indicated:</p>
<blockquote>
<del>
None of the overloads of <code class='backtick'>insert_after</code> shall
affect the validity of iterators and references,
and <code class='backtick'>erase_after</code> shall invalidate
only iterators and references to the erased elements.
</del>
<ins>The member functions in this subclause do not
affect the validity of iterators and references when inserting elements,
and when erasing elements invalidate iterators and references
to the erased elements only.
</ins>
If an exception is thrown
<del>during <code class='backtick'>insert_after</code></del>
<ins>by any of these member functions</ins>
there <del>shall be</del> <ins>is</ins> no effect
<ins>on the container</ins>.
</blockquote>

</li>
</ol>







<h2 id="tentatively_ready">Tentatively Ready Issues</h2>
<hr>
<h3 id="3216"><a href="https://cplusplus.github.io/LWG/lwg-active.html#3216">3216</a>. Rebinding the allocator before calling <code>construct</code>/<code>destroy</code> in <code>allocate_shared</code></h3>
<p><b>Section:</b> 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Billy O'Neal III <b>Opened:</b> 2019-06-11 <b>Last modified:</b> 2024-10-02</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#util.smartptr.shared.create">active issues</a> in [util.smartptr.shared.create].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#util.smartptr.shared.create">issues</a> in [util.smartptr.shared.create].</p>
<p><b>Discussion:</b></p>
<p>
The new <code>allocate_shared</code> wording says we need to rebind the allocator back to <code>T</code>'s
type before we can call <code>construct</code> or <code>destroy</code>, but this is suboptimal (might make
extra unnecessary allocator copies), and is inconsistent with the containers' behavior, which call
allocator <code>construct</code> on whatever <code>T</code> they want. (For example,
<code>std::list&lt;T, alloc&lt;T&gt;&gt;</code> rebinds to <code>alloc&lt;_ListNode&lt;T&gt;&gt;</code>,
but calls <code>construct(T*)</code> without rebinding back)
<p/>
It seems like we should be consistent with the containers and not require a rebind here. PR would
look something like this, relative to N4810; I'm still not super happy with this wording because
it looks like it might be saying a copy of the allocator must be made we would like to avoid&hellip;
</p>

<p><i>[2019-07 Issue Prioritization]</i></p>

<p>Priority to 3 after discussion on the reflector.</p>
<p><strong>Previous resolution [SUPERSEDED]:</strong></p>
<blockquote class="note">

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

<ol>
<li><p>Modify 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note:</i> The edits to change <code>pv</code> to <code>pu</code> were suggested by Jonathan
Wakely (thanks!). This wording also has the <code>remove_cv_t</code> fixes specified by LWG <a href="https://cplusplus.github.io/LWG/lwg-active.html#3210" title="allocate_shared is inconsistent about removing const from the pointer
passed to allocator construct and destroy (Status: New)">3210</a><sup><a href="https://cplusplus.github.io/LWG/issue3210" title="Latest snapshot">(i)</a></sup>
&mdash; if that change is rejected some of those have to be stripped here.]
</p>
</blockquote>

<blockquote>
<pre>
template&lt;class T, ...&gt;
  shared_ptr&lt;T&gt; make_shared(<i>args</i>);
template&lt;class T, class A, ...&gt;
  shared_ptr&lt;T&gt; allocate_shared(const A&amp; a, <i>args</i>);
template&lt;class T, ...&gt;
  shared_ptr&lt;T&gt; make_shared_default_init(<i>args</i>);
template&lt;class T, class A, ...&gt;
  shared_ptr&lt;T&gt; allocate_shared_default_init(const A&amp; a, <i>args</i>);
</pre>
<blockquote>
<p>
-2- <i>Requires:</i> [&hellip;]
<p/>
[&hellip;]
<p/>
-7- <i>Remarks:</i>
</p>
<ol style="list-style-type: none">
<li><p>(7.1) &mdash; [&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>(7.5) &mdash; When a (sub)object of a non-array type <code>U</code> is specified to have an initial
value of <code>v</code>, or <code>U(l...)</code>, where <code>l...</code> is a list of constructor arguments,
<code>allocate_shared</code> shall initialize this (sub)object via the expression
</p>
<ol style="list-style-type: none">
<li><p>(7.5.1) &mdash; <code>allocator_traits&lt;A2&gt;::construct(a2, p<del>v</del><ins>u</ins>, v)</code> or</p></li>
<li><p>(7.5.2) &mdash; <code>allocator_traits&lt;A2&gt;::construct(a2, p<del>v</del><ins>u</ins>, l...)</code></p></li>
</ol>
<p>
respectively, where <code>p<del>v</del><ins>u</ins></code> <ins>is a pointer of type
<code>remove_cv_t&lt;U&gt;*</code></ins> point<del>s</del><ins>ing</ins> to storage suitable to hold
an object of type <code><ins>remove_cv_t&lt;</ins>U<ins>&gt;</ins></code> and <code>a2</code> of type
<code>A2</code> is a <ins>potentially</ins> rebound copy of the allocator <code>a</code>
passed to <code>allocate_shared</code> <del>such that its <code>value_type</code> is <code>remove_cv_t&lt;U&gt;</code></del>.
</p>
</li>
<li><p>(7.6) &mdash; [&hellip;]</p></li>
<li><p>(7.7) &mdash; When a (sub)object of non-array type <code>U</code> is specified to have a default
initial value, <code>allocate_shared</code> <del>shall</del> initialize<ins>s</ins> this (sub)object via
the expression <code>allocator_traits&lt;A2&gt;::construct(a2, p<del>v</del><ins>u</ins>)</code>, where
<code>p<del>v</del><ins>u</ins></code> <ins>is a pointer of type <code>remove_cv_t&lt;U&gt;*</code></ins>
point<del>s</del><ins>ing</ins> to storage suitable to hold an object of type
<code><ins>remove_cv_t&lt;</ins>U<ins>&gt;</ins></code> and <code>a2</code> of type <code>A2</code> is a
<ins>potentially</ins> rebound copy of the allocator <code>a</code> passed to <code>allocate_shared</code>
<del>such that its <code>value_type</code> is <code>remove_cv_t&lt;U&gt;</code></del>.</p></li>
<li><p>[&hellip;]</p></li>
<li><p>(7.12) &mdash; When a (sub)object of non-array type <code>U</code> that was initialized by
<code>allocate_shared</code> is to be destroyed, it is destroyed via the expression
<code>allocator_traits&lt;A2&gt;::destroy(a2, p<del>v</del><ins>u</ins>)</code> where
<code>p<del>v</del><ins>u</ins></code> <ins>is a pointer of type <code>remove_cv_t&lt;U&gt;*</code></ins>
point<del>s</del><ins>ing</ins> to that object of type <code>remove_cv_t&lt;U&gt;</code> and
<code>a2</code> of type <code>A2</code> is a <ins>potentially</ins> rebound copy of the
allocator <code>a</code> passed to <code>allocate_shared</code> <del>such that its <code>value_type</code> is
<code>remove_cv_t&lt;U&gt;</code></del>.</p></li>
</ol>
</blockquote>
</blockquote>
</li>
</ol>
</blockquote>

<p><i>[2024-08-23; Jonathan provides updated wording]</i></p>

<p>
<code class='backtick'>make_shared_default_init</code> and <code class='backtick'>allocate_shared_default_init</code> were renamed
by <a href="https://wg21.link/P1973R1" title=" Rename _default_init functions (NB Comment DE002)">P1973R1</a> so this needs a rebase.
The edit to (7.11) is just for consistency, so that <code class='backtick'>pv</code> is always <code class='backtick'>void*</code>
and <code class='backtick'>pu</code> is <code>remove_cv_t&lt;U&gt;*</code>.
Accepting this proposed resolution would also resolve issue <a href="https://cplusplus.github.io/LWG/lwg-active.html#3210" title="allocate_shared is inconsistent about removing const from the pointer
passed to allocator construct and destroy (Status: New)">3210</a><sup><a href="https://cplusplus.github.io/LWG/issue3210" title="Latest snapshot">(i)</a></sup>.
</p>


<p><i>[2024-10-02; Reflector poll]</i></p>

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



<p id="res-3216"><b>Proposed resolution:</b></p>
<p>This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.</p>

<ol>
<li><p>Modify 20.3.2.2.7 <a href="https://wg21.link/util.smartptr.shared.create">[util.smartptr.shared.create]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, ...&gt;
  shared_ptr&lt;T&gt; make_shared(<i>args</i>);
template&lt;class T, class A, ...&gt;
  shared_ptr&lt;T&gt; allocate_shared(const A&amp; a, <i>args</i>);
template&lt;class T, ...&gt;
  shared_ptr&lt;T&gt; make_shared_for_overwrite(<i>args</i>);
template&lt;class T, class A, ...&gt;
  shared_ptr&lt;T&gt; allocate_shared_for_overwrite(const A&amp; a, <i>args</i>);
</pre>
<blockquote>
<p>
-2- <i>Preconditions:</i> [&hellip;]
<p/>
[&hellip;]
<p/>
-7- <i>Remarks:</i>
</p>
<ol style="list-style-type: none">
<li><p>(7.1) &mdash; [&hellip;]</p></li>
<li><p>[&hellip;]</p></li>
<li><p>(7.5) &mdash; When a (sub)object of a non-array type <code>U</code> is specified to have an initial
value of <code>v</code>, or <code>U(l...)</code>, where <code>l...</code> is a list of constructor arguments,
<code>allocate_shared</code> shall initialize this (sub)object via the expression
</p>
<ol style="list-style-type: none">
<li><p>(7.5.1) &mdash; <code>allocator_traits&lt;A2&gt;::construct(a2, p<del>v</del><ins>u</ins>, v)</code> or</p></li>
<li><p>(7.5.2) &mdash; <code>allocator_traits&lt;A2&gt;::construct(a2, p<del>v</del><ins>u</ins>, l...)</code></p></li>
</ol>
<p>
respectively, where <code>p<del>v</del><ins>u</ins></code> <ins>is a pointer of type
<code>remove_cv_t&lt;U&gt;*</code></ins> point<del>s</del><ins>ing</ins> to storage suitable to hold
an object of type <code><ins>remove_cv_t&lt;</ins>U<ins>&gt;</ins></code> and <code>a2</code> of type
<code>A2</code> is a <ins>potentially</ins> rebound copy of the allocator <code>a</code>
passed to <code>allocate_shared</code> <del>such that its <code>value_type</code> is <code>remove_cv_t&lt;U&gt;</code></del>.
</p>
</li>
<li><p>(7.6) &mdash; [&hellip;]</p></li>
<li><p>(7.7) &mdash; When a (sub)object of non-array type <code>U</code> is specified to have a default
initial value, <code>allocate_shared</code> <del>shall</del> initialize<ins>s</ins> this (sub)object via
the expression <code>allocator_traits&lt;A2&gt;::construct(a2, p<del>v</del><ins>u</ins>)</code>, where
<code>p<del>v</del><ins>u</ins></code> <ins>is a pointer of type <code>remove_cv_t&lt;U&gt;*</code></ins>
point<del>s</del><ins>ing</ins> to storage suitable to hold an object of type
<code><ins>remove_cv_t&lt;</ins>U<ins>&gt;</ins></code> and <code>a2</code> of type <code>A2</code> is a
<ins>potentially</ins> rebound copy of the allocator <code>a</code> passed to <code>allocate_shared</code>
<del>such that its <code>value_type</code> is <code>remove_cv_t&lt;U&gt;</code></del>.</p></li>
<li><p>[&hellip;]</p></li>
<li>
<blockquote class="note"><p>[<i>Drafting note</i>:
Issue <a href="https://cplusplus.github.io/LWG/lwg-active.html#4024" title="Underspecified destruction of objects created in std::make_shared_for_overwrite/std::allocate_shared_for_overwrite (Status: Ready)">4024</a><sup><a href="https://cplusplus.github.io/LWG/issue4024" title="Latest snapshot">(i)</a></sup> will add <code class='backtick'>make_shared_for_overwrite</code>
and <code class='backtick'>allocate_shared_for_overwrite</code> to (7.11) but that doesn't conflict with this next edit.]
</p></blockquote>
<p>(7.11) &mdash; When a (sub)object of non-array type <code>U</code> that was initialized by
<code>make_shared</code> is to be destroyed, it is destroyed via the expression
<code>p<del>v</del><ins>u</ins>->~U()</code> where <code>p<del>v</del><ins>u</ins></code>
points to that object of type <code>U</code>.</p></li>
<li><p>(7.12) &mdash; When a (sub)object of non-array type <code>U</code> that was initialized by
<code>allocate_shared</code> is to be destroyed, it is destroyed via the expression
<code>allocator_traits&lt;A2&gt;::destroy(a2, p<del>v</del><ins>u</ins>)</code> where
<code>p<del>v</del><ins>u</ins></code> <ins>is a pointer of type <code>remove_cv_t&lt;U&gt;*</code></ins>
point<del>s</del><ins>ing</ins> to that object of type <code>remove_cv_t&lt;U&gt;</code> and
<code>a2</code> of type <code>A2</code> is a <ins>potentially</ins> rebound copy of the
allocator <code>a</code> passed to <code>allocate_shared</code> <del>such that its <code>value_type</code> is
<code>remove_cv_t&lt;U&gt;</code></del>.</p></li>
</ol>
</blockquote>
</blockquote>
</li>
</ol>




<hr>
<h3 id="3886"><a href="https://cplusplus.github.io/LWG/lwg-active.html#3886">3886</a>. Monad mo' problems</h3>
<p><b>Section:</b> 22.5.3.1 <a href="https://wg21.link/optional.optional.general">[optional.optional.general]</a>, 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">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2023-02-13 <b>Last modified:</b> 2024-09-19</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#optional.optional.general">active issues</a> in [optional.optional.general].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#optional.optional.general">issues</a> in [optional.optional.general].</p>
<p><b>Discussion:</b></p>
<p>
While implementing <a href="https://wg21.link/P2505R5" title=" Monadic Functions for std::expected">P2505R5</a> "Monadic Functions for <code>std::expected</code>" we found it odd that
the template type parameter for the assignment operator that accepts an argument by forwarding reference is
defaulted, but the template type parameter for <code>value_or</code> is not. For consistency, it would seem that
<code><i>meow</i>.value_or(<i>woof</i>)</code> should accept the same arguments <code><i>woof</i></code> as does
<code><i>meow</i> = <i>woof</i></code>, even when those arguments are braced-initializers.
<p/>
That said, it would be peculiar to default the template type parameter of <code>value_or</code> to <code>T</code>
instead of <code>remove_cv_t&lt;T&gt;</code>. For <code>expected&lt;const vector&lt;int&gt;, int&gt; <i>meow</i>{unexpect, 42};</code>,
for example, <code><i>meow</i>.value_or({1, 2, 3})</code> would create a temporary <code>const vector&lt;int&gt;</code>
for the argument and return a copy of that argument. Were the default template argument instead
<code>remove_cv_t&lt;T&gt;</code>, <code><i>meow</i>.value_or({1, 2, 3})</code> could move construct its return value
from the argument <code>vector&lt;int&gt;</code>. For the same reason, the constructor that accepts a forwarding
reference with a default template argument of <code>T</code> should default that argument to <code>remove_cv_t&lt;T&gt;</code>.
<p/>
For consistency, it would be best to default the template argument of the perfect-forwarding construct,
perfect-forwarding assignment operator, and <code>value_or</code> to <code>remove_cv_t&lt;T&gt;</code>. Since all of
the arguments presented apply equally to <code>optional</code>, we believe <code>optional</code> should be changed
consistently with <code>expected</code>. MSVCSTL has prototyped these changes successfully.
</p>

<p><i>[2023-03-22; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>
<p><i>[2024-09-18; Reflector poll]</i></p>

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



<p id="res-3886"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4928" title=" Working Draft, Standard for Programming Language C++">N4928</a>.
</p>

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

<blockquote>
<pre>
namespace std {
  template&lt;class T&gt;
  class optional {
  public:
    [&hellip;]
    template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt;
      constexpr explicit(<i>see below</i>) optional(U&amp;&amp;);
    [&hellip;]
    template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt; constexpr optional&amp; operator=(U&amp;&amp;);
    [&hellip;]
    template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp;) const &amp;;
    template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp;) &amp;&amp;;
    [&hellip;]
  };
  [&hellip;]
}
</pre>
</blockquote>

</li>

<li><p>Modify 22.5.3.2 <a href="https://wg21.link/optional.ctor">[optional.ctor]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt; constexpr explicit(<i>see below</i>) optional(U&amp;&amp; v);
</pre>
<blockquote>
<p>
-23- <i>Constraints</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>

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

<blockquote>
<pre>
template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt; constexpr optional&amp; operator=(U&amp;&amp; v);
</pre>
<blockquote>
<p>
-12- <i>Constraints</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>

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

<blockquote>
<pre>
template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp; v) const &amp;;
</pre>
<blockquote>
<p>
-15- <i>Mandates</i>: [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp; v) &amp;&amp;;
</pre>
<blockquote>
<p>
-17- <i>Mandates</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>

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

<blockquote>
<pre>
namespace std {
  template&lt;class T, class E&gt;
  class expected {
  public:
    [&hellip;]
    template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt;
      constexpr explicit(<i>see below</i>) expected(U&amp;&amp; v);
    [&hellip;]
    template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt; constexpr expected&amp; operator=(U&amp;&amp;);
    [&hellip;]
    template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp;) const &amp;;
    template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp;) &amp;&amp;;
    [&hellip;]
  };
  [&hellip;]
}
</pre>
</blockquote>

</li>

<li><p>Modify 22.8.6.2 <a href="https://wg21.link/expected.object.cons">[expected.object.cons]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt;
  constexpr explicit(!is_convertible_v&lt;U, T&gt;) expected(U&amp;&amp; v);
</pre>
<blockquote>
<p>
-23- <i>Constraints</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>

<li><p>Modify 22.8.6.4 <a href="https://wg21.link/expected.object.assign">[expected.object.assign]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class U = <ins>remove_cv_t&lt;</ins>T<ins>&gt;</ins>&gt;
  constexpr expected&amp; operator=(U&amp;&amp; v);
</pre>
<blockquote>
<p>
-9- <i>Constraints</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>

<li><p>Modify 22.8.6.6 <a href="https://wg21.link/expected.object.obs">[expected.object.obs]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp; v) const &amp;;
</pre>
<blockquote>
<p>
-16- <i>Mandates</i>: [&hellip;]
<p/>
[&hellip;]
</p>
</blockquote>
<pre>
template&lt;class U <ins>= remove_cv_t&lt;T&gt;</ins>&gt; constexpr T value_or(U&amp;&amp; v) &amp;&amp;;
</pre>
<blockquote>
<p>
-18- <i>Mandates</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>

</ol>





<hr>
<h3 id="4084"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4084">4084</a>. <code>std::fixed</code> ignores <code>std::uppercase</code></h3>
<p><b>Section:</b> 28.3.4.3.3.3 <a href="https://wg21.link/facet.num.put.virtuals">[facet.num.put.virtuals]</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> 2024-04-30 <b>Last modified:</b> 2024-09-19</p>
<p><b>Priority: </b>3
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#facet.num.put.virtuals">active issues</a> in [facet.num.put.virtuals].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#facet.num.put.virtuals">issues</a> in [facet.num.put.virtuals].</p>
<p><b>Discussion:</b></p>
<p>
In Table 114 &ndash; Floating-point conversions [tab:facet.num.put.fp]
we specify that a floating-point value should be printed as if by <code class='backtick'>%f</code>
when <code>(flags &amp; floatfield) == fixed</code>.
This ignores whether <code class='backtick'>uppercase</code> is also set in <code class='backtick'>flags</code>,
meaning there is no way to use the conversion specifier <code class='backtick'>%F</code>
that was added to <code class='backtick'>printf</code> in C99.
</p>
<p>
That's fine for finite values, because 1.23 in fixed format has
no exponent character and no hex digits that would need to use uppercase.
But <code class='backtick'>%f</code> and <code class='backtick'>%F</code> are not equivalent for non-finite values,
because <code class='backtick'>%F</code> prints <code class='backtick'>"NAN"</code> and <code class='backtick'>"INF"</code> (or <code class='backtick'>"INFINITY"</code>).
It seems there is no way to print <code class='backtick'>"NAN"</code> or <code class='backtick'>"INF"</code> using <code class='backtick'>std::num_put</code>.
</p>
<p>
Libstdc++ and MSVC print <code class='backtick'>"inf"</code> for the following code,
but libc++ prints <code class='backtick'>"INF"</code> which I think is non-conforming:
</p>
<pre><code>    std::cout &lt;&lt; std::uppercase &lt;&lt; std::fixed &lt;&lt; std::numeric_limits&lt;double&gt;::infinity();
</code></pre>
<p>
The libc++ behaviour seems more useful and less surprising.
</p>

<p><i>[2024-05-08; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll. Send to LEWG.
</p>
<p><i>[2024-09-17; LEWG mailing list vote]</i></p>

<p>
Set status to Open after LEWG approved the proposed change.
</p>
<p><i>[2024-09-19; Reflector poll]</i></p>

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



<p id="res-4084"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>
<ol>
<li><p>Modify 28.3.4.3.3.3 <a href="https://wg21.link/facet.num.put.virtuals">[facet.num.put.virtuals]</a> as indicated:</p>

<blockquote>
<table style="border: 1px solid">
<caption style="caption-side: top">
Table 114 &ndash; Floating-point conversions [tab:facet.num.put.fp]
</caption>
<tr style="text-align: center">
<th style="border-bottom: 1px solid">State</th>
<th style="border-bottom: 1px solid"><code class='backtick'>stdio</code> equivalent</th>
</tr>
<tr>
<td>
<code class='backtick'>floatfield == ios_base::fixed</code> <ins><code>&amp;&amp; !uppercase</code></ins>
</td>
<td style="text-align: center"><code class='backtick'>%f</code></td>
</tr>
<tr>
<td><ins><code class='backtick'>floatfield == ios_base::fixed</code></ins></td>
<td style="text-align: center"><ins><code class='backtick'>%F</code></ins></td>
</tr>
<tr>
<td><code>floatfield == ios_base::scientific &amp;&amp; !uppercase</code></td>
<td style="text-align: center"><code class='backtick'>%e</code></td>
</tr>
<tr>
<td><code>floatfield == ios_base::scientific</code></td>
<td style="text-align: center"><code class='backtick'>%E</code></td>
</tr>
<tr>
<td>
<code>
floatfield == (ios_base::fixed | ios_base::scientific)` &amp;&amp; !uppercase
</code>
</td>
<td style="text-align: center"><code class='backtick'>%a</code></td>
</tr>
<tr>
<td><code>floatfield == (ios_base::fixed | ios_base::scientific)</code></td>
<td style="text-align: center"><code class='backtick'>%A</code></td>
</tr>
<tr>
<td><code class='backtick'>!uppercase</code></td>
<td style="text-align: center"><code class='backtick'>%g</code></td>
</tr>
<tr>
<td><em>otherwise</em></td>
<td style="text-align: center"><code class='backtick'>%G</code></td>
</tr>
</table>
</blockquote>
</li>
</ol>






<hr>
<h3 id="4088"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4088">4088</a>. <code>println</code> ignores the locale imbued in <code>std::ostream</code></h3>
<p><b>Section:</b> 31.7.6.3.5 <a href="https://wg21.link/ostream.formatted.print">[ostream.formatted.print]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Jens Maurer <b>Opened:</b> 2024-04-30 <b>Last modified:</b> 2024-10-03</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#ostream.formatted.print">active issues</a> in [ostream.formatted.print].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#ostream.formatted.print">issues</a> in [ostream.formatted.print].</p>
<p><b>Discussion:</b></p>
<p>
31.7.6.3.5 <a href="https://wg21.link/ostream.formatted.print">[ostream.formatted.print]</a> specifies that <code>std::print</code> uses the locale
imbued in the <code>std::ostream&amp;</code> argument for formatting, by using this equivalence:
</p>
<blockquote>
<pre>
vformat(os.getloc(), fmt, args);
</pre>
</blockquote>
<p>
(in the <code>vformat_(non)unicode</code> delegation).
<p/>
However, <code>std::println</code> ignores the <code>std::ostream</code>'s locale
for its locale-dependent formatting:
</p>
<blockquote>
<pre>
print(os, "{}\n", format(fmt, std::forward&lt;Args&gt;(args)...));
</pre>
</blockquote>
<p>
This is inconsistent.
</p>

<p><i>[2024-10-03; Reflector poll]</i></p>

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



<p id="res-4088"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

<ol>

<li><p>Modify 31.7.6.3.5 <a href="https://wg21.link/ostream.formatted.print">[ostream.formatted.print]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class... Args&gt;
  void println(ostream&amp; os, format_string&lt;Args...&gt; fmt, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
-2- <i>Effects</i>: Equivalent to:
</p>
<blockquote>
<pre>
print(os, "{}\n", format(<ins>os.getloc(),</ins> fmt, std::forward&lt;Args&gt;(args)...));
</pre>
</blockquote>
</blockquote>
</blockquote>

</li>
</ol>






<hr>
<h3 id="4113"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4113">4113</a>. Disallow <code>has_unique_object_representations&lt;Incomplete[]&gt;</code></h3>
<p><b>Section:</b> 21.3.5.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</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> 2024-06-25 <b>Last modified:</b> 2024-08-02</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#meta.unary.prop">active issues</a> in [meta.unary.prop].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#meta.unary.prop">issues</a> in [meta.unary.prop].</p>
<p><b>Discussion:</b></p>
<p>
The type completeness requirements for <code class='backtick'>has_unique_object_representations</code> say:
<blockquote>
<code class='backtick'>T</code> shall be a complete type, <i>cv</i> <code class='backtick'>void</code>, or an array of unknown bound.
</blockquote>
</p>
<p>
This implies that the trait works for all arrays of unknown bound,
whether the element type is complete or not. That seems to be incorrect,
because <code>has_unique_object_representations_v&lt;Incomplete[]&gt;</code>
is required to have the same result as
<code>has_unique_object_representations_v&lt;Incomplete&gt;</code>
which is ill-formed if <code class='backtick'>Incomplete</code> is an incomplete class type.
</p>

<p>
I think we need the element type to be complete to be able to give an answer.
Alternatively, if the intended result for an array of unknown bound is false
(maybe because there can be no objects of type <code class='backtick'>T[]</code>, or because we can't
know that two objects declared as <code class='backtick'>extern T a[];</code> and <code class='backtick'>extern T b[];</code> have
the same number of elements?) then the condition for the trait needs to be
special-cased as <code class='backtick'>false</code> for arrays of unknown bound.
The current spec is inconsistent, we can't allow arrays of unknown bound
and apply the current rules to determine the trait's result.
</p>

<p><i>[2024-08-02; Reflector poll]</i></p>

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



<p id="res-4113"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4981" title=" Working Draft, Programming Languages — C++">N4981</a>.
</p>

<ol>
<li><p>Modify 21.3.5.4 <a href="https://wg21.link/meta.unary.prop">[meta.unary.prop]</a> as indicated:</p>

<blockquote>
<table style="border: 1px solid; border-spacing: 1.5em">
<thead style="text-align: center">
<tr><th>Template</th><th>Condition</th><th>Preconditions</th></tr>
</thead>
<tbody style="vertical-align: top">
<tr><td>&hellip;</td><td>&hellip;</td><td>&hellip;</td></tr>
<tr>
<td>
<pre><code>template&lt;class T&gt;
struct has_unique_object_representations;</code></pre>
</td>
<td>
For an array type <code class='backtick'>T</code>, the same result as
<code>has_unique_object_representations_v&lt;remove_all_extents_t&lt;T&gt;&gt;</code>,
otherwise <i>see below</i>.
</td>
<td>
<ins><code>remove_all_extents_t&lt;T&gt;</code></ins>
<del><code>T</code></del>
shall be a complete type<del>,</del>
<ins>or</ins> <i>cv</i> <code class='backtick'>void</code><del>, or an array of unknown bound</del>.
</td>
</tr>
</tbody>
</table>
</blockquote>
<blockquote class="note">
<p>
[<i>Drafting note</i>: We could use <code>remove_extent_t&lt;T&gt;</code>
to remove just the first array dimension, because only that first one can
have an unknown bound.
The proposed resolution uses <code>remove_all_extents_t&lt;T&gt;</code>
for consistency with the <b>Condition</b> column.]
</p>
</blockquote>

</li>
</ol>





<hr>
<h3 id="4119"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4119">4119</a>. <code>generator::promise_type::yield_value(ranges::elements_of&lt;R, Alloc&gt;)</code>'s nested <code>generator</code> may be ill-formed</h3>
<p><b>Section:</b> 25.8.5 <a href="https://wg21.link/coro.generator.promise">[coro.generator.promise]</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> 2024-07-11 <b>Last modified:</b> 2024-08-02</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#coro.generator.promise">active issues</a> in [coro.generator.promise].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#coro.generator.promise">issues</a> in [coro.generator.promise].</p>
<p><b>Discussion:</b></p>
<p>
The nested coroutine is specified to return <code>generator&lt;yielded, ranges::range_value_t&lt;R&gt;, Alloc&gt;</code> 
which can be problematic as the value type of <code>R</code> is really irrelevant to <code>yielded</code>, 
unnecessarily violating the <code>generator</code>'s <i>Mandates</i> (<a href="https://godbolt.org/z/PzGP3G7rr">demo</a>):
</p>
<blockquote><pre>
#include &lt;generator&gt;
#include &lt;vector&gt;

std::generator&lt;std::span&lt;int&gt;&gt; f() {
  std::vector&lt;int&gt; v;
  co_yield v; // ok
}

std::generator&lt;std::span&lt;int&gt;&gt; g() {
  std::vector&lt;std::vector&lt;int&gt;&gt; v;
  co_yield std::ranges::elements_of(v); // <span style="color:red;font-weight:bolder">hard error</span>
}
</pre></blockquote>
<p>
This proposed resolution is to change the second template parameter from <code>range_value_t&lt;R&gt;</code> 
to <code>void</code> since that type doesn't matter to us.
</p>

<p><i>[2024-08-02; Reflector poll]</i></p>

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



<p id="res-4119"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4986" title=" Working Draft, Programming Languages — C++">N4986</a>.
</p>
<ol>
<li><p>Modify 25.8.5 <a href="https://wg21.link/coro.generator.promise">[coro.generator.promise]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;ranges::input_range R, class Alloc&gt;
  requires convertible_to&lt;ranges::range_reference_t&lt;R&gt;, yielded&gt;
  auto yield_value(ranges::elements_of&lt;R, Alloc&gt; r);
</pre>
<blockquote>
<p>
-13- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
auto nested = [](allocator_arg_t, Alloc, ranges::iterator_t&lt;R&gt; i, ranges::sentinel_t&lt;R&gt; s)
  -&gt; generator&lt;yielded, <del>ranges::range_value_t&lt;R&gt;</del><ins>void</ins>, Alloc&gt; {
    for (; i != s; ++i) {
      co_yield static_cast&lt;yielded&gt;(*i);
    }
  };
return yield_value(ranges::elements_of(nested(
  allocator_arg, r.allocator, ranges::begin(r.range), ranges::end(r.range))));
</pre></blockquote>
[&hellip;]
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4124"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4124">4124</a>. Cannot format <code class='backtick'>zoned_time</code> with resolution coarser than seconds</h3>
<p><b>Section:</b> 30.12 <a href="https://wg21.link/time.format">[time.format]</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> 2024-07-26 <b>Last modified:</b> 2024-08-02</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#time.format">active issues</a> in [time.format].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#time.format">issues</a> in [time.format].</p>
<p><b>Discussion:</b></p>
<p>
The
<code>std::formatter&lt;std::chrono::zoned_time&lt;Duration, TimeZonePtr&gt;&gt;</code>
specialization calls <code class='backtick'>tp.get_local_time()</code> for the object it passes to its
base class' <code class='backtick'>format</code> function. But <code class='backtick'>get_local_time()</code> does not return a
<code>local_time&lt;Duration&gt;</code>, it returns
<code>local_time&lt;common_type_t&lt;Duration, seconds&gt;&gt;</code>.
The base class' <code class='backtick'>format</code> function is only defined for
<code>local_time&lt;Duration&gt;</code>.
That means this is ill-formed, even though the static assert passes:
<pre><code>using namespace std::chrono;
  static_assert( std::formattable&lt;zoned_time&lt;minutes&gt;, char&gt; );
  zoned_time&lt;minutes&gt; zt;
  (void) std::format("{}", zt); // error: cannot convert local_time&lt;seconds&gt; to local_time&lt;minutes&gt;
</code></pre>
</p>

<p>
Additionally, it's not specified what output you should get for:
<pre><code><code class='backtick'>std::format("{}", local_time_format(zt.get_local_time()));</code>
</code></pre>
30.12 <a href="https://wg21.link/time.format">[time.format]</a> p7 says it's formatted as if by streaming to an
<code class='backtick'>ostringstream</code>,
but there is no <code>operator&lt;&lt;</code> for <i><code class='backtick'>local-time-format-t</code></i>.
Presumably it should give the same result as <code>operator&lt;&lt;</code> for 
a <code class='backtick'>zoned_time</code>, i.e. <code class='backtick'>"{:L%F %T %Z}"</code> with padding adjustments etc.
</p>
<p>
The proposed resolution below has been implemented in libstdc++.
</p>

<p><i>[2024-08-02; Reflector poll]</i></p>

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



<p id="res-4124"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4986" title=" Working Draft, Programming Languages — C++">N4986</a>.
</p>

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

<blockquote>
<pre>
template&lt;classDuration, class charT&gt;
  struct formatter&lt;chrono::<i>local-time-format-t</i>&lt;Duration&gt;, charT&gt;;
</pre>
<p>-17-
Let <code class='backtick'>f</code> be a <code><i>locale-time-format-t</i>&lt;Duration&gt;</code> object
passed to <code class='backtick'>formatter::format</code>.
</p>
<p>-18- <i>Remarks</i>:
<ins>If the <i>chrono-specs</i> is omitted, the result is equivalent to
using <code class='backtick'>%F %T %Z</code> as the <i>chrono-specs</i>.</ins>
If <code class='backtick'>%Z</code> is used,
it is replaced with <code class='backtick'>*f.abbrev</code> if <code class='backtick'>f.abbrev</code> is not a null pointer value.
If <code class='backtick'>%Z</code> is used and <code class='backtick'>f.abbrev</code> is a null pointer value,
an exception of type <code class='backtick'>format_error</code> is thrown.
If <code class='backtick'>%z</code> (or a modified variant of <code class='backtick'>%z</code>) is used,
it is formatted with the value of <code class='backtick'>*f.offset_sec</code> if <code class='backtick'>f.offset_sec</code> is
not a null pointer value.
If <code class='backtick'>%z</code> (or a modified variant of <code class='backtick'>%z</code>) is used and <code class='backtick'>f.offset_sec</code>
is a null pointer value, then an exception of type <code class='backtick'>format_error</code> is thrown.
</p>
<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;<ins>common_type_t&lt;</ins>Duration<ins>, seconds&gt;</ins>&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) const;
  };
</pre>
<pre>
template&lt;class FormatContext&gt;
  typename FormatContext::iterator
    format(const chrono::zoned_time&lt;Duration, TimeZonePtr&gt;&amp; tp, FormatContext&amp; ctx) const;
</pre>
<p>-19- <i>Effects</i>: Equivalent to:
<blockquote>
<pre>
sys_info info = tp.get_info();
return formatter&lt;chrono::<i>local-time-format-t</i>&lt;<ins>common_type_t&lt;</ins>Duration<ins>, seconds&gt;</ins>&gt;, charT&gt;::
         format({tp.get_local_time(), &amp;info.abbrev, &amp;info.offset}, ctx);
</pre>
</blockquote>
</p>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4126"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4126">4126</a>. Some feature-test macros for fully freestanding features are not yet marked freestanding</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> Jiang An <b>Opened:</b> 2024-07-24 <b>Last modified:</b> 2024-08-02</p>
<p><b>Priority: </b>2
</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>
Currently (<a href="https://wg21.link/N4986" title=" Working Draft, Programming Languages — C++">N4986</a>), it's a bit weird in 17.3.2 <a href="https://wg21.link/version.syn">[version.syn]</a> that some feature-test
macros are not marked freestanding, despite the indicated features being fully freestanding. The 
freestanding status seems sometimes implicitly covered by "also in" headers that are mostly or all 
freestanding, but sometimes not.
<p/>
I think it's more consistent to ensure feature-test macros for fully freestanding features are also freestanding.
</p>

<p><i>[2024-08-02; Reflector poll]</i></p>

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



<p id="res-4126"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4986" title=" Working Draft, Programming Languages — C++">N4986</a>.
</p>

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

<blockquote class="note">
<p>
[<i>Drafting note</i>:  <code>&lt;charconv&gt;</code> is not fully freestanding, but all functions made <code>constexpr</code> 
by <a href="https://wg21.link/P2291R3" title=" Add Constexpr Modifiers to Functions to_chars and from_chars for Integral Types in Header">P2291R3</a> are furtherly made freestanding by <a href="https://wg21.link/P2338R4" title=" Freestanding Library: Character primitives and the C library">P2338R4</a>. ]
</p>
</blockquote>

<blockquote>
<pre>
[&hellip;]
#define __cpp_lib_common_reference                  202302L // <i><ins>freestanding,</ins> also in</i> &lt;type_traits&gt;
#define __cpp_lib_common_reference_wrapper          202302L // <i><ins>freestanding,</ins> also in</i> &lt;functional&gt;
[&hellip;]                                                                              
#define __cpp_lib_constexpr_charconv                202207L // <i><ins>freestanding,</ins> also in</i> &lt;charconv&gt;
[&hellip;]                                                                              
#define __cpp_lib_coroutine                         201902L // <i><ins>freestanding,</ins> also in</i> &lt;coroutine&gt;
[&hellip;]                                                                              
#define __cpp_lib_is_implicit_lifetime              202302L // <i><ins>freestanding,</ins> also in</i> &lt;type_traits&gt;
[&hellip;]                                                                              
#define __cpp_lib_is_virtual_base_of                202406L // <i><ins>freestanding,</ins> also in</i> &lt;type_traits&gt;
[&hellip;]                                                                              
#define __cpp_lib_is_within_lifetime                202306L // <i><ins>freestanding,</ins> also in</i> &lt;type_traits&gt;
[&hellip;]                                                                              
#define __cpp_lib_mdspan                            202406L // <i><ins>freestanding,</ins> also in</i> &lt;mdspan&gt;
[&hellip;]                                                                              
#define __cpp_lib_ratio                             202306L // <i><ins>freestanding,</ins> also in</i> &lt;ratio&gt;
[&hellip;]                                                                              
#define __cpp_lib_span_initializer_list             202311L // <i><ins>freestanding,</ins> also in</i> &lt;span&gt;
[&hellip;]                                                                              
#define __cpp_lib_submdspan                         202403L // <i><ins>freestanding,</ins> also in</i> &lt;mdspan&gt;
[&hellip;]                                                                              
#define __cpp_lib_to_array                          201907L // <i><ins>freestanding,</ins> also in</i> &lt;array&gt;
[&hellip;]
</pre>
</blockquote>

</li>

</ol>





<hr>
<h3 id="4135"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4135">4135</a>. The helper lambda of <code>std::erase</code> for <code>list</code> should specify return type as
  <code>bool</code></h3>
<p><b>Section:</b> 23.3.7.7 <a href="https://wg21.link/forward.list.erasure">[forward.list.erasure]</a>, 23.3.9.6 <a href="https://wg21.link/list.erasure">[list.erasure]</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> 2024-08-07 <b>Last modified:</b> 2024-08-21</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
<code>std::erase</code> for <code>list</code> is specified to return
<code>erase_if(c, [&amp;](auto&amp; elem) { return elem == value; })</code>.
However, the template parameter <code>Predicate</code> of <code>erase_if</code> only requires that the
type of <code>decltype(pred(...))</code> satisfies <code><i>boolean-testable</i></code>, i.e., the
return type of <code>elem == value</code> is not necessarily <code>bool</code>.
<p/>
This means it's worth explicitly specifying the lambda's return type as <code>bool</code> to avoid some 
pedantic cases (<a href="https://godbolt.org/z/xPvYYnvY6">demo</a>):
</p>
<blockquote><pre>
#include &lt;list&gt;

struct Bool {
  Bool(const Bool&amp;) = delete;
  operator bool() const;
};

struct Int {
  Bool&amp; operator==(Int) const;
};

int main() {
  std::list&lt;Int&gt; l;
  std::erase(l, Int{}); // <span  style="color:#C80000;font-weight:bold">unnecessary hard error</span>
}
</pre></blockquote>

<p><i>[2024-08-21; Reflector poll]</i></p>

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



<p id="res-4135"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

<ol>

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

<blockquote>
<pre>
template&lt;class T, class Allocator, class U = T&gt;
  typename forward_list&lt;T, Allocator&gt;::size_type
    erase(forward_list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<blockquote>
<p>
-1- <i>Effects</i>: Equivalent to:
  <code>return erase_if(c, [&amp;](<ins>const</ins> auto&amp; elem) <ins>-&gt; bool</ins> { return elem == value; });</code>
</p>
</blockquote>
</blockquote>
</li>

<li><p>Modify 23.3.9.6 <a href="https://wg21.link/list.erasure">[list.erasure]</a> as indicated:</p>

<blockquote>
<pre>
template&lt;class T, class Allocator, class U = T&gt;
  typename list&lt;T, Allocator&gt;::size_type
    erase(list&lt;T, Allocator&gt;&amp; c, const U&amp; value);
</pre>
<blockquote>
<p>
-1- <i>Effects</i>: Equivalent to:
  <code>return erase_if(c, [&amp;](<ins>const</ins> auto&amp; elem) <ins>-&gt; bool</ins> { return elem == value; });</code>
</p>
</blockquote>
</blockquote>
</li>

</ol>





<hr>
<h3 id="4140"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4140">4140</a>. Useless default constructors for bit reference types</h3>
<p><b>Section:</b> 22.9.2.1 <a href="https://wg21.link/template.bitset.general">[template.bitset.general]</a>, 23.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> Jonathan Wakely <b>Opened:</b> 2024-08-21 <b>Last modified:</b> 2024-09-18</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>Discussion:</b></p>
<p>
The standard shows a private default constructor for
<code>bitset&lt;N&gt;::reference</code>
but does not define its semantics, and nothing in the spec refers to it.
It was present in C++98, then in C++11 it got <code class='backtick'>noexcept</code> added to it,
and in C++23 it was made <code class='backtick'>constexpr</code> by <a href="https://wg21.link/P2417R2" title=" A more constexpr bitset">P2417R2</a>. That's quite
a lot of churn for an unusuable member function with no definition.
</p>
<p>
In libstdc++ it's declared as private, but never defined.
In libc++ it doesn't exist at all.
In MSVC it is private and defined (and presumably used somewhere).
There's no reason for the standard to declare it.
Implementers can define it as private if they want to, or not.
The spec doesn't need to say anything for that to be true.
We can also remove the friend declaration, because implementers know how to
do that too.
</p>
<p>
I suspect it was added as private originally so that it didn't look like
<code class='backtick'>reference</code> should have an implicitly-defined default constructor,
which would have been the case in previous standards with no other
constructors declared.
However, C++20 added <code>reference(const reference&amp;) = default;</code>
which suppresses the implicit default constructor, so declaring the
default constructor as private is now unnecessary.
</p>
<p>
Jiang An pointed out in an editorial pull request that
<code>vector&lt;bool, Alloc&gt;::reference</code>
has exactly the same issue.
</p>

<p><i>[2024-09-18; Reflector poll]</i></p>

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



<p id="res-4140"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

<ol>
<li><p>Modify 22.9.2.1 <a href="https://wg21.link/template.bitset.general">[template.bitset.general]</a> as indicated:</p>
<blockquote>
<pre>
namespace std {
  template&lt;size_t N&gt; class bitset {
  public:
    <i>// bit reference</i>
    class reference {
      <del>friend class bitset;</del>
      <del>constexpr reference() noexcept;</del>

    public:
      constexpr reference(const reference&amp;) = default;
      constexpr ~reference();
      constexpr reference&amp; operator=(bool x) noexcept;            <i>// for</i> b[i] = x;
      constexpr reference&amp; operator=(const reference&amp;) noexcept;  <i>// for</i> b[i] = b[j];
      constexpr bool operator~() const noexcept;                  <i>// flips the bit</i>
      constexpr operator bool() const noexcept;                   <i>// for</i> x = b[i];
      constexpr reference&amp; flip() noexcept;                       <i>// for</i> b[i].flip();
    };
</pre>
</blockquote>
</li>

<li><p>Modify 23.3.12.1 <a href="https://wg21.link/vector.bool.pspc">[vector.bool.pspc]</a>, <code>vector&lt;bool, Allocator&gt;</code> synopsis, as indicated:</p>
<blockquote>
<pre>
namespace std {
  template&lt;class Allocator&gt;
  class vector&lt;bool, Allocator&gt; {
  public:
    <i>// types</i>
    [&hellip;]
    <i>// bit reference</i>
    class reference {
      <del>friend class vector;</del>
      <del>constexpr reference() noexcept;</del>

    public:
      constexpr reference(const reference&amp;) = default;
      constexpr ~reference();
      constexpr operator bool() const noexcept;
      constexpr reference&amp; operator=(bool x) noexcept;
      constexpr reference&amp; operator=(const reference&amp; x) noexcept;
      constexpr const reference&amp; operator=(bool x) const noexcept;
      constexpr void flip() noexcept;   <i>// flips the bit</i>
    };
</pre>
</blockquote>
</li>
</ol>






<hr>
<h3 id="4141"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4141">4141</a>. Improve prohibitions on "additional storage"</h3>
<p><b>Section:</b> 22.5.3.1 <a href="https://wg21.link/optional.optional.general">[optional.optional.general]</a>, 22.6.3.1 <a href="https://wg21.link/variant.variant.general">[variant.variant.general]</a>, 22.8.6.1 <a href="https://wg21.link/expected.object.general">[expected.object.general]</a>, 22.8.7.1 <a href="https://wg21.link/expected.void.general">[expected.void.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> 2024-08-22 <b>Last modified:</b> 2024-09-18</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#optional.optional.general">active issues</a> in [optional.optional.general].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#optional.optional.general">issues</a> in [optional.optional.general].</p>
<p><b>Discussion:</b></p>
<p>
This issue was split out from issue <a href="https://cplusplus.github.io/LWG/lwg-active.html#4015" title="LWG 3973 broke const overloads of std::optional monadic operations (Status: Open)">4015</a><sup><a href="https://cplusplus.github.io/LWG/issue4015" title="Latest snapshot">(i)</a></sup>.
</p>
<p>
<code class='backtick'>optional</code>, <code class='backtick'>variant</code> and <code class='backtick'>expected</code> all use similar wording to require
their contained value to be a subobject, rather than dynamically allocated
and referred to by a pointer, e.g.
<blockquote>
When an instance of <code>optional&lt;T&gt;</code> contains a value,
it means that an object of type <code>T</code>, referred to as the
optional object’s <i>contained value</i>,
is allocated within the storage of the optional object.
Implementations are not permitted to use additional storage,
such as dynamic memory, to allocate its contained value.
</blockquote>
</p>

<p>
During the LWG reviews of <a href="https://wg21.link/P2300" title=" `std::execution`">P2300</a> in St. Louis, concerns were
raised about the form of this wording and whether it's normatively meaningful.
Except for the special case of standard-layout class types, the standard has
very few requirements on where or how storage for subobjects is allocated.
The library should not be trying to dictate more than the language guarantees.
It would be better to refer to wording from 6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>
such as <i>subobject</i>, <i>provides storage</i>, or <i>nested within</i>.
Any of these terms would provide the desired properties, without using
different (and possibly inconsistent) terminology.
</p>
<p>
Using an array of bytes to <i>provide storage</i> for the contained value would
make it tricky to meet the constexpr requirements of types like <code class='backtick'>optional</code>.
This means in practice, the most restrictive of these terms, <i>subobject</i>,
is probably accurate and the only plausible implementation strategy.
However, I don't see any reason to outlaw other implementation strategies that
might be possible in future (say, with a constexpr type cast, or non-standard
compiler-specific instrinics).
For this reason, the proposed resolution below uses <i>nested within</i>,
which provides the desired guarantee without imposing additional restrictions
on implementations.
</p>

<p><i>[2024-09-18; Reflector poll]</i></p>

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



<p id="res-4141"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

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

<blockquote class="note">
[<i>Drafting note</i>:
This edit modifies the same paragraph as issue <a href="https://cplusplus.github.io/LWG/lwg-active.html#4015" title="LWG 3973 broke const overloads of std::optional monadic operations (Status: Open)">4015</a><sup><a href="https://cplusplus.github.io/LWG/issue4015" title="Latest snapshot">(i)</a></sup>,
but that other issue intentionally doesn't touch the affected sentence here
(except for removing the italics on "contained value").
The intention is that the merge conflict can be resolved in the obvious way:
"An optional object's contained value
is nested within (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>) the optional object."]
</blockquote>

<blockquote>
<p>
-1-
Any instance of <code>optional&lt;T&gt;</code> at any given time either
contains a value or does not contain a value.
When an instance of <code>optional&lt;T&gt;</code> <i>contains a value</i>,
it means that an object of type <code>T</code>,
referred to as the optional object's <i>contained value</i>,
is
<del>allocated within the storage of</del>
<ins>nested within (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>)</ins>
the optional object.
<del>
Implementations are not permitted to use additional storage,
such as dynamic memory, to allocate its contained value.
</del>
When an object of type <code>optional&lt;T&gt;</code>
is contextually converted to <code>bool</code>,
the conversion returns <code class='backtick'>true</code> if the object contains a value;
otherwise the conversion returns <code class='backtick'>false</code>.
</p>
</blockquote>
</li>

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

<blockquote>
<p>
-1-
Any instance of <code>variant</code> at any given time either
holds a value of one of its alternative types or holds no value.
When an instance of <code>variant</code> holds a value of alternative type <code class='backtick'>T</code>,
it means that a value of type <code>T</code>,
referred to as the <code class='backtick'>variant</code> object's <i>contained value</i>,
is
<del>allocated within the storage of</del>
<ins>nested within (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>)</ins>
the <code class='backtick'>variant</code> object.
<del>
Implementations are not permitted to use additional storage,
such as dynamic memory, to allocate the contained value.
</del>
</p>
</blockquote>
</li>

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

<blockquote>
<p>
-1-
Any object of type <code>expected&lt;T, E&gt;</code> either contains
a value of type <code class='backtick'>T</code> or a value of type <code class='backtick'>E</code>
<del>within its own storage</del>
<ins>nested within (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>) it</ins>.
<del>
Implementations are not permitted to use additional storage,
such as dynamic memory,
to allocate the object of type <code class='backtick'>T</code> or the object of type <code class='backtick'>E</code>.
</del>
Member <i><code>has_val</code></i> indicates whether the
<code>expected&lt;T, E&gt;</code> object contains an object of type <code class='backtick'>T</code>.
</p>
</blockquote>
</li>

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

<blockquote>
<p>
-1-
Any object of type <code>expected&lt;T, E&gt;</code> either represents
a value of type <code class='backtick'>T</code>, or contains a value of type <code class='backtick'>E</code>
<del>within its own storage</del>
<ins>nested within (6.7.2 <a href="https://wg21.link/intro.object">[intro.object]</a>) it</ins>.
<del>
Implementations are not permitted to use additional storage,
such as dynamic memory, to allocate the object of type <code class='backtick'>E</code>.
</del>
Member <i><code>has_val</code></i> indicates whether the
<code>expected&lt;T, E&gt;</code> represents a value of type <code class='backtick'>T</code>.
</p>
</blockquote>
</li>
</ol>






<hr>
<h3 id="4142"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4142">4142</a>. <code>format_parse_context::check_dynamic_spec</code> should require at least one type</h3>
<p><b>Section:</b> 28.5.6.6 <a href="https://wg21.link/format.parse.ctx">[format.parse.ctx]</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> 2024-08-28 <b>Last modified:</b> 2024-09-18</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#format.parse.ctx">issues</a> in [format.parse.ctx].</p>
<p><b>Discussion:</b></p>
<p>
The <i>Mandates</i>: conditions for <code class='backtick'>format_parse_context::check_dynamic_spec</code>
are:
<blockquote>
-14- <i>Mandates</i>:
The types in <code class='backtick'>Ts...</code> are unique. Each type in <code class='backtick'>Ts...</code> is one of <code class='backtick'>bool</code>,
<code class='backtick'>char_type</code>, <code class='backtick'>int</code>, <code class='backtick'>unsigned int</code>, <code class='backtick'>long long int</code>, <code class='backtick'>unsigned long long int</code>,
<code class='backtick'>float</code>, <code class='backtick'>double</code>, <code class='backtick'>long double</code>, <code class='backtick'>const char_type*</code>,
<code>basic_string_view&lt;char_type&gt;</code>, or <code class='backtick'>const void*</code>.
</blockquote>
</p>
<p>
There seems to be no reason to allow <code class='backtick'>Ts</code> to be an empty pack,
that's not useful. There is no valid arg-id value that can be passed to it
if the list of types is empty, since <code class='backtick'>arg(n)</code> will never be one of the types
in an empty pack. So it's never a constant expression if the pack is empty.
</p>

<p><i>[2024-09-18; Reflector poll]</i></p>

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



<p id="res-4142"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

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

<pre><code>template&lt;class... Ts&gt;
  constexpr void check_dynamic_spec(size_t id) noexcept;
</code></pre>
<blockquote>
<p>
-14- <i>Mandates</i>:
<ins><code class='backtick'>sizeof...(Ts)</code> &ge; 1.</ins>
The types in <code class='backtick'>Ts...</code> are unique. Each type in <code class='backtick'>Ts...</code> is one of <code class='backtick'>bool</code>,
<code class='backtick'>char_type</code>, <code class='backtick'>int</code>, <code class='backtick'>unsigned int</code>, <code class='backtick'>long long int</code>, <code class='backtick'>unsigned long long int</code>,
<code class='backtick'>float</code>, <code class='backtick'>double</code>, <code class='backtick'>long double</code>, <code class='backtick'>const char_type*</code>,
<code>basic_string_view&lt;char_type&gt;</code>, or <code class='backtick'>const void*</code>.
</p>
<p>
-15- <i>Remarks</i>:
A call to this function is a core constant expression only if:
<ol style="list-style-type: none">
<li>(15.1) &mdash; <code>id &lt; num_args_</code> is <code class='backtick'>true</code> and</li>
<li>(15.2) &mdash; the type of the corresponding format argument
(after conversion to <code>basic_format_arg&lt;Context&gt;</code>)
is one of the types in <code class='backtick'>Ts...</code>.</li>
</ol>
</p>
</blockquote>
</li>
</ol>






<hr>
<h3 id="4144"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4144">4144</a>. Disallow <code>unique_ptr&lt;T&amp;, D&gt;</code></h3>
<p><b>Section:</b> 20.3.1.3.1 <a href="https://wg21.link/unique.ptr.single.general">[unique.ptr.single.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> 2024-08-30 <b>Last modified:</b> 2024-11-13</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#unique.ptr.single.general">issues</a> in [unique.ptr.single.general].</p>
<p><b>Discussion:</b></p>
<p>
It seems that we currently allow nonsensical specializations of <code class='backtick'>unique_ptr</code>
such as <code>unique_ptr&lt;int&amp;, D&gt;</code>
and <code>unique_ptr&lt;void()const, D&gt;</code>
(a custom deleter that defines <code class='backtick'>D::pointer</code> is needed, because otherwise
the <code class='backtick'>pointer</code> type would default to invalid types like
<code>int&amp;*</code> or <code>void(*)()const</code>).
There seems to be no reason to support these "unique pointer to reference"
and "unique pointer to abominable function type" specializations,
or any specialization for a type that you couldn't form a raw pointer to.
</p>

<p>
Prior to C++17, the major library implementations rejected such specializations
as a side effect of the constraints for the
<code>unique_ptr(auto_ptr&lt;U&gt;&amp;&amp;)</code> constructor
being defined in terms of <code>is_convertible&lt;U*, T*&gt;</code>.
This meant that overload resolution for any constructor of <code class='backtick'>unique_ptr</code>
would attempt to form the type <code class='backtick'>T*</code> and fail if that was invalid.
With the removal of <code class='backtick'>auto_ptr</code> in C++17, that constructor was removed
and now <code>unique_ptr&lt;int&amp;, D&gt;</code> can be instantiated
(assuming any zombie definition of <code class='backtick'>auto_ptr</code> is not enabled by the library).
This wasn't intentional, but just an accident caused by not explicitly
forbidding such types.
</p>

<p>
Discussion on the LWG reflector led to near-unanimous support for explicitly
disallowing these specializations for non-pointable types.
</p>

<p><i>[2024-11-13; Reflector poll]</i></p>

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



<p id="res-4144"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

<ol>
<li><p>Modify 20.3.1.3.1 <a href="https://wg21.link/unique.ptr.single.general">[unique.ptr.single.general]</a> as indicated:</p>
<blockquote>
<p><ins>-?-
A program that instantiates the definition of
<code>unique_ptr&lt;T, D&gt;</code>
is ill-formed if <code class='backtick'>T*</code> is an invalid type.
<br/>
[<em>Note</em>:
This prevents the intantiation of specializations such as
<code>unique_ptr&lt;T&amp;, D&gt;</code>
and <code>unique_ptr&lt;int() const, D&gt;</code>.
&mdash; <em>end note</em>]
</ins>
</p>
<p>-1-
The default type for the template parameter <code class='backtick'>D</code> is <code class='backtick'>default_delete</code>.
A client-supplied template argument <code class='backtick'>D</code> shall be a function object type
(22.10 <a href="https://wg21.link/function.objects">[function.objects]</a>), lvalue reference to function,
or lvalue reference to function object type for which,
given a value <code class='backtick'>d</code> of type <code class='backtick'>D</code> and a value <code class='backtick'>ptr</code> of type
<code>unique_ptr&lt;T, D&gt;::pointer</code>,
the expression <code class='backtick'>d(ptr)</code> is valid and has the effect of disposing of the pointer
as appropriate for that deleter.
</p>
<p>-2-
If the deleter’s type <code class='backtick'>D</code> is not a reference type,
<code class='backtick'>D</code> shall meet the <em>Cpp17Destructible</em> requirements (Table 35).
</p>
<p>-3-
If the <i>qualified-id</i> <code>remove_reference_t&lt;D&gt;::pointer</code>
is valid and denotes a type (13.10.3 <a href="https://wg21.link/temp.deduct">[temp.deduct]</a>),
then <code>unique_ptr&lt;T, D&gt;::pointer</code>
shall be a synonym for <code>remove_reference_t&lt;D&gt;::pointer</code>.
Otherwise <code>unique_ptr&lt;T, D&gt;::pointer</code> shall be a synonym for
<code>element_type*</code>.
The type <code>unique_ptr&lt;T, D&gt;::pointer</code> shall meet the
<em>Cpp17NullablePointer</em> requirements (Table 36).
</p>
<p>-4-
[<em>Example 1</em>:
 Given an allocator type <code class='backtick'>X</code> (16.4.4.6.1 <a href="https://wg21.link/allocator.requirements.general">[allocator.requirements.general]</a>)
and letting <code class='backtick'>A</code> be a synonym for <code>allocator_traits&lt;X&gt;</code>,
the types <code class='backtick'>A::pointer</code>, <code class='backtick'>A::const_pointer</code>, <code class='backtick'>A::void_pointer</code>,
and <code class='backtick'>A::const_void_pointer</code> may be used as
<code>unique_ptr&lt;T, D&gt;::pointer</code>.
&mdash; <em>end example</em>]
</p>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4147"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4147">4147</a>. Precondition on <code>inplace_vector::emplace</code></h3>
<p><b>Section:</b> 23.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> Arthur O'Dwyer <b>Opened:</b> 2024-08-26 <b>Last modified:</b> 2024-09-18</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>
Inserting into the middle of an <code>inplace_vector</code>, just like inserting into the middle of a 
<code>vector</code> or <code>deque</code>, requires that we construct the new element out-of-line, shift 
down the trailing elements (<i>Cpp17MoveAssignable</i>), and then move-construct the new element 
into place (<i>Cpp17MoveInsertable</i>). <a href="https://wg21.link/P0843R14" title=" inplace_vector">P0843R14</a> failed to make this change, but 
it should have.
</p>

<p><i>[2024-09-18; Reflector poll]</i></p>

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



<p id="res-4147"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

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

<blockquote><pre>
a.emplace(p, args)
</pre>
<blockquote>
<p>
-19- <i>Result</i>: <code>iterator</code>.
<p/>
-20- <i>Preconditions</i>: <code>T</code> is <i>Cpp17EmplaceConstructible</i> into <code>X</code> 
from <code>args</code>. For <code>vector</code><ins>, inplace_vector,</ins> and <code>deque</code>, 
<code>T</code> is also <i>Cpp17MoveInsertable</i> into <code>X</code> and <i>Cpp17MoveAssignable</i>.
<p/>
-21- <i>Effects</i>: Inserts an object of type <code>T</code> constructed with 
<code>std::forward&lt;Args&gt;(args)...</code> before <code>p</code>.
<p/>
[<i>Note 1</i>: <code>args</code> can directly or indirectly refer to a value in <code>a</code>. 
&mdash; <i>end note</i>]
<p/>
-22- <i>Returns</i>: An iterator that points to the new element constructed from <code>args</code> 
into <code>a</code>.
</p>
</blockquote>
</blockquote>
</li>

</ol>






<hr>
<h3 id="4148"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4148">4148</a>. <code>unique_ptr::operator*</code> should not allow dangling references</h3>
<p><b>Section:</b> 20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Jonathan Wakely <b>Opened:</b> 2024-09-02 <b>Last modified:</b> 2024-09-18</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#unique.ptr.single.observers">active issues</a> in [unique.ptr.single.observers].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#unique.ptr.single.observers">issues</a> in [unique.ptr.single.observers].</p>
<p><b>Discussion:</b></p>
<p>
If <code>unique_ptr&lt;T,D&gt;::element_type*</code> and <code>D::pointer</code>
are not the same type, it's possible for <code class='backtick'>operator*()</code> to return a dangling
reference that has undefined behaviour.
</p>
<pre><code>
  struct deleter {
    using pointer = long*;
    void operator()(pointer) const {}
  };
  long l = 0;
  std::unique_ptr&lt;const int, deleter&gt; p(&amp;l);
  int i = *p; <i><strong>// undefined</strong></i>
</code></pre>
<p>
We should make this case ill-formed.
</p>

<p><i>[2024-09-18; Reflector poll]</i></p>

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



<p id="res-4148"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>
<ol>
<li><p>Modify 20.3.1.3.5 <a href="https://wg21.link/unique.ptr.single.observers">[unique.ptr.single.observers]</a> as indicated:</p>
<blockquote>
<pre>
constexpr add_lvalue_reference_t&lt;T&gt; operator*() const noexcept(noexcept(*declval&lt;pointer&gt;()));
</pre>
<blockquote>
<p>
<ins>-?- <i>Mandates</i>:
<code>reference_converts_from_temporary_v&lt;add_lvalue_reference_t&lt;T&gt;,
decltype(*declval&lt;pointer&gt;())&gt;</code>
is <code class='backtick'>false</code>.
</ins>
</p>
<p>
-1- <i>Preconditions</i>: <code class='backtick'>get() != nullptr</code> <ins>is <code class='backtick'>true</code></ins>.
</p>
<p>
-2- <i>Returns</i>: <code class='backtick'>*get()</code>.
</p>
</blockquote>
</blockquote>
</li>
</ol>





<hr>
<h3 id="4153"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4153">4153</a>. Fix extra "-1" for <code>philox_engine::max()</code></h3>
<p><b>Section:</b> 29.5.4.5 <a href="https://wg21.link/rand.eng.philox">[rand.eng.philox]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Ruslan Arutyunyan <b>Opened:</b> 2024-09-18 <b>Last modified:</b> 2024-10-02</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#rand.eng.philox">active issues</a> in [rand.eng.philox].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#rand.eng.philox">issues</a> in [rand.eng.philox].</p>
<p><b>Discussion:</b></p>
<p>
There is a typo in <code class='backtick'>philox_engine</code> wording that makes "-1" two times
instead of one for <code class='backtick'>max()</code> method.
The reason for that typo is that the wording was originally inspired by
<code class='backtick'>mersenne_twister_engine</code> but after getting feedback that what is written in
the <code class='backtick'>philox_engine</code> synopsis is not C++ code, the authors introduced the
<i>m</i> variable (as in <code class='backtick'>subtract_with_carry_engine</code>) but forgot to remove
"-1" in the <i>m</i> definition.
</p>
<p>
Note: after the proposed resolution below is applied the <i>m</i> variable
could be reused in other places: basically in all places where the <code class='backtick'>mod  2^w</code>
pattern appears (like <code class='backtick'>subtract_with_carry_engine</code> does).
The authors don’t think it’s worth changing the rest of the wording to reuse
the <i>m</i> variable.
If somebody thinks otherwise, please provide such feedback.
</p>

<p><i>[2024-10-02; Reflector poll]</i></p>

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



<p id="res-4153"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>

<ol>
<li><p>Modify 29.5.4.5 <a href="https://wg21.link/rand.eng.philox">[rand.eng.philox]</a> as indicated:</p>
<blockquote>
-1-
A <code class='backtick'>philox_engine</code> random number engine produces unsigned integer random numbers
in the <del>closed</del> interval [0, <i>m</i><del>]</del><ins>)</ins>,
where <i>m</i> = 2<sup><i>w</i></sup><del> − 1</del>
and the template parameter <i>w</i> defines the range of the produced numbers.
</blockquote>
</li>
</ol>






<hr>
<h3 id="4157"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4157">4157</a>. The resolution of LWG3465 was damaged by P2167R3</h3>
<p><b>Section:</b> 17.11.6 <a href="https://wg21.link/cmp.alg">[cmp.alg]</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> 2024-09-18 <b>Last modified:</b> 2024-10-02</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View other</b> <a href="https://cplusplus.github.io/LWG/lwg-index-open.html#cmp.alg">active issues</a> in [cmp.alg].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#cmp.alg">issues</a> in [cmp.alg].</p>
<p><b>Discussion:</b></p>
<p>
In the resolution of LWG <a href="https://cplusplus.github.io/LWG/lwg-defects.html#3465" title="compare_partial_order_fallback requires F &lt; E (Status: C++23)">3465</a><sup><a href="https://cplusplus.github.io/LWG/issue3465" title="Latest snapshot">(i)</a></sup>,
<code>F &lt; E</code> was required to be well-formed and
implicitly convertible to <code class='backtick'>bool</code>.
However, <a href="https://wg21.link/P2167R3" title=" Improved Proposed Wording for LWG 2114 (contextually convertible to bool)">P2167R3</a> replaced the convertibility requirements
with just "each of <code class='backtick'>decltype(E == F)</code> and <code>decltype(E &lt; F)</code>
models <i><code class='backtick'>boolean-testable</code></i>",
which rendered the type of <code>F &lt; E</code> underconstrained.
</p>

<p><i>[2024-10-02; Reflector poll]</i></p>

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



<p id="res-4157"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4988" title=" Working Draft, Programming Languages — C++">N4988</a>.
</p>
<ol>
<li><p>Modify 17.11.6 <a href="https://wg21.link/cmp.alg">[cmp.alg]</a> as indicated:</p>
<blockquote>
(6.3) &mdash;
Otherwise, if the expressions
<code>E == F</code>, <code>E &lt; F</code>, and <code>F &lt; E</code>
are all well-formed and each of <code class='backtick'>decltype(E == F)</code>
<del>and</del><ins>,</ins>
<code>decltype(E &lt; F)</code>
<ins>, and <code>decltype(F &lt; E)</code></ins>
models <i><code class='backtick'>boolean-testable</code></i>,
<pre><code>
  E == F ? partial_ordering::equivalent :
  E &lt; F  ? partial_ordering::less :
  F &lt; E  ? partial_ordering::greater :
           partial_ordering::unordered
</code></pre>
except that <code class='backtick'>E</code> and <code class='backtick'>F</code> are evaluated only once.
</blockquote>
</li>
</ol>





<hr>
<h3 id="4169"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4169">4169</a>. <code>std::atomic&lt;T&gt;</code>'s default constructor should be constrained</h3>
<p><b>Section:</b> 32.5.8.2 <a href="https://wg21.link/atomics.types.operations">[atomics.types.operations]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Giuseppe D'Angelo <b>Opened:</b> 2024-10-15 <b>Last modified:</b> 2024-11-13</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.types.operations">active issues</a> in [atomics.types.operations].</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#atomics.types.operations">issues</a> in [atomics.types.operations].</p>
<p><b>Discussion:</b></p>
<p>
The current wording for <code class='backtick'>std::atomic</code>'s default constructor in
32.5.8.2 <a href="https://wg21.link/atomics.types.operations">[atomics.types.operations]</a> specifies:
</p>
<blockquote>
<pre>
constexpr atomic() noexcept(is_nothrow_default_constructible_v&lt;T&gt;);
</pre>
<blockquote>
<p>
<i>Mandates</i>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>.
</p>
</blockquote>
</blockquote>
<p>
This wording has been added by <a href="https://wg21.link/P0883R2" title=" Fixing Atomic Initialization">P0883R2</a> for C++20, which changed
<code class='backtick'>std::atomic</code>'s default constructor to always value-initialize. Before,
the behavior of this constructor was not well specified (this was LWG
issue <a href="https://cplusplus.github.io/LWG/lwg-defects.html#2334" title="atomic's default constructor requires &quot;uninitialized&quot; state even for types with non-trivial default-constructor (Status: Resolved)">2334</a><sup><a href="https://cplusplus.github.io/LWG/issue2334" title="Latest snapshot">(i)</a></sup>).
<p/>
The usage of a <i>Mandates</i> element in the specification has as a
consequence that <code>std::atomic&lt;T&gt;</code> is always default constructible, even
when <code>T</code> is not. For instance:
</p>
<blockquote>
<pre>
// not default constructible:
struct NDC { NDC(int) {} };

static_assert(std::is_default_constructible&lt;std::atomic&lt;NDC&gt;&gt;); // OK
</pre>
</blockquote>
<p>
The above check is OK as per language rules, but this is user-hostile:
actually using <code>std::atomic&lt;NDC&gt;</code>'s default constructor results in an
error, despite the detection saying otherwise.
<p/>
Given that <code>std::atomic&lt;T&gt;</code> already requires <code>T</code> to be complete anyhow
(32.5.8.1 <a href="https://wg21.link/atomics.types.generic.general">[atomics.types.generic.general]</a> checks for various type properties
which require completeness) it would be more appropriate to use a
constraint instead, so that <code>std::atomic&lt;T&gt;</code> is default constructible if
and only if <code>T</code> also is.
</p>

<p><i>[2024-11-13; Reflector poll]</i></p>

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



<p id="res-4169"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4993" title=" Working Draft, Programming Languages — C++">N4993</a>.
</p>

<ol>
<li><p>Modify 32.5.8.2 <a href="https://wg21.link/atomics.types.operations">[atomics.types.operations]</a> as indicated:</p>

<blockquote class="note">
<p>
[<i>Drafting note</i>: There is implementation divergence at the moment; libstdc++ already
implements the proposed resolution and has done so for a while.]
</p>
</blockquote>

<blockquote>
<pre>
constexpr atomic() noexcept(is_nothrow_default_constructible_v&lt;T&gt;);
</pre>
<blockquote>
<p>
-1- <i><ins>Constraints</ins><del>Mandates</del></i>: <code>is_default_constructible_v&lt;T&gt;</code> is <code>true</code>.
<p/>
-2- <i>Effects</i>: [&hellip;]
</p>
</blockquote>
</blockquote>

</li>
</ol>




<hr>
<h3 id="4170"><a href="https://cplusplus.github.io/LWG/lwg-active.html#4170">4170</a>. <code class='backtick'>contiguous_iterator</code> should require <code class='backtick'>to_address(I{})</code></h3>
<p><b>Section:</b> 24.3.4.14 <a href="https://wg21.link/iterator.concept.contiguous">[iterator.concept.contiguous]</a> <b>Status:</b> <a href="https://cplusplus.github.io/LWG/lwg-active.html#Ready">Tentatively Ready</a>
 <b>Submitter:</b> Casey Carter <b>Opened:</b> 2024-11-01 <b>Last modified:</b> 2024-11-13</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="https://cplusplus.github.io/LWG/lwg-index.html#iterator.concept.contiguous">issues</a> in [iterator.concept.contiguous].</p>
<p><b>Discussion:</b></p>
<p>
The design intent of the <code class='backtick'>contiguous_iterator</code> concept is that iterators can be converted
to pointers denoting the same sequence of elements. This enables a common range <code class='backtick'>[i, j)</code>
or counted range <code class='backtick'>i + [0, n)</code> to be processed with extremely efficient low-level C
or assembly code that operates on <code class='backtick'>[to_address(i), to_address(j))</code> (respectively
<code class='backtick'>to_address(i) + [0, n)</code>).
</p><p>
A value-initialized iterator <code class='backtick'>I{}</code> can be used to denote the empty ranges <code class='backtick'>[I{}, I{})</code>
and <code class='backtick'>I{} + [0, 0)</code>. While the existing semantic requirements of <code class='backtick'>contiguous_iterator</code> enable us
to convert both dereferenceable and past-the-end iterators with <code class='backtick'>to_address</code>, converting
ranges involving value-initialized iterators to pointer ranges additionally needs
<code class='backtick'>to_address(I{})</code> to be well-defined. Note that <code class='backtick'>to_address</code> is already implicitly
equality-preserving for <code class='backtick'>contiguous_iterator</code> arguments. Given this additional requirement
<code class='backtick'>to_address(I{}) == to_address(I{})</code> and <code class='backtick'>to_address(I{}) == to_address(I{)) + 0</code>
both hold, so the two types of empty ranges involving value-initialized iterators convert
to empty pointer ranges as desired.
</p>

<p><i>[2024-11-13; Reflector poll]</i></p>

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



<p id="res-4170"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4993" title=" Working Draft, Programming Languages — C++">N4993</a>.
</p>

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

<blockquote>
<p>
-1- The <code class='backtick'>contiguous_iterator</code> concept provides a guarantee that the denoted elements are stored contiguously
in memory.
</p>
<blockquote>
<pre>
template&lt;class I&gt;
  concept contiguous_iterator =
    random_access_iterator&lt;I&gt; &amp;&amp;
    derived_from&lt;<i>ITER_CONCEPT</i>(I), contiguous_iterator_tag&gt; &amp;&amp;
    is_lvalue_reference_v&lt;iter_reference_t&lt;I&gt;&gt; &amp;&amp;
    same_as&lt;iter_value_t&lt;I&gt;, remove_cvref_t&lt;iter_reference_t&lt;I&gt;&gt;&gt; &amp;&amp;
    requires(const I&amp; i) {
      { to_address(i) } -&gt; same_as&lt;add_pointer_t&lt;iter_reference_t&lt;I&gt;&gt;&gt;;
    };
</pre>
</blockquote>
<p>
-2- Let <code class='backtick'>a</code> and <code class='backtick'>b</code> be dereferenceable iterators and <code class='backtick'>c</code> be a non-dereferenceable iterator of type
<code class='backtick'>I</code> such that <code class='backtick'>b</code> is reachable from <code class='backtick'>a</code> and <code class='backtick'>c</code> is reachable from <code class='backtick'>b</code>, and let <code class='backtick'>D</code> be
<code>iter_difference_t&lt;I&gt;</code>. The type <code class='backtick'>I</code> models <code class='backtick'>contiguous_iterator</code> only if
</p>

<ol style="list-style-type: none">
<li><p>(2.1) &mdash; <code class='backtick'>to_address(a) == addressof(*a)</code>,</p></li>
<li><p>(2.2) &mdash; <code class='backtick'>to_address(b) == to_address(a) + D(b - a)</code>,</p></li>
<li><p>(2.3) &mdash; <code class='backtick'>to_address(c) == to_address(a) + D(c - a)</code>,</p></li>
<li><p><ins>(2.?) &mdash; <code class='backtick'>to_address(I{})</code> is well-defined,</ins></p></li>
<li><p>(2.4) &mdash; <code class='backtick'>ranges::iter_move(a)</code> has the same type, value category, and effects as
<code class='backtick'>std::move(*a)</code>, and</p></li>
<li><p>(2.5) &mdash; if <code class='backtick'>ranges::iter_swap(a, b)</code> is well-formed, it has effects equivalent to
<code class='backtick'>ranges::swap(*a, *b)</code>.</p></li>
</ol>
</blockquote>

</li>
</ol>




</body>
</html>
