[patch] first_iterator, second_iterator?

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); }

Daniel Colascione wrote:
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?
Isn't that a trivial application of transform_iterator? Also, why did you post that message as a reply to socket and thread issues?

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 1/7/10 6:25 AM, Mathias Gaunard wrote:
Daniel Colascione wrote:
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?
Isn't that a trivial application of transform_iterator?
Sure, it can be implemented via transform_iterator too. And it is a trivial application. But it serves two purposes: 1) provides commonly-needed functionality with only a little additional code 2) provides examples for library users -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (Darwin) iEYEARECAAYFAktGWKoACgkQ17c2LVA10VsawgCgj1TBlPOLeIoaxub541hdxVWY FFMAoJovYYwOPtseJlDbCxGUOVr+jlfK =3w8v -----END PGP SIGNATURE-----

On Thu, Jan 7, 2010 at 4:56 PM, Daniel Colascione <daniel@censorshipresearch.org> wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 1/7/10 6:25 AM, Mathias Gaunard wrote:
Daniel Colascione wrote:
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?
Isn't that a trivial application of transform_iterator?
Sure, it can be implemented via transform_iterator too. And it is a trivial application. But it serves two purposes:
1) provides commonly-needed functionality with only a little additional code
2) provides examples for library users -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (Darwin)
iEYEARECAAYFAktGWKoACgkQ17c2LVA10VsawgCgj1TBlPOLeIoaxub541hdxVWY FFMAoJovYYwOPtseJlDbCxGUOVr+jlfK =3w8v -----END PGP SIGNATURE-----
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
FWIW, I've implemented exactly this tool in the codebase at work, using the transform_iterator technique. I've also written an analogous tool which extracts a particular element from each element in a collection of boost::tuples. I'd have been happy to see either or both as part of boost, or at least as examples in the iterator library. -Gabe

Sure, it can be implemented via transform_iterator too. And it is a trivial application. But it serves two purposes:
1) provides commonly-needed functionality with only a little additional code
Once a functor for selecting an elem of std::pair is available, wouldn't it also require little additional code to automate the creation of the associated transform_iterator? I illustrated this for fusion::map here: https://svn.boost.org/svn/boost/sandbox/statistics/detail/fusion/boost/stati... One small issue pertains to my post 10/5/09 11:01PM in the user's mailing list. In the same list I think I've already seen some posts about functors for std::pair and boost::tuple. HTH
participants (4)
-
Daniel Colascione
-
er
-
Gabriel Redner
-
Mathias Gaunard