iterator/doc/new-iter-concepts.html
Jeremy Siek 85873e924a some minor edits
[SVN r20124]
2003-09-20 23:43:30 +00:00

954 lines
54 KiB
HTML
Executable File

<?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>New Iterator Concepts</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="2003-09-14" />
<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="new-iterator-concepts">
<h1 class="title">New Iterator Concepts</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>2003-09-14</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body"><strong>This document is a revised version of the official</strong> N1477=03-0060</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">We propose a new system of iterator concepts that treat
access and positioning independently. This allows the
concepts to more closely match the requirements
of algorithms and provides better categorizations
of iterators that are used in practice. This proposal
is a revision of paper <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2001/n1297.html">n1297</a>.</td>
</tr>
</tbody>
</table>
<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="#motivation" id="id1" name="id1">Motivation</a></li>
<li><a class="reference" href="#impact-on-the-standard" id="id2" name="id2">Impact on the Standard</a></li>
<li><a class="reference" href="#design" id="id3" name="id3">Design</a></li>
<li><a class="reference" href="#proposed-text" id="id4" name="id4">Proposed Text</a><ul>
<li><a class="reference" href="#addition-to-lib-iterator-requirements" id="id5" name="id5">Addition to [lib.iterator.requirements]</a><ul>
<li><a class="reference" href="#iterator-value-access-concepts-lib-iterator-value-access" id="id6" name="id6">Iterator Value Access Concepts [lib.iterator.value.access]</a><ul>
<li><a class="reference" href="#readable-iterators-lib-readable-iterators" id="id7" name="id7">Readable Iterators [lib.readable.iterators]</a></li>
<li><a class="reference" href="#writable-iterators-lib-writable-iterators" id="id8" name="id8">Writable Iterators [lib.writable.iterators]</a></li>
<li><a class="reference" href="#swappable-iterators-lib-swappable-iterators" id="id9" name="id9">Swappable Iterators [lib.swappable.iterators]</a></li>
<li><a class="reference" href="#readable-lvalue-iterators-lib-readable-lvalue-iterators" id="id10" name="id10">Readable Lvalue Iterators [lib.readable.lvalue.iterators]</a></li>
<li><a class="reference" href="#writable-lvalue-iterators-lib-writable-lvalue-iterators" id="id11" name="id11">Writable Lvalue Iterators [lib.writable.lvalue.iterators]</a></li>
</ul>
</li>
<li><a class="reference" href="#iterator-traversal-concepts-lib-iterator-traversal" id="id12" name="id12">Iterator Traversal Concepts [lib.iterator.traversal]</a><ul>
<li><a class="reference" href="#incrementable-iterators-lib-incrementable-iterators" id="id13" name="id13">Incrementable Iterators [lib.incrementable.iterators]</a></li>
<li><a class="reference" href="#single-pass-iterators-lib-single-pass-iterators" id="id14" name="id14">Single Pass Iterators [lib.single.pass.iterators]</a></li>
<li><a class="reference" href="#forward-traversal-iterators-lib-forward-traversal-iterators" id="id15" name="id15">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></li>
<li><a class="reference" href="#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators" id="id16" name="id16">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></li>
<li><a class="reference" href="#random-access-traversal-iterators-lib-random-access-traversal-iterators" id="id17" name="id17">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference" href="#addition-to-lib-iterator-synopsis" id="id18" name="id18">Addition to [lib.iterator.synopsis]</a></li>
<li><a class="reference" href="#addition-to-lib-iterator-traits" id="id19" name="id19">Addition to [lib.iterator.traits]</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="motivation">
<h1><a class="toc-backref" href="#id1" name="motivation">Motivation</a></h1>
<p>The standard iterator categories and requirements are flawed because
they use a single hierarchy of concepts to address two orthogonal
issues: <em>iterator traversal</em> and <em>value access</em>. As a result, many
algorithms with requirements expressed in terms of the iterator
categories are too strict. Also, many real-world iterators can not be
accurately categorized. A proxy-based iterator with random-access
traversal, for example, may only legally have a category of &quot;input
iterator&quot;, so generic algorithms are unable to take advantage of its
random-access capabilities. The current iterator concept hierarchy is
geared towards iterator traversal (hence the category names), while
requirements that address value access sneak in at various places. The
following table gives a summary of the current value access
requirements in the iterator categories.</p>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="31%" />
<col width="69%" />
</colgroup>
<tbody valign="top">
<tr><td>Output Iterator</td>
<td><tt class="literal"><span class="pre">*i</span> <span class="pre">=</span> <span class="pre">a</span></tt></td>
</tr>
<tr><td>Input Iterator</td>
<td><tt class="literal"><span class="pre">*i</span></tt> is convertible to <tt class="literal"><span class="pre">T</span></tt></td>
</tr>
<tr><td>Forward Iterator</td>
<td><tt class="literal"><span class="pre">*i</span></tt> is <tt class="literal"><span class="pre">T&amp;</span></tt> (or <tt class="literal"><span class="pre">const</span> <span class="pre">T&amp;</span></tt> once <a class="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><tt class="literal"><span class="pre">i[n]</span></tt> is convertible to <tt class="literal"><span class="pre">T</span></tt> (also <tt class="literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt>
is required for mutable iterators once <a class="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, <tt class="literal"><span class="pre">vector&lt;bool&gt;::iterator</span></tt> is almost a
random access iterator, but the return type is not <tt class="literal"><span class="pre">bool&amp;</span></tt> (see
<a class="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 <tt class="literal"><span class="pre">vector&lt;bool&gt;</span></tt> only meet the
requirements of input iterator and output iterator. This is so
nonintuitive that at least one implementation erroneously assigns
<tt class="literal"><span class="pre">random_access_iterator_tag</span></tt> as its <tt class="literal"><span class="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 <a class="reference" href="http://www.boost.org/libs/utility/transform_iterator.htm">transform_iterator</a>).
For unary functions such as <tt class="literal"><span class="pre">times</span></tt>, the return type of
<tt class="literal"><span class="pre">operator*</span></tt> clearly needs to be the <tt class="literal"><span class="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 <tt class="literal"><span class="pre">operator*</span></tt>, if you
wrap <tt class="literal"><span class="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
<a class="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 <tt class="literal"><span class="pre">input_iterator_tag</span></tt>, which means that,
strictly speaking, you could not use these iterators with algorithms
like <tt class="literal"><span class="pre">min_element()</span></tt>. As a temporary solution, the concept
<a class="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>
<ul class="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>
<div class="section" id="impact-on-the-standard">
<h1><a class="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 -&gt; Forward Traversal Iterator and Readable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">find_end,</span> <span class="pre">adjacent_find,</span> <span class="pre">search,</span> <span class="pre">search_n,</span> <span class="pre">rotate_copy,</span> <span class="pre">lower_bound,</span> <span class="pre">upper_bound,</span> <span class="pre">equal_range,</span> <span class="pre">binary_search,</span> <span class="pre">min_element,</span> <span class="pre">max_element</span></tt></blockquote>
<p>Forward Iterator (1) -&gt; Single Pass Iterator and Readable Iterator
Forward Iterator (2) -&gt; Forward Traversal Iterator and Readable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">find_first_of</span></tt></blockquote>
<p>Forward Iterator -&gt; Readable Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">iter_swap</span></tt></blockquote>
<p>Forward Iterator -&gt; Single Pass Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">fill,</span> <span class="pre">generate</span></tt></blockquote>
<p>Forward Iterator -&gt; Forward Traversal Iterator and Swappable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">rotate</span></tt></blockquote>
<p>Forward Iterator (1) -&gt; Swappable Iterator and Single Pass Iterator
Forward Iterator (2) -&gt; Swappable Iterator and Incrementable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">swap_ranges</span></tt></blockquote>
<dl>
<dt>Forward Iterator -&gt; Forward Traversal Iterator and Readable Iterator and Writable Iterator</dt>
<dd><tt class="literal"><span class="pre">remove,</span> <span class="pre">remove_if,</span> <span class="pre">unique</span></tt></dd>
</dl>
<p>Forward Iterator -&gt; Single Pass Iterator and Readable Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">replace,</span> <span class="pre">replace_if</span></tt></blockquote>
<dl>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Swappable Iterator</dt>
<dd><tt class="literal"><span class="pre">reverse</span></tt></dd>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Readable and Swappable Iterator</dt>
<dd><tt class="literal"><span class="pre">partition</span></tt></dd>
</dl>
<p>Bidirectional Iterator (1) -&gt; Bidirectional Traversal Iterator and Readable Iterator,
Bidirectional Iterator (2) -&gt; Bidirectional Traversal Iterator and Writable Iterator</p>
<blockquote>
<tt class="literal"><span class="pre">copy_backwards</span></tt></blockquote>
<dl>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Swappable Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">next_permutation,</span> <span class="pre">prev_permutation</span></tt></dd>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Readable Iterator and Writable Iterator</dt>
<dd><tt class="literal"><span class="pre">stable_partition,</span> <span class="pre">inplace_merge</span></tt></dd>
<dt>Bidirectional Iterator -&gt; Bidirectional Traversal Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">reverse_copy</span></tt></dd>
<dt>Random Access Iterator -&gt; Random Access Traversal Iterator and Readable and Swappable Iterator</dt>
<dd><tt class="literal"><span class="pre">random_shuffle,</span> <span class="pre">sort,</span> <span class="pre">stable_sort,</span> <span class="pre">partial_sort,</span> <span class="pre">nth_element,</span> <span class="pre">push_heap,</span> <span class="pre">pop_heap</span>
<span class="pre">make_heap,</span> <span class="pre">sort_heap</span></tt></dd>
<dt>Input Iterator (2) -&gt; Incrementable Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">equal</span></tt></dd>
<dt>Input Iterator (2) -&gt; Incrementable Iterator and Readable Iterator</dt>
<dd><tt class="literal"><span class="pre">transform</span></tt></dd>
</dl>
</div>
<div class="section" id="design">
<h1><a class="toc-backref" href="#id3" name="design">Design</a></h1>
<p>The iterator requirements are be separated into two hierarchies. One
set of concepts handles the syntax and semantics of value access:</p>
<ul class="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><img alt="access.png" src="access.png" /></p>
<p>The access concepts describe requirements related to <tt class="literal"><span class="pre">operator*</span></tt> and
<tt class="literal"><span class="pre">operator-&gt;</span></tt>, including the <tt class="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>, and
<tt class="literal"><span class="pre">pointer</span></tt> associated types.</p>
<p>The other set of concepts handles traversal:</p>
<ul class="simple">
<li>Incrementable Iterator</li>
<li>Single Pass Iterator</li>
<li>Forward Traversal Iterator</li>
<li>Bidirectional Traversal Iterator</li>
<li>Random Access Traversal Iterator</li>
</ul>
<p>The refinement relationships for the traversal concepts are in the
following diagram.</p>
<p><img alt="traversal.png" src="traversal.png" /></p>
<p>In addition to the iterator movement operators, such as
<tt class="literal"><span class="pre">operator++</span></tt>, the traversal concepts also include requirements on
position comparison such as <tt class="literal"><span class="pre">operator==</span></tt> and <tt class="literal"><span class="pre">operator&lt;</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><img alt="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 <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::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>
<pre class="literal-block">
template &lt;class AccessTag, class TraversalTag&gt;
struct iterator_tag : /* appropriate old category or categories */
{
typedef AccessTag access;
typedef TraversalTag traversal;
};
</pre>
<p>The <tt class="literal"><span class="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 <tt class="literal"><span class="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 <tt class="literal"><span class="pre">input_iterator_tag</span></tt> and <tt class="literal"><span class="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 <tt class="literal"><span class="pre">iterator_category</span></tt> is
<tt class="literal"><span class="pre">iterator_tag</span></tt> and also for iterators using the original iterator
categories.</p>
<pre class="literal-block">
template &lt;class Iterator&gt; struct access_category { typedef ... type; };
template &lt;class Iterator&gt; struct traversal_category { typedef ... type; };
</pre>
<p>The most difficult design decision concerned the <tt class="literal"><span class="pre">operator[]</span></tt>. The
direct approach for specifying <tt class="literal"><span class="pre">operator[]</span></tt> would have a return type
of <tt class="literal"><span class="pre">reference</span></tt>; the same as <tt class="literal"><span class="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 <a class="reference" href="http://anubis.dkuug.dk/JTC1/SC22/WG21/docs/lwg-active.html#299">issue 299</a>: <tt class="literal"><span class="pre">operator[]</span></tt> is
only required to return something convertible to the <tt class="literal"><span class="pre">value_type</span></tt>
(for a Readable Iterator), and is required to support assignment
<tt class="literal"><span class="pre">i[n]</span> <span class="pre">=</span> <span class="pre">t</span></tt> (for a Writable Iterator).</p>
</div>
<div class="section" id="proposed-text">
<h1><a class="toc-backref" href="#id4" name="proposed-text">Proposed Text</a></h1>
<div class="section" id="addition-to-lib-iterator-requirements">
<h2><a class="toc-backref" href="#id5" name="addition-to-lib-iterator-requirements">Addition to [lib.iterator.requirements]</a></h2>
<div class="section" id="iterator-value-access-concepts-lib-iterator-value-access">
<h3><a class="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, <tt class="literal"><span class="pre">X</span></tt> is an iterator type, <tt class="literal"><span class="pre">a</span></tt> is a constant
object of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">T</span></tt> is
<tt class="literal"><span class="pre">std::iterator_traits&lt;X&gt;::value_type</span></tt>, and <tt class="literal"><span class="pre">v</span></tt> is a constant
object of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<a class="target" id="readable-iterator" name="readable-iterator"></a><div class="section" id="readable-iterators-lib-readable-iterators">
<h4><a class="toc-backref" href="#id7" name="readable-iterators-lib-readable-iterators">Readable Iterators [lib.readable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Readable Iterator</em> concept
for the value type <tt class="literal"><span class="pre">T</span></tt> if the following expressions are valid and
respect the stated semantics. <tt class="literal"><span class="pre">U</span></tt> is the type of any specified
member of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="34%" />
<col width="30%" />
<col width="36%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Readable Iterator Requirements (in addition to CopyConstructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Note/Precondition/Postcondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt></td>
<td><tt class="literal"><span class="pre">T</span></tt></td>
<td>Any non-reference, non-cv-qualified type</td>
</tr>
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">readable_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
<td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td>pre: <tt class="literal"><span class="pre">a</span></tt> is dereferenceable. If <tt class="literal"><span class="pre">a</span> <span class="pre">==</span>
<span class="pre">b</span></tt> then <tt class="literal"><span class="pre">*a</span></tt> is equivalent to <tt class="literal"><span class="pre">*b</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">a-&gt;m</span></tt></td>
<td><tt class="literal"><span class="pre">U&amp;</span></tt></td>
<td>pre: <tt class="literal"><span class="pre">(*a).m</span></tt> is well-defined.
Equivalent to <tt class="literal"><span class="pre">(*a).m</span></tt></td>
</tr>
</tbody>
</table>
</blockquote>
<a class="target" id="writable-iterator" name="writable-iterator"></a></div>
<div class="section" id="writable-iterators-lib-writable-iterators">
<h4><a class="toc-backref" href="#id8" name="writable-iterators-lib-writable-iterators">Writable Iterators [lib.writable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Writable Iterator</em> concept
if the following expressions are valid and respect the stated
semantics. In addition, a model of <em>Writable Iterator</em> must include
in its documentation the <em>set of value types</em> that it allows for
output.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="42%" />
<col width="27%" />
<col width="31%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Writable Iterator Requirements (in addition to CopyConstructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Precondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">writable_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">*a</span> <span class="pre">=</span> <span class="pre">o</span></tt></td>
<td>&nbsp;</td>
<td>pre: The type of <tt class="literal"><span class="pre">o</span></tt>
is in the set of
value types of <tt class="literal"><span class="pre">X</span></tt></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="swappable-iterators-lib-swappable-iterators">
<h4><a class="toc-backref" href="#id9" name="swappable-iterators-lib-swappable-iterators">Swappable Iterators [lib.swappable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Swappable Iterator</em> concept
if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="38%" />
<col width="14%" />
<col width="48%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Swappable Iterator Requirements (in addition to CopyConstructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Postcondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iter_swap(a,</span> <span class="pre">b)</span></tt></td>
<td><tt class="literal"><span class="pre">void</span></tt></td>
<td>post: the pointed to values are exchanged</td>
</tr>
</tbody>
</table>
</blockquote>
<dl>
<dt>[<em>Note:</em> An iterator that is a model of the <em>Readable</em> and <em>Writable Iterator</em> concepts</dt>
<dd>is also a model of <em>Swappable Iterator</em>. <em>--end note</em>]</dd>
</dl>
</div>
<div class="section" id="readable-lvalue-iterators-lib-readable-lvalue-iterators">
<h4><a class="toc-backref" href="#id10" name="readable-lvalue-iterators-lib-readable-lvalue-iterators">Readable Lvalue Iterators [lib.readable.lvalue.iterators]</a></h4>
<p>The <em>Readable Lvalue Iterator</em> concept adds the requirement that the
<tt class="literal"><span class="pre">reference</span></tt> type be a reference to the value type of the iterator.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="35%" />
<col width="32%" />
<col width="34%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Readable Lvalue Iterator Requirements (in addition to Readable Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td><tt class="literal"><span class="pre">T&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">T</span></tt> is <em>cv</em>
<tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt>
where <em>cv</em> is an optional
cv-qualification</td>
</tr>
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">readable_lvalue_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="writable-lvalue-iterators-lib-writable-lvalue-iterators">
<h4><a class="toc-backref" href="#id11" name="writable-lvalue-iterators-lib-writable-lvalue-iterators">Writable Lvalue Iterators [lib.writable.lvalue.iterators]</a></h4>
<p>The <em>Writable Lvalue Iterator</em> concept adds the requirement that the
<tt class="literal"><span class="pre">reference</span></tt> type be a non-const reference to the value type of the
iterator.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="45%" />
<col width="55%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="2">Writable Lvalue Iterator Requirements (in addition to Readable Lvalue Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type&amp;</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">access_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to <tt class="literal"><span class="pre">writable_lvalue_iterator_tag</span></tt></td>
</tr>
</tbody>
</table>
</blockquote>
</div>
</div>
<div class="section" id="iterator-traversal-concepts-lib-iterator-traversal">
<h3><a class="toc-backref" href="#id12" name="iterator-traversal-concepts-lib-iterator-traversal">Iterator Traversal Concepts [lib.iterator.traversal]</a></h3>
<p>In the tables below, <tt class="literal"><span class="pre">X</span></tt> is an iterator type, <tt class="literal"><span class="pre">a</span></tt> and <tt class="literal"><span class="pre">b</span></tt> are
constant objects of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">r</span></tt> and <tt class="literal"><span class="pre">s</span></tt> are mutable objects of
type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">T</span></tt> is <tt class="literal"><span class="pre">std::iterator_traits&lt;X&gt;::value_type</span></tt>, and
<tt class="literal"><span class="pre">v</span></tt> is a constant object of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<div class="section" id="incrementable-iterators-lib-incrementable-iterators">
<h4><a class="toc-backref" href="#id13" name="incrementable-iterators-lib-incrementable-iterators">Incrementable Iterators [lib.incrementable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Incrementable Iterator</em>
concept if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="27%" />
<col width="38%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Incrementable Iterator Requirements (in addition to Assignable, Copy Constructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Semantics</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">&amp;r</span> <span class="pre">==</span> <span class="pre">&amp;++r</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">r++</span></tt></td>
<td><tt class="literal"><span class="pre">X</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">r;</span> <span class="pre">++r;</span> <span class="pre">return</span> <span class="pre">tmp;</span> <span class="pre">}</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to <tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="single-pass-iterators-lib-single-pass-iterators">
<h4><a class="toc-backref" href="#id14" name="single-pass-iterators-lib-single-pass-iterators">Single Pass Iterators [lib.single.pass.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Single Pass Iterator</em>
concept if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="33%" />
<col width="27%" />
<col width="39%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Single Pass Iterator Requirements (in addition to Incrementable Iterator and Equality Comparable)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Semantics/Pre-/Post-condition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td>pre: <tt class="literal"><span class="pre">r</span></tt> is dereferenceable; post:
<tt class="literal"><span class="pre">r</span></tt> is dereferenceable or <tt class="literal"><span class="pre">r</span></tt> is
past-the-end</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">==</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">==</span></tt> is an equivalence relation over
its domain</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">!=</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">==</span> <span class="pre">b)</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">single_pass_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="forward-traversal-iterators-lib-forward-traversal-iterators">
<h4><a class="toc-backref" href="#id15" name="forward-traversal-iterators-lib-forward-traversal-iterators">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Forward Traversal Iterator</em>
concept if the following expressions are valid and respect the stated
semantics.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="39%" />
<col width="37%" />
<col width="24%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Forward Traversal Iterator Requirements (in addition to Single Pass Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Note</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">X</span> <span class="pre">u;</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">note:</span> <span class="pre">u</span> <span class="pre">may</span> <span class="pre">have</span> <span class="pre">a</span>
<span class="pre">singular</span> <span class="pre">value.</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">++r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">r</span> <span class="pre">==</span> <span class="pre">s</span></tt> and <tt class="literal"><span class="pre">r</span></tt> is
dereferenceable implies
<tt class="literal"><span class="pre">++r</span> <span class="pre">==</span> <span class="pre">++s.</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::difference_type</span></tt></td>
<td>A signed integral type representing
the distance between iterators</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">forward_traversal_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">
<h4><a class="toc-backref" href="#id16" name="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> models the <em>Bidirectional Traversal
Iterator</em> concept if the following expressions are valid and respect
the stated semantics.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="28%" />
<col width="36%" />
<col width="35%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Semantics/Pre-/Post-condition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">--r</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td>pre: there exists <tt class="literal"><span class="pre">s</span></tt> such that <tt class="literal"><span class="pre">r</span>
<span class="pre">==</span> <span class="pre">++s</span></tt>. post: <tt class="literal"><span class="pre">s</span></tt> is
dereferenceable. <tt class="literal"><span class="pre">--(++r)</span> <span class="pre">==</span> <span class="pre">r</span></tt>.
<tt class="literal"><span class="pre">--r</span> <span class="pre">==</span> <span class="pre">--s</span></tt> implies <tt class="literal"><span class="pre">r</span> <span class="pre">==</span> <span class="pre">s</span></tt>. <tt class="literal"><span class="pre">&amp;r</span>
<span class="pre">==</span> <span class="pre">&amp;--r</span></tt>.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">r--</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">const</span> <span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">r;</span> <span class="pre">--r;</span> <span class="pre">return</span> <span class="pre">tmp;</span> <span class="pre">}</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">bidirectional_traversal_iterator_tag</span></tt></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
<div class="section" id="random-access-traversal-iterators-lib-random-access-traversal-iterators">
<h4><a class="toc-backref" href="#id17" name="random-access-traversal-iterators-lib-random-access-traversal-iterators">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="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, <tt class="literal"><span class="pre">Distance</span></tt> is
<tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::difference_type</span></tt> and <tt class="literal"><span class="pre">n</span></tt> represents a
constant object of type <tt class="literal"><span class="pre">Distance</span></tt>.</p>
<blockquote>
<table class="table" frame="border" rules="all">
<colgroup>
<col width="26%" />
<col width="33%" />
<col width="18%" />
<col width="24%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="4">Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Operational Semantics</th>
<th>Assertion/Precondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">r</span> <span class="pre">+=</span> <span class="pre">n</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><pre class="first last literal-block">
{
Distance m = n;
if (m &gt;= 0)
while (m--)
++r;
else
while (m++)
--r;
return r;
}
</pre>
</td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">n</span></tt>, <tt class="literal"><span class="pre">n</span> <span class="pre">+</span> <span class="pre">a</span></tt></td>
<td><tt class="literal"><span class="pre">X</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">a;</span> <span class="pre">return</span>
<span class="pre">tmp</span> <span class="pre">+=</span> <span class="pre">n;</span> <span class="pre">}</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">r</span> <span class="pre">-=</span> <span class="pre">n</span></tt></td>
<td><tt class="literal"><span class="pre">X&amp;</span></tt></td>
<td><tt class="literal"><span class="pre">return</span> <span class="pre">r</span> <span class="pre">+=</span> <span class="pre">-n</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">-</span> <span class="pre">n</span></tt></td>
<td><tt class="literal"><span class="pre">X</span></tt></td>
<td><tt class="literal"><span class="pre">{</span> <span class="pre">X</span> <span class="pre">tmp</span> <span class="pre">=</span> <span class="pre">a;</span> <span class="pre">return</span>
<span class="pre">tmp</span> <span class="pre">-=</span> <span class="pre">n;</span> <span class="pre">}</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">b</span> <span class="pre">-</span> <span class="pre">a</span></tt></td>
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
<td><tt class="literal"><span class="pre">a</span> <span class="pre">&lt;</span> <span class="pre">b</span> <span class="pre">?</span>
<span class="pre">distance(a,b)</span> <span class="pre">:</span>
<span class="pre">-distance(b,a)</span></tt></td>
<td>pre: there exists a value
<tt class="literal"><span class="pre">n</span></tt> of <tt class="literal"><span class="pre">Distance</span></tt> such
that <tt class="literal"><span class="pre">a</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">b</span></tt>. <tt class="literal"><span class="pre">b</span> <span class="pre">==</span>
<span class="pre">a</span> <span class="pre">+</span> <span class="pre">(b</span> <span class="pre">-</span> <span class="pre">a)</span></tt>.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a[n]</span></tt></td>
<td>convertible to T</td>
<td><tt class="literal"><span class="pre">*(a</span> <span class="pre">+</span> <span class="pre">n)</span></tt></td>
<td>pre: a is a <a class="reference" href="#readable-iterator">readable
iterator</a></td>
</tr>
<tr><td><tt class="literal"><span class="pre">a[n]</span> <span class="pre">=</span> <span class="pre">v</span></tt></td>
<td>convertible to T</td>
<td><tt class="literal"><span class="pre">*(a</span> <span class="pre">+</span> <span class="pre">n)</span> <span class="pre">=</span> <span class="pre">v</span></tt></td>
<td>pre: a is a <a class="reference" href="#writable-iterator">writable
iterator</a></td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&lt;</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">b</span> <span class="pre">-</span> <span class="pre">a</span> <span class="pre">&gt;</span> <span class="pre">0</span></tt></td>
<td><tt class="literal"><span class="pre">&lt;</span></tt> is a total ordering
relation</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&gt;</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">b</span> <span class="pre">&lt;</span> <span class="pre">a</span></tt></td>
<td><tt class="literal"><span class="pre">&gt;</span></tt> is a total ordering
relation</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&gt;=</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">&lt;</span> <span class="pre">b)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">a</span> <span class="pre">&lt;=</span> <span class="pre">b</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(a</span> <span class="pre">&gt;</span> <span class="pre">b)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">random_access_traversal_iterator_tag</span></tt></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</blockquote>
</div>
</div>
</div>
<div class="section" id="addition-to-lib-iterator-synopsis">
<h2><a class="toc-backref" href="#id18" name="addition-to-lib-iterator-synopsis">Addition to [lib.iterator.synopsis]</a></h2>
<pre class="literal-block">
// lib.iterator.traits, traits and tags
template &lt;class Iterator&gt; struct access_category;
template &lt;class Iterator&gt; struct traversal_category;
template &lt;class AccessTag, class TraversalTag&gt;
struct iterator_tag : /* appropriate old category or categories */ {
typedef AccessTag access;
typedef TraversalTag traversal;
};
struct readable_iterator_tag { };
struct writable_iterator_tag { };
struct swappable_iterator_tag { };
struct readable_writable_iterator_tag
: virtual readable_iterator_tag
, virtual writable_iterator_tag
, virtual swappable_iterator_tag { };
struct readable_lvalue_iterator_tag
: virtual readable_iterator_tag { };
struct writable_lvalue_iterator_tag
: virtual public readable_writable_iterator_tag
, virtual public readable_lvalue_iterator_tag { };
struct incrementable_iterator_tag { };
struct single_pass_iterator_tag : incrementable_iterator_tag { };
struct forward_traversal_tag : single_pass_iterator_tag { };
struct bidirectional_traversal_tag : forward_traversal_tag { };
struct random_access_traversal_tag : bidirectional_traversal_tag { };
struct null_category_tag { };
struct input_output_iterator_tag : input_iterator_tag, output_iterator_tag {};
</pre>
</div>
<div class="section" id="addition-to-lib-iterator-traits">
<h2><a class="toc-backref" href="#id19" name="addition-to-lib-iterator-traits">Addition to [lib.iterator.traits]</a></h2>
<p>The <tt class="literal"><span class="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 <tt class="literal"><span class="pre">iterator_tag</span></tt> class inherits
from one of the original iterator tags according to the following
pseudo-code.</p>
<pre class="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>If the argument for the template parameter <tt class="literal"><span class="pre">AccessTag</span></tt> is not
convertible to one or more of: <tt class="literal"><span class="pre">readable_iterator_tag</span></tt>,
<tt class="literal"><span class="pre">writable_iterator_tag</span></tt>, <tt class="literal"><span class="pre">swappable_iterator_tag</span></tt>, or if the
argument for <tt class="literal"><span class="pre">TraversalTag</span></tt> is not convertible to
<tt class="literal"><span class="pre">incrementable_iterator_tag</span></tt> then the behavior of <tt class="literal"><span class="pre">iterator_tag</span></tt>
is not defined.</p>
<p>The <tt class="literal"><span class="pre">access_category</span></tt> and <tt class="literal"><span class="pre">traversal_category</span></tt> class templates are
traits classes. For iterators whose
<tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> type is <tt class="literal"><span class="pre">iterator_tag</span></tt>,
the <tt class="literal"><span class="pre">access_category</span></tt> and <tt class="literal"><span class="pre">traversal_category</span></tt> traits access the
<tt class="literal"><span class="pre">access</span></tt> and <tt class="literal"><span class="pre">traversal</span></tt> member types within <tt class="literal"><span class="pre">iterator_tag</span></tt>.
For iterators whose <tt class="literal"><span class="pre">iterator_traits&lt;Iter&gt;::iterator_category</span></tt> type
is not <tt class="literal"><span class="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>
<pre class="literal-block">
access-category(Iterator) =
cat = iterator_traits&lt;Iterator&gt;::iterator_category;
if (cat == iterator_tag&lt;Access,Traversal&gt;)
return Access;
else if (cat is convertible to forward_iterator_tag) {
if (iterator_traits&lt;Iterator&gt;::reference is a const reference)
return readable_lvalue_iterator_tag;
else
return writable_lvalue_iterator_tag;
} else if (cat is convertible to input_iterator_tag)
return readable_iterator_tag;
else if (cat is convertible to output_iterator_tag)
return writable_iterator_tag;
else
return null_category_tag;
traversal-category(Iterator) =
cat = iterator_traits&lt;Iterator&gt;::iterator_category;
if (cat == iterator_tag&lt;Access,Traversal&gt;)
return Traversal;
else if (cat is convertible to random_access_iterator_tag)
return random_access_traversal_tag;
else if (cat is convertible to bidirectional_iterator_tag)
return bidirectional_traversal_tag;
else if (cat is convertible to forward_iterator_tag)
return forward_traversal_tag;
else if (cat is convertible to input_iterator_tag)
return single_pass_iterator_tag;
else if (cat is convertible to output_iterator_tag)
return incrementable_iterator_tag;
else
return null_category_tag;
</pre>
<p>The following specializations provide the access and traversal
category tags for pointer types.</p>
<pre class="literal-block">
template &lt;typename T&gt;
struct access_category&lt;const T*&gt;
{
typedef readable_lvalue_iterator_tag type;
};
template &lt;typename T&gt;
struct access_category&lt;T*&gt;
{
typedef writable_lvalue_iterator_tag type;
};
template &lt;typename T&gt;
struct traversal_category&lt;T*&gt;
{
typedef random_access_traversal_tag type;
};
</pre>
<!-- LocalWords: Abrahams Siek Witt const bool Sutter's WG int UL LI href Lvalue
LocalWords: ReadableIterator WritableIterator SwappableIterator cv pre iter
LocalWords: ConstantLvalueIterator MutableLvalueIterator CopyConstructible TR
LocalWords: ForwardTraversalIterator BidirectionalTraversalIterator lvalue
LocalWords: RandomAccessTraversalIterator dereferenceable Incrementable tmp
LocalWords: incrementable xxx min prev inplace png oldeqnew AccessTag struct
LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
</div>
</div>
</div>
</body>
</html>