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-04

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_;