Boost logo

Boost :

From: Herve Bronnimann (hbr_at_[hidden])
Date: 2002-11-19 01:11:00


Dave, Jeremy: one iterator adaptor I needed often (and once again today)
is the projection on the first or second member of a pair. I could make
it using projection_iterator<> and select1st, except that select1st is
an std extension from SGI. I haven't found any other out-of-the-box way
to do this, did I miss something?

I find them especially useful in connection with map::iterator, since
std::map does not have a value_iterator. I guess that alone provides the
rationale for including such an iterator adaptor, not to mention better
support of std::pair.

It's simple enough to make two adaptors, so if you don't see anything
wrong with it, I'm proposing the patch for you. I'll even write the
corresponding portion of the documentation if you go ahead with it.
Hope you like it,

-- 
Herve'
PS: I'll send you attachments, one is the patch and the second is the test file I
(quickly) wrote to test the patch, plus one more example to explore
further iterators and check, etc. I didn't want to post attachments to
the mailing list, but if anyone else would like to see them, please ask me.
PPS: since the patch is small enough, I'll just copy it below, and let
everyone see it.
Index: boost/iterator_adaptors.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/iterator_adaptors.hpp,v
retrieving revision 1.68
diff -u -r1.68 iterator_adaptors.hpp
--- boost/iterator_adaptors.hpp	11 Sep 2002 14:46:40 -0000	1.68
+++ boost/iterator_adaptors.hpp	19 Nov 2002 06:09:09 -0000
@@ -12,6 +12,9 @@
 //
 // Revision History:
 
+// 14 Nov 2002   Herve Bronnimann
+//      Added select_first_iterator and select_second_iterator, for
+//      iterating over std::map keys and values (among other uses).
 // 01 Feb 2002   Jeremy Siek
 //      Added more comments in default_iterator_policies.
 // 08 Jan 2001   David Abrahams
@@ -1240,6 +1243,116 @@
     typedef typename reverse_iterator_generator<BidirectionalIterator>::type result_t;
     return result_t(base);
 }
+
+
+//=============================================================================
+// Select First Iterator Adaptor
+
+struct select_first_iterator_policies : public default_iterator_policies
+{
+    select_first_iterator_policies() { }
+
+    template <class IteratorAdaptor>
+    typename IteratorAdaptor::reference
+    dereference(IteratorAdaptor const& iter) const {
+        return (*iter.base()).first;
+    }
+};
+
+template <class Iterator>
+class select_first_iterator_generator {
+    typedef typename boost::detail::iterator_traits<Iterator>
+	      ::value_type::first_type value_type;
+    typedef select_first_iterator_policies policies;
+public:
+    typedef iterator_adaptor<Iterator,policies,value_type,value_type&,value_type*> type;
+};
+
+template <class Iterator>
+class const_select_first_iterator_generator {
+    typedef typename boost::detail::iterator_traits<Iterator>
+	      ::value_type::first_type value_type;
+    typedef select_first_iterator_policies policies;
+public:
+    typedef iterator_adaptor<Iterator,policies,value_type,const value_type&,const value_type*> type;
+};
+
+template <class Iterator, class ConstIterator>
+struct select_first_iterator_pair_generator {
+    typedef typename select_first_iterator_generator<Iterator>::type iterator;
+    typedef typename const_select_first_iterator_generator<ConstIterator>::type const_iterator;
+};
+
+template <class Iterator>
+inline typename select_first_iterator_generator<Iterator>::type
+make_select_first_iterator( Iterator iter )
+{
+    typedef typename select_first_iterator_generator<Iterator>::type result_t;
+    return result_t(iter);
+}
+
+template <class Iterator>
+inline typename const_select_first_iterator_generator<Iterator>::type
+make_const_select_first_iterator(Iterator iter)
+{
+    typedef typename const_select_first_iterator_generator<Iterator>::type result_t;
+    return result_t(iter);
+}
+
+
+//=============================================================================
+// Select Second Iterator Adaptor
+
+struct select_second_iterator_policies : public default_iterator_policies
+{
+    select_second_iterator_policies() { }
+
+    template <class IteratorAdaptor>
+    typename IteratorAdaptor::reference dereference(IteratorAdaptor const& iter) const {
+        return (*iter.base()).second;
+    }
+};
+
+template <class Iterator>
+class select_second_iterator_generator {
+    typedef typename boost::detail::iterator_traits<Iterator>
+	      ::value_type::second_type value_type;
+    typedef select_second_iterator_policies policies;
+public:
+    typedef iterator_adaptor<Iterator,policies,value_type,value_type&,value_type*> type;
+};
+
+template <class Iterator>
+class const_select_second_iterator_generator {
+    typedef typename boost::detail::iterator_traits<Iterator>
+	      ::value_type::second_type value_type;
+    typedef select_second_iterator_policies policies;
+public:
+    typedef iterator_adaptor<Iterator,policies,value_type,const value_type&,const value_type*> type;
+};
+
+template <class Iterator, class ConstIterator>
+struct select_second_iterator_pair_generator {
+    typedef typename select_second_iterator_generator<Iterator>::type iterator;
+    typedef typename const_select_second_iterator_generator<ConstIterator>::type const_iterator;
+};
+
+template <class Iterator>
+inline typename select_second_iterator_generator<Iterator>::type
+make_select_second_iterator( Iterator iter )
+{
+    typedef typename select_second_iterator_generator<Iterator>::type result_t;
+    return result_t(iter);
+}
+
+template <class Iterator>
+inline typename const_select_second_iterator_generator<Iterator>::type
+make_const_select_second_iterator(Iterator iter)
+{
+    typedef typename const_select_second_iterator_generator<Iterator>::type result_t;
+    return result_t(iter);
+}
+
 
 //=============================================================================
 // Projection Iterators Adaptor

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk