$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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