<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 4010: subrange::advance should be improved</title>
<meta property="og:title" content="Issue 4010: subrange::advance should be improved">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue4010.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#New">New</a> status.</em></p>
<h3 id="4010"><a href="lwg-active.html#4010">4010</a>. <code>subrange::advance</code> should be improved</h3>
<p><b>Section:</b> 25.5.4.3 <a href="https://wg21.link/range.subrange.access">[range.subrange.access]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a>
 <b>Submitter:</b> Hewill Kang <b>Opened:</b> 2023-11-09 <b>Last modified:</b> 2024-03-11</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="lwg-index.html#range.subrange.access">issues</a> in [range.subrange.access].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
<code>subrange::advance</code> always increments <code><i>begin_</i></code> via <code>ranges::advance(<i>begin_</i>, 
n, <i>end_</i>)</code>, which has &#x1d4aa;(<code>n</code>) complexity for non-common random-access ranges,
which can be improved to &#x1d4aa;(1) with the help of the <code><i>size_</i></code> member (if provided).
</p>

<p><i>[2024-03-11; Reflector poll]</i></p>

<p>
Set priority to 3 after reflector poll.
</p>
<p>
Jonathan: The "Effects: Equivalent to" wording strongly suggests doing exactly
what it suggests there, and  the difference would be observable in the number
of times the iterator is compared to the sentinel. I'm not sure if we care
about that, or if an implementation would be free to make this change as QoI.
Regarding the proposed resolution, we know the type of <code>n</code>
so we don't need to use <code>decltype(n)</code> in the cast.
</p>



<p id="res-4010"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/N4964" title=" Working Draft, Programming Languages — C++">N4964</a>.
</p>

<ol>

<li><p>Modify 25.5.4.3 <a href="https://wg21.link/range.subrange.access">[range.subrange.access]</a> as indicated:</p>

<pre>
constexpr subrange&amp; advance(iter_difference_t&lt;I&gt; n);
</pre>
<blockquote>
<p>
-9- <i>Effects</i>: Equivalent to:
</p>
<blockquote><pre>
if constexpr (bidirectional_iterator&lt;I&gt;) {
  if (n &lt; 0) {
    ranges::advance(<i>begin_</i>, n);
    if constexpr (<i>StoreSize</i>)
      <i>size_</i> += <i>to-unsigned-like</i>(-n);
    return *this;
  }
}

<del>auto d = n - ranges::advance(<i>begin_</i>, n, <i>end_</i>);</del>
if constexpr (<i>StoreSize</i>) <ins>{
  n = std::min(n, static_cast&lt;decltype(n)&gt;(<i>size_</i>));
  ranges::advance(<i>begin_</i>, n);</ins>
  <i>size_</i> -= <i>to-unsigned-like</i>(<ins>n</ins><del>d</del>);
<ins>} else {
  ranges::advance(<i>begin_</i>, n, <i>end_</i>);
}</ins>
return *this;
</pre></blockquote>
</blockquote>

</li>

</ol>





</body>
</html>
