I try to find a turnkey iterator over integers, which supports all operations of boost::counting_iterator
, but also supports increment and decrement by a number (Iter operator (Integer num);
); Is there a simple way to make it without writing myself (for example, a base in boost which takes tags and provides a ready-to-use random access integer iterator)?
CodePudding user response:
Is using the iterator_facade
to ease implementing one enough?
struct Seq : boost::iterator_facade<Seq, int, boost::random_access_traversal_tag, int> {
Seq(int initial = 0) : _val(initial) {}
ptrdiff_t distance_to(Seq const& rhs) const { return rhs._val - _val; }
void advance(ptrdiff_t n) { _val = n; }
int dereference() const { return _val; }
private:
int _val;
};
See Live Demo
for (Seq it(100), e(197); it <= e; it = 13) {
std::cout << *it << " " << std::flush;
}
Prints
100 113 126 139 152 165 178 191
CodePudding user response:
What you are asking for is impossible.
counted_iterator
is intended to mirror the functionality of the iterator it is given. But it can only work with what it is given. If you give it a random-access iterator, it will mirror that functionality.
If you give it a forward iterator and then allow the user to increment it with any integer, you are lying to the user. Random access iterator incrementing means more than that you can call operator
with an integer. It means that this operation has O(1) complexity. And if the underlying iterator doesn't have that complexity on its iteration advancement... you cannot manufacture it from outside of the iterator.
Well, you could by heap-allocating an array of iterators of the size determined by the range you're given. But that's a really bad idea.
If you want to increment an iterator a bunch, but you don't know that the iterator is random-access, use std::next
or std::advance
.