<metaname="author"content="David Abrahams, Jeremy Siek, Thomas Witt"/>
<metaname="organization"content="Boost Consulting, Indiana University Open Systems Lab, University of Hanover Institute for Transport Railway Operation and Construction"/>
<td><aclass="first reference"href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <aclass="reference"href="http://www.osl.iu.edu">Open Systems Lab</a>, University of Hanover <aclass="last reference"href="http://www.ive.uni-hannover.de">Institute for Transport Railway Operation and Construction</a></td></tr>
<trclass="field"><thclass="docinfo-name">Number:</th><tdclass="field-body"><strong>This document is a revised version of the official</strong> N1477=03-0060</td>
<li><aclass="reference"href="#addition-to-lib-iterator-requirements"id="id5"name="id5">Addition to [lib.iterator.requirements]</a><ul>
<li><aclass="reference"href="#iterator-value-access-concepts-lib-iterator-value-access"id="id6"name="id6">Iterator Value Access Concepts [lib.iterator.value.access]</a><ul>
<td><ttclass="literal"><spanclass="pre">*i</span></tt> is convertible to <ttclass="literal"><spanclass="pre">T</span></tt></td>
</tr>
<tr><td>Forward Iterator</td>
<td><ttclass="literal"><spanclass="pre">*i</span></tt> is <ttclass="literal"><spanclass="pre">T&</span></tt> (or <ttclass="literal"><spanclass="pre">const</span><spanclass="pre">T&</span></tt> once <aclass="reference"href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#200">issue 200</a>
is resolved)</td>
</tr>
<tr><td>Random Access Iterator</td>
<td><ttclass="literal"><spanclass="pre">i[n]</span></tt> is convertible to <ttclass="literal"><spanclass="pre">T</span></tt> (also <ttclass="literal"><spanclass="pre">i[n]</span><spanclass="pre">=</span><spanclass="pre">t</span></tt>
is required for mutable iterators once <aclass="reference"href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>
is resolved)</td>
</tr>
</tbody>
</table>
<p>Because iterator traversal and value access are mixed together in a
single hierarchy, many useful iterators can not be appropriately
categorized. For example, <ttclass="literal"><spanclass="pre">vector<bool>::iterator</span></tt> is almost a
random access iterator, but the return type is not <ttclass="literal"><spanclass="pre">bool&</span></tt> (see
<aclass="reference"href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#96">issue 96</a> and Herb Sutter's paper J16/99-0008 = WG21
N1185). Therefore, the iterators of <ttclass="literal"><spanclass="pre">vector<bool></span></tt> only meet the
requirements of input iterator and output iterator. This is so
nonintuitive that at least one implementation erroneously assigns
<ttclass="literal"><spanclass="pre">random_access_iterator_tag</span></tt> as its <ttclass="literal"><spanclass="pre">iterator_category</span></tt>.</p>
<p>Another difficult-to-categorize iterator is the transform iterator, an
adaptor which applies a unary function object to the dereferenced
value of the some underlying iterator (see <aclass="reference"href="http://www.boost.org/libs/utility/transform_iterator.htm">transform_iterator</a>).
For unary functions such as <ttclass="literal"><spanclass="pre">times</span></tt>, the return type of
<ttclass="literal"><spanclass="pre">operator*</span></tt> clearly needs to be the <ttclass="literal"><spanclass="pre">result_type</span></tt> of the function
object, which is typically not a reference. Because random access
iterators are required to return lvalues from <ttclass="literal"><spanclass="pre">operator*</span></tt>, if you
wrap <ttclass="literal"><spanclass="pre">int*</span></tt> with a transform iterator, you do not get a random
access iterator as might be expected, but an input iterator.</p>
<p>A third example is found in the vertex and edge iterators of the
<aclass="reference"href="http://www.boost.org/libs/graph/doc/table_of_contents.html">Boost Graph Library</a>. These iterators return vertex and edge
descriptors, which are lightweight handles created on-the-fly. They
must be returned by-value. As a result, their current standard
iterator category is <ttclass="literal"><spanclass="pre">input_iterator_tag</span></tt>, which means that,
strictly speaking, you could not use these iterators with algorithms
like <ttclass="literal"><spanclass="pre">min_element()</span></tt>. As a temporary solution, the concept
<aclass="reference"href="http://www.boost.org/libs/utility/MultiPassInputIterator.html">Multi-Pass Input Iterator</a> was introduced to describe the vertex and
edge descriptors, but as the design notes for the concept suggest, a
better solution is needed.</p>
<p>In short, there are many useful iterators that do not fit into the
current standard iterator categories. As a result, the following bad
things happen:</p>
<ulclass="simple">
<li>Iterators are often mis-categorized.</li>
<li>Algorithm requirements are more strict than necessary, because they
cannot separate the need for random access or bidirectional
traversal from the need for a true reference return type.</li>
</ul>
</div>
<divclass="section"id="impact-on-the-standard">
<h1><aclass="toc-backref"href="#id2"name="impact-on-the-standard">Impact on the Standard</a></h1>
<p>The new iterator concepts are backward-compatible with the old
iterator requirements, and old iterators are forward-compatible with
the new iterator concepts. That is to say, iterators that satisfy the
old requirements also satisfy appropriate concepts in the new system,
and iterators modeling the new concepts will automatically satisfy the
appropriate old requirements.</p>
<!-- I think we need to say something about the resolution to allow
convertibility to any of the old-style tags as a TR issue (hope it
made it). -DWA -->
<!-- Hmm, not sure I understand. Are you talking about whether a
standards conforming input iterator is allowed to have
a tag that is not input_iterator_tag but that
is convertible to input_iterator_tag? -JGS -->
<p>The algorithms in the standard library benefit from the new iterator
concepts because the new concepts provide a more accurate way to
express their type requirements. The result is algorithms that are
usable in more situations and have fewer type requirements. The
following lists the proposed changes to the type requirements of
algorithms.</p>
<p>Forward Iterator -> Forward Traversal Iterator and Readable Iterator</p>
<p>The iterator requirements are be separated into two hierarchies. One
set of concepts handles the syntax and semantics of value access:</p>
<ulclass="simple">
<li>Readable Iterator</li>
<li>Writable Iterator</li>
<li>Swappable Iterator</li>
<li>Readable Lvalue Iterator</li>
<li>Writable Lvalue Iterator</li>
</ul>
<p>The refinement relationships among these iterator concepts are given
in the following diagram.</p>
<p><imgalt="access.png"src="access.png"/></p>
<p>The access concepts describe requirements related to <ttclass="literal"><spanclass="pre">operator*</span></tt> and
<ttclass="literal"><spanclass="pre">operator-></span></tt>, including the <ttclass="literal"><spanclass="pre">value_type</span></tt>, <ttclass="literal"><spanclass="pre">reference</span></tt>, and
<p>In addition to the iterator movement operators, such as
<ttclass="literal"><spanclass="pre">operator++</span></tt>, the traversal concepts also include requirements on
position comparison such as <ttclass="literal"><spanclass="pre">operator==</span></tt> and <ttclass="literal"><spanclass="pre">operator<</span></tt>. The
reason for the fine grain slicing of the concepts into the
Incrementable and Single Pass is to provide concepts that are exact
matches with the original input and output iterator requirements.</p>
<p>The relationship between the new iterator concepts and the old are
given in the following diagram.</p>
<p><imgalt="oldeqnew.png"src="oldeqnew.png"/></p>
<p>Like the old iterator requirements, we provide tags for purposes of
dispatching. There are two hierarchies of tags, one for the access
concepts and one for the traversal concepts. We provide an access
mechanism for mapping iterator types to these new tags. Our design
reuses <ttclass="literal"><spanclass="pre">iterator_traits<Iter>::iterator_category</span></tt> as the access
mechanism. To enable this, a pair of access and traversal tags are
combined into a single type using the following <cite>iterator_tag</cite> class.</p>
<preclass="literal-block">
template <class AccessTag, class TraversalTag>
struct iterator_tag : /* appropriate old category or categories */
{
typedef AccessTag access;
typedef TraversalTag traversal;
};
</pre>
<p>The <ttclass="literal"><spanclass="pre">iterator_tag</span></tt> class template is derived from the appropriate
iterator tag or tags from the old requirements based on the new-style
tags passed as template parameters. The algorithm for determining the
old tag or tags from the new tags picks the least-refined old concepts
that include all of the requirements of the access and traversal
concepts (that is, the closest fit), if any such category exists. For
example, a the category tag for a Readable Single Pass Iterator will
always be derived from <ttclass="literal"><spanclass="pre">input_iterator_tag</span></tt>, while the category tag
for a Single Pass Iterator that is both Readable and Writable will be
derived from both <ttclass="literal"><spanclass="pre">input_iterator_tag</span></tt> and <ttclass="literal"><spanclass="pre">output_iterator_tag</span></tt>.</p>
<p>We also provide two helper classes that make it convenient to obtain
the access and traversal tags of an iterator. These helper classes
work both for iterators whose <ttclass="literal"><spanclass="pre">iterator_category</span></tt> is
<ttclass="literal"><spanclass="pre">iterator_tag</span></tt> and also for iterators using the original iterator
<p>The most difficult design decision concerned the <ttclass="literal"><spanclass="pre">operator[]</span></tt>. The
direct approach for specifying <ttclass="literal"><spanclass="pre">operator[]</span></tt> would have a return type
of <ttclass="literal"><spanclass="pre">reference</span></tt>; the same as <ttclass="literal"><spanclass="pre">operator*</span></tt>. However, going in this
direction would mean that an iterator satisfying the old Random Access
Iterator requirements would not necessarily be a model of Readable or
Writable Lvalue Iterator. Instead we have chosen a design that
matches the preferred resolution of <aclass="reference"href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <ttclass="literal"><spanclass="pre">operator[]</span></tt> is
only required to return something convertible to the <ttclass="literal"><spanclass="pre">value_type</span></tt>
(for a Readable Iterator), and is required to support assignment
<ttclass="literal"><spanclass="pre">i[n]</span><spanclass="pre">=</span><spanclass="pre">t</span></tt> (for a Writable Iterator).</p>
<h3><aclass="toc-backref"href="#id6"name="iterator-value-access-concepts-lib-iterator-value-access">Iterator Value Access Concepts [lib.iterator.value.access]</a></h3>
<p>In the tables below, <ttclass="literal"><spanclass="pre">X</span></tt> is an iterator type, <ttclass="literal"><spanclass="pre">a</span></tt> is a constant
object of type <ttclass="literal"><spanclass="pre">X</span></tt>, <ttclass="literal"><spanclass="pre">T</span></tt> is
<ttclass="literal"><spanclass="pre">std::iterator_traits<X>::value_type</span></tt>, and <ttclass="literal"><spanclass="pre">v</span></tt> is a constant
object of type <ttclass="literal"><spanclass="pre">T</span></tt>.</p>
<td>pre: <ttclass="literal"><spanclass="pre">a</span></tt> is dereferenceable. If <ttclass="literal"><spanclass="pre">a</span><spanclass="pre">==</span>
<spanclass="pre">b</span></tt> then <ttclass="literal"><spanclass="pre">*a</span></tt> is equivalent to <ttclass="literal"><spanclass="pre">*b</span></tt></td>
<p>In the tables below, <ttclass="literal"><spanclass="pre">X</span></tt> is an iterator type, <ttclass="literal"><spanclass="pre">a</span></tt> and <ttclass="literal"><spanclass="pre">b</span></tt> are
constant objects of type <ttclass="literal"><spanclass="pre">X</span></tt>, <ttclass="literal"><spanclass="pre">r</span></tt> and <ttclass="literal"><spanclass="pre">s</span></tt> are mutable objects of
type <ttclass="literal"><spanclass="pre">X</span></tt>, <ttclass="literal"><spanclass="pre">T</span></tt> is <ttclass="literal"><spanclass="pre">std::iterator_traits<X>::value_type</span></tt>, and
<ttclass="literal"><spanclass="pre">v</span></tt> is a constant object of type <ttclass="literal"><spanclass="pre">T</span></tt>.</p>
<td><ttclass="literal"><spanclass="pre">r</span><spanclass="pre">==</span><spanclass="pre">s</span></tt> and <ttclass="literal"><spanclass="pre">r</span></tt> is
<p>A class or built-in type <ttclass="literal"><spanclass="pre">X</span></tt> models the <em>Random Access Traversal
Iterator</em> concept if the following expressions are valid and respect
the stated semantics. In the table below, <ttclass="literal"><spanclass="pre">Distance</span></tt> is
<ttclass="literal"><spanclass="pre">iterator_traits<X>::difference_type</span></tt> and <ttclass="literal"><spanclass="pre">n</span></tt> represents a
constant object of type <ttclass="literal"><spanclass="pre">Distance</span></tt>.</p>
<ttclass="literal"><spanclass="pre">n</span></tt> of <ttclass="literal"><spanclass="pre">Distance</span></tt> such
that <ttclass="literal"><spanclass="pre">a</span><spanclass="pre">+</span><spanclass="pre">n</span><spanclass="pre">==</span><spanclass="pre">b</span></tt>. <ttclass="literal"><spanclass="pre">b</span><spanclass="pre">==</span>
<h2><aclass="toc-backref"href="#id19"name="addition-to-lib-iterator-traits">Addition to [lib.iterator.traits]</a></h2>
<p>The <ttclass="literal"><spanclass="pre">iterator_tag</span></tt> class template is an iterator category tag that
encodes the access and traversal tags in addition to being compatible
with the original iterator tags. The <ttclass="literal"><spanclass="pre">iterator_tag</span></tt> class inherits
from one of the original iterator tags according to the following
pseudo-code.</p>
<preclass="literal-block">
inherit-category(access-tag, traversal-tag) =
if (access-tag is convertible to readable_lvalue_iterator_tag) {
if (traversal-tag is convertible to random_access_traversal_tag)
return random_access_iterator_tag;
else if (traversal-tag is convertible to bidirectional_traversal_tag)
return bidirectional_iterator_tag;
else if (traversal-tag is convertible to forward_traversal_tag)
return forward_iterator_tag;
else if (traversal-tag is convertible to single_pass_traversal_tag)
if (access-tag is convertible to writable_iterator_tag)
return input_output_iterator_tag;
else
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
} else if (access-tag is convertible to readable_writable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_output_iterator_tag;
else if (access-tag is convertible to readable_iterator_tag
and traversal-tag is convertible to single_pass_iterator_tag)
return input_iterator_tag;
else if (access-tag is convertible to writable_iterator_tag
and traversal-tag is convertible to incrementable_iterator_tag)
return output_iterator_tag;
else
return null_category_tag;
</pre>
<p>The <ttclass="literal"><spanclass="pre">access_category</span></tt> and <ttclass="literal"><spanclass="pre">traversal_category</span></tt> class templates are
traits classes. For iterators whose
<ttclass="literal"><spanclass="pre">iterator_traits<Iter>::iterator_category</span></tt> type is <ttclass="literal"><spanclass="pre">iterator_tag</span></tt>,
the <ttclass="literal"><spanclass="pre">access_category</span></tt> and <ttclass="literal"><spanclass="pre">traversal_category</span></tt> traits access the
<ttclass="literal"><spanclass="pre">access</span></tt> and <ttclass="literal"><spanclass="pre">traversal</span></tt> member types within <ttclass="literal"><spanclass="pre">iterator_tag</span></tt>.
For iterators whose <ttclass="literal"><spanclass="pre">iterator_traits<Iter>::iterator_category</span></tt> type
is not <ttclass="literal"><spanclass="pre">iterator_tag</span></tt> and instead is a tag convertible to one of the
original tags, the appropriate traversal and access tags is deduced.
The following pseudo-code describes the algorithm.</p>
Generated by <aclass="reference"href="http://docutils.sourceforge.net/">Docutils</a> from <aclass="reference"href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.