Cleaning up bidirectional iterator code - c++

I've modified James' flattening iterator to act as a bidirectional iterator if possible, but I don't think my changes are very elegant (particularly relying on a bool to see if the inner iterator has been set). However, I can't seem to come up with a nicer solution. Does anyone have any ideas?
#include <algorithm>
#include <iostream>
#include <set>
#include <vector>
#include <iterator>
#include <type_traits>
// An iterator that "flattens" a container of containers. For example,
// a vector<vector<int>> containing { { 1, 2, 3 }, { 4, 5, 6 } } is iterated as
// a single range, { 1, 2, 3, 4, 5, 6 }.
template <typename OuterIterator>
class flattening_iterator
{
public:
typedef OuterIterator outer_iterator;
typedef typename std::iterator_traits<outer_iterator>::value_type::iterator inner_iterator;
typedef typename std::iterator_traits<outer_iterator>::iterator_category outer_category;
typedef typename std::iterator_traits<inner_iterator>::iterator_category inner_category;
typedef typename std::common_type<outer_category, inner_category>::type common_category;
typedef typename std::conditional<std::is_same<common_category, std::random_access_iterator_tag>::value,
std::bidirectional_iterator_tag,
common_category>::type iterator_category;
typedef typename std::iterator_traits<inner_iterator>::value_type value_type;
typedef typename std::iterator_traits<inner_iterator>::difference_type difference_type;
typedef typename std::iterator_traits<inner_iterator>::pointer pointer;
typedef typename std::iterator_traits<inner_iterator>::reference reference;
flattening_iterator() { }
flattening_iterator(outer_iterator it, outer_iterator begin, outer_iterator end)
: outer_it_(it),
outer_begin_(begin),
outer_end_(end),
inner_it_assigned_(false)
{
if (outer_begin_ == outer_end_) { return; }
if (outer_it_ == outer_end_) { return; }
inner_it_ = outer_it_->begin();
inner_it_assigned_ = true;
advance_past_empty_inner_containers();
}
reference operator*() const { return *inner_it_; }
pointer operator->() const { return &*inner_it_; }
flattening_iterator& operator++()
{
++inner_it_;
if (inner_it_ == outer_it_->end())
advance_past_empty_inner_containers();
return *this;
}
flattening_iterator operator++(int)
{
flattening_iterator it(*this);
++*this;
return it;
}
flattening_iterator& operator--()
{
if(!inner_it_assigned_)
{
if(outer_begin_ != outer_end_)
{
decrement_through_empty_inner_containers();
}
return *this;
}
if(inner_it_ == outer_it_->begin())
{
decrement_through_empty_inner_containers();
}
else
{
--inner_it_;
}
return *this;
}
flattening_iterator operator--(int)
{
flattening_iterator it(*this);
--*this;
return it;
}
friend bool operator==(const flattening_iterator& a,
const flattening_iterator& b)
{
if (a.outer_it_ != b.outer_it_)
return false;
if(a.outer_it_ != a.outer_end_ &&
b.outer_it_ != b.outer_end_ &&
a.inner_it_assigned_ == false &&
b.inner_it_assigned_ == false)
return true;
if (a.outer_it_ != a.outer_end_ &&
b.outer_it_ != b.outer_end_ &&
a.inner_it_ != b.inner_it_)
return false;
return true;
}
friend bool operator!=(const flattening_iterator& a,
const flattening_iterator& b)
{
return !(a == b);
}
private:
void advance_past_empty_inner_containers()
{
while (outer_it_ != outer_end_ && inner_it_ == outer_it_->end())
{
++outer_it_;
if (outer_it_ != outer_end_)
inner_it_ = outer_it_->begin();
}
}
void decrement_through_empty_inner_containers()
{
--outer_it_;
while(outer_it_ != outer_begin_ && outer_it_->begin() == outer_it_->end())
{
--outer_it_;
}
if(outer_it_->begin() != outer_it_->end())
{
inner_it_ = --outer_it_->end();
inner_it_assigned_ = true;
}
}
outer_iterator outer_it_;
outer_iterator outer_begin_;
outer_iterator outer_end_;
inner_iterator inner_it_;
bool inner_it_assigned_;
};
template <typename Iterator>
flattening_iterator<Iterator> flatten(Iterator start, Iterator first, Iterator last)
{
return flattening_iterator<Iterator>(start, first, last);
}
template <typename Iterator>
std::reverse_iterator<flattening_iterator<Iterator>> flatten_reverse(Iterator start, Iterator first, Iterator last)
{
return std::reverse_iterator<flattening_iterator<Iterator>>(flatten(start, first, last));
}
int main()
{
std::vector<std::vector<int>> v(3);
int i(0);
for (auto it(v.begin()); it != v.end(); ++it)
{
it->push_back(i++); it->push_back(i++);
it->push_back(i++); it->push_back(i++);
}
v.insert(v.begin(), std::vector<int>());
v.insert(v.begin(), std::vector<int>());
v.insert(v.begin() + 4, std::vector<int>());
v.push_back(std::vector<int>());
v.push_back(std::vector<int>());
for (auto it(flatten(v.begin(), v.begin(), v.end())), end = flatten(v.end(), v.begin(), v.end());
it != end;
++it)
{
std::cout << *it << ", ";
}
std::cout << "\n";
for (auto it(flatten_reverse(v.end(), v.begin(), v.end())), end = flatten_reverse(v.begin(), v.begin(), v.end());
it != end;
++it)
{
std::cout << *it << ", ";
}
std::cout << "\n";
std::vector<std::vector<int>> v2;
for (auto it(flatten(v2.end(), v2.begin(), v2.end())), end = flatten(v2.begin(), v2.begin(), v2.end());
it != end;
--it)
{
std::cout << *it << ", ";
}
std::cout << "\n";
}

Great question, and great attempt.
An iterator should always refer to a valid value, or one-past-the-end. *iter should always be valid unless iter == end where end is one-past-the-end. That "one-past-the-end" iterator is the cause of your worries. Either inner_it_ refers to a valid value, or your iterator is one-past-the-end.
James's "one-past-the-end" iterator exists when outer_it_ == outer_end_, and this is the situation you need to check for. This is the only situation in which inner_it_ should have an invalid value. As a result, you can get rid of the bool and just directly check outer_it_ == outer_end_.
Also, I find this line suspect:
inner_it_ = --outer_it_->end();
Is it possible that outer_it_ is a typedef to a pointer? If so, you can't call -- on a pointer value. This will definitely work:
inner_it_ = outer_it_->end();
--inner_it_;
and moreover, it conveys intent better, because the first looks like you're decrementing the end() iterator itself!

Related

C++ std::find_if on iterator in reverse order

In the following code, is there an elegant way to find it_end?
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <type_traits>
template <class Iterator, class U = typename std::iterator_traits<Iterator>::value_type>
void process(Iterator begin, Iterator end)
{
// first nonzero
auto it_begin = std::find_if(begin, end, [](U val){return val != 0;});
// end of nonzero values
int n = std::distance(begin, end);
int index = n-1;
for(int i=n-1; i>=0; --i) {
if(*(begin+i) == 0) {
index = i;
} else {
break;
}
}
auto it_end = begin;
std::advance(it_end, index);
// ******* is there a way to use std::find_if or similar function to get it_end? *******
for(auto it=it_begin; it!=it_end; ++it) {
// a whole bunch of things
// ...
std::cout << *it << std::endl;
}
}
int main()
{
std::vector<int> v{0,0,1,2,3,0,0};
process(v.begin(), v.end());
}
use std::reverse_iterator.
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>
#include <type_traits>
#include <list>
template <class Iterator, class U = typename std::iterator_traits<Iterator>::value_type>
void process(Iterator begin, Iterator end)
{
// first nonzero
auto it_begin = std::find_if(begin, end, [](U val){return val != 0;});
if (it_begin == end)
return; // all value is zeros.
// reverser iterator
auto r_begin = std::reverse_iterator(end);
auto r_end = std::reverse_iterator(it_begin);
auto r_find = std::find_if(r_begin, r_end, [](U val) { return val != 0; });
auto it_end = r_find.base();
for(auto it = it_begin; it != it_end; ++it) {
std::cout << *it << std::endl;
}
}
int main()
{
std::list<int> v{0,0,0,2,0,3,4};
process(v.begin(), v.end());
}
You can use the reverse iterator.
My implementation:
template <class Iterator, class U = typename std::iterator_traits<Iterator>::value_type>
void yet_another_process(Iterator begin, Iterator end, std::reverse_iterator<Iterator> rbegin, std::reverse_iterator<Iterator> rend) {
auto it_begin = std::find_if(begin, end, [](U val) { return val != 0; });
auto it_end = std::find_if(rbegin, rend, [](U val) { return val != 0; }).base(); // Notice this base()
for (auto it = it_begin; it != it_end; ++it) {
std::cout << *it << std::endl;
}
}
and in main():
int main() {
std::vector<int> v { 0, 0, 1, 2, 3, 0, 0 };
yet_another_process(v.begin(), v.end(), v.rbegin(), v.rend());
}
The base() method of a reverse iterator returns the underlying "normal" iterator.

How to look for an element inside a set of sets in C++?

Following is my code:
set<set<int,greater<int>>> output;
set<int,greater<int>> k;
k.insert(5);
output.insert(k);
Now how do I find out if element 5 is present in my 'output' set or not?
And how do I find out which set, inside my 'output' set, the element 5 belongs to?
Use a simple for loop:
size_t ii = 0;
for (const auto& inner : output) {
if (inner.count(5))
std::cout << "found in set " << ii << std::endl;
++ii;
}
There's a pre C++20 and a C++20 (using ranges) solution
Pre-C++20 I'm using std::find_if and set::find.
C++20 I'm using std::ranges::find_if and set::contains.
For the C++20 I'm also using std::optional std::reference_wrapper return type. And concepts, so it's a generic solution applicable to all sets and maps.
#include <set>
#include <algorithm>
template<typename T, typename Comp = std::less<T>>
std::set<T, Comp> const* findInSetOfSets(std::set<std::set<T, Comp>> const& setOfSets, T const& value) {
auto const it = std::find_if(cbegin(setOfSets), cend(setOfSets),
[&](std::set<T, Comp> const& set) { return set.find(value) != end(set); } );
if (it != cend(setOfSets)) return &*it;
return nullptr;
}
#include <optional>
#include <functional>
#include <type_traits>
template<typename T, typename U>
concept hasContains = requires(T& t, U& u) {
{ t.contains(u) } -> std::same_as<bool>;
};
template<std::ranges::input_range R, typename T,
typename U = std::remove_reference<R>::type::value_type>
requires hasContains<U, T>
[[nodiscard]] auto findCpp20(R&& r, T const& value) noexcept
->std::optional<std::reference_wrapper<U const>> {
auto it = std::ranges::find_if(r,
[&](U const& u) { return u.contains(value); } );
if (it != std::ranges::end(r)) return *it;
return std::nullopt;
}
#include <cstdio>
int main(){
std::set<std::set<int,std::greater<int>>> output;
std::set<int,std::greater<int>> k;
k.insert(5);
output.insert(k);
auto setPtr = findInSetOfSets(output, 5);
if (setPtr != nullptr) printf("set found!\n");
auto optionalSet = findCpp20(output, 5);
if (optionalSet.has_value()) printf("set found!\n");
}
godbolt
Here's a boolean function that looks for element p inside a set of sets s
bool findelem(int p, set<set<int>> const& s)
{
for (auto itr1= s.cbegin(); itr1 != s.cend(); ++itr1) {
for (auto itr2 = itr1->cbegin(); itr2 != itr1->cend(); ++itr2) {
if (*itr2==p) {
return true;
}
}
}
return false;
}

How to prevent infinite loop of custom iterator

