This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 3489. Improve `istream_view` wording

Section: 24.6.5.3 [range.istream.iterator] Status: New Submitter: Michael Schellenberger Costa Opened: 2020-10-09 Last modified: 2021-09-02

Priority: 3

View all other issues in [range.istream.iterator].

View all issues with New status.

Discussion:

While implementing `iranges::stream_view` we found some issues with the Preconditions on the member functions of `istream_view::iterator`, which are superfluous or incorrect.

1. 24.6.5.3 [range.istream.iterator] p2 reads as:

   > Preconditions: `parent_->stream_ != nullptr` is `true`.

   However in the Effects element 24.6.5.3 [range.istream.iterator] p3 it reads:

   > Effects: Equivalent to:

   > >     *parent_->stream_ >> parent_->object_;
   > >     return *this;

   For the Effects element to be valid, we implicitly require that `parent_ != nullptr`, `parent_->stream_ != nullptr` and — because we are reading from the underlying stream — `!*x.parent_->stream_`.

   Given that the Preconditions element only mentions one of the three preconditions and essentially means that we are not at the end of the stream, we should replace 24.6.5.3 [range.istream.iterator] p2 by:

   > Preconditions: `*this != default_sentinel`.

2. We should use the same precondition for 24.6.5.3 [range.istream.iterator] p4, even if it is implicit via the Effects element in 24.6.5.3 [range.istream.iterator] p5, as that requires experts knowledge of the standard.

3. The Precondition in 24.6.5.3 [range.istream.iterator] 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:

   > Preconditions: `*this != default_sentinel`.

[2020-10-14; Priority to P3 after reflector discusssion]

[2021-09-02; Jonathan comments:]

The preconditions were removed by P2325R3 approved in June 2021. Although the pointers now cannot be null, it's unclear if we want to require `fail()` to be false for the stream.

Proposed resolution:

This wording is relative to N4861.

1. Modify 24.6.5.3 [range.istream.iterator] as indicated:

   >     iterator& operator++();

   > > -2- Preconditions: `parent_->stream_ != nullptr*this != default_sentinel` is `true`.

   > > -3- Effects: Equivalent to:

   > > >     *parent_->stream_ >> parent_->object_;
   > > >     return *this;

   >     void operator++(int);

   > > -4- Preconditions: `parent_->stream_ != nullptr*this != default_sentinel` is `true`.

   > > -5- Effects: Equivalent to `++*this`.

   >     Val& operator*() const;

   > > -6- Preconditions: `parent_->stream_ != nullptr*this != default_sentinel` is `true`.

   > > -7- Effects: Equivalent to: `return parent_->object_;`

   >     friend bool operator==(const iterator& x, default_sentinel_t);

   > > -8- Effects: Equivalent to: `return x.parent_ == nullptr || !*x.parent_->stream_;`