<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 3489: Improve istream_view wording</title>
<meta property="og:title" content="Issue 3489: Improve istream_view wording">
<meta property="og:description" content="C++ library issue. Status: New">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue3489.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="3489"><a href="lwg-active.html#3489">3489</a>. Improve <code>istream_view</code> wording</h3>
<p><b>Section:</b> 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> <b>Status:</b> <a href="lwg-active.html#New">New</a>
 <b>Submitter:</b> Michael Schellenberger Costa <b>Opened:</b> 2020-10-09 <b>Last modified:</b> 2021-09-02</p>
<p><b>Priority: </b>3
</p>
<p><b>View all other</b> <a href="lwg-index.html#range.istream.iterator">issues</a> in [range.istream.iterator].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#New">New</a> status.</p>
<p><b>Discussion:</b></p>
<p>
While implementing <code>iranges::stream_view</code> we found some issues with the <i>Preconditions</i> 
on the member functions of <code>istream_view::iterator</code>, which are superfluous or incorrect.
</p>

<ol>
<li>
<p>
25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> p2 reads as:
</p>
<blockquote><p>
<i>Preconditions:</i> <code><i>parent_</i>-&gt;<i>stream_</i> != nullptr</code> is <code>true</code>.
</p></blockquote>
<p>
However in the <i>Effects</i> element 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> p3 it reads:
</p>
<blockquote>
<p>
<i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
*<i>parent_</i>-&gt;<i>stream_</i> &gt;&gt; <i>parent_</i>-&gt;<i>object_</i>;
return *this;
</pre></blockquote>
</blockquote>
<p>
For the <i>Effects</i> element to be valid, we implicitly require that <code><i>parent_</i> != nullptr</code>, 
<code><i>parent_</i>-&gt;<i>stream_</i> != nullptr</code> and &mdash; because we are reading from the underlying 
stream &mdash; <code>!*x.<i>parent_</i>-&gt;<i>stream_</i></code>.
<p/>
Given that the <i>Preconditions</i> element only mentions one of the three preconditions and essentially 
means that we are not at the end of the stream, we should replace 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> p2 
by:
</p>
<blockquote><p>
<i>Preconditions:</i> <code>*this != default_sentinel</code>.
</p></blockquote>
</li>
<li>
<p>
We should use the same precondition for 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> p4, even if it is implicit 
via the <i>Effects</i> element in 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> p5, as that requires experts knowledge 
of the standard.
</p>
</li>
<li>
<p>
The Precondition in 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> p6 is completely bogus, as accessing the 
cached object has no dependency on the stream. We assume it is meant that we are not at the end of the stream. 
Again we should change this to:
</p>
<blockquote><p>
<i>Preconditions:</i> <code>*this != default_sentinel</code>.
</p></blockquote>
</li>
</ol>

<p><i>[2020-10-14; Priority to P3 after reflector discusssion]</i></p>


<p><i>[2021-09-02; Jonathan comments:]</i></p>

<p>
The preconditions were removed by <a href="https://wg21.link/P2325R3" title=" Views should not be required to be default constructible">P2325R3</a> approved in June 2021.
Although the pointers now cannot be null, it's unclear if we want to require
<code>fail()</code> to be false for the stream.
</p>



<p id="res-3489"><b>Proposed resolution:</b></p>
<p>
This wording is relative to <a href="https://wg21.link/n4861">N4861</a>. 
</p>

<ol>
<li>
<p>
Modify 25.6.6.3 <a href="https://wg21.link/range.istream.iterator">[range.istream.iterator]</a> as indicated:
</p>
<blockquote>
<pre>
<i>iterator</i>&amp; operator++();
</pre>
<blockquote>
<p>
-2- <i>Preconditions:</i> <code><del><i>parent_</i>-&gt;<i>stream_</i> != nullptr</del><ins>*this != default_sentinel</ins></code> 
is <code>true</code>.
<p/>
-3- <i>Effects:</i> Equivalent to:
</p>
<blockquote><pre>
*<i>parent_</i>-&gt;<i>stream_</i> &gt;&gt; <i>parent_</i>-&gt;<i>object_</i>;
return *this;
</pre></blockquote>
</blockquote>
<pre>
void operator++(int);
</pre>
<blockquote>
<p>
-4- <i>Preconditions:</i> <code><del><i>parent_</i>-&gt;<i>stream_</i> != nullptr</del><ins>*this != default_sentinel</ins></code> 
is <code>true</code>.
<p/>
-5- <i>Effects:</i> Equivalent to <code>++*this</code>.
</p>
</blockquote>
<pre>
Val&amp; operator*() const;
</pre>
<blockquote>
<p>
-6- <i>Preconditions:</i> <code><del><i>parent_</i>-&gt;<i>stream_</i> != nullptr</del><ins>*this != default_sentinel</ins></code> 
is <code>true</code>.
<p/>
-7- <i>Effects:</i> Equivalent to: <code>return <i>parent_</i>-&gt;<i>object_</i>;</code>
</p>
</blockquote>
<pre>
friend bool operator==(const <i>iterator</i>&amp; x, default_sentinel_t);
</pre>
<blockquote>
<p>
-8- <i>Effects:</i> Equivalent to: <code>return x.<i>parent_</i> == nullptr || !*x.<i>parent_</i>-&gt;<i>stream_</i>;</code>
</p>
</blockquote>
</blockquote>
</li>
</ol>





</body>
</html>
