mirror of
				https://github.com/boostorg/utility.git
				synced 2025-11-04 02:11:45 +01:00 
			
		
		
		
	
		
			
	
	
		
			630 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
		
		
			
		
	
	
			630 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| 
								 | 
							
								<html>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<head>
							 | 
						|||
| 
								 | 
							
								<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
							 | 
						|||
| 
								 | 
							
								<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
							 | 
						|||
| 
								 | 
							
								<meta name="ProgId" content="FrontPage.Editor.Document">
							 | 
						|||
| 
								 | 
							
								<title>Header boost/iterator_adaptors.hpp Documentation</title>
							 | 
						|||
| 
								 | 
							
								</head>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<body bgcolor="#FFFFFF" text="#000000">
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
							 | 
						|||
| 
								 | 
							
								align="center" width="277" height="86">
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h1>Header
							 | 
						|||
| 
								 | 
							
								<a href="../../boost/pending/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a></h1>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The file <tt>boost/iterator_adaptors.hpp</tt>
							 | 
						|||
| 
								 | 
							
								includes the main <tt>iterator_adaptors</tt> class and several other classes
							 | 
						|||
| 
								 | 
							
								for constructing commonly used iterator adaptors.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<ul>
							 | 
						|||
| 
								 | 
							
								  <li><a href="#iterator_adaptors"><tt>iterator_adaptors</tt></a>.
							 | 
						|||
| 
								 | 
							
								  <li><a href="#iterator_adaptor"><tt>iterator_adaptor</tt></a>.
							 | 
						|||
| 
								 | 
							
								  <li><a href="#transform_iterator"><tt>transform_iterator</tt></a>
							 | 
						|||
| 
								 | 
							
								  <li><a href="#indirect_iterators"><tt>indirect_iterators</tt></a>
							 | 
						|||
| 
								 | 
							
								  <li><a href="#reverse_iterators"><tt>reverse_iterators</tt></a>
							 | 
						|||
| 
								 | 
							
								  <li><a href="#integer_range"><tt>integer_range</tt></a>
							 | 
						|||
| 
								 | 
							
								</ul>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<!-- put in something about Andrei Alexandrescu's contribution? -->
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p><a href="http://www.boost.org/people/dave_abrahams.htm">Dave
							 | 
						|||
| 
								 | 
							
								Abrahams</a> started the library, coming up with the idea to use
							 | 
						|||
| 
								 | 
							
								policy classes and how to handle the const/non-const iterator
							 | 
						|||
| 
								 | 
							
								interactions. He also contributed the <tt>indirect_iterators</tt> and
							 | 
						|||
| 
								 | 
							
								<tt>reverse_iterators</tt> classes.<br>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>
							 | 
						|||
| 
								 | 
							
								contributed <tt>transform_iterator</tt>, <tt>integer_range</tt>,
							 | 
						|||
| 
								 | 
							
								and this documentation.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="iterator_adaptors">The Iterator Adaptors Class</a></h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Implementing standard conforming iterators is a non-trivial task.
							 | 
						|||
| 
								 | 
							
								There are some fine-points such as iterator/const_iterator
							 | 
						|||
| 
								 | 
							
								interactions and there are the myriad of operators that should be
							 | 
						|||
| 
								 | 
							
								implemented but are easily forgotten such as
							 | 
						|||
| 
								 | 
							
								<tt>operator->()</tt>. The purpose of the
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptors</tt> class is to make it easier to implement an
							 | 
						|||
| 
								 | 
							
								iterator class, and even easier to extend and adapt existing iterator
							 | 
						|||
| 
								 | 
							
								types. The <tt>iterator_adaptors</tt> class itself is not an adaptor
							 | 
						|||
| 
								 | 
							
								class but a <i>type generator</i>. It generates a pair of adaptor classes,
							 | 
						|||
| 
								 | 
							
								one class for the mutable iterator and one class for the const
							 | 
						|||
| 
								 | 
							
								iterator. The definition of the <tt>iterator_adaptors</tt> class is as
							 | 
						|||
| 
								 | 
							
								follows:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								template <class Iterator, 
							 | 
						|||
| 
								 | 
							
								          class ConstIterator, 
							 | 
						|||
| 
								 | 
							
								          class Traits = std::iterator_traits<Iterator>,
							 | 
						|||
| 
								 | 
							
								          class ConstTraits = std::iterator_traits<ConstIterator>, 
							 | 
						|||
| 
								 | 
							
								          class Policies = default_iterator_policies>
							 | 
						|||
| 
								 | 
							
								struct iterator_adaptors
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  typedef ... iterator;
							 | 
						|||
| 
								 | 
							
								  typedef ... const_iterator;
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The <tt>Iterator</tt> and <tt>ConstIterator</tt> template parameters
							 | 
						|||
| 
								 | 
							
								are the iterator types that you want to adapt. The <tt>Traits</tt> and
							 | 
						|||
| 
								 | 
							
								<tt>ConstTraits</tt> must be iterator traits classes.  The traits
							 | 
						|||
| 
								 | 
							
								parameters default to the specialization of the
							 | 
						|||
| 
								 | 
							
								<tt>std::iterator_traits</tt> class for the adapted iterators. If you
							 | 
						|||
| 
								 | 
							
								want the traits for your new iterator adaptor (<tt>value_type</tt>,
							 | 
						|||
| 
								 | 
							
								<tt>iterator_category</tt>, etc.) to be the same as the adapted
							 | 
						|||
| 
								 | 
							
								iterator then use the default, otherwise create your own traits
							 | 
						|||
| 
								 | 
							
								classes and pass them in <a href="#1">[1]</a>. 
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>The <tt>Policies</tt> class that you pass in will become the heart of
							 | 
						|||
| 
								 | 
							
								the iterator adaptor. The policy class determines how your new adaptor
							 | 
						|||
| 
								 | 
							
								class will behave. The <tt>Policies</tt> class must implement 3, 4, or
							 | 
						|||
| 
								 | 
							
								7 of the core iterator operations depending on whether you wish the
							 | 
						|||
| 
								 | 
							
								new iterator adaptor class to be a
							 | 
						|||
| 
								 | 
							
								<a href="http://www.sgi.com/Technology/STL/ForwardIterator.html">
							 | 
						|||
| 
								 | 
							
								ForwardIterator</a>,
							 | 
						|||
| 
								 | 
							
								<a href="http://www.sgi.com/Technology/STL/BidirectionalIterator.html">
							 | 
						|||
| 
								 | 
							
								BidirectionalIterator</a>, or <a
							 | 
						|||
| 
								 | 
							
								href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
							 | 
						|||
| 
								 | 
							
								RandomAccessIterator</a>. Make sure that the
							 | 
						|||
| 
								 | 
							
								<tt>iterator_category</tt> type of the traits class you pass in
							 | 
						|||
| 
								 | 
							
								matches the category of iterator that you want to create. The default
							 | 
						|||
| 
								 | 
							
								policy class, <tt>default_iterator_policies</tt>, implements all 7 of
							 | 
						|||
| 
								 | 
							
								the core operations in the usual way. If you wish to create an
							 | 
						|||
| 
								 | 
							
								iterator adaptor that only changes a few of the iterator's behaviors,
							 | 
						|||
| 
								 | 
							
								then you can have your new policy class inherit from
							 | 
						|||
| 
								 | 
							
								<tt>default_iterator_policies</tt> to avoid retyping the usual
							 | 
						|||
| 
								 | 
							
								behaviours. You should also look at <tt>default_iterator_policies</tt>
							 | 
						|||
| 
								 | 
							
								as the "boiler-plate" for your own policy classes. The
							 | 
						|||
| 
								 | 
							
								following is definition of the <tt>default_iterator_policies</tt>
							 | 
						|||
| 
								 | 
							
								class:
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								struct default_iterator_policies
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  // required for a ForwardIterator
							 | 
						|||
| 
								 | 
							
								  template <class Reference, class Iterator>
							 | 
						|||
| 
								 | 
							
								  Reference dereference(type<Reference>, const Iterator& x) const
							 | 
						|||
| 
								 | 
							
								    { return *x; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  template <class Iterator>
							 | 
						|||
| 
								 | 
							
								  void increment(Iterator& x) const
							 | 
						|||
| 
								 | 
							
								    { ++x; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  template <class Iterator1, class Iterator2>
							 | 
						|||
| 
								 | 
							
								  bool equal(Iterator1& x, Iterator2& y) const
							 | 
						|||
| 
								 | 
							
								    { return x == y; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  // required for a BidirectionalIterator
							 | 
						|||
| 
								 | 
							
								  template <class Iterator>
							 | 
						|||
| 
								 | 
							
								  void decrement(Iterator& x) const
							 | 
						|||
| 
								 | 
							
								    { --x; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  // required for a RandomAccessIterator
							 | 
						|||
| 
								 | 
							
								  template <class Iterator, class DifferenceType>
							 | 
						|||
| 
								 | 
							
								  void advance(Iterator& x, DifferenceType n) const
							 | 
						|||
| 
								 | 
							
								    { x += n; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  template <class Difference, class Iterator1, class Iterator2>
							 | 
						|||
| 
								 | 
							
								  Difference distance(type<Difference>, Iterator1& x, Iterator2& y) const
							 | 
						|||
| 
								 | 
							
								    { return y - x; }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  template <class Iterator1, class Iterator2>
							 | 
						|||
| 
								 | 
							
								  bool less(Iterator1& x, Iterator2& y) const
							 | 
						|||
| 
								 | 
							
								    { return x < y; }
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								The generated iterator adaptor types will have the following
							 | 
						|||
| 
								 | 
							
								constructors.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								<i>iterator</i>(const Iterator& i, const Policies& p = Policies())
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<i>const_iterator</i>(const ConstIterator& i, const Policies& p = Policies())
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="iterator_adaptor">The Iterator Adaptor Class</a></h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								This is the class used inside of the <tt>iterator_adaptors</tt> type
							 | 
						|||
| 
								 | 
							
								generator. Use this class directly (instead of using
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptors</tt>) when there is no difference between the
							 | 
						|||
| 
								 | 
							
								const and non-const versions of the iterator type. Often this is
							 | 
						|||
| 
								 | 
							
								because there is only a const (read-only) version of the iterator, as
							 | 
						|||
| 
								 | 
							
								is the case for <tt>std::set</tt>'s iterators. Use the same type for
							 | 
						|||
| 
								 | 
							
								the <tt>Iterator</tt> and <tt>NonconstIterator</tt> template
							 | 
						|||
| 
								 | 
							
								arguments.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								template <class Iterator, 
							 | 
						|||
| 
								 | 
							
								          class Policies = default_iterator_policies,
							 | 
						|||
| 
								 | 
							
								          class NonconstIterator = Iterator,         
							 | 
						|||
| 
								 | 
							
								          class Traits = std::iterator_traits<Iterator> >
							 | 
						|||
| 
								 | 
							
								struct iterator_adaptor;
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								Next we will look at some iterator adaptors that are examples of how
							 | 
						|||
| 
								 | 
							
								to use the iterator adaptors class, and that are useful iterator
							 | 
						|||
| 
								 | 
							
								adaptors in their own right.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="transform_iterator">The Transform Iterator Class</a></h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								It is often useful to automatically apply some function to the value
							 | 
						|||
| 
								 | 
							
								returned by dereferencing (<tt>operator*()</tt>) an iterator. The
							 | 
						|||
| 
								 | 
							
								<tt>transform_iterators</tt> class makes it easy to create an iterator
							 | 
						|||
| 
								 | 
							
								adaptor that does just that.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								First let us consider what the <tt>Policies</tt> class for the transform
							 | 
						|||
| 
								 | 
							
								iterator should look like. We are only changing one of the iterator
							 | 
						|||
| 
								 | 
							
								behaviours, so we will inherit from
							 | 
						|||
| 
								 | 
							
								<tt>default_iterator_policies</tt>. In addition, we will need a
							 | 
						|||
| 
								 | 
							
								function object to apply, so we will have a template parameter and a
							 | 
						|||
| 
								 | 
							
								data member for the function object. The function will take one
							 | 
						|||
| 
								 | 
							
								argument (the dereferenced value) and we will need to know the
							 | 
						|||
| 
								 | 
							
								<tt>result_type</tt> of the function, so <a
							 | 
						|||
| 
								 | 
							
								href="http://www.sgi.com/Technology/STL/AdaptableUnaryFunction.html">
							 | 
						|||
| 
								 | 
							
								AdaptableUnaryFunction</a> is the corrent concept to choose for the
							 | 
						|||
| 
								 | 
							
								function object type. Now for the heart of our iterator adaptor, we
							 | 
						|||
| 
								 | 
							
								implement the <tt>dereference</tt> method, applying the function
							 | 
						|||
| 
								 | 
							
								object to <tt>*i</tt>. The <tt>type<Reference></tt> class is
							 | 
						|||
| 
								 | 
							
								there to tell you what the reference type of the iterator is, which is
							 | 
						|||
| 
								 | 
							
								handy when writing generic iterator adaptors such as this one <a
							 | 
						|||
| 
								 | 
							
								href="#2">[2]</a>.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								  template <class AdaptableUnaryFunction>
							 | 
						|||
| 
								 | 
							
								  struct transform_iterator_policies : public default_iterator_policies
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    transform_iterator_policies(const AdaptableUnaryFunction& f) : m_f(f) { }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    template <class Reference, class Iterator>
							 | 
						|||
| 
								 | 
							
								    Reference dereference(type<Reference>, const Iterator& i) const
							 | 
						|||
| 
								 | 
							
								      { return m_f(*i); }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    AdaptableUnaryFunction m_f;
							 | 
						|||
| 
								 | 
							
								  };
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Next we need to create the traits class for our new iterator.  In some
							 | 
						|||
| 
								 | 
							
								situations you may need to create a separate traits class for the
							 | 
						|||
| 
								 | 
							
								const and non-const iterator types, but here a single traits class
							 | 
						|||
| 
								 | 
							
								will do. The <tt>value_type</tt> and <tt>reference</tt> type of our
							 | 
						|||
| 
								 | 
							
								transform iterator will be the <tt>result_type</tt> of the function
							 | 
						|||
| 
								 | 
							
								object.  The <tt>difference_type</tt> and <tt>iterator_category</tt>
							 | 
						|||
| 
								 | 
							
								will be the same as the adapted iterator.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								  template <class AdaptableUnaryFunction, class IteratorTraits>
							 | 
						|||
| 
								 | 
							
								  struct transform_iterator_traits {
							 | 
						|||
| 
								 | 
							
								    typedef typename AdaptableUnaryFunction::result_type value_type;
							 | 
						|||
| 
								 | 
							
								    typedef value_type reference;
							 | 
						|||
| 
								 | 
							
								    typedef value_type* pointer;
							 | 
						|||
| 
								 | 
							
								    typedef typename IteratorTraits::difference_type difference_type;
							 | 
						|||
| 
								 | 
							
								    typedef typename IteratorTraits::iterator_category iterator_category;
							 | 
						|||
| 
								 | 
							
								  };
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								The final step is to use the <tt>iterator_adaptor</tt> class to
							 | 
						|||
| 
								 | 
							
								construct our transform iterator. We will use the single iterator
							 | 
						|||
| 
								 | 
							
								adaptor version because we will not need to create both a mutable and
							 | 
						|||
| 
								 | 
							
								const version of the transform iterator. The transform iterator is
							 | 
						|||
| 
								 | 
							
								inherently a read-only iterator.  The nicest way to package up our new
							 | 
						|||
| 
								 | 
							
								transform iterator is to create a type generator similar to
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptor</tt>. The first template parameter will be the
							 | 
						|||
| 
								 | 
							
								type of the function object. The second parameter will be the adapted
							 | 
						|||
| 
								 | 
							
								iterator type. The third parameter is the trait class for
							 | 
						|||
| 
								 | 
							
								the adapted iterator.  Inside the <tt>transform_iterators</tt> class
							 | 
						|||
| 
								 | 
							
								we use the <tt>transform_iterator_traits</tt> class defined above to
							 | 
						|||
| 
								 | 
							
								create the traits class for the new transform iterator. We then use
							 | 
						|||
| 
								 | 
							
								the <tt>iterator_adaptor</tt> class to extract the generated
							 | 
						|||
| 
								 | 
							
								iterator adaptor type.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								template <class AdaptableUnaryFunction,
							 | 
						|||
| 
								 | 
							
								          class Iterator,
							 | 
						|||
| 
								 | 
							
								          class Traits = std::iterator_traits<Iterator>
							 | 
						|||
| 
								 | 
							
								         >
							 | 
						|||
| 
								 | 
							
								struct transform_iterator
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  typedef transform_iterator_traits<AdaptableUnaryFunction,Traits>
							 | 
						|||
| 
								 | 
							
								    TransTraits;
							 | 
						|||
| 
								 | 
							
								  typedef iterator_adaptor<Iterator, TransTraits,
							 | 
						|||
| 
								 | 
							
								    transform_iterator_policies<AdaptableUnaryFunction> >::type type;
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								The following is a simple example of how to use the
							 | 
						|||
| 
								 | 
							
								<tt>transform_iterators</tt> class to iterate through a range of
							 | 
						|||
| 
								 | 
							
								numbers, multiplying each of them by 2 when they are dereferenced.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								#include <functional>
							 | 
						|||
| 
								 | 
							
								#include <iostream>
							 | 
						|||
| 
								 | 
							
								#include <boost/iterator_adaptors.hpp>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								int
							 | 
						|||
| 
								 | 
							
								main(int, char*[])
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  typedef std::binder1st< std::multiplies<int> > Function;
							 | 
						|||
| 
								 | 
							
								  typedef boost::transform_iterator<Function, int*, 
							 | 
						|||
| 
								 | 
							
								    boost::iterator<std::random_access_iterator_tag, int>
							 | 
						|||
| 
								 | 
							
								  >::type doubling_iterator;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
							 | 
						|||
| 
								 | 
							
								    i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  std::cout << "multiplying the array by 2:" << std::endl;
							 | 
						|||
| 
								 | 
							
								  while (i != i_end)
							 | 
						|||
| 
								 | 
							
								    std::cout << *i++ << " ";
							 | 
						|||
| 
								 | 
							
								  std::cout << std::endl;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  return 0;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="indirect_iterators">The Indirect Iterators Class</a></h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								It is not all that uncommon to create data structures that consist of
							 | 
						|||
| 
								 | 
							
								pointers to pointers. For such a structure it might be nice to have an
							 | 
						|||
| 
								 | 
							
								iterator that applies a double-dereference inside the
							 | 
						|||
| 
								 | 
							
								<tt>operator*()</tt>. The implementation of this is similar to the
							 | 
						|||
| 
								 | 
							
								<tt>transform_iterators</tt><a href="#3">[3]</a>. We first create a
							 | 
						|||
| 
								 | 
							
								policies class which does a double-dereference in the
							 | 
						|||
| 
								 | 
							
								<tt>dereference()</tt> method. We then create a traits class, this
							 | 
						|||
| 
								 | 
							
								time also including a template parameter for the traits of the second
							 | 
						|||
| 
								 | 
							
								level iterators as well as the first. Lastly we wrap this up in the
							 | 
						|||
| 
								 | 
							
								type generator <tt>indirect_iterators</tt>, using
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptors</tt> to do most of the work.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								  struct indirect_iterator_policies : public default_iterator_policies
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    template <class Reference, class Iterator>
							 | 
						|||
| 
								 | 
							
								    Reference dereference(type<Reference>, const Iterator& x) const
							 | 
						|||
| 
								 | 
							
								      { return **x; }
							 | 
						|||
| 
								 | 
							
								  };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  template <class IndirectIterator,
							 | 
						|||
| 
								 | 
							
									    class IndirectTraits = std::iterator_traits<IndirectIterator>,
							 | 
						|||
| 
								 | 
							
									    class Traits = 
							 | 
						|||
| 
								 | 
							
									      std::iterator_traits<typename IndirectTraits::value_type>
							 | 
						|||
| 
								 | 
							
									   >
							 | 
						|||
| 
								 | 
							
								  struct indirect_traits
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    typedef typename IndirectTraits::difference_type difference_type;
							 | 
						|||
| 
								 | 
							
								    typedef typename Traits::value_type value_type;
							 | 
						|||
| 
								 | 
							
								    typedef typename Traits::pointer pointer;
							 | 
						|||
| 
								 | 
							
								    typedef typename Traits::reference reference;
							 | 
						|||
| 
								 | 
							
								    typedef typename IndirectTraits::iterator_category iterator_category;
							 | 
						|||
| 
								 | 
							
								  };
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  template <class IndirectIterator, class ConstIndirectIterator,
							 | 
						|||
| 
								 | 
							
								            class IndirectTraits = 
							 | 
						|||
| 
								 | 
							
								              std::iterator_traits<IndirectIterator>,
							 | 
						|||
| 
								 | 
							
								            class ConstIndirectTraits = 
							 | 
						|||
| 
								 | 
							
								              std::iterator_traits<ConstIndirectIterator>,
							 | 
						|||
| 
								 | 
							
								            class Traits =
							 | 
						|||
| 
								 | 
							
								              std::iterator_traits<typename IndirectTraits::value_type>
							 | 
						|||
| 
								 | 
							
								           >
							 | 
						|||
| 
								 | 
							
								  struct indirect_iterators
							 | 
						|||
| 
								 | 
							
								  {
							 | 
						|||
| 
								 | 
							
								    typedef typename IndirectTraits::value_type Iterator;
							 | 
						|||
| 
								 | 
							
								    typedef typename Traits::value_type ValueType;
							 | 
						|||
| 
								 | 
							
								    typedef iterator_adaptors<IndirectIterator, ConstIndirectIterator,
							 | 
						|||
| 
								 | 
							
								      indirect_traits<IndirectIterator, IndirectTraits, Traits>,
							 | 
						|||
| 
								 | 
							
								      indirect_traits<ConstIndirectIterator, ConstIndirectTraits, Traits>,
							 | 
						|||
| 
								 | 
							
								      indirect_iterator_policies
							 | 
						|||
| 
								 | 
							
								      > Adaptors;
							 | 
						|||
| 
								 | 
							
								    typedef typename Adaptors::iterator iterator;
							 | 
						|||
| 
								 | 
							
								    typedef typename Adaptors::const_iterator const_iterator;
							 | 
						|||
| 
								 | 
							
								  };
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="reverse_iterators">The Reverse Iterators Class</a></h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								Yes, there is already a <tt>reverse_iterator</tt> adaptor class
							 | 
						|||
| 
								 | 
							
								defined in the C++ Standard, but using the <tt>iterator_adaptors</tt>
							 | 
						|||
| 
								 | 
							
								class we can re-implement this classic adaptor in a more succinct and
							 | 
						|||
| 
								 | 
							
								elegant fashion. Also, this makes for a good example of using
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptors</tt> that is in familiar territory.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								The first step is to create the <tt>Policies</tt> class. As in the
							 | 
						|||
| 
								 | 
							
								<tt>std::reverse_iterator</tt> class, we need to flip all the
							 | 
						|||
| 
								 | 
							
								operations of the iterator. Increment will become decrement, advancing
							 | 
						|||
| 
								 | 
							
								by <tt>n</tt> will become retreating by <tt>n</tt>, etc. 
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								struct reverse_iterator_policies
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  template <class Reference, class Iterator>
							 | 
						|||
| 
								 | 
							
								  Reference dereference(type<Reference>, const Iterator& x) const
							 | 
						|||
| 
								 | 
							
								    { return *boost::prior(x); }
							 | 
						|||
| 
								 | 
							
								    // this is equivalent to { Iterator tmp = x; return *--tmp; }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								  template <class Iterator>
							 | 
						|||
| 
								 | 
							
								  void increment(Iterator& x) const
							 | 
						|||
| 
								 | 
							
								    { --x; }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								  template <class Iterator>
							 | 
						|||
| 
								 | 
							
								  void decrement(Iterator& x) const
							 | 
						|||
| 
								 | 
							
								    { ++x; }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								  template <class Iterator, class DifferenceType>
							 | 
						|||
| 
								 | 
							
								  void advance(Iterator& x, DifferenceType n) const
							 | 
						|||
| 
								 | 
							
								    { x -= n; }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								  template <class Difference, class Iterator1, class Iterator2>
							 | 
						|||
| 
								 | 
							
								  Difference distance(type<Difference>, Iterator1& x, Iterator2& y) const
							 | 
						|||
| 
								 | 
							
								    { return x - y; }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								  template <class Iterator1, class Iterator2>
							 | 
						|||
| 
								 | 
							
								  bool equal(Iterator1& x, Iterator2& y) const
							 | 
						|||
| 
								 | 
							
								    { return x == y; }
							 | 
						|||
| 
								 | 
							
								    
							 | 
						|||
| 
								 | 
							
								  template <class Iterator1, class Iterator2>
							 | 
						|||
| 
								 | 
							
								  bool less(Iterator1& x, Iterator2& y) const
							 | 
						|||
| 
								 | 
							
								    { return y < x; }
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Since the traits of the reverse iterator adaptor will be the same as
							 | 
						|||
| 
								 | 
							
								the adapted iterator's traits, we do not need to create new traits
							 | 
						|||
| 
								 | 
							
								classes as was the case for <tt>transform_iterator</tt>. We can skip to
							 | 
						|||
| 
								 | 
							
								the final stage of creating a type generator class for our reverse
							 | 
						|||
| 
								 | 
							
								iterators using the <tt>iterator_adaptor</tt> class.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								template <class Iterator, class ConstIterator,
							 | 
						|||
| 
								 | 
							
								          class Traits = std::iterator_traits<Iterator>, 
							 | 
						|||
| 
								 | 
							
								          class ConstTraits = std::iterator_traits<ConstIterator>
							 | 
						|||
| 
								 | 
							
								         >
							 | 
						|||
| 
								 | 
							
								struct reverse_iterators
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  typedef iterator_adaptors<Iterator,ConstIterator,Traits,ConstTraits,
							 | 
						|||
| 
								 | 
							
								    reverse_iterator_policies> Adaptor;
							 | 
						|||
| 
								 | 
							
								  typedef typename Adaptor::iterator iterator;
							 | 
						|||
| 
								 | 
							
								  typedef typename Adaptor::const_iterator const_iterator;
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								A typical use of the <tt>reverse_iterators</tt> class is in
							 | 
						|||
| 
								 | 
							
								user-defined container types. You can use the
							 | 
						|||
| 
								 | 
							
								<tt>reverse_iterators</tt> class to generate the reverse iterators for
							 | 
						|||
| 
								 | 
							
								your container.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								class my_container {
							 | 
						|||
| 
								 | 
							
								  ...
							 | 
						|||
| 
								 | 
							
								  typedef ... iterator;
							 | 
						|||
| 
								 | 
							
								  typedef ... const_iterator;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  typedef reverse_iterators<iterator, const_iterator> RevIters;
							 | 
						|||
| 
								 | 
							
								  typedef typename RevIters::iterator reverse_iterator;
							 | 
						|||
| 
								 | 
							
								  typedef typename RevIters::const_iterator const_reverse_iterator;
							 | 
						|||
| 
								 | 
							
								  ...
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3><a name="integer_range">The Integer Range Class</a></h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								The <tt>iterator_adaptors</tt> class can not only be used for adapting
							 | 
						|||
| 
								 | 
							
								iterators, but it can also be used to take a non-iterator type and use
							 | 
						|||
| 
								 | 
							
								it to build an iterator. An especially simple example of this is
							 | 
						|||
| 
								 | 
							
								turning an integer type into an iterator, a counting iterator. The
							 | 
						|||
| 
								 | 
							
								builtin integer types of C++ are almost iterators. They have
							 | 
						|||
| 
								 | 
							
								<tt>operator++()</tt>, <tt>operator--()</tt>, etc. The one operator
							 | 
						|||
| 
								 | 
							
								they are lacking is the <tt>operator*()</tt>, which we will want to
							 | 
						|||
| 
								 | 
							
								simply return the current value of the integer. The following few
							 | 
						|||
| 
								 | 
							
								lines of code implement the policy and traits class for the counting
							 | 
						|||
| 
								 | 
							
								iterator.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								struct counting_iterator_policies : public default_iterator_policies
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								  template <class IntegerType>
							 | 
						|||
| 
								 | 
							
								  IntegerType dereference(type<IntegerType>, const IntegerType& i) const
							 | 
						|||
| 
								 | 
							
								    { return i; }
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								template <class IntegerType>
							 | 
						|||
| 
								 | 
							
								struct counting_iterator_traits {
							 | 
						|||
| 
								 | 
							
								  typedef IntegerType value_type;
							 | 
						|||
| 
								 | 
							
								  typedef IntegerType reference;
							 | 
						|||
| 
								 | 
							
								  typedef value_type* pointer;
							 | 
						|||
| 
								 | 
							
								  typedef std::ptrdiff_t difference_type;
							 | 
						|||
| 
								 | 
							
								  typedef std::random_access_iterator_tag iterator_category;
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								Typically we will want to count the integers in some range, so a nice
							 | 
						|||
| 
								 | 
							
								interface would be to have a fake container that represents the range
							 | 
						|||
| 
								 | 
							
								of integers. The following is the definition of such a class called
							 | 
						|||
| 
								 | 
							
								<tt>integer_range</tt>.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								template <class IntegerType>
							 | 
						|||
| 
								 | 
							
								struct integer_range {
							 | 
						|||
| 
								 | 
							
								  typedef typename iterator_adaptor<IntegerType, 
							 | 
						|||
| 
								 | 
							
								                           counting_iterator_traits<IntegerType>,
							 | 
						|||
| 
								 | 
							
								                           counting_iterator_policies >::type iterator;
							 | 
						|||
| 
								 | 
							
								  typedef iterator const_iterator;
							 | 
						|||
| 
								 | 
							
								  typedef IntegerType value_type;
							 | 
						|||
| 
								 | 
							
								  typedef std::ptrdiff_t difference_type;
							 | 
						|||
| 
								 | 
							
								  typedef IntegerType reference;
							 | 
						|||
| 
								 | 
							
								  typedef IntegerType* pointer;
							 | 
						|||
| 
								 | 
							
								  typedef IntegerType size_type;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  integer_range(IntegerType start, IntegerType finish)
							 | 
						|||
| 
								 | 
							
								    : m_start(start), m_finish(finish) { }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								  iterator begin() const { return iterator(m_start); }
							 | 
						|||
| 
								 | 
							
								  iterator end() const { return iterator(m_finish); }
							 | 
						|||
| 
								 | 
							
								  size_type size() const { return m_finish - m_start; }
							 | 
						|||
| 
								 | 
							
								  bool empty() const { return m_finish == m_start; }
							 | 
						|||
| 
								 | 
							
								  void swap(integer_range& x) {
							 | 
						|||
| 
								 | 
							
								    std::swap(m_start, x.m_start);
							 | 
						|||
| 
								 | 
							
								    std::swap(m_finish, x.m_finish);
							 | 
						|||
| 
								 | 
							
								  }
							 | 
						|||
| 
								 | 
							
								protected:
							 | 
						|||
| 
								 | 
							
								  IntegerType m_start, m_finish;
							 | 
						|||
| 
								 | 
							
								};
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								The following is an example of how to use the
							 | 
						|||
| 
								 | 
							
								<tt>integer_range</tt> class to count from 0 to 4.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
							 | 
						|||
| 
								 | 
							
								<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
							 | 
						|||
| 
								 | 
							
								<PRE>
							 | 
						|||
| 
								 | 
							
								boost::integer_range<int> r(0,5);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								cout << "counting to from 0 to 4:" << endl;
							 | 
						|||
| 
								 | 
							
								std::copy(r.begin(), r.end(), ostream_iterator<int>(cout, " "));
							 | 
						|||
| 
								 | 
							
								cout << endl;
							 | 
						|||
| 
								 | 
							
								</PRE></TD></TABLE>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3>Challenge</h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								There is an unlimited number of ways the the
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptors</tt> class can be used to create iterators. One
							 | 
						|||
| 
								 | 
							
								interesting exercise would be to re-implement the iterators of
							 | 
						|||
| 
								 | 
							
								<tt>std::list</tt> and <tt>std::slist</tt> using
							 | 
						|||
| 
								 | 
							
								<tt>iterator_adaptors</tt>, where the adapted <tt>Iterator</tt> types
							 | 
						|||
| 
								 | 
							
								would be node pointers.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3>Notes</h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<a name="1">[1]</a>
							 | 
						|||
| 
								 | 
							
								If your compiler does not support partial specialization and hence
							 | 
						|||
| 
								 | 
							
								does not have a working <tt>std::iterator_traits</tt> class, you will
							 | 
						|||
| 
								 | 
							
								not be able to use the defaults and will need to supply your own
							 | 
						|||
| 
								 | 
							
								<tt>Traits</tt> and <tt>ConstTraits</tt> classes.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<a name="2">[2]</a>
							 | 
						|||
| 
								 | 
							
								The reference type could also be obtained from
							 | 
						|||
| 
								 | 
							
								<tt>std::iterator_traits</tt>, but that is not portable on compilers
							 | 
						|||
| 
								 | 
							
								that do not support partial specialization.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<p>
							 | 
						|||
| 
								 | 
							
								<a name="3">[3]</a>
							 | 
						|||
| 
								 | 
							
								It would have been more elegant to implement <tt>indirect_iterators</tt>
							 | 
						|||
| 
								 | 
							
								using <tt>transform_iterators</tt>, but for subtle reasons that would require
							 | 
						|||
| 
								 | 
							
								the use of <tt>boost::remove_cv</tt> which is not portable.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<h3>Implementation Notes</h3>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								The code is somewhat complicated because there are three iterator
							 | 
						|||
| 
								 | 
							
								adaptor class: <tt>forward_iterator_adaptor</tt>,
							 | 
						|||
| 
								 | 
							
								<tt>bidirectional_iterator_adaptor</tt>, and
							 | 
						|||
| 
								 | 
							
								<tt>random_access_iterator_adaptor</tt>. The alternative would be to
							 | 
						|||
| 
								 | 
							
								just have one iterator adaptor equivalent to the
							 | 
						|||
| 
								 | 
							
								<tt>random_access_iterator_adaptor</tt>.  The reason for going with
							 | 
						|||
| 
								 | 
							
								the three adaptors is that according to 14.5.3p5 in the C++ Standard,
							 | 
						|||
| 
								 | 
							
								friend functions defined inside a template class body are instantiated
							 | 
						|||
| 
								 | 
							
								when the template class is instantiated. This means that if we only
							 | 
						|||
| 
								 | 
							
								used the one iterator adaptor, then if the adapted iterator did not
							 | 
						|||
| 
								 | 
							
								meet all of the requirements for a
							 | 
						|||
| 
								 | 
							
								<a href="http://www.sgi.com/Technology/STL/RandomAccessIterator.html">
							 | 
						|||
| 
								 | 
							
								RandomAccessIterator</a> then a compiler error should occur.  Many
							 | 
						|||
| 
								 | 
							
								current compilers in fact do not instantiate the friend functions
							 | 
						|||
| 
								 | 
							
								unless used, so we could get away with the one iterator adaptor in
							 | 
						|||
| 
								 | 
							
								most cases. However, out of respect for the standard this implementation
							 | 
						|||
| 
								 | 
							
								uses the three adaptors.
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								<hr>
							 | 
						|||
| 
								 | 
							
								<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Jun 2000<!--webbot bot="Timestamp" endspan i-checksum="15055" --></p>
							 | 
						|||
| 
								 | 
							
								<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
							 | 
						|||
| 
								 | 
							
								modify, sell and distribute this document is granted provided this copyright
							 | 
						|||
| 
								 | 
							
								notice appears in all copies. This document is provided "as is"
							 | 
						|||
| 
								 | 
							
								without express or implied warranty, and with no claim as to its suitability for
							 | 
						|||
| 
								 | 
							
								any purpose.</p>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								</body>
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								</html>
							 |