Skip to content

Commit 91439ec

Browse files
committed
New issue from Frank Birbacher: "Have hive::erase_if reevaluate end()"
1 parent 3840c56 commit 91439ec

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

xml/issue4318.xml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4318" status="New">
5+
<title>Have `hive::erase_if` reevaluate `end()` to avoid UB</title>
6+
<section>
7+
<sref ref="[hive.erasure]"/>
8+
</section>
9+
<submitter>Frank Birbacher</submitter>
10+
<date>16 Aug 2025</date>
11+
<priority>99</priority>
12+
13+
<discussion>
14+
<p>
15+
Background: <a href="https://github.com/cplusplus/draft/pull/8162">https://github.com/cplusplus/draft/pull/8162</a>
16+
<p/>
17+
For <sref ref="[hive.erasure]"/> p2, the defining code must not cache the end-iterator. In case the last
18+
element of the sequence is removed, the past-the-end iterator will be invalidated. This will trigger UB
19+
in the loop condition. Instead, re-evaluate `end()` each time.
20+
</p>
21+
</discussion>
22+
23+
<resolution>
24+
<p>
25+
This wording is relative to <paper num="N5014"/>.
26+
</p>
27+
28+
<blockquote class="note">
29+
<p>
30+
[<i>Drafting note:</i> There are other ways to fix this code while keeping the caching behaviour, but I don't
31+
see any particular reason to do so for the definition of the effects.]
32+
</p>
33+
</blockquote>
34+
35+
<ol>
36+
37+
<li><p>Modify <sref ref="[hive.erasure]"/> as indicated:</p>
38+
39+
<blockquote>
40+
<pre>
41+
template&lt;class T, class Allocator, class Predicate&gt;
42+
typename hive&lt;T, Allocator&gt;::size_type
43+
erase_if(hive&lt;T, Allocator&gt;&amp; c, Predicate pred);
44+
</pre>
45+
<blockquote>
46+
<p>
47+
-2- <i>Effects</i>: Equivalent to:
48+
</p>
49+
<blockquote><pre>
50+
auto original_size = c.size();
51+
for (auto i = c.begin()<del>, last = c.end()</del>; i != <del>last</del><ins>c.end()</ins>; ) {
52+
if (pred(*i)) {
53+
i = c.erase(i);
54+
} else {
55+
++i;
56+
}
57+
}
58+
return original_size - c.size();
59+
</pre></blockquote>
60+
</blockquote>
61+
</blockquote>
62+
63+
</li>
64+
65+
</ol>
66+
</resolution>
67+
68+
</issue>

0 commit comments

Comments
 (0)