|
Boost : |
Subject: [boost] [patch] first_iterator, second_iterator?
From: Daniel Colascione (daniel_at_[hidden])
Date: 2010-01-07 02:35:10
Iterating over the first and second elements of a collection of pairs is
a pretty common problem. Would it be possible to get something like the
following into boost?
#include <boost/iterator/iterator_adaptor.hpp>
/* For testing, below */
#include <map>
#include <string>
#include <iostream>
#include <iterator>
template<typename BaseIt>
struct first_iterator : boost::iterator_adaptor<
first_iterator<BaseIt>,
BaseIt,
typename BaseIt::value_type::first_type >
{
first_iterator()
: first_iterator::iterator_adaptor_()
{}
first_iterator(const BaseIt& bi)
: first_iterator::iterator_adaptor_(bi)
{}
operator const BaseIt&() {
return this->base_reference();
}
private:
friend struct boost::iterator_core_access;
typename BaseIt::value_type::first_type&
dereference() const
{
return this->base_reference()->first;
}
};
template<typename T>
first_iterator<T>
make_first_iterator(const T& it) {
return first_iterator<T>(it);
}
template<typename BaseIt>
struct second_iterator : boost::iterator_adaptor<
second_iterator<BaseIt>,
BaseIt,
typename BaseIt::value_type::second_type >
{
second_iterator()
: second_iterator::iterator_adaptor_()
{}
second_iterator(const BaseIt& bi)
: second_iterator::iterator_adaptor_(bi)
{}
operator const BaseIt&() {
return this->base_reference();
}
private:
friend struct boost::iterator_core_access;
typename BaseIt::value_type::second_type&
dereference() const
{
return this->base_reference()->second;
}
};
template<typename T>
second_iterator<T>
make_second_iterator(const T& it) {
return second_iterator<T>(it);
}
int main() {
typedef std::map<int, std::string> testmap;
testmap t;
t.insert(std::pair<int, std::string>(5, "middle"));
t.insert(std::pair<int, std::string>(2, "first"));
t.insert(std::pair<int, std::string>(8, "last"));
std::copy(make_first_iterator(t.begin()),
make_first_iterator(t.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << "\n";
std::copy(make_second_iterator(t.begin()),
make_second_iterator(t.end()),
std::ostream_iterator<std::string>(std::cout, " "));
std::cout << "\n";
first_iterator<testmap::iterator> x = t.begin();
++x;
t.erase(x);
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk