iterator/doc/counting_iterator.html

271 lines
15 KiB
HTML

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.2.8: http://docutils.sourceforge.net/" />
<title>Counting Iterator</title>
<meta name="author" content="David Abrahams, Jeremy Siek, Thomas Witt" />
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction" />
<meta name="date" content="2004-01-12" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="counting-iterator">
<h1 class="title">Counting Iterator</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>David Abrahams, Jeremy Siek, Thomas Witt</td></tr>
<tr><th class="docinfo-name">Contact:</th>
<td><a class="first reference" href="mailto:dave&#64;boost-consulting.com">dave&#64;boost-consulting.com</a>, <a class="reference" href="mailto:jsiek&#64;osl.iu.edu">jsiek&#64;osl.iu.edu</a>, <a class="last reference" href="mailto:witt&#64;ive.uni-hannover.de">witt&#64;ive.uni-hannover.de</a></td></tr>
<tr><th class="docinfo-name">Organization:</th>
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="reference" href="http://www.osl.iu.edu">Open Systems
Lab</a>, University of Hanover <a class="last reference" href="http://www.ive.uni-hannover.de">Institute for Transport
Railway Operation and Construction</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2004-01-12</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
</tbody>
</table>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">How would you fill up a vector with the numbers zero
through one hundred using <tt class="literal"><span class="pre">std::copy()</span></tt>? The only iterator
operation missing from builtin integer types is an
<tt class="literal"><span class="pre">operator*()</span></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 <strong>Incrementable</strong> (see type requirements
below).</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">counting_iterator</span></tt> adapts an incrementable type such as <tt class="literal"><span class="pre">int</span></tt>
or <tt class="literal"><span class="pre">std::list&lt;std::string&gt;::iterator</span></tt>, by adding an <tt class="literal"><span class="pre">operator*</span></tt>
that returns the current value of the object.</p>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents">Table of Contents</a></p>
<ul class="simple">
<li><a class="reference" href="#counting-iterator-synopsis" id="id2" name="id2"><tt class="literal"><span class="pre">counting_iterator</span></tt> synopsis</a></li>
<li><a class="reference" href="#counting-iterator-requirements" id="id3" name="id3"><tt class="literal"><span class="pre">counting_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#counting-iterator-models" id="id4" name="id4"><tt class="literal"><span class="pre">counting_iterator</span></tt> models</a></li>
<li><a class="reference" href="#counting-iterator-operations" id="id5" name="id5"><tt class="literal"><span class="pre">counting_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#example" id="id6" name="id6">Example</a></li>
</ul>
</div>
<div class="section" id="counting-iterator-synopsis">
<h1><a class="toc-backref" href="#id2" name="counting-iterator-synopsis"><tt class="literal"><span class="pre">counting_iterator</span></tt> synopsis</a></h1>
<pre class="literal-block">
template &lt;
class Incrementable
, class CategoryOrTraversal = use_default
, class Difference = use_default
&gt;
class counting_iterator
{
public:
typedef Incrementable value_type;
typedef const Incrementable&amp; reference;
typedef const Incrementable* pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
counting_iterator();
counting_iterator(counting_iterator const&amp; rhs);
explicit counting_iterator(Incrementable x);
Incrementable base() const;
reference operator*() const;
counting_iterator&amp; operator++();
counting_iterator&amp; operator--();
private:
Incrementable m_inc; // exposition
};
</pre>
<p>If the <tt class="literal"><span class="pre">Diference</span></tt> argument is <tt class="literal"><span class="pre">use_default</span></tt> then the
<tt class="literal"><span class="pre">difference_type</span></tt> member is an implementation defined signed
integral type.</p>
<p>If <tt class="literal"><span class="pre">CategoryOrTraversal</span></tt> is not <tt class="literal"><span class="pre">use_default</span></tt> then the member
<tt class="literal"><span class="pre">iterator_category</span></tt> is <tt class="literal"><span class="pre">CategoryOrTraversal</span></tt>. Otherwise, if
<tt class="literal"><span class="pre">Incrementable</span></tt> is a numeric type then <tt class="literal"><span class="pre">iterator_category</span></tt> is a
type convertible to <tt class="literal"><span class="pre">random_access_traversal_tag</span></tt> and
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt>. If <tt class="literal"><span class="pre">Incrementable</span></tt> is not a numeric
type then <tt class="literal"><span class="pre">iterator_category</span></tt> is
<tt class="literal"><span class="pre">iterator_traversal&lt;Incrementable&gt;::type</span></tt>.</p>
<dl>
<dt>[<em>Note:</em> implementers are encouraged to provide an implementation of</dt>
<dd><tt class="literal"><span class="pre">distance_to</span></tt> and a <tt class="literal"><span class="pre">difference_type</span></tt> that avoids overflows in
the cases when the <tt class="literal"><span class="pre">Incrementable</span></tt> type is a numeric type.]</dd>
</dl>
</div>
<div class="section" id="counting-iterator-requirements">
<h1><a class="toc-backref" href="#id3" name="counting-iterator-requirements"><tt class="literal"><span class="pre">counting_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">Incrementable</span></tt> type must be Default Constructible, Copy
Constructible, and Assignable.</p>
<p>If <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to <tt class="literal"><span class="pre">forward_iterator_tag</span></tt> or
<tt class="literal"><span class="pre">forward_traversal_tag</span></tt> then the following expressions must be valid:</p>
<pre class="literal-block">
Incrementable i, j;
++i // pre-increment
i == j // operator equal
</pre>
<p>If <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
<tt class="literal"><span class="pre">bidirectional_iterator_tag</span></tt> or <tt class="literal"><span class="pre">bidirectional_traversal_tag</span></tt> then
pre-decrement is required:</p>
<pre class="literal-block">
--i
</pre>
<p>If <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt> or <tt class="literal"><span class="pre">random_access_traversal_tag</span></tt> then
these additional expressions are also required:</p>
<pre class="literal-block">
counting_iterator::difference_type n;
i += n
n = i - j
i &lt; j
</pre>
</div>
<div class="section" id="counting-iterator-models">
<h1><a class="toc-backref" href="#id4" name="counting-iterator-models"><tt class="literal"><span class="pre">counting_iterator</span></tt> models</a></h1>
<p><tt class="literal"><span class="pre">counting_iterator</span></tt> models Readable Lvalue Iterator. In addition,
<tt class="literal"><span class="pre">counting_iterator</span></tt> models the concepts corresponding to the
iterator tags that <tt class="literal"><span class="pre">counting_iterator::iterator_category</span></tt> is
convertible to.</p>
</div>
<div class="section" id="counting-iterator-operations">
<h1><a class="toc-backref" href="#id5" name="counting-iterator-operations"><tt class="literal"><span class="pre">counting_iterator</span></tt> operations</a></h1>
<p>In addition to the operations required by the concepts modeled by
<tt class="literal"><span class="pre">counting_iterator</span></tt>, <tt class="literal"><span class="pre">counting_iterator</span></tt> provides the following
operations.</p>
<p><tt class="literal"><span class="pre">counting_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A default constructed instance of <tt class="literal"><span class="pre">counting_iterator</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">counting_iterator(counting_iterator</span> <span class="pre">const&amp;</span> <span class="pre">rhs);</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">rhs</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">counting_iterator(Incrementable</span> <span class="pre">x);</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator</span></tt> with <tt class="literal"><span class="pre">m_inc</span></tt>
constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">reference</span> <span class="pre">operator*()</span> <span class="pre">const;</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_inc</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">counting_iterator&amp;</span> <span class="pre">operator++();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">++m_inc</span></tt></td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">counting_iterator&amp;</span> <span class="pre">operator--();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Effects:</th><td class="field-body"><tt class="literal"><span class="pre">--m_inc</span></tt></td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">*this</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Incrementable</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_inc</span></tt></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class Incrementable&gt;
counting_iterator&lt;Incrementable&gt; make_counting_iterator(Incrementable x);
</pre>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">counting_iterator&lt;Incrementable&gt;</span></tt>
with <tt class="literal"><span class="pre">current</span></tt> constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="example">
<h1><a class="toc-backref" href="#id6" name="example">Example</a></h1>
<p>This example fills an array with numbers and a second array with
pointers into the first array, using <tt class="literal"><span class="pre">counting_iterator</span></tt> for both
tasks. Finally <tt class="literal"><span class="pre">indirect_iterator</span></tt> is used to print out the numbers
into the first array via indirection through the second array.</p>
<pre class="literal-block">
int N = 7;
std::vector&lt;int&gt; numbers;
typedef std::vector&lt;int&gt;::iterator n_iter;
std::copy(boost::counting_iterator&lt;int&gt;(0),
boost::counting_iterator&lt;int&gt;(N),
std::back_inserter(numbers));
std::vector&lt;std::vector&lt;int&gt;::iterator&gt; pointers;
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
std::cout &lt;&lt; &quot;indirectly printing out the numbers from 0 to &quot;
&lt;&lt; N &lt;&lt; std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator&lt;int&gt;(std::cout, &quot; &quot;));
std::cout &lt;&lt; std::endl;
</pre>
<p>The output is:</p>
<pre class="literal-block">
indirectly printing out the numbers from 0 to 7
0 1 2 3 4 5 6
</pre>
<p>The source code for this example can be found <a class="reference" href="../example/counting_iterator_example.cpp">here</a>.</p>
</div>
</div>
<hr class="footer"/>
<div class="footer">
<a class="reference" href="counting_iterator.rst">View document source</a>.
Generated on: 2004-01-12 21:18 UTC.
Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>