Boost logo

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