Such a class wouldn't be that difficult to write, here's something that
I cobbled together just now (standard warning applies; hasn't been
tested, yadda, yadda, yadda), should give you an idea where to start
----Begin code ---
#include <deque>
#include <utility>
template<typename Iterator>
class DisjointIterator
{
public:
typedef std::input_iterator_tag iterator_category;
typedef typename std::iterator_traits<Iterator>::value_type
value_type;
typedef typename std::iterator_traits<Iterator>::difference_type
difference_type;
typedef typename std::iterator_traits<Iterator>::pointer pointer;
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef const reference const_reference;
typedef const pointer const_pointer;
private:
bool m_is_end;
std::deque<std::pair<Iterator,Iterator> > m_iters; //Pairs of begin
and end iterators
Iterator m_iter;
Iterator m_next_end;
void pop_next_iterator_range()
{
m_is_end = m_iters.empty();
if(!m_is_end)
{
m_iter = m_iters.front().first;
m_next_end = m_iters.front().second;
m_iters.pop_front();
}
}
public:
DisjointIterator() : m_is_end(true) {}
DisjointIterator(const DisjointIterator &other) :
m_is_end(other.m_is_end), m_iters(other.m_iters), m_iter(other.m_iter),
m_next_end(other.m_next_end) {}
template<typename IteratorListInputIterator> //Should be an
InputIterator into a sequence of std::pair<Iterator,Iterator>
DisjointIterator(IteratorListInputIterator iter,
IteratorListInputIterator end)
{
for(;iter != end; ++iter)
{
if(iter->first != iter->second)
{
m_iters.push_back(*iter);
}
}
pop_next_iterator_range();
}
DisjointIterator &operator=(const DisjointIterator &other)
{
m_is_end = other.m_is_end;
m_iters = other.m_iters;
m_iter = other.m_iter;
m_next_end = other.m_next_end;
return *this;
}
DisjointIterator &operator++()
{
if(!m_is_end)
{
++m_iter;
if(m_iter == m_next_end)
{
pop_next_iterator_range();
}
}
return *this;
}
DisjointIterator operator++(int)
{
DisjointIterator temp(*this);
++*this;
return temp;
}
bool operator==(const DisjointIterator &other) const
{
if(m_is_end)
{
return other.m_is_end;
}
else
{
return m_iter == other.m_iter;
}
}
bool operator!=(const DisjointIterator &other) const { return
!operator==(other); }
reference operator*() { return *m_iter; }
const_reference operator*() const { return *m_iter; }
pointer operator->() { return &(operator*()); }
const_pointer operator->() const { return &(operator*()); }
};
---- end code ----
And, for a sanity check, I just used it like so:
---- begin code ----
#include <vector>
using std::vector;
#include <utility>
using std::pair;
using std::make_pair;
#include <iterator>
using std::ostream_iterator;
#include <iostream>
using std::cout;
int main()
{
vector<int> vec;
for(int i = 0; i<100; ++i)
{
vec.push_back(i);
}
vector<pair<vector<int>::iterator, vector<int>::iterator> > iters;
iters.push_back(make_pair(vec.begin(), vec.begin()+3));
iters.push_back(make_pair(vec.begin()+20, vec.begin()+20));
iters.push_back(make_pair(vec.begin()+21, vec.begin()+30));
iters.push_back(make_pair(vec.begin()+90, vec.end()));
iters.push_back(make_pair(vec.begin()+20, vec.begin()+25));
DisjointIterator<vector<int>::iterator>
disjoint_begin(iters.begin(), iters.end());
DisjointIterator<vector<int>::iterator> disjoint_end;
std::copy(disjoint_begin, disjoint_end, ostream_iterator<int>(cout,
", "));
cout << "\n";
return 0;
}
---- end code ----
Which produced the following output:
0, 1, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 20, 21, 22, 23, 24,
[ See
http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]