Massive edits

[SVN r9222]
This commit is contained in:
Dave Abrahams
2001-02-16 05:30:49 +00:00
parent 352e392fcb
commit bf13bd7b3f

View File

@@ -1,44 +1,44 @@
<html> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<head> <meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 4.0"> <meta name="GENERATOR" content="Microsoft FrontPage 4.0">
<meta name="ProgId" content="FrontPage.Editor.Document"> <meta name="ProgId" content="FrontPage.Editor.Document">
<title>Indirect Iterator Adaptor Documentation</title>
</head>
<title>Indirect Iterator Adaptor Documentation</title>
<body bgcolor="#FFFFFF" text="#000000"> <body bgcolor="#FFFFFF" text="#000000">
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" <img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
align="center" width="277" height="86"> "center" width="277" height="86">
<h1>Indirect Iterator Adaptor</h1> <h1>Indirect Iterator Adaptor</h1>
Defined in header <a href=
"../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
Defined in header <p>The indirect iterator adaptor augments an iterator by applying an
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a> <b>extra</b> dereference inside of <tt>operator*()</tt>. For example, this
iterator makes it possible to view a container of pointers or
<p> smart-pointers (e.g. <tt>std::list&lt;boost::shared_ptr&lt;foo&gt;
The indirect iterator adaptor augments an iterator by applying an &gt;</tt>) as if it were a container of the pointed-to type. The following
<b>extra</b> dereference inside of <tt>operator*()</tt>. For example, <b>pseudo-code</b> shows the basic idea of the indirect iterator:
this iterator makes it possible to view containers of pointers such as
<tt>std::list&lt;foo*&gt;</tt> as if there were containers of the
pointed-to type (in this case <tt>std::list&lt;foo&gt;</tt>). The
following <b>pseudo-code</b> shows the basic idea of the indirect
iterator:
<blockquote>
<pre> <pre>
// inside a hypothetical indirect_iterator class... // inside a hypothetical indirect_iterator class...
typedef std::iterator_traits&lt;BaseIterator&gt;::value_type Pointer; typedef std::iterator_traits&lt;BaseIterator&gt;::value_type Pointer;
typedef std::iterator_traits&lt;Pointer&gt;::reference reference; typedef std::iterator_traits&lt;Pointer&gt;::reference reference;
reference indirect_iterator::operator*() const { reference indirect_iterator::operator*() const {
return **this->base_iterator; return **this-&gt;base_iterator;
} }
</pre> </pre>
</blockquote>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<blockquote>
<pre> <pre>
namespace boost { namespace boost {
template &lt;class BaseIterator, template &lt;class BaseIterator,
@@ -55,38 +55,41 @@ namespace boost {
make_indirect_iterator(BaseIterator base) make_indirect_iterator(BaseIterator base)
} }
</pre> </pre>
</blockquote>
<hr> <hr>
<h2><a name="indirect_iterator_generator">The Indirect Iterator Type <h2><a name="indirect_iterator_generator">The Indirect Iterator Type
Generator</a></h2> Generator</a></h2>
The <tt>indirect_iterator_generator</tt> template is a <a href=
"../../more/generic_programming.html#type_generator">generator</a> of
indirect iterator types. The main template parameter for this class is the
<tt>BaseIterator</tt> type that is being wrapped. In most cases the type of
the elements being pointed to can be deduced using
<tt>std::iterator_traits</tt>, but in some situations the user may want to
override this type, so there are also template parameters that allow a user
to control the <tt>value_type</tt>, <tt>pointer</tt>, and
<tt>reference</tt> types of the resulting iterators.
The class <tt>indirect_iterator_generator</tt> is a helper class whose <blockquote>
purpose is to construct an indirect iterator type. The main template
parameter for this class is the <tt>BaseIterator</tt> type that is
being wrapped. In most cases the type of the elements being pointed to
can be deduced using <tt>std::iterator_traits</tt>, but in some
situations the user may want to override this type, so there are also
template parameters for the type being pointed to (the <tt>Value</tt>)
as well as reference and pointer versions of the type.
<pre> <pre>
template &lt;class BaseIterator, template &lt;class BaseIterator,
class Value, class Reference, class Pointer&gt; class Value, class Reference, class Pointer&gt;
class indirect_iterator_generator class indirect_iterator_generator
{ {
public: public:
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt...&gt;</tt> type; // the resulting indirect iterator type typedef <tt><a href=
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt;</tt> type; // the resulting indirect iterator type
}; };
</pre> </pre>
</blockquote>
<h3>Example</h3> <h3>Example</h3>
This example uses the <tt>indirect_iterator_generator</tt> to create This example uses the <tt>indirect_iterator_generator</tt> to create
indirect iterators that dereference the pointers stored in the indirect iterators which dereference the pointers stored in the
<tt>pointers_to_chars</tt> array to access the <tt>char</tt>'s in the <tt>pointers_to_chars</tt> array to access the <tt>char</tt>s in the
<tt>characters</tt> array. <tt>characters</tt> array.
<blockquote>
<pre> <pre>
#include &lt;boost/config.hpp&gt; #include &lt;boost/config.hpp&gt;
#include &lt;vector&gt; #include &lt;vector&gt;
@@ -100,7 +103,7 @@ int main(int, char*[])
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
char* pointers_to_chars[N]; // at the end. char* pointers_to_chars[N]; // at the end.
for (int i = 0; i &lt; N; ++i) for (int i = 0; i &lt; N; ++i)
pointers_to_chars[i] = &characters[i]; pointers_to_chars[i] = &amp;characters[i];
boost::indirect_iterator_generator&lt;char**, char&gt;::type boost::indirect_iterator_generator&lt;char**, char&gt;::type
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N); indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
@@ -110,77 +113,82 @@ int main(int, char*[])
// to be continued... // to be continued...
</pre> </pre>
</blockquote>
<h3>Template Parameters</h3> <h3>Template Parameters</h3>
<Table border> <table border>
<TR> <tr>
<TH>Parameter</TH><TH>Description</TH> <th>Parameter
</TR>
<TR> <th>Description
<TD><tt>BaseIterator</tt></TD>
<TD>The iterator type being wrapped. The value type of the base iterator
should be a pointer (a <a
href="http://www.sgi.com/tech/stl/trivial.html">Trivial
Iterator</a>).</TD>
</TD>
</TR>
<TR> <tr>
<TD><tt>Value</tt></TD> <td><tt>BaseIterator</tt>
<TD>The value-type of the value-type of the base iterator. That is, the
type of object that is accessed by dereferences in the base iterator twice.<br>
<b>Default:</b><br>
<tt>std::iterator_traits&lt;std::iterator_traits&lt;BaseIterator&gt;::value_type&gt;::value_type</tt>
</TD>
<TR> <td>The iterator type being wrapped. The <tt>value_type</tt> of the
<TD><tt>Reference</tt></TD> base iterator should itself be dereferenceable (a <a href=
<TD>The corresponding reference type for the <tt>Value</tt>.<br> "http://www.sgi.com/tech/stl/trivial.html">Trivial Iterator</a>).
<b>Default:</b> <tt>Value&</tt></TD>
</TD>
<TR> <tr>
<TD><tt>Pointer</tt></TD> <td><tt>Value</tt>
<TD>The corresponding pointer type for the <tt>Value</tt>.<br>
<b>Default:</b> <tt>Value*</tt></TD>
</TD>
</Table> <td>The <tt>value_type</tt> of the resulting iterator, unless const. If
Value is <tt>const X</tt>, a conforming compiler makes the
<tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
"iterator_adaptors.htm#1">[1]</a>.<br>
<b>Default:</b> <tt>std::iterator_traits&lt;<br>
<20> std::iterator_traits&lt;BaseIterator&gt;::value_type
&gt;::value_type</tt><a href="#2">[2]</a>
<h3>Model of</h3> <tr>
<td><tt>Reference</tt>
If the base iterator is a model of <a <td>The <tt>reference</tt> type of the resulting iterator, and in
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random particular, the result type of <tt>operator*()</tt>.<br>
Access Iterator</a> then so is the resulting indirect iterator. If <b>Default:</b> <tt>Value&amp;</tt>
the base iterator supports less functionality than this the resulting
indirect iterator will also support less functionality. <tr>
<td><tt>Pointer</tt>
<td>The <tt>pointer</tt> type of the resulting iterator, and in
particular, the result type of <tt>operator-&gt;()</tt>.<br>
<b>Default:</b> <tt>Value*</tt>
</table>
<h3>Concept Model</h3>
The indirect iterator will model whichever <a href=
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator concept
category</a> is modeled by the base iterator. Thus, if the base iterator is
a model of <a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
Iterator</a> then so is the resulting indirect iterator. If the base
iterator models a more restrictive concept, the resulting indirect iterator
will model the same concept.
<h3>Members</h3> <h3>Members</h3>
The indirect iterator type implements the member functions and operators
The indirect iterator type implements the member functions and required of the <a href=
operators required of the <a "http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Iterator</a> concept. In addition it has the following constructor:
Access Iterator</a> concept.
In addition it has the following constructor:
<pre> <pre>
indirect_iterator_generator::type(const BaseIterator&amp; it) indirect_iterator_generator::type(const BaseIterator&amp; it)
</pre> </pre>
<br>
<br>
<p>
<hr> <hr>
<p> <p>
<h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair <h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair
Generator</a></h2> Generator</a></h2>
Sometimes a pair of <tt>const</tt>/non-<tt>const</tt> pair of iterators is
needed, such as when implementing a container. The
<tt>indirect_iterator_pair_generator</tt> class makes it more convenient to
create this pair of iterator types.
Sometimes a mutable/const pair of iterator types is needed, such as <blockquote>
when implementing a container type. The
<tt>indirect_iterator_pair_generator</tt> class makes it more
convenient to create this pair of iterator types.
<pre> <pre>
template &lt;class BaseIterator, template &lt;class BaseIterator,
class Value, class Pointer, class Reference, class Value, class Pointer, class Reference,
@@ -188,23 +196,27 @@ template &lt;class BaseIterator,
class indirect_iterator_pair_generator class indirect_iterator_pair_generator
{ {
public: public:
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt...&gt;</tt> iterator; // the mutable indirect iterator type typedef <tt><a href=
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt...&gt;</tt> const_iterator; // the immutable indirect iterator type "./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt;</tt> iterator; // the mutable indirect iterator type
typedef <tt><a href=
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt;...&gt;</tt> const_iterator; // the immutable indirect iterator type
}; };
</pre> </pre>
</blockquote>
<h3>Example</h3> <h3>Example</h3>
<blockquote>
<pre> <pre>
// continuing from the last example... // continuing from the last example...
typedef boost::indirect_iterator_pair_generator<char**, typedef boost::indirect_iterator_pair_generator&lt;char**,
char, char*, char&, const char*, const char&> PairGen; char, char*, char&amp;, const char*, const char&amp;&gt; PairGen;
char mutable_characters[N]; char mutable_characters[N];
char* pointers_to_mutable_chars[N]; char* pointers_to_mutable_chars[N];
for (int i = 0; i < N; ++i) for (int i = 0; i &lt; N; ++i)
pointers_to_mutable_chars[i] = &mutable_characters[i]; pointers_to_mutable_chars[i] = &amp;mutable_characters[i];
PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars), PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
mutable_indirect_last(pointers_to_mutable_chars + N); mutable_indirect_last(pointers_to_mutable_chars + N);
@@ -212,148 +224,174 @@ public:
const_indirect_last(pointers_to_chars + N); const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last, std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind1st(std::plus<char>(), 1)); mutable_indirect_first, std::bind1st(std::plus&lt;char&gt;(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last, std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ",")); std::ostream_iterator&lt;char&gt;(std::cout, ","));
std::cout << std::endl; std::cout &lt;&lt; std::endl;
// to be continued... // to be continued...
</pre> </pre>
The output is: </blockquote>
<p>The output is:
<blockquote>
<pre> <pre>
b,c,d,e,f,g,h, b,c,d,e,f,g,h,
</pre> </pre>
</blockquote>
<h3>Template Parameters</h3> <h3>Template Parameters</h3>
<Table border> <table border>
<TR> <tr>
<TH>Parameter</TH><TH>Description</TH> <th>Parameter
</TR>
<TR> <th>Description
<TD><tt>BaseIterator</tt></TD>
<TD>The iterator type being wrapped. The value type of the base iterator
should be a pointer (a <a
href="http://www.sgi.com/tech/stl/trivial.html">Trivial
Iterator</a>).</TD>
</TD>
</TR>
<TR> <tr>
<TD><tt>Value</tt></TD> <td><tt>BaseIterator</tt>
<TD>The value-type of the value-type of the base iterator. That is, the
type of object that is accessed by dereferences in the base iterator twice.<br>
<b>Default:</b><br>
<tt>std::iterator_traits&lt;std::iterator_traits&lt;BaseIterator&gt;::value_type&gt;::value_type</tt>
</TD>
<TR> <td>The iterator type being wrapped. The <tt>value_type</tt> of the
<TD><tt>Reference</tt></TD> base iterator should itself be dereferenceable (a <a href=
<TD>The corresponding reference type for the <tt>Value</tt>.<br> "http://www.sgi.com/tech/stl/trivial.html">Trivial Iterator</a>).
<b>Default:</b> <tt>Value&</tt></TD>
</TD>
<TR> <tr>
<TD><tt>Pointer</tt></TD> <td><tt>Value</tt>
<TD>The corresponding pointer type for the <tt>Value</tt>.<br>
<b>Default:</b> <tt>Value*</tt></TD>
</TD>
<TR> <td>The <tt>value_type</tt> of the resulting iterators<br>
<TD><tt>ConstReference</tt></TD> <b>Default:</b> <tt>std::iterator_traits&lt;<br>
<TD>The corresponding const reference type for the <tt>Value</tt>.<br> <20> std::iterator_traits&lt;BaseIterator&gt;::value_type
<b>Default:</b> <tt>const Value&</tt></TD> &gt;::value_type</tt><a href="#2">[2]</a>
</TD>
<TR> <tr>
<TD><tt>ConstPointer</tt></TD> <td><tt>Reference</tt>
<TD>The corresponding const pointer type for the <tt>Value</tt>.<br>
<b>Default:</b> <tt>const Value*</tt></TD>
</TD>
</Table> <td>The <tt>reference</tt> type of the resulting <tt>iterator</tt>, and
in particular, the result type of its <tt>operator*()</tt>.<br>
<b>Default:</b> <tt>Value&amp;</tt>
<h3>Model of</h3> <tr>
<td><tt>Pointer</tt>
If the base iterator is a model of <a <td>The <tt>pointer</tt> type of the resulting <tt>iterator</tt>, and
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random in particular, the result type of its <tt>operator-&gt;()</tt>.<br>
Access Iterator</a> then so is the resulting indirect iterator types. <b>Default:</b> <tt>Value*</tt>
If the base iterator supports less functionality the
resulting indirect iterator types will also support less <tr>
functionality. The resulting <tt>iterator</tt> type is mutable, and <td><tt>ConstReference</tt>
the resulting <tt>const_iterator</tt> type is constant.
<td>The <tt>reference</tt> type of the resulting
<tt>const_iterator</tt>, and in particular, the result type of its
<tt>operator*()</tt>.<br>
<b>Default:</b> <tt>const Value&amp;</tt>
<tr>
<td><tt>ConstPointer</tt>
<td>The <tt>pointer</tt> type of the resulting <tt>const_iterator</tt>,
and in particular, the result type of its <tt>operator-&gt;()</tt>.<br>
<b>Default:</b> <tt>const Value*</tt>
</table>
<h3>Concept Model</h3>
The indirect iterators will model whichever <a href=
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator concept
category</a> is modeled by the base iterator. Thus, if the base iterator is
a model of <a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
Iterator</a> then so are the resulting indirect iterators. If the base
iterator models a more restrictive concept, the resulting indirect
iterators will model the same concept.
<h3>Members</h3> <h3>Members</h3>
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types implement
the member functions and operators required of the <a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
Iterator</a> concept. In addition they support the following constructors:
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types <blockquote>
implements the member functions and operators required of the <a
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
Access Iterator</a> concept. In addition they support the following
constructors:
<pre> <pre>
indirect_iterator_pair_generator::iterator(const BaseIterator&amp; it) indirect_iterator_pair_generator::iterator(const BaseIterator&amp; it)
</pre>
<pre>
indirect_iterator_pair_generator::const_iterator(const BaseIterator&amp; it) indirect_iterator_pair_generator::const_iterator(const BaseIterator&amp; it)
</pre> </pre>
</blockquote>
<br>
<br>
<p>
<hr> <hr>
<p> <p>
<h2><a name="make_indirect_iterator">The Indirect Iterator Object Generator</a></h2> <h2><a name="make_indirect_iterator">The Indirect Iterator Object
Generator</a></h2>
The <tt>make_indirect_iterator()</tt> function provides a more The <tt>make_indirect_iterator()</tt> function provides a more convenient
convenient way to create indirect iterator objects. The function saves way to create indirect iterator objects. The function saves the user the
the user the trouble of explicitly writing out the iterator types. trouble of explicitly writing out the iterator types.
<blockquote>
<pre> <pre>
template &lt;class BaseIterator&gt; template &lt;class BaseIterator&gt;
typename indirect_iterator_generator&lt;BaseIterator&gt;::type typename indirect_iterator_generator&lt;BaseIterator&gt;::type
make_indirect_iterator(BaseIterator base) make_indirect_iterator(BaseIterator base)
</pre> </pre>
</blockquote>
<h3>Example</h3> <h3>Example</h3>
Here we again print the <tt>char</tt>s from the array <tt>characters</tt>
by accessing them through the array of pointers <tt>pointer_to_chars</tt>,
but this time we use the <tt>make_indirect_iterator()</tt> function which
saves us some typing.
Here we again print the <tt>char</tt>'s from the array <blockquote>
<tt>characters</tt> by accessing them through the array of pointers
<tt>pointer_to_chars</tt>, but this time we use the
<tt>make_indirect_iterator()</tt> function which saves us some typing.
<pre> <pre>
// continuing from the last example... // continuing from the last example...
std::copy(boost::make_indirect_iterator(pointers_to_chars), std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N), boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ",")); std::ostream_iterator&lt;char&gt;(std::cout, ","));
std::cout << std::endl; std::cout &lt;&lt; std::endl;
return 0; return 0;
} }
</pre> </pre>
</blockquote>
The output is: The output is:
<blockquote>
<pre> <pre>
a,b,c,d,e,f,g, a,b,c,d,e,f,g,
</pre> </pre>
</blockquote>
<hr> <hr>
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->10 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --></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 &quot;as is&quot;
without express or implied warranty, and with no claim as to its suitability for
any purpose.</p>
</body> <h3>Notes</h3>
</html> <p>
<p><a name="2">[2]</a> If your compiler does not support partial
specialization and the base iterator or its <tt>value_type</tt> is a
builtin pointer type, you will not be able to use the default for
<tt>Value</tt> and will need to specify this type explicitly.
<hr>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->10
Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" -->
<p>&copy; Copyright Jeremy Siek and David Abrahams 2001. 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.
<!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct <!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct
--> -->
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg <!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
--> -->
<!-- LocalWords: sizeof PairGen pre Siek <!-- LocalWords: sizeof PairGen pre Jeremy Siek David Abrahams
--> -->
</body>