
07.11.2013 18:20, Eric Niebler:
I wrote an article describing the "fat" std::istream_iterator and how it can be slimmed down by giving it an owning istream_range[1].
Note, for some cases "fat" std::istream_iterator is actually good. For example when it is used as CountedRange [i, n) : std::copy_n(istream_iterator<int>(cin), 10, out); "slim" version would do superfluous check on each increment.
I see there already is an istream_range in Boost.Range, but it suffers from the fat-iterator problem I describe there. Is there a compelling reason why the implementation of boost::istream_range shouldn't be changed to be more like the one I describe?
I like your solution for istream_range - it is "slim" indeed. It can be generalized to wrapper around new special concept of range/iterator, which would be similar to InputRange from D language: http://dlang.org/phobos/std_range.html#isInputRange Here is proof-of-concept: http://coliru.stacked-crooked.com/a/f82b76fb6b13521b class NullTerminated { const char *position; public: explicit NullTerminated(const char *position) : position{position} {} NullTerminated &operator++() { ++position; return *this; } const char &operator*() const { return *position; } friend bool empty(const NullTerminated &x) { return *x == 0; } }; int main() { for(auto x : make_range(NullTerminated{"Sentinel iteration"})) cout << x; cout << "!" << endl; } Note, that we can have special algorithms for new kinds of iterators/ranges. Plus, I think we can make reverse adaptor: from STL iterators to new iterator/range.
Also, as a commented pointed out, the same problem exists for the filtered range and the transformed range, too.
boost::adaptors::filtered returns up to BidirectionalRange and boost::adaptors::transformed returns up to RandomAccessRange, which is useful. And "fat" is actually not a problem, because in most cases predicates/transformations are empty or rather small objects, with locality benefits as noted. Do you propose to add special case for InputRanges into present adaptors? Or do you propose to add new "slim" adaptors like boost::adaptors::transformed_slim, which would have shared functors between iterators for all Range categories? -- Evgeny Panasyuk