Boost logo

Boost :

Subject: Re: [boost] [range] fat iterators?
From: Evgeny Panasyuk (evgeny.panasyuk_at_[hidden])
Date: 2013-11-07 15:40:23


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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk