istream_view
wordingSection: 25.6.6.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.
25.6.6.3 [range.istream.iterator] p2 reads as:
Preconditions:
parent_->stream_ != nullptr
istrue
.
However in the Effects element 25.6.6.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_
.
Preconditions:
*this != default_sentinel
.
We should use the same precondition for 25.6.6.3 [range.istream.iterator] p4, even if it is implicit via the Effects element in 25.6.6.3 [range.istream.iterator] p5, as that requires experts knowledge of the standard.
The Precondition in 25.6.6.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.
Modify 25.6.6.3 [range.istream.iterator] as indicated:
iterator& operator++();-2- Preconditions:
-3- Effects: Equivalent to:is
parent_->stream_ != nullptr*this != default_sentineltrue
.*parent_->stream_ >> parent_->object_; return *this;void operator++(int);-4- Preconditions:
-5- Effects: Equivalent tois
parent_->stream_ != nullptr*this != default_sentineltrue
.++*this
.Val& operator*() const;-6- Preconditions:
-7- Effects: Equivalent to:is
parent_->stream_ != nullptr*this != default_sentineltrue
.return parent_->object_;
friend bool operator==(const iterator& x, default_sentinel_t);-8- Effects: Equivalent to:
return x.parent_ == nullptr || !*x.parent_->stream_;