I implemented my first custom iterator, which is supposed to return an std::pair at each iteration. The only problem, is it loops infinitely and I do not know how to provide stop condition. The code looks like so:
#include <iostream>
#include <vector>
#include <utility>
class Simple
{
private:
std::vector<std::size_t> indices;
std::vector<int> values;
public:
void insert(std::size_t index, int value)
{
indices.push_back(index);
values.push_back(value);
}
int at(std::size_t index)
{
return values[indices[index]];
}
class Iterator
{
private:
const std::vector<std::size_t>* indices;
const std::vector<int>* values;
std::size_t pos = 0;
public:
Iterator(const std::vector<std::size_t>* indices_, const std::vector<int>* values_, const std::size_t &pos_ = 0):
values(values_), indices(indices_), pos(pos_){ }
bool operator==(const Iterator& other){
return this == &other;
}
bool operator!=(const Iterator& other){
return !operator==(other);
}
Iterator operator++() {
pos++;
Iterator i = *this;
return i;
}
std::pair<std::size_t, int> operator*()
{
if (pos < (*values).size())
{
return std::make_pair((*indices)[pos], (*values)[pos]);
}
std::cout << "EMPTY PAIR" << std::endl; //loops infinitely and prints this message
return std::pair<std::size_t,int>{};
}
std::pair<std::size_t, int>* operator->()
{
if (pos < (*values).size())
{
std::pair<std::size_t,int> *p;
*p = std::make_pair((*indices)[pos], (*values)[pos]);
return p;
}
return nullptr;
}
};
Iterator begin() const
{
return Iterator(&indices, &values, 0);
}
Iterator end() const
{
return Iterator(&indices, &values, values.size());
}
};
int main() {
Simple s;
s.insert(10, 100);
std::cout << s.at(10) << std::endl;
int i = 0;
for (const std::pair<std::size_t, int> &p : s)
{
std::cout << p.first << " " << p.second << std::endl;
if (i > 3) break; // otherwise it will loop infinitely
i++;
}
return 0;
}
I would like to stress, that this example is simplified and for demonstration purposes, so you may not ask me, why I'm not using map or unorded_map (just because what I'm implementing looks like a map). The question is solely about iterator and I need understanding what may be wrong with iterator itself and how to provide stop condition.

Design operator++ for iterating over certain elements of a multimap

