Boost logo

Boost Users :

Subject: [Boost-users] [Range] Proposal to add a new range adaptor (first_nd), or modify sliced
From: Gábor Márton (martongabesz_at_[hidden])
Date: 2012-08-26 14:19:57


Hi,

Problem:
Get the first N element of a SinglePassRange. It is not possible with
sliced, because it requires RandamAccessRange.
(Similar discussion was on the list about this in 2011 January:
http://lists.boost.org/boost-users/2011/01/65757.php)

Possible solutions:
A)
Modify sliced implementation to use std::advance instead of
boost::size. (Boost::size calls operator+ on the end iterator of the
adapted range, that is why it requires the random access.)
However using std::advance is not efficient in case of iterators which
are not random access ones. I think this efficiency problem is the
reason why the author(s) decided to not use std::advance, but rather
boost::size. So this is not a real solution.
B)
Introduce a new range adaptor, which has an underlying adapted
iterator with a "count" member:
template <class Iterator>
class first_n_iterator : public
boost::iterator_adaptor<first_n_iterator<Iterator>, Iterator>
{
        ...
        first_n_iterator(const Iterator& it, std::size_t n)
                        : first_n_iterator::iterator_adaptor_(it),
initial(it), count(n) {}
        ...
        void increment() { ++(this->base_reference()); ++count; }
        bool equal(first_n_iterator const& other) const
        {
                return this->initial == other.initial && this->count
== other.count;
        }

        Iterator initial; // used to be able to differentiate ranges
        std::size_t count;
};
One can find the whole solution and the test for it attached
(first_nd.hpp, first_nd_test.cpp). I think this is more effective than
a sliced implementation with std::advance would be.

The structure first_nd could be changed to support two parameters, so
one could provide the start position too (so it wouldn't be fixed to
zero). In the implementation (first_nd_range) std::advance could be
used to point the starting iterator to the start position. However in
this case we would get the same functionality as slice now has ...

I am asking the boost community,
1) Would it be useful, to have such a new range adaptor?
If yes,
    -- what would be the best name for it (first_nd is not the best, I know) ?
    -- I would be pretty enthusiastic to contribute it to boost.
2) Are the upper arguments valid against the current implementation of
sliced? If yes, would it worth to change it to a similar to first_nd
one? Or maybe, it would even be better to specialize sliced_range
based on the iterator_tag of the range, what do you think?

Best Regards,
Gabor





Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net