2001-02-12 21:35:20 +00:00
|
|
|
|
<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>Counting Iterator Adaptor 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>Counting Iterator Adaptor</h1>
|
|
|
|
|
|
|
|
|
|
|
|
Defined in header
|
2001-02-15 05:53:10 +00:00
|
|
|
|
<a href="../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a>
|
2001-02-12 21:35:20 +00:00
|
|
|
|
|
|
|
|
|
|
<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
|
|
|
|
|
|
through one hundred using <a
|
|
|
|
|
|
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
|
|
|
|
|
|
counting iterator adaptor not only with integer types, but with any
|
2001-02-15 05:53:10 +00:00
|
|
|
|
type that is incrementable (see type requirements below). The
|
|
|
|
|
|
following <b>pseudo-code</b> shows the general idea of how the
|
|
|
|
|
|
counting iterator is implemented.
|
2001-02-12 21:35:20 +00:00
|
|
|
|
</p>
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
// inside a hypothetical counting_iterator class...
|
|
|
|
|
|
typedef Incrementable value_type;
|
|
|
|
|
|
value_type counting_iterator::operator*() const {
|
|
|
|
|
|
return this->base; // no dereference!
|
|
|
|
|
|
}
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
All of the other operators of the counting iterator behave in the same
|
|
|
|
|
|
fashion as the incrementable base type.
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Synopsis</h2>
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
namespace boost {
|
2001-02-15 05:53:10 +00:00
|
|
|
|
template <class Incrementable>
|
|
|
|
|
|
struct counting_iterator_traits;
|
|
|
|
|
|
|
2001-02-12 21:35:20 +00:00
|
|
|
|
template <class Incrementable>
|
|
|
|
|
|
struct counting_iterator_generator;
|
|
|
|
|
|
|
|
|
|
|
|
template <class Incrementable>
|
|
|
|
|
|
typename counting_iterator_generator<Incrementable>::type
|
|
|
|
|
|
make_counting_iterator(Incrementable x);
|
|
|
|
|
|
}
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
2001-02-15 05:53:10 +00:00
|
|
|
|
<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 <class Incrementable>
|
|
|
|
|
|
struct counting_iterator_traits
|
|
|
|
|
|
{
|
|
|
|
|
|
<i>if (numeric_limits<Incrementable>::is_specialized == true) {</i>
|
|
|
|
|
|
typedef <i>detail::numeric_traits</i><Incrementable>::difference_type difference_type;
|
|
|
|
|
|
typedef std::random_access_iterator_tag iterator_category;
|
|
|
|
|
|
<i>} else {</i>
|
|
|
|
|
|
typedef std::iterator_traits<Incrementable>::difference_type difference_type;
|
|
|
|
|
|
typedef std::iterator_traits<Incrementable>::iterator_category iterator_category;
|
|
|
|
|
|
<i>}</i>
|
|
|
|
|
|
};
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
|
2001-02-12 21:35:20 +00:00
|
|
|
|
<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.
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
template <class Incrementable>
|
|
|
|
|
|
class counting_iterator_generator
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
|
|
|
|
|
};
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Example</h3>
|
|
|
|
|
|
|
|
|
|
|
|
In this example we use the counting iterator generator to create a
|
|
|
|
|
|
counting iterator, and count from zero to four.
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
#include <boost/config.hpp>
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
#include <boost/counting_iterator.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
int main(int, char*[])
|
|
|
|
|
|
{
|
|
|
|
|
|
// Example of using counting_iterator_generator
|
|
|
|
|
|
std::cout << "counting from 0 to 4:" << std::endl;
|
|
|
|
|
|
boost::counting_iterator_generator<int>::type first(0), last(4);
|
|
|
|
|
|
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
// to be continued...
|
|
|
|
|
|
</pre>
|
2001-02-12 21:57:19 +00:00
|
|
|
|
The output from this part is:
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
counting from 0 to 4:
|
|
|
|
|
|
0 1 2 3
|
|
|
|
|
|
</pre>
|
2001-02-12 21:35:20 +00:00
|
|
|
|
|
|
|
|
|
|
<h3>Template Parameters</h3>
|
|
|
|
|
|
|
|
|
|
|
|
<Table border>
|
|
|
|
|
|
<TR>
|
|
|
|
|
|
<TH>Parameter</TH><TH>Description</TH>
|
|
|
|
|
|
</TR>
|
|
|
|
|
|
|
|
|
|
|
|
<TR>
|
|
|
|
|
|
<TD><tt>Incrementable</tt></TD>
|
|
|
|
|
|
<TD>The type being wrapped by the adaptor.</TD>
|
|
|
|
|
|
</TR>
|
|
|
|
|
|
|
|
|
|
|
|
</Table>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Model of</h3>
|
|
|
|
|
|
|
|
|
|
|
|
If the <tt>Incrementable</tt> type has all of the functionality of a
|
|
|
|
|
|
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
|
|
|
|
|
Access Iterator</a> except the <tt>operator*()</tt>, then the counting
|
|
|
|
|
|
iterator will be a model of <a
|
|
|
|
|
|
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
2001-02-12 21:57:19 +00:00
|
|
|
|
Access Iterator</a>. If the <tt>Incrementable</tt> type has less
|
2001-02-12 21:35:20 +00:00
|
|
|
|
functionality, then the counting iterator will have correspondingly
|
|
|
|
|
|
less functionality.
|
|
|
|
|
|
|
2001-02-15 05:53:10 +00:00
|
|
|
|
<h3>Type Requirements</h3>
|
|
|
|
|
|
|
|
|
|
|
|
The <tt>Incrementable</tt> type must be <a
|
|
|
|
|
|
href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
|
|
|
|
|
|
Constructible</a>, <a href="./CopyConstructible.html">Copy
|
|
|
|
|
|
Constructible</a>, and <a href="./Assignable.html">Assignable</a>.
|
|
|
|
|
|
Furthermore, if you wish to create a counting iterator that is a <a
|
|
|
|
|
|
href="http://www.sgi.com/tech/stl/ForwardIterator.html"> Forward
|
|
|
|
|
|
Iterator</a>, then the following expressions must be valid:
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
Incrementable i, j;
|
|
|
|
|
|
++i // pre-increment
|
|
|
|
|
|
i == j // operator equal
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
If you wish to create a counting iterator that is a <a
|
|
|
|
|
|
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">
|
|
|
|
|
|
Bidirectional Iterator</a>, then pre-decrement is also required:
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
--i
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
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<Incrementable>::difference_type n;
|
|
|
|
|
|
i += n
|
|
|
|
|
|
n = i - j
|
|
|
|
|
|
i < j
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
2001-02-12 21:35:20 +00:00
|
|
|
|
<h3>Members</h3>
|
|
|
|
|
|
|
|
|
|
|
|
The counting iterator type 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 it has the following
|
|
|
|
|
|
constructor:
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
counting_iterator_generator::type(const Incrementable& i)
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
<hr>
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2><a name="make_counting_iterator">The Counting Iterator Object Generator</a></h2>
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
template <class Incrementable>
|
|
|
|
|
|
typename counting_iterator_generator<Incrementable>::type
|
|
|
|
|
|
make_counting_iterator(Incrementable base);
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
This function provides a convenient way to create counting iterators.
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Example</h3>
|
|
|
|
|
|
|
|
|
|
|
|
In this example we count from negative five to positive five, this
|
|
|
|
|
|
time using the <tt>make_counting_iterator()</tt> function to save some
|
|
|
|
|
|
typing.
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
// continuing from previous example...
|
2001-02-12 21:57:19 +00:00
|
|
|
|
|
|
|
|
|
|
std::cout << "counting from -5 to 4:" << std::endl;
|
2001-02-12 21:35:20 +00:00
|
|
|
|
std::copy(boost::make_counting_iterator(-5),
|
|
|
|
|
|
boost::make_counting_iterator(5),
|
|
|
|
|
|
std::ostream_iterator<int>(std::cout, " "));
|
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
|
2001-02-12 21:57:19 +00:00
|
|
|
|
// to be continued...
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
The output from this part is:
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
counting from -5 to 4:
|
|
|
|
|
|
-5 -4 -3 -2 -1 0 1 2 3 4
|
|
|
|
|
|
</pre>
|
2001-02-12 21:35:20 +00:00
|
|
|
|
|
2001-02-12 21:57:19 +00:00
|
|
|
|
In the next example we create an array of numbers, and then create a
|
|
|
|
|
|
second array of pointers, where each pointer is the address of a
|
|
|
|
|
|
number in the first array. The counting iterator makes it easy to do
|
|
|
|
|
|
this since dereferencing a counting iterator that is wrapping an
|
|
|
|
|
|
iterator over the array of numbers just returns a pointer to the
|
|
|
|
|
|
current location in the array. We then use the <a
|
|
|
|
|
|
href="./indirect_iterator.htm">indirect iterator adaptor</a> to print
|
|
|
|
|
|
out the number in the array by accessing the numbers through the array
|
|
|
|
|
|
of pointers.
|
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
// continuing from previous example...
|
|
|
|
|
|
|
|
|
|
|
|
const int N = 7;
|
|
|
|
|
|
std::vector<int> numbers;
|
|
|
|
|
|
// Fill "numbers" array with [0,N)
|
|
|
|
|
|
std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
|
|
|
|
|
|
std::back_inserter(numbers));
|
2001-02-12 21:59:25 +00:00
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<int>::iterator> pointers;
|
2001-02-12 21:57:19 +00:00
|
|
|
|
|
|
|
|
|
|
// Use counting iterator to fill in the array of pointers.
|
|
|
|
|
|
std::copy(boost::make_counting_iterator(numbers.begin()),
|
|
|
|
|
|
boost::make_counting_iterator(numbers.end()),
|
|
|
|
|
|
std::back_inserter(pointers));
|
|
|
|
|
|
|
|
|
|
|
|
// Use indirect iterator to print out numbers by accessing
|
|
|
|
|
|
// them through the array of pointers.
|
|
|
|
|
|
std::cout << "indirectly printing out the numbers from 0 to "
|
|
|
|
|
|
<< N << std::endl;
|
|
|
|
|
|
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
|
|
|
|
|
boost::make_indirect_iterator(pointers.end()),
|
|
|
|
|
|
std::ostream_iterator<int>(std::cout, " "));
|
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
The output is:
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
indirectly printing out the numbers from 0 to 7
|
|
|
|
|
|
0 1 2 3 4 5 6
|
2001-02-12 21:35:20 +00:00
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<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 "as is"
|
|
|
|
|
|
without express or implied warranty, and with no claim as to its suitability for
|
|
|
|
|
|
any purpose.</p>
|
|
|
|
|
|
|
|
|
|
|
|
</body>
|
|
|
|
|
|
|
|
|
|
|
|
</html>
|
|
|
|
|
|
<!-- LocalWords: html charset alt gif hpp incrementable const namespace htm
|
|
|
|
|
|
-->
|
2001-02-15 05:53:10 +00:00
|
|
|
|
<!-- LocalWords: struct typename iostream int Siek CopyConstructible pre
|
2001-02-12 21:35:20 +00:00
|
|
|
|
-->
|