Skip to content

Commit 4fbe46a

Browse files
committed
New issue from Hewill: "Missing Preconditions for take/drop adaptor"
1 parent 6b29837 commit 4fbe46a

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

xml/issue4214.xml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4214" status="New">
5+
<title>Missing <i>Preconditions</i> for <code>take</code>/<code>drop</code> adaptor</title>
6+
<section>
7+
<sref ref="[range.take.overview]"/><sref ref="[range.drop.overview]"/>
8+
</section>
9+
<submitter>Hewill Kang</submitter>
10+
<date>15 Feb 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
The <code>take</code>/<code>drop</code> adaptor does not explicitly require <i>N</i> to be non-negative (although
16+
the view class does), which makes it possible for some specialized cases to be well-defined when <i>N</i> is negative,
17+
since no <i>Preconditions</i> are violated:</p>
18+
<blockquote><pre>
19+
auto e = std::views::empty&lt;int&gt;
20+
| std::views::take(-1); // []
21+
auto i = std::views::iota(1, 5)
22+
| std::views::drop(-1); // [0, 1, 2, 3, 4]
23+
auto r = std::views::repeat('a', 2)
24+
| std::views::drop(-1); // ['a', 'a', 'a']
25+
</pre></blockquote>
26+
<p>
27+
This is not the intention, we should ban these cases.
28+
</p>
29+
</discussion>
30+
31+
<resolution>
32+
<p>
33+
This wording is relative to <paper num="N5001"/>.
34+
</p>
35+
36+
<ol>
37+
<li><p>Modify <sref ref="[range.take.overview]"/> as indicated:</p>
38+
39+
<blockquote>
40+
<p>
41+
-2- The name <code>views::take</code> denotes a range adaptor object (<sref ref="[range.adaptor.object]"/>).
42+
Let <code>E</code> and <code>F</code> be expressions, let <code>T</code> be
43+
<code>remove_cvref_t&lt;decltype((E))&gt;</code>, and let <code>D</code> be
44+
<code>range_difference_t&lt;decltype((E))&gt;</code>.
45+
If <code>decltype((F))</code> does not model <code>convertible_to&lt;D&gt;</code>,
46+
<code>views::take(E, F)</code> is ill-formed. Otherwise, the expression <code>views::take(E, F)</code>
47+
is expression-equivalent to:
48+
</p>
49+
<ol style="list-style-type: none">
50+
<li><p>(2.?) <ins>&mdash; <i>Preconditions</i>: <code>static_cast&lt;D&gt;(F) &gt;= 0</code> is <code>true</code>.</ins>
51+
</p></li>
52+
<li><p>(2.1) &mdash; if <code>T</code> is a specialization of <code>empty_view</code> (<sref ref="[range.empty.view]"/>),
53+
then <code>((void)F, <i>decay-copy</i>(E))</code>, except that the evaluations of <code>E</code>
54+
and <code>F</code> are indeterminately sequenced.
55+
</p></li>
56+
</ol>
57+
</blockquote>
58+
</li>
59+
60+
<li><p>Modify <sref ref="[range.drop.overview]"/> as indicated:</p>
61+
62+
<blockquote>
63+
<p>
64+
-2- The name <code>views::drop</code> denotes a range adaptor object (<sref ref="[range.adaptor.object]"/>).
65+
Let <code>E</code> and <code>F</code> be expressions, let <code>T</code> be
66+
<code>remove_cvref_t&lt;decltype((E))&gt;</code>, and let <code>D</code> be
67+
<code>range_difference_t&lt;decltype((E))&gt;</code>.
68+
If <code>decltype((F))</code> does not model <code>convertible_to&lt;D&gt;</code>,
69+
<code>views::drop(E, F)</code> is ill-formed. Otherwise, the expression <code>views::drop(E, F)</code>
70+
is expression-equivalent to:
71+
</p>
72+
<ol style="list-style-type: none">
73+
<li><p>(2.?) <ins>&mdash; <i>Preconditions</i>: <code>static_cast&lt;D&gt;(F) &gt;= 0</code> is <code>true</code>.</ins>
74+
</p></li>
75+
<li><p>(2.1) &mdash; if <code>T</code> is a specialization of <code>empty_view</code> (<sref ref="[range.empty.view]"/>),
76+
then <code>((void)F, <i>decay-copy</i>(E))</code>, except that the evaluations of <code>E</code>
77+
and <code>F</code> are indeterminately sequenced.
78+
</p></li>
79+
</ol>
80+
</blockquote>
81+
</li>
82+
83+
</ol>
84+
85+
</resolution>
86+
87+
</issue>

0 commit comments

Comments
 (0)