|
| 1 | +<?xml version='1.0' encoding='utf-8' standalone='no'?> |
| 2 | +<!DOCTYPE issue SYSTEM "lwg-issue.dtd"> |
| 3 | + |
| 4 | +<issue num="4236" status="New"> |
| 5 | +<title><tt>chunk_view::<i>outer-iterator</i>::value_type</tt> should provide <tt>reserve_hint</tt></title> |
| 6 | +<section> |
| 7 | +<sref ref="[range.chunk.outer.value]"/> |
| 8 | +</section> |
| 9 | +<submitter>Hewill Kang</submitter> |
| 10 | +<date>26 Mar 2025</date> |
| 11 | +<priority>99</priority> |
| 12 | + |
| 13 | +<discussion> |
| 14 | +<p> |
| 15 | +Consider: |
| 16 | +</p> |
| 17 | +<blockquote><pre> |
| 18 | +views::istream<int>(is) | views::chunk(N) | ranges::to<std::list<std::vector<int>>>(); |
| 19 | +</pre></blockquote> |
| 20 | +<p> |
| 21 | +When the stream is large enough, each chunk will be of size <tt>N</tt> in most cases, except it is the |
| 22 | +last chunk. |
| 23 | +</p> |
| 24 | +<p> |
| 25 | +In this case, there is no reason not to provide a <code>reserve_hint</code> as this can be easily done by just |
| 26 | +return <code><i>remainder_</i></code>. Otherwise, when <tt>N</tt> is large, each vector will be reallocated |
| 27 | +multiple times unnecessarily. |
| 28 | +</p> |
| 29 | +<p> |
| 30 | +This is also consistent with the <code>forward_range</code> version, since its value type is |
| 31 | +<code>views::take(subrange(<i>current_</i>, <i>end_</i>), <i>n_</i>)</code>, which always has a |
| 32 | +<code>reserve_hint</code> as <code>take_view</code> unconditionally provides it. |
| 33 | +</p> |
| 34 | +</discussion> |
| 35 | + |
| 36 | +<resolution> |
| 37 | +<p> |
| 38 | +This wording is relative to <paper num="N5008"/>. |
| 39 | +</p> |
| 40 | + |
| 41 | +<ol> |
| 42 | + |
| 43 | +<li><p>Modify <sref ref="[range.chunk.outer.value]"/> as indicated:</p> |
| 44 | + |
| 45 | +<blockquote> |
| 46 | +<blockquote> |
| 47 | +<pre> |
| 48 | +namespace std::ranges { |
| 49 | + template<view V> |
| 50 | + requires input_range<V> |
| 51 | + struct chunk_view<V>::<i>outer-iterator</i>::value_type : view_interface<value_type> { |
| 52 | + […] |
| 53 | + constexpr auto size() const |
| 54 | + requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; |
| 55 | + |
| 56 | + <ins>constexpr auto reserve_hint() const noexcept;</ins> |
| 57 | + }; |
| 58 | +} |
| 59 | +</pre> |
| 60 | +</blockquote> |
| 61 | +[…] |
| 62 | +<pre> |
| 63 | +constexpr auto size() const |
| 64 | + requires sized_sentinel_for<sentinel_t<V>, iterator_t<V>>; |
| 65 | +</pre> |
| 66 | +<blockquote> |
| 67 | +<p> |
| 68 | +-4- <i>Effects</i>: Equivalent to: |
| 69 | +</p> |
| 70 | +<blockquote><pre> |
| 71 | +return <i>to-unsigned-like</i>(ranges::min(<i>parent_</i>->remainder_, |
| 72 | + ranges::end(<i>parent_</i>-><i>base_</i>) - *<i>parent_</i>-><i>current_</i>)); |
| 73 | +</pre></blockquote> |
| 74 | +</blockquote> |
| 75 | +<pre> |
| 76 | +<ins>constexpr auto reserve_hint() const noexcept;</ins> |
| 77 | +</pre> |
| 78 | +<blockquote> |
| 79 | +<p> |
| 80 | +<ins> -?- <i>Effects</i>: Equivalent to:</ins> |
| 81 | +</p> |
| 82 | +<blockquote><pre> |
| 83 | +<ins>return <i>to-unsigned-like</i>(<i>parent_</i>-><i>remainder_</i>);</ins> |
| 84 | +</pre></blockquote> |
| 85 | +</blockquote> |
| 86 | +</blockquote> |
| 87 | + |
| 88 | +</li> |
| 89 | + |
| 90 | +</ol> |
| 91 | +</resolution> |
| 92 | + |
| 93 | +</issue> |
0 commit comments