Skip to content

Instantly share code, notes, and snippets.

@blindley
Created October 10, 2014 19:51
Show Gist options
  • Save blindley/b2e2f9cf18ceade29a77 to your computer and use it in GitHub Desktop.
Save blindley/b2e2f9cf18ceade29a77 to your computer and use it in GitHub Desktop.
proposed change to istream_range
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 &current() 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;
}
};
@ericniebler
Copy link

This might work, but it makes me uncomfortable since a mutating operation is happening in cursor::current and cursor::done, which are const member functions. The mitigating factor is that istream_range only has a non-const begin() 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 to N. 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment