Created
October 10, 2014 19:51
-
-
Save blindley/b2e2f9cf18ceade29a77 to your computer and use it in GitHub Desktop.
proposed change to istream_range
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<typename Val> | |
struct istream_range | |
: range_facade<istream_range<Val>> | |
{ | |
private: | |
friend range_access; | |
std::istream *sin_; | |
Val obj_; | |
// new member to keep track of whether we've | |
// read the value for the current position | |
bool up_to_date_; | |
struct cursor | |
{ | |
private: | |
istream_range *rng_; | |
void update() const | |
{ | |
// reading only happens here, and only | |
// if we haven't read the value for the | |
// current position. | |
if (!rng_->up_to_date_) | |
{ | |
*rng_->sin_ >> rng_->obj_; | |
rng_->up_to_date_ = true; | |
} | |
} | |
public: | |
cursor() = default; | |
explicit cursor(istream_range &rng) | |
: rng_(&rng) | |
{} | |
void next() | |
{ | |
update(); | |
rng_->up_to_date_ = false; | |
} | |
Val const ¤t() const | |
{ | |
update(); | |
return rng_->obj_; | |
} | |
bool done() const | |
{ | |
update(); | |
return !*rng_->sin_; | |
} | |
}; | |
cursor begin_cursor() | |
{ | |
return cursor{*this}; | |
} | |
public: | |
istream_range() = default; | |
istream_range(std::istream &sin) | |
: sin_(&sin), obj_{} | |
{ | |
up_to_date_ = false; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This might work, but it makes me uncomfortable since a mutating operation is happening in
cursor::current
andcursor::done
, which areconst
member functions. The mitigating factor is thatistream_range
only has a non-constbegin()
member, so mutation during iteration is implicitly allowed. This is just a strange place for the mutation to happen.The interaction with the
view::take
adaptor happens because the count and the iterator are both incremented before the new count gets compared toN
. We might be able to do something sneaky there, where the underlying iterator isn't incremented if it doesn't need to be. That feels wrong, too; it's likely to screw up something else. Maybe this "fix" is better, or maybe the answer is: Don't Do That. I need to think about it.