Itérateur sur une collection de collections
Le
Marc Duflot

Bonjour,
Je voudrais itérer sur une collection de collections avec une paire
unique d'itérateurs de début et de fin. L'itérateur de début serait
l'itérateur de début de la première collection, l'itérateur de fin
serait celui de fin de la dernière et l'opérateur ++ passerait à la
collection suivante quand on arriverait à la fin d'une collection donnée.
Ça n'est pas très difficile à faire soi-même mais il me semblait qu'il y
avait dans boost un adaptateur simple à cet effet, que je ne le retrouve
pas. Une piste ?
Exemple :
void f(int);
vector<vector<int> > vv;
for_each(adaptateur<>(vv).begin(), adaptateur<>(vv).end(), f);
Merci,
Marc
Je voudrais itérer sur une collection de collections avec une paire
unique d'itérateurs de début et de fin. L'itérateur de début serait
l'itérateur de début de la première collection, l'itérateur de fin
serait celui de fin de la dernière et l'opérateur ++ passerait à la
collection suivante quand on arriverait à la fin d'une collection donnée.
Ça n'est pas très difficile à faire soi-même mais il me semblait qu'il y
avait dans boost un adaptateur simple à cet effet, que je ne le retrouve
pas. Une piste ?
Exemple :
void f(int);
vector<vector<int> > vv;
for_each(adaptateur<>(vv).begin(), adaptateur<>(vv).end(), f);
Merci,
Marc
Je ne crois pas que Boost.Iterator (http://www.boost.org/doc/libs/
1_42_0/libs/iterator/doc/index.html) contienne un tel itérateur. La
librairie contient toutefois deux bases permettant de créer facilement
des itérateurs spécialisés: iterator_facade (pour faciliter la
création d'un type complètement nouveau) et iterator_adaptor (pour
créer un itérateur basé sur un type existant). Si on s'en tient au ca s
où l'adapteur est appliqué sur une collection homogène d'itérateurs ,
j'imagine qu'un iterator_adaptor pourrait être construit relativement
facilement:
// Attention: Pas testé, sans doute plein de trous, pourrait sans
doute être plus efficace, pour illustration seulement, etc.
template<class Base>
class ChainedIterator : public boost::iterator_adaptor<
ChainedIterator<Base>,
Base,
boost::use_default,
boost::forward_traversal_tag
{
public:
template<class CollectionT>
ChainedIterator(CollectionT& Collection)
:
ChainedIterator::iterator_adaptor_(Collection.front().begin())
{
for (CollectionT::iterator i = Collection.begin(), next = +
+Collection.begin();
next != Collection.end();
++i, ++next)
{
m_NextBases.push_back(make_pair(i->end(), next-
}
}
ChainedIterator(Base B)
: ChainedIterator::iterator_adaptor_(B)
{
}
private:
std::deque<std::pair<Base, Base> > m_NextBases;
friend class boost::iterator_core_access;
void increment(){
++this->base_reference();
if (!m_NextBases.empty() && this->base_reference() ==
m_NextBases.front().first){
this->base_reference() = m_NextBases.front().second;
m_NextBases.pop_front();
}
}
};