I have the following class declaration:
class Dictionnary{
private:
map< int,list<string> > data;
public:
bool isPrime();
class prime_iterator{
private:
map< int,list<string> >::iterator it;
public:
iterator(){}
prime_iterator & operator++(){
++it;
while(it != data.end() && !isPrime(it->first)){
++it;
}
return it;
}
...
};
which is intended to provide an iterator over prime keys of a map<int,list<string>>. I'm not sure operator++ is well implemented.
First, is it a good design to do it != data.end()accessing the outer class? Second, is operator++ returning the right thing or should return only prime_iterator?. Also, can you think about any better solution?
My advice is to always try to find solution elsewhere - if not found - then only create by yourself:
You can use boost::fiter_iterator
For your case it would look in this way:
#include <boost/iterator/filter_iterator.hpp>
using DataMap = std::map<int, std::list<std::string>>;
struct is_prime_number {
bool operator()(const DataMap::value_type& x) { return x.first % 2 == 0; }
}; // I know this is just is_even - not is_prime :D
using DataMapPrimeIter = boost::filter_iterator<is_prime_number, DataMap::iterator>;
inline DataMapPrimeIter only_prime_begin(DataMap& dataMap)
{
return boost::make_filter_iterator<is_prime_number>(dataMap.begin(), dataMap.end());
}
inline DataMapPrimeIter only_prime_end(DataMap& dataMap)
{
return boost::make_filter_iterator<is_prime_number>(dataMap.end(), dataMap.end());
}
And usage:
int main()
{
DataMap dataMap{{1,{"A","B"}}, {2,{"C", "D", "E"}}};
for (auto i = only_prime_begin(dataMap), end = only_prime_end(dataMap); i != end; ++i)
{
std::cout << i->first << i->second.front() << std::endl;
}
}
If you want to have your own implementation, or you cannot use boost in your project - then look at boost implementation - it is for free to look at...
My humble solution. The typedef is just for convenience.
#include <iterator>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <algorithm>
typedef std::map<int, std::string> map_t;
class Dictionary {
private:
map_t& m_map;
public:
class prime_iterator {
public:
prime_iterator( map_t::iterator begin, map_t::iterator end )
: m_current(begin), m_end(end) {
runUntilPrime();
}
prime_iterator& operator++() {
m_current++;
runUntilPrime();
return *this;
}
bool operator != (prime_iterator other) {
return other.m_current != m_current;
}
map_t::value_type& operator* () {
return *m_current;
}
private:
map_t::iterator m_current;
map_t::iterator m_end;
bool isPrime(int x) {
std::vector<int> primes = { 1, 2, 3, 5, 7, 11, 13, 17 };
return std::find( primes.begin(), primes.end(), x ) != primes.end();
}
void runUntilPrime() {
while( m_current != m_end && !isPrime(m_current->first) ) {
m_current++;
}
}
};
Dictionary( map_t& tmap )
: m_map(tmap) {}
prime_iterator begin() {
return prime_iterator( m_map.begin(), m_map.end() );
}
prime_iterator end () {
return prime_iterator(m_map.end(), m_map.end());
}
};
int main( int argc, char** argv ) {
map_t map;
map.emplace(0, "zero");
map.emplace(1, "one");
map.emplace(2, "two");
map.emplace(3, "three");
map.emplace(4, "four");
map.emplace(5, "five");
map.emplace(6, "six");
map.emplace(7, "seven");
map.emplace(8, "eight");
map.emplace(9, "nine");
map.emplace(10, "ten");
map.emplace(13, "thirteen");
Dictionary dict( map );
for( auto p : dict ) {
std::cout << p.first << "\t" << p.second << std::endl;
}
return 0;
}

Is there a standard cyclic iterator in C++

Based on the following question: Check if one string is a rotation of other string
I was thinking of making a cyclic iterator type that takes a range, and would be able to solve the above problem like so:
std::string s1 = "abc" ;
std::string s2 = "bca" ;
std::size_t n = 2; // number of cycles
cyclic_iterator it(s2.begin(),s2.end(),n);
cyclic_iterator end;
if (std::search(it, end, s1.begin(),s1.end()) != end)
{
std::cout << "s1 is a rotation of s2" << std::endl;
}
My question, Is there already something like this available? I've checked Boost and STL and neither have an exact implementation.
I've got a simple hand-written (derived from a std::forward_iterator_tag specialised version of std::iterator) one but would rather use an already made/tested implementation.
There is nothing like this in the standard. Cycles don't play well with C++ iterators because a sequence representing the entire cycle would have first == last and hence be the empty sequence.
Possibly you could introduce some state into the iterator, a Boolean flag to represent "not done yet." The flag participates in comparison. Set it true before iterating and to false upon increment/decrement.
But it might just be better to manually write the algorithms you need. Once you've managed to represent the whole cycle, representing an empty sequence might have become impossible.
EDIT: Now I notice that you specified the number of cycles. That makes a big difference.
template< class I >
class cyclic_iterator
/* : public iterator< bidirectional, yadda yadda > */ {
I it, beg, end;
int cnt;
cyclic_iterator( int c, I f, I l )
: it( f ), beg( f ), end( l ), cnt( c ) {}
public:
cyclic_iterator() : it(), beg(), end(), cnt() {}
cyclic_iterator &operator++() {
++ it;
if ( it == end ) {
++ cnt;
it = beg;
}
} // etc for --, post-operations
friend bool operator==
( cyclic_iterator const &lhs, cyclic_iterator const &rhs )
{ return lhs.it == rhs.it && lhs.cnt == rhs.cnt; } // etc for !=
friend pair< cyclic_iterator, cyclic_iterator > cycle_range
( int c, I f, I l ) {//factory function, better style outside this scope
return make_pair( cyclic_iterator( 0, f, l ),
cyclic_iterator( c, f, l ) );
}
};
This should provide some ideas/solutions: 2 renditions, the second is a little lighter in weight. Both tested using a subrange of a vector and a list ...
#include <vector>
template <typename T, typename Container = std::vector<T>, typename Iterator = Container::iterator>
class RingIterator : public std::iterator <std::bidirectional_iterator_tag, T, ptrdiff_t>
{
Container& data;
Iterator cursor;
Iterator begin;
Iterator end;
public:
RingIterator (Container& v) : data(v), cursor(v.begin()), begin(v.begin()), end(v.end()) {}
RingIterator (Container& v, const Iterator& i) : data(v), cursor(i), begin(v.begin()), end(v.end()) {}
RingIterator (Container& v, const Iterator& i, const Iterator& j) : data(v), cursor(i), begin(i), end(j) {}
RingIterator (Container& v, size_t i) : data(v), cursor(v.begin() + i % v.size()), begin(v.begin()), end(v.end()) {}
bool operator == (const RingIterator& x) const
{
return cursor == x.cursor;
}
bool operator != (const RingIterator& x) const
{
return ! (*this == x);
}
reference operator*() const
{
return *cursor;
}
RingIterator& operator++()
{
++cursor;
if (cursor == end)
cursor = begin;
return *this;
}
RingIterator operator++(int)
{
RingIterator ring = *this;
++*this;
return ring;
}
RingIterator& operator--()
{
if (cursor == begin)
cursor = end;
--cursor;
return *this;
}
RingIterator operator--(int)
{
RingIterator ring = *this;
--*this;
return ring;
}
RingIterator insert (const T& x)
{
return RingIterator (data, data.insert (cursor, x));
}
RingIterator erase()
{
return RingIterator (data, data.erase (cursor));
}
};
template <typename T, typename Iterator>
class CyclicIterator : public std::iterator <std::bidirectional_iterator_tag, T, ptrdiff_t>
{
Iterator cursor;
Iterator begin;
Iterator end;
public:
CyclicIterator (const Iterator& i, const Iterator& j) : cursor(i), begin(i), end(j) {}
bool operator == (const CyclicIterator& x) const
{
return cursor == x.cursor;
}
bool operator != (const CyclicIterator& x) const
{
return ! (*this == x);
}
reference operator*() const
{
return *cursor;
}
CyclicIterator& operator++()
{
++cursor;
if (cursor == end)
cursor = begin;
return *this;
}
CyclicIterator operator++(int)
{
CyclicIterator ring = *this;
++*this;
return ring;
}
CyclicIterator& operator--()
{
if (cursor == begin)
cursor = end;
--cursor;
return *this;
}
CyclicIterator operator--(int)
{
CyclicIterator ring = *this;
--*this;
return ring;
}
};
#include <iostream>
#include <iomanip>
#include <list>
enum { CycleSize = 9, ContainerSize };
template <typename cyclicIterator>
void test (cyclicIterator& iterator, size_t mn)
{
int m = mn;
while (m--)
for (int n = mn; n--; ++iterator)
std::cout << std::setw(3) << *iterator << ' ';
--iterator;
m = mn;
while (m--)
for (int n = mn; n--; --iterator)
std::cout << std::setw(3) << *iterator << ' ';
}
template <typename containers>
void load (containers& container)
{
while (container.size() < ContainerSize)
container.push_back (container.size());
}
void main (void)
{
typedef std::vector<int> vContainer;
typedef vContainer::iterator vIterator;
typedef std::list<int> lContainer;
typedef lContainer::iterator lIterator;
vContainer v; load (v);
vIterator vbegin = v.begin() + 1;
RingIterator <int, vContainer, vIterator> vring (v, vbegin, v.end());
CyclicIterator <int, vIterator> vcycle (vbegin, v.end());
lContainer l; load (l);
lIterator lbegin = l.begin(); ++lbegin;
RingIterator <int, lContainer, lIterator> lring (l, lbegin, l.end());
CyclicIterator <int, lIterator> lcycle (lbegin, l.end());
test (vring, CycleSize);
test (vcycle, CycleSize);
test (lring, CycleSize);
test (lcycle, CycleSize);
}
The CGAL library defines Circulators. They are used like this.
template<class Circulator, class T>
bool contains(Circulator c, Circulator d, const T& value) {
if (c != 0) {
do {
if (*c == value)
return true;
} while (++c != d);
}
return false;
}
Note that they look like iterators at first glance but note that the logic (and the structure of the loop) is different than for iterators). if(not empty) do{..}while() instead of while(){...}.
Eric Niebler's ranges-v3 library (on which the upcoming C++20 ranges is based) has ranges::view::cycle. This adapts its source range into an endlessly repeating infinite range. However we require a single repeat which may be easily achieved using ranges::view::concat.
#include <ranges/v3/all.hpp>
int main() {
std::string s1 = "abc";
std::string s2 = "bca";
auto s2s2 = ranges::view::concat(s2, s2);
auto i = std::search(s2s2.begin(), s2s2.end(), s1.begin(), s1.end());
if (i != s2s2.end() && s1.size() == s2.size()) {
std::cout << "s1 is a rotation of s2\n";
}
}
You’re maybe looking for Boost’s Circular Buffer. But if you’ve already checked Boost, it might not be the one you want.
On the other hand, the very idea of cyclic iterator is not compatible to STL container ideology. You should not want cyclic iterator, as the user of this iterator may be surprized by its unusual behavior. Usually in STL you are iterating from the beginning to the end of container. Infinite loop in that case. Because the end is not reachable.
After all, obviously, you are not going to do more than 2 cycles to solve your task. No reason to have special iterator with confusing behavior. That is better to iterate usual linear container twice or may be even less then twice.