Skip to content

Commit c166da4

Browse files
committed
New issue from Ruslan Arutyunyan: "Allow calling std::ranges::size in ranges algorithms"
1 parent 7ee0b79 commit c166da4

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed

xml/issue4490.xml

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4490" status="New">
5+
<title>Allow calling `std::ranges::size` in ranges algorithms</title>
6+
<section><sref ref="[algorithms.requirements]"/></section>
7+
<submitter>Ruslan Arutyunyan</submitter>
8+
<date>12 Dec 2025</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
<sref ref="[algorithms.requirements]"/> paragraph 14 says that the algorithms in `ranges` namespace are implemented
14+
as if they are dispatched to the corresponding overload with iterator and sentinel. However, there are two problems
15+
with the current wording:
16+
</p>
17+
<ol>
18+
<li><p>
19+
We only allow to call either `std::ranges::end(r)` or `std::ranges::next(std::ranges::begin(r)`, `std::ranges::end())`
20+
to calculate a corresponding sentinel. However, this is a pessimization for some ranges because we can have sized
21+
ranges without sized_sentinel_for. Consider the following example:</p>
22+
<blockquote><pre>
23+
const char str[] = "something";
24+
ranges::subrange&lt;const char*,
25+
null_sentinel_t,
26+
subrange_kind::sized> sr(ranges::begin(str),
27+
null_sentinel,
28+
ranges::size(str) - 1);
29+
my::ranges::next(sr.begin(), sr.end()); // <span style="color:green;font-weight:bolder">this line serially calculates iterator that is equal to sr.end()</span>
30+
</pre></blockquote>
31+
<p>
32+
Despite the fact that we know the size of the range and that the range is the random access one,
33+
`std::ranges::next` calculates the iterator serially, because it only has constant time complexity
34+
optimization for `sized_sentinel_for`. We could clearly achieve better complexity with a different
35+
API or with the different overload of the same API.
36+
</p></li>
37+
<li><p>
38+
It is unclear when an algorithm calls `std::ranges::end(r)` and when it calls
39+
`std::ranges::next(std::ranges::begin(r), std::ranges::end())` to calculate the
40+
corresponding sentinel because there is no established priority between them.
41+
Maybe, it's smaller problem but still it's worth clarifying in my opinion.
42+
</p></li>
43+
</ol>
44+
</discussion>
45+
46+
<resolution>
47+
<p>
48+
This wording is relative to <paper num="N5032"/>.
49+
</p>
50+
51+
<ol>
52+
<li><p>Modify <sref ref="[algorithms.requirements]"/> as indicated:</p>
53+
54+
<blockquote>
55+
<p>
56+
[&hellip;]
57+
<p/>
58+
-14- Overloads of algorithms that take `range` arguments (<sref ref="[range.range]"/>) behave as if
59+
they are implemented by dispatching to the overload in namespace `ranges` that takes separate iterator
60+
and sentinel arguments, where for each range argument `r`
61+
</p>
62+
<ul style="list-style-type: none">
63+
<li><p>
64+
(14.1) &mdash; a corresponding iterator argument is initialized with `ranges::begin(r)` and
65+
</p></li>
66+
<li><p>
67+
(14.2) &mdash; a corresponding sentinel argument is initialized with <del>`ranges::end(r)`, or
68+
`ranges::next(ranges::begin(r), ranges::end(r))` if the type of `r` models `forward_range`
69+
and computing `ranges::next` meets the specified complexity requirements.</del><ins>one of the following:</ins>
70+
</p>
71+
<ul style="list-style-type: none">
72+
<li><p>
73+
<ins>(14.2.1) &mdash; if the type of `r` models `forward_range` and computing `ranges::next`
74+
meets the specified complexity requirements then</ins>
75+
</p>
76+
<ul style="list-style-type: none">
77+
<li><p>
78+
<ins>(14.2.1.1) &mdash; `ranges::next(ranges::begin(r), ranges::size(r))` if `r` models `sized_range`, otherwise</ins>
79+
</p></li>
80+
<li><p>
81+
<ins>(14.2.1.2) &mdash; `ranges::next(ranges::begin(r), ranges::end(r))`.</ins>
82+
</p></li>
83+
</ul></li>
84+
<li><p>
85+
<ins>(14.2.2) &mdash; Otherwise, `std::ranges::end(s)`.</ins>
86+
</p></li>
87+
</ul>
88+
</li>
89+
</ul>
90+
</blockquote>
91+
</li>
92+
</ol>
93+
94+
</resolution>
95+
96+
</issue>

0 commit comments

Comments
 (0)