Skip to content

Commit

Permalink
New issue from Hewill Kang: "ranges::to's copy branch is underconstra…
Browse files Browse the repository at this point in the history
…ined"
  • Loading branch information
Dani-Hub committed Nov 25, 2023
1 parent d91e9af commit 123ed37
Showing 1 changed file with 90 additions and 0 deletions.
90 changes: 90 additions & 0 deletions xml/issue4018.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<?xml version='1.0' encoding='utf-8' standalone='no'?>
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">

<issue num="4018" status="New">
<title><tt>ranges::to</tt>'s copy branch is underconstrained</title>
<section><sref ref="[range.utility.conv.to]"/></section>
<submitter>Hewill Kang</submitter>
<date>25 Nov 2023</date>
<priority>99</priority>

<discussion>
<p>
Unlike other branches that return a prvalue <tt>C</tt>, this branch's <tt>C</tt> is returned by elidable move,
indicating that <tt>C</tt> needs to be move constructible (<a href="https://godbolt.org/z/dfqnx6Txq">demo</a>):
</p>
<blockquote><pre>
#include &lt;ranges&gt;
#include &lt;vector&gt;

struct nonmovable {
nonmovable() = default;
nonmovable(const nonmovable&amp;) = delete;
nonmovable&amp; operator=(const nonmovable&amp;) = delete;
};

template&lt;class T&gt;
struct nonmovable_vector : std::vector&lt;T&gt;, nonmovable { };

int main() {
int arr[] = {42};
auto v = std::ranges::to&lt;nonmovable_vector&lt;int&gt;&gt;(arr); // <span style="color:red;font-weight:bolder">hard error</span>
}
</pre></blockquote>
</discussion>

<resolution>
<p>
This wording is relative to <paper num="N4964"/>.
</p>

<ol>

<li><p>Modify <sref ref="[range.utility.conv.to]"/> as indicated:</p>

<blockquote>
<pre>
template&lt;class C, input_range R, class... Args&gt; requires (!view&lt;C&gt;)
constexpr C to(R&amp;&amp; r, Args&amp;&amp;... args);
</pre>
<blockquote>
<p>
-1- <i>Mandates</i>: <tt>C</tt> is a cv-unqualified class type.
</p>
<p>
-2- <i>Returns</i>: An object of type <tt>C</tt> constructed from the elements of <tt>r</tt> in the following manner:
</p>
<ol style="list-style-type: none">
<li><p>(2.1) &mdash; If <tt>C</tt> does not satisfy <tt>input_range</tt> or
<tt>convertible_to&lt;range_reference_t&lt;R&gt;, range_value_t&lt;C&gt;&gt;</tt> is <tt>true</tt>:</p>
<ol style="list-style-type: none">
<li><p>(2.1.1) &mdash; [&hellip;]</p></li>
<li><p>(2.1.2) &mdash; [&hellip;]</p></li>
<li><p>(2.1.3) &mdash; [&hellip;]</p></li>
<li><p>(2.1.4) &mdash; Otherwise, if</p>
<ol style="list-style-type: none">
<li><p><ins>(2.1.4.?) &mdash; <tt>move_constructible&lt;C&gt;</tt> is <tt>true</tt>,</ins></p></li>
<li><p>(2.1.4.1) &mdash; <tt>constructible_from&lt;C, Args...&gt;</tt> is <tt>true</tt>, and</p></li>
<li><p>(2.1.4.2) &mdash; <tt><i>container-insertable</i>&lt;C, range_reference_t&lt;R&gt;&gt;</tt> is <tt>true</tt>:</p>
<blockquote><pre>
C c(std::forward&lt;Args&gt;(args)...);
if constexpr (sized_range&lt;R> &amp;&amp; <i>reservable-container</i>&lt;C&gt;)
c.reserve(static_cast&lt;range_size_t&lt;C&gt;&gt;(ranges::size(r)));
ranges::copy(r, <i>container-inserter</i>&lt;range_reference_t&lt;R&gt;&gt;(c));
</pre></blockquote></li>
</ol>
</li>
<li><p>(2.1.5) &mdash; Otherwise, the program is ill-formed.</p></li>
</ol></li>
<li><p>(2.2) &mdash; [&hellip;]</p></li>
<li><p>(2.3) &mdash; Otherwise, the program is ill-formed.</p></li>
</ol>

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

</ol>
</resolution>

</issue>

0 comments on commit 123ed37

Please sign in to comment.