updated docs for indirect iterators

[SVN r8319]
This commit is contained in:
Jeremy Siek 2000-11-24 20:22:23 +00:00
parent 353c030918
commit ba354377d5

View File

@ -23,7 +23,8 @@ for constructing commonly used iterator adaptors.</p>
<li><a href="#iterator_adaptors"><tt>iterator_adaptors</tt></a>. <li><a href="#iterator_adaptors"><tt>iterator_adaptors</tt></a>.
<li><a href="#iterator_adaptor"><tt>iterator_adaptor</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="#transform_iterator"><tt>transform_iterator</tt></a>
<li><a href="#indirect_iterators"><tt>indirect_iterators</tt></a> <li><a href="#indirect_iterators"><tt>Indirect Iterator Adaptors</tt></a>
<li><a href="#projection_iterators"><tt>Projection Iterator Adaptors</tt></a>
<li><a href="#reverse_iterators"><tt>reverse_iterators</tt></a> <li><a href="#reverse_iterators"><tt>reverse_iterators</tt></a>
<li><a href="#integer_range"><tt>integer_range</tt></a> <li><a href="#integer_range"><tt>integer_range</tt></a>
</ul> </ul>
@ -39,7 +40,11 @@ interactions. He also contributed the <tt>indirect_iterators</tt> and
<a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a> <a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>
contributed <tt>transform_iterator</tt>, <tt>integer_range</tt>, contributed <tt>transform_iterator</tt>, <tt>integer_range</tt>,
and this documentation. and this documentation.<br>
<a href="http://www.boost.org/people/john_potter.htm">John Potter</a>
contributed <tt>indirect_iterator</tt> and <tt>projection_iterator</tt>
and made some simplifications to <tt>iterator_adaptor</tt>.
<h3><a name="iterator_adaptors">The Iterator Adaptors Class</a></h3> <h3><a name="iterator_adaptors">The Iterator Adaptors Class</a></h3>
@ -119,7 +124,7 @@ struct default_iterator_policies
{ return *x; } { return *x; }
template &lt;class Iterator&gt; template &lt;class Iterator&gt;
void increment(Iterator& x) const static void increment(Iterator& x)
{ ++x; } { ++x; }
template &lt;class Iterator1, class Iterator2&gt; template &lt;class Iterator1, class Iterator2&gt;
@ -128,12 +133,12 @@ struct default_iterator_policies
// required for a BidirectionalIterator // required for a BidirectionalIterator
template &lt;class Iterator&gt; template &lt;class Iterator&gt;
void decrement(Iterator& x) const static void decrement(Iterator& x)
{ --x; } { --x; }
// required for a RandomAccessIterator // required for a RandomAccessIterator
template &lt;class Iterator, class DifferenceType&gt; template &lt;class Iterator, class DifferenceType&gt;
void advance(Iterator& x, DifferenceType n) const static void advance(Iterator& x, DifferenceType n)
{ x += n; } { x += n; }
template &lt;class Difference, class Iterator1, class Iterator2&gt; template &lt;class Difference, class Iterator1, class Iterator2&gt;
@ -176,7 +181,6 @@ arguments.
<PRE> <PRE>
template &lt;class Iterator, template &lt;class Iterator,
class Policies = default_iterator_policies, class Policies = default_iterator_policies,
class NonconstIterator = Iterator,
class Traits = std::iterator_traits&lt;Iterator&gt; &gt; class Traits = std::iterator_traits&lt;Iterator&gt; &gt;
struct iterator_adaptor; struct iterator_adaptor;
</PRE></TD></TABLE> </PRE></TD></TABLE>
@ -319,19 +323,21 @@ main(int, char*[])
</PRE></TD></TABLE> </PRE></TD></TABLE>
<h3><a name="indirect_iterators">The Indirect Iterators Class</a></h3> <h3><a name="indirect_iterators">The Indirect Iterator Adaptors</a></h3>
It is not all that uncommon to create data structures that consist of 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 pointers to pointers. For such a structure it might be nice to have an
iterator that applies a double-dereference inside the iterator that applies a double-dereference inside the
<tt>operator*()</tt>. The implementation of this is similar to 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 <tt>transform_iterators</tt><a href="#3">[3]</a>. When talking about a
policies class which does a double-dereference in the data structure of pointers to pointers (or more generally, iterators
<tt>dereference()</tt> method. We then create a traits class, this to iterators), we call the first level iterators the <i>outer</i>
time also including a template parameter for the traits of the second iterators and the second level iterators the <i>inner</i>
level iterators as well as the first. Lastly we wrap this up in the iterators. For example, if the outer iterator type is <tt>T**</tt>
type generator <tt>indirect_iterators</tt>, using then the inner iterator type is <tt>T*</tt>.
<tt>iterator_adaptors</tt> to do most of the work.
To implement the indirect adaptors, we first create a policies class
which does a double-dereference in the <tt>dereference()</tt> method.
<p> <p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2> <TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
@ -343,36 +349,69 @@ type generator <tt>indirect_iterators</tt>, using
Reference dereference(type&lt;Reference&gt;, const Iterator& x) const Reference dereference(type&lt;Reference&gt;, const Iterator& x) const
{ return **x; } { return **x; }
}; };
</PRE></TD></TABLE>
template &lt;class IndirectIterator, We then create a traits class, including a template parameter for both
class IndirectTraits = std::iterator_traits&lt;IndirectIterator&gt;, the inner and outer iterators and traits classes. The
class Traits = <tt>difference_type</tt> and <tt>iterator_category</tt> come from the
std::iterator_traits&lt;typename IndirectTraits::value_type&gt; outer iterator, while the <tt>value_type</tt>, <tt>pointer</tt>, and
<tt>reference</tt> types come from the inner iterator.
<p>
<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 COLS=2>
<TR><TD WIDTH=30 VALIGN=TOP></TD><TD>
<PRE>
template &lt;class OuterIterator, class InnerIterator,
class OuterTraits = std::iterator_traits&lt;OuterIterator&gt;,
class InnerTraits = std::iterator_traits&lt;InnerIterator&gt;
&gt; &gt;
struct indirect_traits struct indirect_traits
{ {
typedef typename IndirectTraits::difference_type difference_type; typedef typename OuterTraits::difference_type difference_type;
typedef typename Traits::value_type value_type; typedef typename InnerTraits::value_type value_type;
typedef typename Traits::pointer pointer; typedef typename InnerTraits::pointer pointer;
typedef typename Traits::reference reference; typedef typename InnerTraits::reference reference;
typedef typename IndirectTraits::iterator_category iterator_category; typedef typename OuterTraits::iterator_category iterator_category;
};
</PRE></TD></TABLE>
Lastly we wrap this up in two type generators:
<tt>indirect_iterator</tt> for creating a single indirect iterator
type, and <tt>indirect_iterators</tt> for creating an const/non-const
pair of indirect iterator types. We use the <tt>iterator_adaptor</tt>
and <tt>iterator_adaptors</tt> classes here 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>
template &lt;class OuterIterator, class InnerIterator,
class OuterTraits = std::iterator_traits&lt;OuterIterator&gt;,
class InnerTraits = std::iterator_traits&lt;InnerIterator&gt;
&gt;
struct indirect_iterator
{
typedef iterator_adaptor&lt;OuterIterator,
indirect_iterator_policies,
indirect_traits&lt;OuterIterator, InnerIterator,
OuterTraits, InnerTraits&gt;
&gt; type;
}; };
template &lt;class IndirectIterator, class ConstIndirectIterator, template &lt;class OuterIterator, // Mutable or Immutable, does not matter
class IndirectTraits = class InnerIterator, // Mutable
std::iterator_traits&lt;IndirectIterator&gt;, class ConstInnerIterator, // Immutable
class ConstIndirectTraits = class OuterTraits = std::iterator_traits&lt;OuterIterator&gt;,
std::iterator_traits&lt;ConstIndirectIterator&gt;, class InnerTraits = std::iterator_traits&lt;InnerIterator&gt;,
class Traits = class ConstInnerTraits = std::iterator_traits&lt;ConstInnerIterator&gt;
std::iterator_traits&lt;typename IndirectTraits::value_type&gt;
&gt; &gt;
struct indirect_iterators struct indirect_iterators
{ {
typedef typename IndirectTraits::value_type Iterator; typedef iterator_adaptors&lt;OuterIterator, OuterIterator,
typedef typename Traits::value_type ValueType; indirect_traits&lt;OuterIterator, InnerIterator,
typedef iterator_adaptors&lt;IndirectIterator, ConstIndirectIterator, OuterTraits, InnerTraits&gt;,
indirect_traits&lt;IndirectIterator, IndirectTraits, Traits&gt;, indirect_traits&lt;OuterIterator, ConstInnerIterator,
indirect_traits&lt;ConstIndirectIterator, ConstIndirectTraits, Traits&gt;, OuterTraits, ConstInnerTraits&gt;,
indirect_iterator_policies indirect_iterator_policies
&gt; Adaptors; &gt; Adaptors;
typedef typename Adaptors::iterator iterator; typedef typename Adaptors::iterator iterator;
@ -380,6 +419,11 @@ type generator <tt>indirect_iterators</tt>, using
}; };
</PRE></TD></TABLE> </PRE></TD></TABLE>
<h3><a name="projection_iterators">The Projection Iterator Adaptors</a></h3>
<h3><a name="reverse_iterators">The Reverse Iterators Class</a></h3> <h3><a name="reverse_iterators">The Reverse Iterators Class</a></h3>
<p> <p>