General edits for clarity; some reorganization.

[SVN r9213]
This commit is contained in:
Dave Abrahams 2001-02-15 16:39:55 +00:00
parent 272025bb07
commit fda44ca17d

View File

@ -18,16 +18,15 @@ Defined in header
<a href="../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a>
<p>
Sometimes it would be nice if one could treat an integer like an
iterator, for example, to fill up a vector with the numbers zero
How would you fill up a vector with the numbers zero
through one hundred using <a
href="http://www.sgi.com/tech/stl/copy.html"><tt>std::copy()</tt></a>. The
href="http://www.sgi.com/tech/stl/copy.html"><tt>std::copy()</tt></a>? The
only iterator operation missing from builtin integer types is an
<tt>operator*()</tt>, which we would want to just return the current
value of the integer. The counting iterator adaptor provides this
functionality, though it is a bit more generalized. One can use the
<tt>operator*()</tt> that returns the current
value of the integer. The counting iterator adaptor adds this crucial piece of
functionality to whatever type it wraps. One can use the
counting iterator adaptor not only with integer types, but with any
type that is incrementable (see type requirements below). The
type that is <tt>Incrementable</tt> (see type requirements <a href="#requirements">below</a>). The
following <b>pseudo-code</b> shows the general idea of how the
counting iterator is implemented.
</p>
@ -41,63 +40,30 @@ counting iterator is implemented.
</pre>
All of the other operators of the counting iterator behave in the same
fashion as the incrementable base type.
fashion as the <tt>Incrementable</tt> base type.
<h2>Synopsis</h2>
<pre>
namespace boost {
template &lt;class Incrementable&gt;
struct counting_iterator_traits;
struct <a href="#counting_iterator_traits">counting_iterator_traits</a>;
template &lt;class Incrementable&gt;
struct counting_iterator_generator;
struct <a href="#counting_iterator_generator">counting_iterator_generator</a>;
template &lt;class Incrementable&gt;
typename counting_iterator_generator&lt;Incrementable&gt;::type
make_counting_iterator(Incrementable x);
<a href="#make_counting_iterator">make_counting_iterator</a>(Incrementable x);
}
</pre>
<hr>
<h2><a name="counting_iterator_traits">Counting Iterator Traits</a></h2>
The counting iterator adaptor needs to know the appropriate
<tt>difference_type</tt> and <tt>iterator_category</tt> to use
depending on the <tt>Incrementable</tt> type supplied by the user.
The <tt>counting_iterator_traits</tt> class provides these types. If
the <tt>Incrementable</tt> type is a numeric type or is an iterator
then these types will be correctly deduced by the below counting
iterator traits. Otherwise, the user must specialize
<tt>counting_iterator_traits</tt> for their type, or add nested
typedefs to their type to fulfill the needs of
<a href="http://www.sgi.com/tech/stl/iterator_traits.html">
<tt>std::iterator_traits</tt></a>.
<pre>
template &lt;class Incrementable&gt;
struct counting_iterator_traits
{
<i>if (numeric_limits&lt;Incrementable&gt::is_specialized == true) {</i>
typedef <i>detail::numeric_traits</i>&lt;Incrementable&gt;::difference_type difference_type;
typedef std::random_access_iterator_tag iterator_category;
<i>} else {</i>
typedef std::iterator_traits&lt;Incrementable&gt;::difference_type difference_type;
typedef std::iterator_traits&lt;Incrementable&gt;::iterator_category iterator_category;
<i>}</i>
};
</pre>
<hr>
<h2><a name="counting_iterator_generator">The Counting Iterator Type
Generator</a></h2>
The class <tt>counting_iterator_generator</tt> is a helper class whose
purpose is to construct a counting iterator type. The template
parameters for this class is the <tt>Incrementable</tt> type that is
being wrapped.
The class template <tt>counting_iterator_generator&lt;Incrementable&gt;</tt> is a <a href="../../more/generic_programming.html#type_generator">type generator</a> for counting iterators.
<pre>
template &lt;class Incrementable&gt;
@ -159,7 +125,7 @@ Access Iterator</a>. If the <tt>Incrementable</tt> type has less
functionality, then the counting iterator will have correspondingly
less functionality.
<h3>Type Requirements</h3>
<h3><a name="requirements">Type Requirements</a></h3>
The <tt>Incrementable</tt> type must be <a
href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
@ -183,7 +149,7 @@ If you wish to create a counting iterator that is a <a
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"> Random
Access Iterator</a>, then these additional expressions are also required:
<pre>
counting_iterator_traits&lt;Incrementable&gt;::difference_type n;
<a href="#counting_iterator_traits">counting_iterator_traits</a>&lt;Incrementable&gt;::difference_type n;
i += n
n = i - j
i < j
@ -214,7 +180,11 @@ typename counting_iterator_generator&lt;Incrementable&gt;::type
make_counting_iterator(Incrementable base);
</pre>
This function provides a convenient way to create counting iterators.
An <a href="../../more/generic_programming.html#object_generator">object
generator</a> function that provides a convenient way to create counting
iterators.<p>
<h3>Example</h3>
@ -280,9 +250,56 @@ indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
</pre>
<hr>
<h2><a name="counting_iterator_traits">Counting Iterator Traits</a></h2>
The counting iterator adaptor needs to determine the appropriate
<tt>difference_type</tt> and <tt>iterator_category</tt> to use based on the
<tt>Incrementable</tt> type supplied by the user. The
<tt>counting_iterator_traits</tt> class provides these types. If the
<tt>Incrementable</tt> type is an integral type or an iterator, these types
will be correctly deduced by the <tt>counting_iterator_traits</tt> provided by
the library. Otherwise, the user must specialize
<tt>counting_iterator_traits</tt> for her type or add nested typedefs to
her type to fulfill the needs of
<a href="http://www.sgi.com/tech/stl/iterator_traits.html">
<tt>std::iterator_traits</tt></a>.
<p>The following pseudocode describes how the <tt>counting_iterator_traits</tt> are determined:
<pre>
template &lt;class Incrementable&gt;
struct counting_iterator_traits
{
if (numeric_limits&lt;Incrementable&gt::is_specialized) {
if (!numeric_limits&lt;Incrementable&gt::is_integral)
COMPILE_TIME_ERROR;
if (!numeric_limits&lt;Incrementable&gt::is_bounded
&amp;&amp; numeric_limits&lt;Incrementable&gt;::is_signed) {
typedef Incrementable difference_type;
}
else if (numeric_limits&lt;Incrementable&gt::is_integral) {
typedef <i>next-larger-signed-type-or-intmax_t</i> difference_type;
}
typedef std::random_access_iterator_tag iterator_category;
} else {
typedef std::iterator_traits&lt;Incrementable&gt;::difference_type difference_type;
typedef std::iterator_traits&lt;Incrementable&gt;::iterator_category iterator_category;
}
};
</pre>
<p>The italicized sections above are implementation details, but it is important
to know that the <tt>difference_type</tt> for integral types is selected so that
it can always represent the difference between two values if such a built-in
integer exists. On platforms with a working <tt>std::numeric_limits</tt>
implementation, the <tt>difference_type</tt> for any variable-length signed
integer type <tt>T</tt> is <tt>T</tt> itself.
<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>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->15 Feb 2001<!--webbot bot="Timestamp" endspan i-checksum="14373" --></p>
<p>© 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;
@ -296,3 +313,4 @@ any purpose.</p>
-->
<!-- LocalWords: struct typename iostream int Siek CopyConstructible pre
-->