Skip to content

Commit 01d89fd

Browse files
authored
New issue: "Inconsistent preconditions in repeat_view::iterator"
1 parent 697c489 commit 01d89fd

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

‎xml/issue4624.xml‎

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4624" status="New">
5+
<title>Inconsistent preconditions in <tt>repeat_view::<i>iterator</i></tt></title>
6+
<section><sref ref="[range.repeat.iterator]"/></section>
7+
<submitter>Tomasz Kamiński</submitter>
8+
<date>21 Sep 2026</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
As currently specified, the preconditions requiring <i>current_</i> to be
14+
non-negative (<sref ref="[range.repeat.iterator]"/> p2, p6, p8, p10) are applied
15+
only if "If <tt>Bound</tt> is not <tt>unreachable_sentinel_t</tt>". In consequence,
16+
decrementing iterator before begin is UB only if `views::repeat` specifies bound:
17+
<pre>
18+
auto rv1 = views::repeat(1, 10);
19+
auto it1 = std::prev(rv1.begin()); // UB
20+
auto rv2 = views::repeat(1);
21+
auto it2 = std::prev(rv2.begin()); // OK
22+
</pre>
23+
In contrast to the precondition on `bound` in `repeat_view` constructor,
24+
the <tt>current_</tt> is of `ptrdiff_t` type in such case, and the check
25+
can always be performed.
26+
</p>
27+
28+
<p>
29+
On the LWG reflector Michał Dominiak (the author of the paper) confirmed, that
30+
this is unintentional copy-paste error in the wording, and the precondition
31+
should always be applied.
32+
</p>
33+
34+
</discussion>
35+
36+
<resolution>
37+
<p>
38+
This wording is relative to <paper num="N5054"/>.
39+
</p>
40+
41+
<p>
42+
The proposed resolution completely removes the precondition on private constructor
43+
<tt>iterator(const T* value, <i>index-type</i> b = <i>index-type()</i>)</tt>,
44+
as it is private and can only be invoked by the library internally.
45+
</p>
46+
47+
<ol>
48+
<li>
49+
<p>Modify <sref ref="[range.repeat.iterator]"/> as indicated:</p>
50+
51+
<blockquote>
52+
<pre>
53+
constexpr explicit <i>iterator</i>(const T* value, <i>index-type</i> b = <i>index-type</i>());
54+
</pre>
55+
<blockquote>
56+
<p><del>-1- <i>Preconditions</i>: If `Bound` is not `unreachable_sentinel_t`, `b` ≥ 0</del>.</p>
57+
<p>-2- <i>Effects</i>: [&hellip;]</p>
58+
</blockquote>
59+
</blockquote>
60+
61+
[&hellip;]
62+
63+
<blockquote>
64+
<pre>
65+
constexpr explicit <i>iterator</i>&amp; operator--();
66+
</pre>
67+
<blockquote>
68+
<p>-6- <i>Preconditions</i>: <del>If `Bound` is not `unreachable_sentinel_t`,</del> <tt><i>current_</i></tt> ≥ 0.</p>
69+
<p>-7- <i>Effects</i>: [&hellip;]</p>
70+
</blockquote>
71+
</blockquote>
72+
73+
<blockquote>
74+
<pre>
75+
constexpr explicit <i>iterator</i>&amp; operator+=(difference_type n);
76+
</pre>
77+
<blockquote>
78+
<p>-8- <i>Preconditions</i>: <del>If `Bound` is not `unreachable_sentinel_t`,</del> <tt><i>current_</i></tt> + `n` ≥ 0.</p>
79+
<p>-9- <i>Effects</i>: [&hellip;]</p>
80+
</blockquote>
81+
</blockquote>
82+
83+
<blockquote>
84+
<pre>
85+
constexpr explicit <i>iterator</i>&amp; operator-=(difference_type n);
86+
</pre>
87+
<blockquote>
88+
<p>-10- <i>Preconditions</i>: <del>If `Bound` is not `unreachable_sentinel_t`,</del> <tt><i>current_</i></tt> - `n` ≥ 0.</p>
89+
<p>-11- <i>Effects</i>: [&hellip;]</p>
90+
</blockquote>
91+
</blockquote>
92+
93+
</li>
94+
</ol>
95+
</resolution>
96+
97+
</issue>

0 commit comments

Comments
 (0)