Bring branch up-to-date with trunk

[SVN r21992]
This commit is contained in:
Dave Abrahams
2004-01-27 04:50:52 +00:00
parent 189533437f
commit d15302e683
38 changed files with 8573 additions and 4216 deletions

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,9 @@
+++++++++++++++++++++++++++++
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@acm.org
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:Number: This is a revised version of N1530_\ =03-0113, which was
@ -22,7 +21,7 @@
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
.. _`Zephyr Associates, Inc.`: http://www.styleadvisor.com
:abstract: We propose a set of class templates that help programmers
build standard-conforming iterators, both from scratch and
@ -197,10 +196,6 @@ which were easily implemented using ``iterator_adaptor``:
* ``transform_iterator``, which applies a user-defined function object
to the underlying values when dereferenced.
* ``projection_iterator``, which is similar to ``transform_iterator``
except that when dereferenced it returns a reference instead of
a value.
* ``filter_iterator``, which provides a view of an iterator range in
which some elements of the underlying range are skipped.
@ -266,6 +261,12 @@ Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
>
class indirect_iterator;
template <class Dereferenceable>
struct pointee;
template <class Dereferenceable>
struct indirect_reference;
template <class Iterator>
class reverse_iterator;
@ -285,7 +286,7 @@ Header ``<iterator_helper>`` synopsis [lib.iterator.helper.synopsis]
, class CategoryOrTraversal = use_default
, class Difference = use_default
>
class counting_iterator
class counting_iterator;
template <class UnaryFunction>
class function_output_iterator;
@ -352,6 +353,16 @@ Indirect iterator
.. include:: indirect_iterator_abstract.rst
Class template ``pointee``
....................................
.. include:: pointee_ref.rst
Class template ``indirect_reference``
.....................................
.. include:: indirect_reference_ref.rst
Class template ``indirect_iterator``
....................................

View File

@ -7,200 +7,9 @@
<title>Filter 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="2003-09-14" />
<meta name="date" content="2004-01-13" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="filter-iterator">
@ -218,7 +27,7 @@ ul.auto-toc {
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>
<td>2004-01-13</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>
@ -227,37 +36,46 @@ Railway Operation and Construction</a></td></tr>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">The filter iterator adaptor creates a view of an iterator range in
which some elements of the range are skipped. A predicate function
object controls which elements are skipped. When the predicate is
applied to an element, if it returns <tt class="literal"><span class="pre">true</span></tt> then the element is
retained and if it returns <tt class="literal"><span class="pre">false</span></tt> then the element is skipped
over. When skipping over elements, it is necessary for the filter
adaptor to know when to stop so as to avoid going past the end of the
underlying range. A filter iterator is therefore constructed with pair
of iterators indicating the range of elements in the unfiltered
sequence to be traversed.</td>
</tr>
</tbody>
</table>
<p>The filter iterator adaptor creates a view of an iterator range in
which some elements of the range are skipped over. A predicate
function object controls which elements are skipped. When the
predicate is applied to an element, if it returns <tt class="literal"><span class="pre">true</span></tt> then the
element is retained and if it returns <tt class="literal"><span class="pre">false</span></tt> then the element is
skipped over. When skipping over elements, it is necessary for the
filter adaptor to know when to stop so as to avoid going past the end
of the underlying range. Therefore the constructor of the filter
iterator takes two iterator parameters: the position for the filtered
iterator and the end of the range.</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="#filter-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#filter-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#filter-iterator-synopsis" id="id2" name="id2"><tt class="literal"><span class="pre">filter_iterator</span></tt> synopsis</a></li>
<li><a class="reference" href="#filter-iterator-requirements" id="id3" name="id3"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#filter-iterator-models" id="id4" name="id4"><tt class="literal"><span class="pre">filter_iterator</span></tt> models</a></li>
<li><a class="reference" href="#filter-iterator-operations" id="id5" name="id5"><tt class="literal"><span class="pre">filter_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="filter-iterator-synopsis">
<h1><a class="toc-backref" href="#id2" name="filter-iterator-synopsis"><tt class="literal"><span class="pre">filter_iterator</span></tt> synopsis</a></h1>
<!-- Copyright David Abrahams, Jeremy Siek, and Thomas Witt -->
<!-- 2004. Use, modification and distribution is subject to the Boost -->
<!-- Software License, Version 1.0. (See accompanying file -->
<!-- LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<pre class="literal-block">
template &lt;class Predicate, class Iterator&gt;
class filter_iterator
: public iterator_adaptor&lt;
filter_iterator&lt;Predicate, Iterator&gt;, Iterator
, use_default
, /* see details */
&gt;
{
public:
typedef iterator_traits&lt;Iterator&gt;::value_type value_type;
typedef iterator_traits&lt;Iterator&gt;::reference reference;
typedef iterator_traits&lt;Iterator&gt;::pointer pointer;
typedef iterator_traits&lt;Iterator&gt;::difference_type difference_type;
typedef /* see below */ iterator_category;
filter_iterator();
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
filter_iterator(Iterator x, Iterator end = Iterator());
@ -268,43 +86,107 @@ class filter_iterator
);
Predicate predicate() const;
Iterator end() const;
private: // as-if specification
void increment()
{
++(this-&gt;base_reference());
satisfy_predicate();
}
void satisfy_predicate()
{
while (this-&gt;base() != this-&gt;m_end &amp;&amp; !this-&gt;m_predicate(*this-&gt;base()))
++(this-&gt;base_reference());
}
Predicate m_predicate;
Iterator m_end;
Iterator const&amp; base() const;
reference operator*() const;
filter_iterator&amp; operator++();
private:
Predicate m_pred; // exposition only
Iterator m_iter; // exposition only
Iterator m_end; // exposition only
};
</pre>
<p>If <tt class="literal"><span class="pre">Iterator</span></tt> models Readable Lvalue Iterator and Forward Traversal
Iterator then <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
<tt class="literal"><span class="pre">std::forward_iterator_tag</span></tt>. Otherwise <tt class="literal"><span class="pre">iterator_category</span></tt> is
convertible to <tt class="literal"><span class="pre">std::input_iterator_tag</span></tt>.</p>
</div>
<div class="section" id="filter-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="filter-iterator-requirements"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></h1>
<p>The base <tt class="literal"><span class="pre">Iterator</span></tt> parameter must be a model of Readable
Iterator and Single Pass Iterator. The resulting
<tt class="literal"><span class="pre">filter_iterator</span></tt> will be a model of Forward Traversal Iterator
if <tt class="literal"><span class="pre">Iterator</span></tt> is, otherwise the <tt class="literal"><span class="pre">filter_iterator</span></tt> will be a
model of Single Pass Iterator. The access category of the
<tt class="literal"><span class="pre">filter_iterator</span></tt> will be the same as the access category of
<tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<!-- Thomas is going to try implementing filter_iterator so that
it will be bidirectional if the underlying iterator is. -JGS -->
<p>The <tt class="literal"><span class="pre">Predicate</span></tt> must be Assignable, Copy Constructible, and the
expression <tt class="literal"><span class="pre">p(x)</span></tt> must be valid where <tt class="literal"><span class="pre">p</span></tt> is an object of type
<h1><a class="toc-backref" href="#id3" name="filter-iterator-requirements"><tt class="literal"><span class="pre">filter_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">Iterator</span></tt> argument shall meet the requirements of Readable
Iterator and Single Pass Iterator or it shall meet the requirements of
Input Iterator.</p>
<p>The <tt class="literal"><span class="pre">Predicate</span></tt> argument must be Assignable, Copy Constructible, and
the expression <tt class="literal"><span class="pre">p(x)</span></tt> must be valid where <tt class="literal"><span class="pre">p</span></tt> is an object of type
<tt class="literal"><span class="pre">Predicate</span></tt>, <tt class="literal"><span class="pre">x</span></tt> is an object of type
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::value_type</span></tt>, and where the type of
<tt class="literal"><span class="pre">p(x)</span></tt> must be convertible to <tt class="literal"><span class="pre">bool</span></tt>.</p>
</div>
<div class="section" id="filter-iterator-models">
<h1><a class="toc-backref" href="#id4" name="filter-iterator-models"><tt class="literal"><span class="pre">filter_iterator</span></tt> models</a></h1>
<p>The concepts that <tt class="literal"><span class="pre">filter_iterator</span></tt> models are dependent on which
concepts the <tt class="literal"><span class="pre">Iterator</span></tt> argument models, as specified in the
following tables.</p>
<table border class="table">
<colgroup>
<col width="33%" />
<col width="67%" />
</colgroup>
<thead valign="bottom">
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
<th>then <tt class="literal"><span class="pre">filter_iterator</span></tt> models</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Single Pass Iterator</td>
<td>Single Pass Iterator</td>
</tr>
<tr><td>Forward Traversal Iterator</td>
<td>Forward Traversal Iterator</td>
</tr>
</tbody>
</table>
<table border class="table">
<colgroup>
<col width="41%" />
<col width="59%" />
</colgroup>
<thead valign="bottom">
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
<th>then <tt class="literal"><span class="pre">filter_iterator</span></tt> models</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Readable Iterator</td>
<td>Readable Iterator</td>
</tr>
<tr><td>Writable Iterator</td>
<td>Writable Iterator</td>
</tr>
<tr><td>Lvalue Iterator</td>
<td>Lvalue Iterator</td>
</tr>
</tbody>
</table>
<table border class="table">
<colgroup>
<col width="63%" />
<col width="38%" />
</colgroup>
<thead valign="bottom">
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
<th>then <tt class="literal"><span class="pre">filter_iterator</span></tt> models</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Readable Iterator, Single Pass Iterator</td>
<td>Input Iterator</td>
</tr>
<tr><td>Readable Lvalue Iterator, Forward Traversal Iterator</td>
<td>Forward Iterator</td>
</tr>
<tr><td>Writable Lvalue Iterator, Forward Traversal Iterator</td>
<td>Mutable Forward Iterator</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">filter_iterator&lt;P1,</span> <span class="pre">X&gt;</span></tt> is interoperable with <tt class="literal"><span class="pre">filter_iterator&lt;P2,</span> <span class="pre">Y&gt;</span></tt>
if and only if <tt class="literal"><span class="pre">X</span></tt> is interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
</div>
<div class="section" id="filter-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="filter-iterator-operations"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></h1>
<h1><a class="toc-backref" href="#id5" name="filter-iterator-operations"><tt class="literal"><span class="pre">filter_iterator</span></tt> operations</a></h1>
<p>In addition to those operations required by the concepts that
<tt class="literal"><span class="pre">filter_iterator</span></tt> models, <tt class="literal"><span class="pre">filter_iterator</span></tt> provides the following
operations.</p>
<p><tt class="literal"><span class="pre">filter_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -312,9 +194,8 @@ expression <tt class="literal"><span class="pre">p(x)</span></tt> must be valid
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> and <tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">a <tt class="literal"><span class="pre">filter_iterator</span></tt> whose
predicate is a default constructed <tt class="literal"><span class="pre">Predicate</span></tt> and
whose <tt class="literal"><span class="pre">end</span></tt> is a default constructed <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a <tt class="literal"><span class="pre">filter_iterator</span></tt> whose``m_pred``, <tt class="literal"><span class="pre">m_iter</span></tt>, and <tt class="literal"><span class="pre">m_end</span></tt>
members are a default constructed.</td>
</tr>
</tbody>
</table>
@ -323,8 +204,10 @@ whose <tt class="literal"><span class="pre">end</span></tt> is a default constru
<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 <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters according
to predicate <tt class="literal"><span class="pre">f</span></tt> and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a <tt class="literal"><span class="pre">filter_iterator</span></tt> where <tt class="literal"><span class="pre">m_iter</span></tt> is either
the first position in the range <tt class="literal"><span class="pre">[x,end)</span></tt> such that <tt class="literal"><span class="pre">f(*m_iter)</span> <span class="pre">==</span> <span class="pre">true</span></tt>
or else``m_iter == end``. The member <tt class="literal"><span class="pre">m_pred</span></tt> is constructed from
<tt class="literal"><span class="pre">f</span></tt> and <tt class="literal"><span class="pre">m_end</span></tt> from <tt class="literal"><span class="pre">end</span></tt>.</td>
</tr>
</tbody>
</table>
@ -333,11 +216,12 @@ to predicate <tt class="literal"><span class="pre">f</span></tt> and that will n
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> must be Default Constructible.</td>
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Predicate</span></tt> must be Default Constructible and
<tt class="literal"><span class="pre">Predicate</span></tt> is a class type (not a function pointer).</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A <tt class="literal"><span class="pre">filter_iterator</span></tt> at position <tt class="literal"><span class="pre">x</span></tt> that filters
according to a default constructed <tt class="literal"><span class="pre">Predicate</span></tt>
and that will not increment past <tt class="literal"><span class="pre">end</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a <tt class="literal"><span class="pre">filter_iterator</span></tt> where <tt class="literal"><span class="pre">m_iter</span></tt> is either
the first position in the range <tt class="literal"><span class="pre">[x,end)</span></tt> such that <tt class="literal"><span class="pre">m_pred(*m_iter)</span> <span class="pre">==</span> <span class="pre">true</span></tt>
or else``m_iter == end``. The member <tt class="literal"><span class="pre">m_pred</span></tt> is default constructed.</td>
</tr>
</tbody>
</table>
@ -354,7 +238,7 @@ filter_iterator(
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">A copy of iterator <tt class="literal"><span class="pre">t</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs a filter iterator whose members are copied from <tt class="literal"><span class="pre">t</span></tt>.</td>
</tr>
</tbody>
</table>
@ -363,7 +247,7 @@ filter_iterator(
<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 copy of the predicate object used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_pred</span></tt></td>
</tr>
</tbody>
</table>
@ -372,16 +256,134 @@ filter_iterator(
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">The object <tt class="literal"><span class="pre">end</span></tt> used to construct <tt class="literal"><span class="pre">*this</span></tt>.</td>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_end</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">const&amp;</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_iterator</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_iter</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">filter_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">Increments <tt class="literal"><span class="pre">m_iter</span></tt> and then continues to
increment <tt class="literal"><span class="pre">m_iter</span></tt> until either <tt class="literal"><span class="pre">m_iter</span> <span class="pre">==</span> <span class="pre">m_end</span></tt>
or <tt class="literal"><span class="pre">m_pred(*m_iter)</span> <span class="pre">==</span> <span class="pre">true</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>
<pre class="literal-block">
template &lt;class Predicate, class Iterator&gt;
filter_iterator&lt;Predicate,Iterator&gt;
make_filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
</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">filter_iterator&lt;Predicate,Iterator&gt;(f, x, end)</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class Predicate, class Iterator&gt;
filter_iterator&lt;Predicate,Iterator&gt;
make_filter_iterator(Iterator x, Iterator end = Iterator());
</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">filter_iterator&lt;Predicate,Iterator&gt;(x, end)</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 uses <tt class="literal"><span class="pre">filter_iterator</span></tt> and then
<tt class="literal"><span class="pre">make_filter_iterator</span></tt> to output only the positive integers from an
array of integers. Then <tt class="literal"><span class="pre">make_filter_iterator</span></tt> is is used to output
the integers greater than <tt class="literal"><span class="pre">-2</span></tt>.</p>
<pre class="literal-block">
struct is_positive_number {
bool operator()(int x) { return 0 &lt; x; }
};
int main()
{
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
const int N = sizeof(numbers_)/sizeof(int);
typedef int* base_iterator;
base_iterator numbers(numbers_);
// Example using filter_iterator
typedef boost::filter_iterator&lt;is_positive_number, base_iterator&gt;
FilterIter;
is_positive_number predicate;
FilterIter filter_iter_first(predicate, numbers, numbers + N);
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator&lt;int&gt;(std::cout, &quot; &quot;));
std::cout &lt;&lt; std::endl;
// Example using make_filter_iterator()
std::copy(boost::make_filter_iterator&lt;is_positive_number&gt;(numbers, numbers + N),
boost::make_filter_iterator&lt;is_positive_number&gt;(numbers + N, numbers + N),
std::ostream_iterator&lt;int&gt;(std::cout, &quot; &quot;));
std::cout &lt;&lt; std::endl;
// Another example using make_filter_iterator()
std::copy(
boost::make_filter_iterator(
std::bind2nd(std::greater&lt;int&gt;(), -2)
, numbers, numbers + N)
, boost::make_filter_iterator(
std::bind2nd(std::greater&lt;int&gt;(), -2)
, numbers + N, numbers + N)
, std::ostream_iterator&lt;int&gt;(std::cout, &quot; &quot;)
);
std::cout &lt;&lt; std::endl;
return boost::exit_success;
}
</pre>
<p>The output is:</p>
<pre class="literal-block">
4 5 8
4 5 8
0 -1 4 5 8
</pre>
<p>The source code for this example can be found <a class="reference" href="../example/filter_iterator_example.cpp">here</a>.</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="filter_iterator.rst">View document source</a>.
Generated on: 2003-11-24 05:00 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>

View File

@ -16,8 +16,14 @@
:abstract:
.. include:: filter_iterator_abstract.rst
.. include:: filter_iterator_abstract.rst
.. contents:: Table of Contents
``filter_iterator`` synopsis
............................
.. include:: filter_iterator_ref.rst
.. include:: make_filter_iterator.rst
.. include:: filter_iterator_eg.rst

View File

@ -1,10 +1,11 @@
The filter iterator adaptor creates a view of an iterator range in
which some elements of the range are skipped over. A predicate
function object controls which elements are skipped. When the
predicate is applied to an element, if it returns ``true`` then the
element is retained and if it returns ``false`` then the element is
skipped over. When skipping over elements, it is necessary for the
filter adaptor to know when to stop so as to avoid going past the end
of the underlying range. Therefore the constructor of the filter
iterator takes two iterator parameters: the position for the filtered
iterator and the end of the range.
which some elements of the range are skipped. A predicate function
object controls which elements are skipped. When the predicate is
applied to an element, if it returns ``true`` then the element is
retained and if it returns ``false`` then the element is skipped
over. When skipping over elements, it is necessary for the filter
adaptor to know when to stop so as to avoid going past the end of the
underlying range. A filter iterator is therefore constructed with pair
of iterators indicating the range of elements in the unfiltered
sequence to be traversed.

View File

@ -1,14 +1,20 @@
.. Copyright David Abrahams, Jeremy Siek, and Thomas Witt
.. 2004. Use, modification and distribution is subject to the Boost
.. Software License, Version 1.0. (See accompanying file
.. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
::
template <class Predicate, class Iterator>
class filter_iterator
: public iterator_adaptor<
filter_iterator<Predicate, Iterator>, Iterator
, use_default
, /* see details */
>
{
public:
typedef iterator_traits<Iterator>::value_type value_type;
typedef iterator_traits<Iterator>::reference reference;
typedef iterator_traits<Iterator>::pointer pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
filter_iterator();
filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());
filter_iterator(Iterator x, Iterator end = Iterator());
@ -19,71 +25,107 @@
);
Predicate predicate() const;
Iterator end() const;
private: // as-if specification
void increment()
{
++(this->base_reference());
satisfy_predicate();
}
void satisfy_predicate()
{
while (this->base() != this->m_end && !this->m_predicate(*this->base()))
++(this->base_reference());
}
Predicate m_predicate;
Iterator m_end;
Iterator const& base() const;
reference operator*() const;
filter_iterator& operator++();
private:
Predicate m_pred; // exposition only
Iterator m_iter; // exposition only
Iterator m_end; // exposition only
};
If ``Iterator`` models Readable Lvalue Iterator and Forward Traversal
Iterator then ``iterator_category`` is convertible to
``std::forward_iterator_tag``. Otherwise ``iterator_category`` is
convertible to ``std::input_iterator_tag``.
``filter_iterator`` requirements
--------------------------------
................................
The base ``Iterator`` parameter must be a model of Readable
Iterator and Single Pass Iterator. The resulting
``filter_iterator`` will be a model of Forward Traversal Iterator
if ``Iterator`` is, otherwise the ``filter_iterator`` will be a
model of Single Pass Iterator. The access category of the
``filter_iterator`` will be the same as the access category of
``Iterator``.
The ``Iterator`` argument shall meet the requirements of Readable
Iterator and Single Pass Iterator or it shall meet the requirements of
Input Iterator.
.. Thomas is going to try implementing filter_iterator so that
it will be bidirectional if the underlying iterator is. -JGS
The ``Predicate`` must be Assignable, Copy Constructible, and the
expression ``p(x)`` must be valid where ``p`` is an object of type
The ``Predicate`` argument must be Assignable, Copy Constructible, and
the expression ``p(x)`` must be valid where ``p`` is an object of type
``Predicate``, ``x`` is an object of type
``iterator_traits<Iterator>::value_type``, and where the type of
``p(x)`` must be convertible to ``bool``.
``filter_iterator`` models
..........................
The concepts that ``filter_iterator`` models are dependent on which
concepts the ``Iterator`` argument models, as specified in the
following tables.
+-----------------------------+----------------------------------------------------------+
| If ``Iterator`` models | then ``filter_iterator`` models |
+=============================+==========================================================+
| Single Pass Iterator | Single Pass Iterator |
+-----------------------------+----------------------------------------------------------+
| Forward Traversal Iterator | Forward Traversal Iterator |
+-----------------------------+----------------------------------------------------------+
+--------------------------------+----------------------------------------------+
| If ``Iterator`` models | then ``filter_iterator`` models |
+================================+==============================================+
| Readable Iterator | Readable Iterator |
+--------------------------------+----------------------------------------------+
| Writable Iterator | Writable Iterator |
+--------------------------------+----------------------------------------------+
| Lvalue Iterator | Lvalue Iterator |
+--------------------------------+----------------------------------------------+
+-------------------------------------------------------+---------------------------------+
| If ``Iterator`` models | then ``filter_iterator`` models |
+=======================================================+=================================+
| Readable Iterator, Single Pass Iterator | Input Iterator |
+-------------------------------------------------------+---------------------------------+
| Readable Lvalue Iterator, Forward Traversal Iterator | Forward Iterator |
+-------------------------------------------------------+---------------------------------+
| Writable Lvalue Iterator, Forward Traversal Iterator | Mutable Forward Iterator |
+-------------------------------------------------------+---------------------------------+
``filter_iterator<P1, X>`` is interoperable with ``filter_iterator<P2, Y>``
if and only if ``X`` is interoperable with ``Y``.
``filter_iterator`` operations
------------------------------
..............................
In addition to those operations required by the concepts that
``filter_iterator`` models, ``filter_iterator`` provides the following
operations.
``filter_iterator();``
:Requires: ``Predicate`` and ``Iterator`` must be Default Constructible.
:Returns: a ``filter_iterator`` whose
predicate is a default constructed ``Predicate`` and
whose ``end`` is a default constructed ``Iterator``.
:Effects: Constructs a ``filter_iterator`` whose``m_pred``, ``m_iter``, and ``m_end``
members are a default constructed.
``filter_iterator(Predicate f, Iterator x, Iterator end = Iterator());``
:Returns: A ``filter_iterator`` at position ``x`` that filters according
to predicate ``f`` and that will not increment past ``end``.
:Effects: Constructs a ``filter_iterator`` where ``m_iter`` is either
the first position in the range ``[x,end)`` such that ``f(*m_iter) == true``
or else``m_iter == end``. The member ``m_pred`` is constructed from
``f`` and ``m_end`` from ``end``.
``filter_iterator(Iterator x, Iterator end = Iterator());``
:Requires: ``Predicate`` must be Default Constructible.
:Returns: A ``filter_iterator`` at position ``x`` that filters
according to a default constructed ``Predicate``
and that will not increment past ``end``.
:Requires: ``Predicate`` must be Default Constructible and
``Predicate`` is a class type (not a function pointer).
:Effects: Constructs a ``filter_iterator`` where ``m_iter`` is either
the first position in the range ``[x,end)`` such that ``m_pred(*m_iter) == true``
or else``m_iter == end``. The member ``m_pred`` is default constructed.
::
@ -95,15 +137,33 @@ expression ``p(x)`` must be valid where ``p`` is an object of type
);``
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
:Returns: A copy of iterator ``t``.
:Effects: Constructs a filter iterator whose members are copied from ``t``.
``Predicate predicate() const;``
:Returns: A copy of the predicate object used to construct ``*this``.
:Returns: ``m_pred``
``Iterator end() const;``
:Returns: The object ``end`` used to construct ``*this``.
:Returns: ``m_end``
``Iterator const& base() const;``
:Returns: ``m_iterator``
``reference operator*() const;``
:Returns: ``*m_iter``
``filter_iterator& operator++();``
:Effects: Increments ``m_iter`` and then continues to
increment ``m_iter`` until either ``m_iter == m_end``
or ``m_pred(*m_iter) == true``.
:Returns: ``*this``

View File

@ -7,200 +7,9 @@
<title>Function Output 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="2003-09-14" />
<meta name="date" content="2004-01-13" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="function-output-iterator">
@ -218,7 +27,7 @@ ul.auto-toc {
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>
<td>2004-01-13</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>
@ -227,76 +36,74 @@ Railway Operation and Construction</a></td></tr>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
</tr>
</tbody>
</table>
<p>The function output iterator adaptor makes it easier to create custom
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">The function output iterator adaptor makes it easier to create custom
output iterators. The adaptor takes a unary function and creates a
model of Output Iterator. Each item assigned to the output iterator is
passed as an argument to the unary function. The motivation for this
iterator is that creating a conforming output iterator is non-trivial,
particularly because the proper implementation usually requires a
proxy object.</p>
proxy object.</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="#function-output-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">function_output_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#function-output-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#function-output-iterator-output-proxy-operations" id="id3" name="id3"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</a></li>
<li><a class="reference" href="#function-output-iterator-models" id="id2" name="id2"><tt class="literal"><span class="pre">function_output_iterator</span></tt> models</a></li>
<li><a class="reference" href="#function-output-iterator-operations" id="id3" name="id3"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#example" id="id4" name="id4">Example</a></li>
</ul>
</div>
<pre class="literal-block">
template &lt;class UnaryFunction&gt;
class function_output_iterator {
public:
typedef iterator_tag&lt;
writable_iterator
, incrementable_traversal_tag
&gt; iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator(const UnaryFunction&amp; f = UnaryFunction());
explicit function_output_iterator();
struct output_proxy {
output_proxy(UnaryFunction&amp; f);
template &lt;class T&gt; output_proxy&amp; operator=(const T&amp; value);
};
output_proxy operator*();
explicit function_output_iterator(const UnaryFunction&amp; f);
/* see below */ operator*();
function_output_iterator&amp; operator++();
function_output_iterator&amp; operator++(int);
private:
UnaryFunction m_f; // exposition only
};
</pre>
<div class="section" id="function-output-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="function-output-iterator-requirements"><tt class="literal"><span class="pre">function_output_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and the
expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid, where <tt class="literal"><span class="pre">f</span></tt> is an object of type
<tt class="literal"><span class="pre">UnaryFunction</span></tt> and <tt class="literal"><span class="pre">x</span></tt> is an object of a type accepted by <tt class="literal"><span class="pre">f</span></tt>.
The resulting <tt class="literal"><span class="pre">function_output_iterator</span></tt> is a model of the Writable
and Incrementable Iterator concepts.</p>
<p><tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable and Copy Constructible.</p>
</div>
<div class="section" id="function-output-iterator-models">
<h1><a class="toc-backref" href="#id2" name="function-output-iterator-models"><tt class="literal"><span class="pre">function_output_iterator</span></tt> models</a></h1>
<p><tt class="literal"><span class="pre">function_output_iterator</span></tt> is a model of the Writable and
Incrementable Iterator concepts.</p>
</div>
<div class="section" id="function-output-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="function-output-iterator-operations"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></h1>
<h1><a class="toc-backref" href="#id3" name="function-output-iterator-operations"><tt class="literal"><span class="pre">function_output_iterator</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">function_output_iterator(const</span> <span class="pre">UnaryFunction&amp;</span> <span class="pre">f</span> <span class="pre">=</span> <span class="pre">UnaryFunction());</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">function_output_iterator</span></tt> with
<tt class="literal"><span class="pre">f</span></tt> stored as a data member.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">function_output_iterator</span></tt>
with <tt class="literal"><span class="pre">m_f</span></tt> constructed from <tt class="literal"><span class="pre">f</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">output_proxy</span> <span class="pre">operator*();</span></tt></p>
<p><tt class="literal"><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">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">output_proxy</span></tt> constructed with
a copy of the unary function <tt class="literal"><span class="pre">f</span></tt>.</td>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An object <tt class="literal"><span class="pre">r</span></tt> of unspecified type such that <tt class="literal"><span class="pre">r</span> <span class="pre">=</span> <span class="pre">t</span></tt>
is equivalent to <tt class="literal"><span class="pre">m_f(t)</span></tt> for all <tt class="literal"><span class="pre">t</span></tt>.</td>
</tr>
</tbody>
</table>
@ -319,37 +126,45 @@ a copy of the unary function <tt class="literal"><span class="pre">f</span></tt>
</tbody>
</table>
</div>
<div class="section" id="function-output-iterator-output-proxy-operations">
<h1><a class="toc-backref" href="#id3" name="function-output-iterator-output-proxy-operations"><tt class="literal"><span class="pre">function_output_iterator::output_proxy</span></tt> operations</a></h1>
<p><tt class="literal"><span class="pre">output_proxy(UnaryFunction&amp;</span> <span class="pre">f);</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">output_proxy</span></tt> with <tt class="literal"><span class="pre">f</span></tt> stored as
a data member.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">template</span> <span class="pre">&lt;class</span> <span class="pre">T&gt;</span> <span class="pre">output_proxy&amp;</span> <span class="pre">operator=(const</span> <span class="pre">T&amp;</span> <span class="pre">value);</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"><pre class="first last literal-block">
m_f(value);
return *this;
<div class="section" id="example">
<h1><a class="toc-backref" href="#id4" name="example">Example</a></h1>
<pre class="literal-block">
struct string_appender
{
string_appender(std::string&amp; s)
: m_str(&amp;s)
{}
void operator()(const std::string&amp; x) const
{
*m_str += x;
}
std::string* m_str;
};
int main(int, char*[])
{
std::vector&lt;std::string&gt; x;
x.push_back(&quot;hello&quot;);
x.push_back(&quot; &quot;);
x.push_back(&quot;world&quot;);
x.push_back(&quot;!&quot;);
std::string s = &quot;&quot;;
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
std::cout &lt;&lt; s &lt;&lt; std::endl;
return 0;
}
</pre>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="function_output_iterator.rst">View document source</a>.
Generated on: 2003-11-24 05:00 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>

View File

@ -16,8 +16,9 @@
:abstract:
.. include:: function_output_iterator_abstract.rst
.. include:: function_output_iterator_abstract.rst
.. contents:: Table of Contents
.. include:: function_output_iterator_ref.rst
.. include:: function_output_iterator_eg.rst

View File

@ -3,50 +3,53 @@
template <class UnaryFunction>
class function_output_iterator {
public:
typedef iterator_tag<
writable_iterator
, incrementable_traversal_tag
> iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
typedef std::output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());
explicit function_output_iterator();
struct output_proxy {
output_proxy(UnaryFunction& f);
template <class T> output_proxy& operator=(const T& value);
};
output_proxy operator*();
explicit function_output_iterator(const UnaryFunction& f);
/* see below */ operator*();
function_output_iterator& operator++();
function_output_iterator& operator++(int);
private:
UnaryFunction m_f; // exposition only
};
``function_output_iterator`` requirements
-----------------------------------------
The ``UnaryFunction`` must be Assignable, Copy Constructible, and the
expression ``f(x)`` must be valid, where ``f`` is an object of type
``UnaryFunction`` and ``x`` is an object of a type accepted by ``f``.
The resulting ``function_output_iterator`` is a model of the Writable
and Incrementable Iterator concepts.
``function_output_iterator`` requirements
.........................................
``UnaryFunction`` must be Assignable and Copy Constructible.
``function_output_iterator`` models
...................................
``function_output_iterator`` is a model of the Writable and
Incrementable Iterator concepts.
``function_output_iterator`` operations
---------------------------------------
.......................................
``explicit function_output_iterator(const UnaryFunction& f = UnaryFunction());``
:Returns: An instance of ``function_output_iterator`` with
``f`` stored as a data member.
:Effects: Constructs an instance of ``function_output_iterator``
with ``m_f`` constructed from ``f``.
``output_proxy operator*();``
``operator*();``
:Returns: An instance of ``output_proxy`` constructed with
a copy of the unary function ``f``.
:Returns: An object ``r`` of unspecified type such that ``r = t``
is equivalent to ``m_f(t)`` for all ``t``.
``function_output_iterator& operator++();``
@ -57,21 +60,3 @@ and Incrementable Iterator concepts.
``function_output_iterator& operator++(int);``
:Returns: ``*this``
``function_output_iterator::output_proxy`` operations
-----------------------------------------------------
``output_proxy(UnaryFunction& f);``
:Returns: An instance of ``output_proxy`` with ``f`` stored as
a data member.
``template <class T> output_proxy& operator=(const T& value);``
:Effects:
::
m_f(value);
return *this;

View File

@ -23,7 +23,7 @@ else:
for s in sources
]
print 'make %s' % ' '.join(all)
syscmd('make %s' % ' '.join(all))
print 'make -k %s' % ' '.join(all)
syscmd('make -k %s' % ' '.join(all))

View File

@ -5,198 +5,7 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
<title>The Boost.Iterator Library Boost</title>
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="the-boost-iterator-library-logo">
@ -208,11 +17,10 @@ ul.auto-toc {
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">David Abrahams, Jeremy Siek, Thomas Witt</td>
</tr>
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="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="reference" href="mailto:witt&#64;ive.uni-hannover.de">witt&#64;ive.uni-hannover.de</a></td>
<tr class="field"><th class="field-name">Contact:</th><td class="field-body"><a class="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="reference" href="mailto:witt&#64;styleadvisor.com">witt&#64;styleadvisor.com</a></td>
</tr>
<tr class="field"><th class="field-name">organizations:</th><td class="field-body"><a class="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="reference" href="http://www.ive.uni-hannover.de">Institute for Transport
Railway Operation and Construction</a></td>
Lab</a>, <a class="reference" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td>
</tr>
<tr class="field"><th class="field-name">date:</th><td class="field-body">$Date$</td>
</tr>
@ -245,21 +53,21 @@ older Boost Iterator Adaptor Library.</td>
<div class="contents topic" id="table-of-contents">
<p class="topic-title"><a name="table-of-contents"><strong>Table of Contents</strong></a></p>
<ul class="simple">
<li><a class="reference" href="#new-style-iterators" id="id6" name="id6">New-Style Iterators</a></li>
<li><a class="reference" href="#iterator-facade-and-adaptor" id="id7" name="id7">Iterator Facade and Adaptor</a></li>
<li><a class="reference" href="#specialized-adaptors" id="id8" name="id8">Specialized Adaptors</a></li>
<li><a class="reference" href="#iterator-utilities" id="id9" name="id9">Iterator Utilities</a><ul>
<li><a class="reference" href="#traits" id="id10" name="id10">Traits</a></li>
<li><a class="reference" href="#testing-and-concept-checking" id="id11" name="id11">Testing and Concept Checking</a></li>
<li><a class="reference" href="#new-style-iterators" id="id22" name="id22">New-Style Iterators</a></li>
<li><a class="reference" href="#iterator-facade-and-adaptor" id="id23" name="id23">Iterator Facade and Adaptor</a></li>
<li><a class="reference" href="#specialized-adaptors" id="id24" name="id24">Specialized Adaptors</a></li>
<li><a class="reference" href="#iterator-utilities" id="id25" name="id25">Iterator Utilities</a><ul>
<li><a class="reference" href="#traits" id="id26" name="id26">Traits</a></li>
<li><a class="reference" href="#testing-and-concept-checking" id="id27" name="id27">Testing and Concept Checking</a></li>
</ul>
</li>
<li><a class="reference" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id12" name="id12">Upgrading from the old Boost Iterator Adaptor Library</a></li>
<li><a class="reference" href="#history" id="id13" name="id13">History</a></li>
<li><a class="reference" href="#upgrading-from-the-old-boost-iterator-adaptor-library" id="id28" name="id28">Upgrading from the old Boost Iterator Adaptor Library</a></li>
<li><a class="reference" href="#history" id="id29" name="id29">History</a></li>
</ul>
</div>
<hr />
<div class="section" id="new-style-iterators">
<h1><a class="toc-backref" href="#id6" name="new-style-iterators">New-Style Iterators</a></h1>
<h1><a class="toc-backref" href="#id22" name="new-style-iterators">New-Style Iterators</a></h1>
<p>The iterator categories defined in C++98 are extremely limiting
because they bind together two orthogonal concepts: traversal and
element access. For example, because a random access iterator is
@ -275,71 +83,84 @@ iterators already in use which can't be adequately represented by
the existing concepts. For details about the new iterator
concepts, see our</p>
<blockquote>
<a class="reference" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a></blockquote>
<a class="reference" href="new-iter-concepts.html">Standard Proposal For New-Style Iterators</a> (<a class="reference" href="new-iter-concepts.pdf">PDF</a>)</blockquote>
</div>
<div class="section" id="iterator-facade-and-adaptor">
<h1><a class="toc-backref" href="#id7" name="iterator-facade-and-adaptor">Iterator Facade and Adaptor</a></h1>
<h1><a class="toc-backref" href="#id23" name="iterator-facade-and-adaptor">Iterator Facade and Adaptor</a></h1>
<p>Writing standard-conforming iterators is tricky, but the need comes
up often. In order to ease the implementation of new iterators,
the Boost.Iterator library provides the <a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> class template,
the Boost.Iterator library provides the <tt class="literal"><span class="pre">iterator_facade</span></tt> class template,
which implements many useful defaults and compile-time checks
designed to help the author iterator ensure that his iterator is
correct. It is common to define a new iterator which behaves like
another iterator, but which modifies some aspect of its behavior.
For that purpose, the library supplies the <a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> class
template, which is specially designed to take advantage of as much
of the underlying iterator's behavior as possible.</p>
<p>Both <a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> and <a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> as well as many of the <a class="reference" href="#specialized-adaptors">specialized
designed to help the iterator author ensure that his iterator is
correct.</p>
<p>It is also common to define a new iterator that is similar to some
underlying iterator or iterator-like type, but that modifies some
aspect of the underlying type's behavior. For that purpose, the
library supplies the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> class template, which is specially
designed to take advantage of as much of the underlying type's
behavior as possible.</p>
<p>The documentation for these two classes can be found at the following
web pages:</p>
<ul class="simple">
<li><a class="reference" href="iterator_facade.html"><tt class="literal"><span class="pre">iterator_facade</span></tt></a> (<a class="reference" href="iterator_facade.pdf">PDF</a>)</li>
<li><a class="reference" href="iterator_adaptor.html"><tt class="literal"><span class="pre">iterator_adaptor</span></tt></a> (<a class="reference" href="iterator_adaptor.pdf">PDF</a>)</li>
</ul>
<p>Both <tt class="literal"><span class="pre">iterator_facade</span></tt> and <tt class="literal"><span class="pre">iterator_adaptor</span></tt> as well as many of the <a class="reference" href="#specialized-adaptors">specialized
adaptors</a> mentioned below have been proposed for standardization,
and accepted into the first C++ technical report; see our</p>
<blockquote>
<a class="reference" href="facade-and-adaptor.html">Standard Proposal For Iterator Facade and Adaptor</a></blockquote>
<a class="reference" href="facade-and-adaptor.html">Standard Proposal For Iterator Facade and Adaptor</a> (<a class="reference" href="facade-and-adaptor.pdf">PDF</a>)</blockquote>
<p>for more details.</p>
</div>
<div class="section" id="specialized-adaptors">
<h1><a class="toc-backref" href="#id8" name="specialized-adaptors">Specialized Adaptors</a></h1>
<h1><a class="toc-backref" href="#id24" name="specialized-adaptors">Specialized Adaptors</a></h1>
<p>The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost <a class="reference" href="#iterator-facade-and-adaptor">iterator facade and adaptor</a>.</p>
<ul class="simple">
<li><a class="reference" href="counting_iterator.html"><tt class="literal"><span class="pre">counting_iterator</span></tt></a>: an iterator over a sequence of consecutive values.
<li><a class="reference" href="counting_iterator.html"><tt class="literal"><span class="pre">counting_iterator</span></tt></a> (<a class="reference" href="counting_iterator.pdf">PDF</a>): an iterator over a sequence of consecutive values.
Implements a &quot;lazy sequence&quot;</li>
<li><a class="reference" href="filter_iterator.html"><tt class="literal"><span class="pre">filter_iterator</span></tt></a>: an iterator over the subset of elements of some
<li><a class="reference" href="filter_iterator.html"><tt class="literal"><span class="pre">filter_iterator</span></tt></a> (<a class="reference" href="filter_iterator.pdf">PDF</a>): an iterator over the subset of elements of some
sequence which satisfy a given predicate</li>
<li><a class="reference" href="indirect_iterator.html"><tt class="literal"><span class="pre">indirect_iterator</span></tt></a>: an iterator over the objects <em>pointed-to</em> by the
<li><a class="reference" href="indirect_iterator.html"><tt class="literal"><span class="pre">indirect_iterator</span></tt></a> (<a class="reference" href="indirect_iterator.pdf">PDF</a>): an iterator over the objects <em>pointed-to</em> by the
elements of some sequence.</li>
<li><a class="reference" href="permutation_iterator.html"><tt class="literal"><span class="pre">permutation_iterator</span></tt></a>: an iterator over the elements of some random-access
<li><a class="reference" href="permutation_iterator.html"><tt class="literal"><span class="pre">permutation_iterator</span></tt></a> (<a class="reference" href="permutation_iterator.pdf">PDF</a>): an iterator over the elements of some random-access
sequence, rearranged according to some sequence of integer indices.</li>
<li><a class="reference" href="reverse_iterator.html"><tt class="literal"><span class="pre">reverse_iterator</span></tt></a>: an iterator which traverses the elements of some
<li><a class="reference" href="reverse_iterator.html"><tt class="literal"><span class="pre">reverse_iterator</span></tt></a> (<a class="reference" href="reverse_iterator.pdf">PDF</a>): an iterator which traverses the elements of some
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's <tt class="literal"><span class="pre">std::reverse_iterator</span></tt>.</li>
<li><a class="reference" href="transform_iterator.html"><tt class="literal"><span class="pre">transform_iterator</span></tt></a>: an iterator over elements which are the result of
<li><a class="reference" href="transform_iterator.html"><tt class="literal"><span class="pre">transform_iterator</span></tt></a> (<a class="reference" href="transform_iterator.pdf">PDF</a>): an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
<tt class="literal"><span class="pre">projection_iterator_adaptor</span></tt>.</li>
<li><a class="reference" href="zip_iterator.html"><tt class="literal"><span class="pre">zip_iterator</span></tt></a> (<a class="reference" href="zip_iterator.pdf">PDF</a>): an iterator over tuples of the elements at corresponding
positions of heterogeneous underlying iterators.</li>
</ul>
</div>
<div class="section" id="iterator-utilities">
<h1><a class="toc-backref" href="#id9" name="iterator-utilities">Iterator Utilities</a></h1>
<h1><a class="toc-backref" href="#id25" name="iterator-utilities">Iterator Utilities</a></h1>
<div class="section" id="traits">
<h2><a class="toc-backref" href="#id10" name="traits">Traits</a></h2>
<h2><a class="toc-backref" href="#id26" name="traits">Traits</a></h2>
<ul class="simple">
<li><a class="reference" href="iterator_traits.html"><tt class="literal"><span class="pre">iterator_traits.hpp</span></tt></a>: Provides <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunctions which
<li><a class="reference" href="pointee.html"><tt class="literal"><span class="pre">pointee.hpp</span></tt></a> (<a class="reference" href="pointee.pdf">PDF</a>): Provides the capability to deduce the referent types
of pointers, smart pointers and iterators in generic code. Used
in <tt class="literal"><span class="pre">indirect_iterator</span></tt>.</li>
<li><a class="reference" href="iterator_traits.html"><tt class="literal"><span class="pre">iterator_traits.hpp</span></tt></a> (<a class="reference" href="iterator_traits.pdf">PDF</a>): Provides <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunctions which
retrieve an iterator's traits. Also corrects for the deficiencies
of broken implementations of <tt class="literal"><span class="pre">std::iterator_traits</span></tt>.</li>
<li><a class="reference" href="interoperable.html"><tt class="literal"><span class="pre">interoperable.hpp</span></tt></a>: Provides an <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunction for
<li><a class="reference" href="interoperable.html"><tt class="literal"><span class="pre">interoperable.hpp</span></tt></a> (<a class="reference" href="interoperable.pdf">PDF</a>): Provides an <a class="reference" href="../../mpl/doc/index.html">MPL</a>-compatible metafunction for
testing iterator interoperability</li>
</ul>
</div>
<div class="section" id="testing-and-concept-checking">
<h2><a class="toc-backref" href="#id11" name="testing-and-concept-checking">Testing and Concept Checking</a></h2>
<h2><a class="toc-backref" href="#id27" name="testing-and-concept-checking">Testing and Concept Checking</a></h2>
<ul class="simple">
<li><a class="reference" href="iterator_archetypes.html"><tt class="literal"><span class="pre">iterator_archetypes.hpp</span></tt></a>: Add summary here</li>
<li><a class="reference" href="iterator_concepts.html"><tt class="literal"><span class="pre">iterator_concepts.hpp</span></tt></a>: Add summary</li>
<li><a class="reference" href="iterator_concepts.html"><tt class="literal"><span class="pre">iterator_concepts.hpp</span></tt></a> (<a class="reference" href="iterator_concepts.pdf">PDF</a>): Concept checking classes for the new iterator concepts.</li>
<li><a class="reference" href="iterator_archetypes.html"><tt class="literal"><span class="pre">iterator_archetypes.hpp</span></tt></a> (<a class="reference" href="iterator_archetypes.pdf">PDF</a>): Concept archetype classes for the new iterators concepts.</li>
</ul>
</div>
</div>
<div class="section" id="upgrading-from-the-old-boost-iterator-adaptor-library">
<h1><a class="toc-backref" href="#id12" name="upgrading-from-the-old-boost-iterator-adaptor-library">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
<h1><a class="toc-backref" href="#id28" name="upgrading-from-the-old-boost-iterator-adaptor-library">Upgrading from the old Boost Iterator Adaptor Library</a></h1>
<a class="target" id="upgrading" name="upgrading"></a><p>If you have been using the old Boost Iterator Adaptor library to
implement iterators, you probably wrote a <tt class="literal"><span class="pre">Policies</span></tt> class which
captures the core operations of your iterator. In the new library
@ -349,7 +170,7 @@ you probably wrote a <a class="reference" href="../../../more/generic_programmin
<tt class="literal"><span class="pre">iterator_adaptor</span></tt> specialization you needed; in the new library
design you don't need a type generator (though may want to keep it
around as a compatibility aid for older code) because, due to the
use of the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id5" name="id5">[Cop95]</a>,
use of the Curiously Recurring Template Pattern (CRTP) <a class="citation-reference" href="#cop95" id="id21" name="id21">[Cop95]</a>,
you can now define the iterator class yourself and acquire
functionality through inheritance from <tt class="literal"><span class="pre">iterator_facade</span></tt> or
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. As a result, you also get much finer control
@ -364,7 +185,7 @@ type, <tt class="literal"><span class="pre">transform_iterator</span></tt> will
<tt class="literal"><span class="pre">projection_iterator</span></tt> used to.</p>
</div>
<div class="section" id="history">
<h1><a class="toc-backref" href="#id13" name="history">History</a></h1>
<h1><a class="toc-backref" href="#id29" name="history">History</a></h1>
<p>In 2000 Dave Abrahams was writing an iterator for a container of
pointers, which would access the pointed-to elements when
dereferenced. Naturally, being a library writer, he decided to
@ -393,7 +214,7 @@ library you see today.</p>
<colgroup><col class="label" /><col /></colgroup>
<col />
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id5" name="cop95">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
<tr><td class="label"><a class="fn-backref" href="#id21" name="cop95">[Cop95]</a></td><td>[Coplien, 1995] Coplien, J., Curiously Recurring Template
Patterns, C++ Report, February 1995, pp. 24-27.</td></tr>
</tbody>
</table>
@ -409,7 +230,6 @@ LocalWords: TraversalTag typename lvalues DWA Hmm JGS -->
<hr class="footer" />
<div class="footer">
<a class="reference" href="index.rst">View document source</a>.
Generated on: 2003-11-24 04:21 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>

View File

@ -12,16 +12,16 @@ __ ../../../index.htm
:Authors: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@ive.uni-hannover.de
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organizations: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, University of Hanover `Institute for Transport
Railway Operation and Construction`_
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:copyright: Copyright David Abrahams, Jeremy Siek, Thomas Witt 2003. All rights reserved
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Institute for Transport Railway Operation and Construction`: http://www.ive.uni-hannover.de
.. _`Zephyr Associates, Inc.`: http://www.styleadvisor.com
:Abstract: The Boost Iterator Library contains two parts. The first
is a system of concepts_ which extend the C++ standard
@ -71,9 +71,10 @@ concepts, see our
__ http://www.gotw.ca/gotw/050.htm
`Standard Proposal For New-Style Iterators`__
`Standard Proposal For New-Style Iterators`__ (PDF__)
__ new-iter-concepts.html
__ new-iter-concepts.pdf
=============================
Iterator Facade and Adaptor
@ -81,29 +82,44 @@ __ new-iter-concepts.html
Writing standard-conforming iterators is tricky, but the need comes
up often. In order to ease the implementation of new iterators,
the Boost.Iterator library provides the |facade|_ class template,
the Boost.Iterator library provides the |facade| class template,
which implements many useful defaults and compile-time checks
designed to help the author iterator ensure that his iterator is
correct. It is common to define a new iterator which behaves like
another iterator, but which modifies some aspect of its behavior.
For that purpose, the library supplies the |adaptor|_ class
template, which is specially designed to take advantage of as much
of the underlying iterator's behavior as possible.
designed to help the iterator author ensure that his iterator is
correct.
It is also common to define a new iterator that is similar to some
underlying iterator or iterator-like type, but that modifies some
aspect of the underlying type's behavior. For that purpose, the
library supplies the |adaptor| class template, which is specially
designed to take advantage of as much of the underlying type's
behavior as possible.
The documentation for these two classes can be found at the following
web pages:
* |facade|_ (PDF__)
* |adaptor|_ (PDF__)
.. |facade| replace:: ``iterator_facade``
.. _facade: iterator_facade.html
__ iterator_facade.pdf
.. |adaptor| replace:: ``iterator_adaptor``
.. _adaptor: iterator_adaptor.html
__ iterator_adaptor.pdf
Both |facade|_ and |adaptor|_ as well as many of the `specialized
Both |facade| and |adaptor| as well as many of the `specialized
adaptors`_ mentioned below have been proposed for standardization,
and accepted into the first C++ technical report; see our
`Standard Proposal For Iterator Facade and Adaptor`__
`Standard Proposal For Iterator Facade and Adaptor`__ (PDF__)
for more details.
__ facade-and-adaptor.html
__ facade-and-adaptor.pdf
======================
Specialized Adaptors
@ -112,44 +128,57 @@ __ facade-and-adaptor.html
The iterator library supplies a useful suite of standard-conforming
iterator templates based on the Boost `iterator facade and adaptor`_.
* |counting|_: an iterator over a sequence of consecutive values.
* |counting|_ (PDF__): an iterator over a sequence of consecutive values.
Implements a "lazy sequence"
* |filter|_: an iterator over the subset of elements of some
* |filter|_ (PDF__): an iterator over the subset of elements of some
sequence which satisfy a given predicate
* |indirect|_: an iterator over the objects *pointed-to* by the
* |indirect|_ (PDF__): an iterator over the objects *pointed-to* by the
elements of some sequence.
* |permutation|_: an iterator over the elements of some random-access
* |permutation|_ (PDF__): an iterator over the elements of some random-access
sequence, rearranged according to some sequence of integer indices.
* |reverse|_: an iterator which traverses the elements of some
* |reverse|_ (PDF__): an iterator which traverses the elements of some
bidirectional sequence in reverse. Corrects many of the
shortcomings of C++98's ``std::reverse_iterator``.
* |transform|_: an iterator over elements which are the result of
* |transform|_ (PDF__): an iterator over elements which are the result of
applying some functional transformation to the elements of an
underlying sequence. This component also replaces the old
``projection_iterator_adaptor``.
* |zip|_ (PDF__): an iterator over tuples of the elements at corresponding
positions of heterogeneous underlying iterators.
.. |counting| replace:: ``counting_iterator``
.. _counting: counting_iterator.html
__ counting_iterator.pdf
.. |filter| replace:: ``filter_iterator``
.. _filter: filter_iterator.html
__ filter_iterator.pdf
.. |indirect| replace:: ``indirect_iterator``
.. _indirect: indirect_iterator.html
__ indirect_iterator.pdf
.. |permutation| replace:: ``permutation_iterator``
.. _permutation: permutation_iterator.html
__ permutation_iterator.pdf
.. |reverse| replace:: ``reverse_iterator``
.. _reverse: reverse_iterator.html
__ reverse_iterator.pdf
.. |transform| replace:: ``transform_iterator``
.. _transform: transform_iterator.html
__ transform_iterator.pdf
.. |zip| replace:: ``zip_iterator``
.. _zip: zip_iterator.html
__ zip_iterator.pdf
====================
Iterator Utilities
@ -158,34 +187,45 @@ iterator templates based on the Boost `iterator facade and adaptor`_.
Traits
------
* |iterator_traits|_: Provides MPL_\ -compatible metafunctions which
* |pointee|_ (PDF__): Provides the capability to deduce the referent types
of pointers, smart pointers and iterators in generic code. Used
in |indirect|.
* |iterator_traits|_ (PDF__): Provides MPL_\ -compatible metafunctions which
retrieve an iterator's traits. Also corrects for the deficiencies
of broken implementations of ``std::iterator_traits``.
* |interoperable|_: Provides an MPL_\ -compatible metafunction for
* |interoperable|_ (PDF__): Provides an MPL_\ -compatible metafunction for
testing iterator interoperability
.. |pointee| replace:: ``pointee.hpp``
.. _pointee: pointee.html
__ pointee.pdf
.. |iterator_traits| replace:: ``iterator_traits.hpp``
.. _iterator_traits: iterator_traits.html
__ iterator_traits.pdf
.. |interoperable| replace:: ``interoperable.hpp``
.. _interoperable: interoperable.html
__ interoperable.pdf
.. _MPL: ../../mpl/doc/index.html
Testing and Concept Checking
----------------------------
* |iterator_archetypes|_: Add summary here
* |iterator_concepts|_ (PDF__): Concept checking classes for the new iterator concepts.
* |iterator_concepts|_: Add summary
.. |iterator_archetypes| replace:: ``iterator_archetypes.hpp``
.. _iterator_archetypes: iterator_archetypes.html
* |iterator_archetypes|_ (PDF__): Concept archetype classes for the new iterators concepts.
.. |iterator_concepts| replace:: ``iterator_concepts.hpp``
.. _iterator_concepts: iterator_concepts.html
__ iterator_concepts.pdf
.. |iterator_archetypes| replace:: ``iterator_archetypes.hpp``
.. _iterator_archetypes: iterator_archetypes.html
__ iterator_archetypes.pdf
=======================================================
Upgrading from the old Boost Iterator Adaptor Library

View File

@ -7,200 +7,9 @@
<title>Indirect 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="2003-09-14" />
<meta name="date" content="2004-01-15" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="indirect-iterator">
@ -218,7 +27,7 @@ ul.auto-toc {
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>
<td>2004-01-15</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>
@ -227,85 +36,145 @@ Railway Operation and Construction</a></td></tr>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"><tt class="literal"><span class="pre">indirect_iterator</span></tt> adapts an iterator by applying an
<em>extra</em> dereference inside of <tt class="literal"><span class="pre">operator*()</span></tt>. For example, this
iterator adaptor makes it possible to view a container of pointers
(e.g. <tt class="literal"><span class="pre">list&lt;foo*&gt;</span></tt>) as if it were a container of the pointed-to type
(e.g. <tt class="literal"><span class="pre">list&lt;foo&gt;</span></tt>). <tt class="literal"><span class="pre">indirect_iterator</span></tt> depends on two
auxiliary traits, <tt class="literal"><span class="pre">pointee</span></tt> and <tt class="literal"><span class="pre">indirect_reference</span></tt>, to
provide support for underlying iterators whose <tt class="literal"><span class="pre">value_type</span></tt> is
not an iterator.</td>
</tr>
</tbody>
</table>
<p>The indirect iterator adapts an iterator by applying an <em>extra</em>
dereference inside of <tt class="literal"><span class="pre">operator*()</span></tt>. For example, this iterator
adaptor makes it possible to view a container of pointers
(e.g. <tt class="literal"><span class="pre">list&lt;foo*&gt;</span></tt>) as if it were a container of the pointed-to type
(e.g. <tt class="literal"><span class="pre">list&lt;foo&gt;</span></tt>) .</p>
<!-- At some point we should add the capability to handle
iterators over smart pointers, which the impl handles. -JGS -->
<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="#indirect-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#indirect-iterator-operations" id="id2" name="id2"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#indirect-iterator-synopsis" id="id2" name="id2"><tt class="literal"><span class="pre">indirect_iterator</span></tt> synopsis</a></li>
<li><a class="reference" href="#indirect-iterator-requirements" id="id3" name="id3"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#indirect-iterator-models" id="id4" name="id4"><tt class="literal"><span class="pre">indirect_iterator</span></tt> models</a></li>
<li><a class="reference" href="#indirect-iterator-operations" id="id5" name="id5"><tt class="literal"><span class="pre">indirect_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="indirect-iterator-synopsis">
<h1><a class="toc-backref" href="#id2" name="indirect-iterator-synopsis"><tt class="literal"><span class="pre">indirect_iterator</span></tt> synopsis</a></h1>
<pre class="literal-block">
template &lt;
class Iterator
, class Value = use_default
, unsigned Access = use_default_access
, class Traversal = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Difference = use_default
&gt;
class indirect_iterator
: public iterator_adaptor&lt;/* see discussion */&gt;
{
friend class iterator_core_access;
public:
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
indirect_iterator();
indirect_iterator(Iterator x);
template &lt;
class Iterator2, class Value2, unsigned Access2, class Traversal2
class Iterator2, class Value2, class Category2
, class Reference2, class Difference2
&gt;
indirect_iterator(
indirect_iterator&lt;
Iterator2, Value2, Access2, Traversal2, Reference2, Difference2
Iterator2, Value2, Category2, Reference2, Difference2
&gt; const&amp; y
, typename enable_if_convertible&lt;Iterator2, Iterator&gt;::type* = 0 // exposition
);
private: // as-if specification
typename indirect_iterator::reference dereference() const
{
return **this-&gt;base();
}
Iterator const&amp; base() const;
reference operator*() const;
indirect_iterator&amp; operator++();
indirect_iterator&amp; operator--();
private:
Iterator m_iterator; // exposition
};
</pre>
<div class="section" id="indirect-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="indirect-iterator-requirements"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></h1>
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of the <tt class="literal"><span class="pre">Iterator</span></tt> template parameter should
itself be dereferenceable. The return type of the <tt class="literal"><span class="pre">operator*</span></tt> for
the <tt class="literal"><span class="pre">value_type</span></tt> must be the same type as the <tt class="literal"><span class="pre">Reference</span></tt> template
parameter. The <tt class="literal"><span class="pre">Value</span></tt> template parameter will be the <tt class="literal"><span class="pre">value_type</span></tt>
for the <tt class="literal"><span class="pre">indirect_iterator</span></tt>, unless <tt class="literal"><span class="pre">Value</span></tt> is const. If <tt class="literal"><span class="pre">Value</span></tt>
is <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>, then <tt class="literal"><span class="pre">value_type</span></tt> will be <em>non-</em> <tt class="literal"><span class="pre">const</span> <span class="pre">X</span></tt>. The
default for <tt class="literal"><span class="pre">Value</span></tt> is</p>
<p>The member types of <tt class="literal"><span class="pre">indirect_iterator</span></tt> are defined according to
the following pseudo-code, where <tt class="literal"><span class="pre">V</span></tt> is
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::value_type</span></tt></p>
<pre class="literal-block">
iterator_traits&lt; iterator_traits&lt;Iterator&gt;::value_type &gt;::value_type
if (Value is use_default) then
typedef remove_const&lt;pointee&lt;V&gt;::type&gt;::type value_type;
else
typedef remove_const&lt;Value&gt;::type value_type;
if (Reference is use_default) then
if (Value is use_default) then
typedef indirect_reference&lt;V&gt;::type reference;
else
typedef Value&amp; reference;
else
typedef Reference reference;
if (Value is use_default) then
typedef pointee&lt;V&gt;::type* pointer;
else
typedef Value* pointer;
if (Difference is use_default)
typedef iterator_traits&lt;Iterator&gt;::difference_type difference_type;
else
typedef Difference difference_type;
if (CategoryOrTraversal is use_default)
typedef <em>iterator-category</em> (
iterator_traversal&lt;Iterator&gt;::type,``reference``,``value_type``
) iterator_category;
else
typedef <em>iterator-category</em> (
CategoryOrTraversal,``reference``,``value_type``
) iterator_category;
</pre>
<p>If the default is used for <tt class="literal"><span class="pre">Value</span></tt>, then there must be a valid
specialization of <tt class="literal"><span class="pre">iterator_traits</span></tt> for the value type of the base
iterator.</p>
<p>The <tt class="literal"><span class="pre">Reference</span></tt> parameter will be the <tt class="literal"><span class="pre">reference</span></tt> type of the
<tt class="literal"><span class="pre">indirect_iterator</span></tt>. The default is <tt class="literal"><span class="pre">Value&amp;</span></tt>.</p>
<p>The <tt class="literal"><span class="pre">Access</span></tt> and <tt class="literal"><span class="pre">Traversal</span></tt> parameters are passed unchanged to
the corresponding parameters of the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> base
class, and the <tt class="literal"><span class="pre">Iterator</span></tt> parameter is passed unchanged as the
<tt class="literal"><span class="pre">Base</span></tt> parameter to the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class.</p>
<p>The indirect iterator will model the most refined standard traversal
concept that is modeled by the <tt class="literal"><span class="pre">Iterator</span></tt> type. The indirect
iterator will model the most refined standard access concept that is
modeled by the value type of <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
</div>
<div class="section" id="indirect-iterator-requirements">
<h1><a class="toc-backref" href="#id3" name="indirect-iterator-requirements"><tt class="literal"><span class="pre">indirect_iterator</span></tt> requirements</a></h1>
<p>The expression <tt class="literal"><span class="pre">*v</span></tt>, where <tt class="literal"><span class="pre">v</span></tt> is an object of
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::value_type</span></tt>, shall be valid
expression and convertible to <tt class="literal"><span class="pre">reference</span></tt>. <tt class="literal"><span class="pre">Iterator</span></tt> shall
model the traversal concept indicated by <tt class="literal"><span class="pre">iterator_category</span></tt>.
<tt class="literal"><span class="pre">Value</span></tt>, <tt class="literal"><span class="pre">Reference</span></tt>, and <tt class="literal"><span class="pre">Difference</span></tt> shall be chosen so
that <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">difference_type</span></tt> meet
the requirements indicated by <tt class="literal"><span class="pre">iterator_category</span></tt>.</p>
<p>[Note: there are further requirements on the
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::value_type</span></tt> if the <tt class="literal"><span class="pre">Value</span></tt>
parameter is not <tt class="literal"><span class="pre">use_default</span></tt>, as implied by the algorithm for
deducing the default for the <tt class="literal"><span class="pre">value_type</span></tt> member.]</p>
</div>
<div class="section" id="indirect-iterator-models">
<h1><a class="toc-backref" href="#id4" name="indirect-iterator-models"><tt class="literal"><span class="pre">indirect_iterator</span></tt> models</a></h1>
<p>In addition to the concepts indicated by <tt class="literal"><span class="pre">iterator_category</span></tt>
and by <tt class="literal"><span class="pre">iterator_traversal&lt;indirect_iterator&gt;::type</span></tt>, a
specialization of <tt class="literal"><span class="pre">indirect_iterator</span></tt> models the following
concepts, Where <tt class="literal"><span class="pre">v</span></tt> is an object of
<tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::value_type</span></tt>:</p>
<blockquote>
<ul class="simple">
<li>Readable Iterator if <tt class="literal"><span class="pre">reference(*v)</span></tt> is convertible to
<tt class="literal"><span class="pre">value_type</span></tt>.</li>
<li>Writable Iterator if <tt class="literal"><span class="pre">reference(*v)</span> <span class="pre">=</span> <span class="pre">t</span></tt> is a valid
expression (where <tt class="literal"><span class="pre">t</span></tt> is an object of type
<tt class="literal"><span class="pre">indirect_iterator::value_type</span></tt>)</li>
<li>Lvalue Iterator if <tt class="literal"><span class="pre">reference</span></tt> is a reference type.</li>
</ul>
</blockquote>
<p><tt class="literal"><span class="pre">indirect_iterator&lt;X,V1,C1,R1,D1&gt;</span></tt> is interoperable with
<tt class="literal"><span class="pre">indirect_iterator&lt;Y,V2,C2,R2,D2&gt;</span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is
interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
</div>
<div class="section" id="indirect-iterator-operations">
<h1><a class="toc-backref" href="#id2" name="indirect-iterator-operations"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></h1>
<h1><a class="toc-backref" href="#id5" name="indirect-iterator-operations"><tt class="literal"><span class="pre">indirect_iterator</span></tt> operations</a></h1>
<p>In addition to the operations required by the concepts described
above, specializations of <tt class="literal"><span class="pre">indirect_iterator</span></tt> provide the
following operations.</p>
<p><tt class="literal"><span class="pre">indirect_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -313,8 +182,8 @@ modeled by the value type of <tt class="literal"><span class="pre">Iterator</spa
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
a default constructed base object.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
a default-constructed <tt class="literal"><span class="pre">m_iterator</span></tt>.</td>
</tr>
</tbody>
</table>
@ -323,8 +192,8 @@ a default constructed base object.</td>
<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">indirect_iterator</span></tt> with
the <tt class="literal"><span class="pre">iterator_adaptor</span></tt> subobject copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> with
<tt class="literal"><span class="pre">m_iterator</span></tt> copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
@ -346,16 +215,117 @@ indirect_iterator(
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator2</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">y</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">indirect_iterator</span></tt> whose
<tt class="literal"><span class="pre">m_iterator</span></tt> subobject is constructed from <tt class="literal"><span class="pre">y.base()</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">const&amp;</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_iterator</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_iterator</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">indirect_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_iterator</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">indirect_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_iterator</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>
</div>
<div class="section" id="example">
<h1><a class="toc-backref" href="#id6" name="example">Example</a></h1>
<p>This example prints an array of characters, using
<tt class="literal"><span class="pre">indirect_iterator</span></tt> to access the array of characters through an
array of pointers. Next <tt class="literal"><span class="pre">indirect_iterator</span></tt> is used with the
<tt class="literal"><span class="pre">transform</span></tt> algorithm to copy the characters (incremented by one) to
another array. A constant indirect iterator is used for the source and
a mutable indirect iterator is used for the destination. The last part
of the example prints the original array of characters, but this time
using the <tt class="literal"><span class="pre">make_indirect_iterator</span></tt> helper function.</p>
<pre class="literal-block">
char characters[] = &quot;abcdefg&quot;;
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
char* pointers_to_chars[N]; // at the end.
for (int i = 0; i &lt; N; ++i)
pointers_to_chars[i] = &amp;characters[i];
// Example of using indirect_iterator
boost::indirect_iterator&lt;char**, char&gt;
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
std::copy(indirect_first, indirect_last, std::ostream_iterator&lt;char&gt;(std::cout, &quot;,&quot;));
std::cout &lt;&lt; std::endl;
// Example of making mutable and constant indirect iterators
char mutable_characters[N];
char* pointers_to_mutable_chars[N];
for (int j = 0; j &lt; N; ++j)
pointers_to_mutable_chars[j] = &amp;mutable_characters[j];
boost::indirect_iterator&lt;char* const*&gt; mutable_indirect_first(pointers_to_mutable_chars),
mutable_indirect_last(pointers_to_mutable_chars + N);
boost::indirect_iterator&lt;char* const*, char const&gt; const_indirect_first(pointers_to_chars),
const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind1st(std::plus&lt;char&gt;(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator&lt;char&gt;(std::cout, &quot;,&quot;));
std::cout &lt;&lt; std::endl;
// Example of using make_indirect_iterator()
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator&lt;char&gt;(std::cout, &quot;,&quot;));
std::cout &lt;&lt; std::endl;
</pre>
<p>The output is:</p>
<pre class="literal-block">
a,b,c,d,e,f,g,
b,c,d,e,f,g,h,
a,b,c,d,e,f,g,
</pre>
<p>The source code for this example can be found <a class="reference" href="../example/indirect_iterator_example.cpp">here</a>.</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="indirect_iterator.rst">View document source</a>.
Generated on: 2003-11-24 05:00 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>

View File

@ -16,8 +16,15 @@
:abstract:
.. include:: indirect_iterator_abstract.rst
.. include:: indirect_iterator_abstract.rst
.. contents:: Table of Contents
``indirect_iterator`` synopsis
..............................
.. include:: indirect_iterator_ref.rst
.. include:: indirect_iterator_eg.rst
.. _iterator-category: iterator_facade.html#iterator-category
.. |iterator-category| replace:: *iterator-category*

View File

@ -1,8 +1,11 @@
The indirect iterator adapts an iterator by applying an *extra*
dereference inside of ``operator*()``. For example, this iterator
adaptor makes it possible to view a container of pointers
``indirect_iterator`` adapts an iterator by applying an
*extra* dereference inside of ``operator*()``. For example, this
iterator adaptor makes it possible to view a container of pointers
(e.g. ``list<foo*>``) as if it were a container of the pointed-to type
(e.g. ``list<foo>``) .
(e.g. ``list<foo>``). ``indirect_iterator`` depends on two
auxiliary traits, ``pointee`` and ``indirect_reference``, to
provide support for underlying iterators whose ``value_type`` is
not an iterator.
.. At some point we should add the capability to handle
iterators over smart pointers, which the impl handles. -JGS

View File

@ -8,17 +8,14 @@
, class Difference = use_default
>
class indirect_iterator
: public iterator_adaptor<
indirect_iterator<Iterator, Value, Access, Traversal,
Reference, Difference>,
Iterator,
/* Value = see below */,
CategoryOrTraversal,
Reference,
Difference>
{
friend class iterator_core_access;
public:
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef /* see below */ difference_type;
typedef /* see below */ iterator_category;
indirect_iterator();
indirect_iterator(Iterator x);
@ -32,80 +29,113 @@
> const& y
, typename enable_if_convertible<Iterator2, Iterator>::type* = 0 // exposition
);
private: // as-if specification
typename indirect_iterator::reference dereference() const
{
return **this->base();
}
};
template <class Dereferenceable>
struct referent {
typedef /* see below */ type;
Iterator const& base() const;
reference operator*() const;
indirect_iterator& operator++();
indirect_iterator& operator--();
private:
Iterator m_iterator; // exposition
};
If ``Value`` is not ``use_default`` then the the argument for the
``iterator_adaptor`` base class' ``Value`` parameter is ``Value`` with
cv-qualifiers removed. If ``Value`` is ``use_default``, then the
argument for the ``iterator_adaptor`` base class' ``Value`` parameter
is computed as follows. We use the abbreviation
``V=iterator_traits<Iterator>::value_type`` and ``v`` is an object of
type ``V``.::
The member types of ``indirect_iterator`` are defined according to
the following pseudo-code, where ``V`` is
``iterator_traits<Iterator>::value_type``
if (*v returns a constant lvalue or an rvalue) then
referent<V>::type
else
add_const<referent<V>::type>::type
.. parsed-literal::
The algorithm for the ``type`` member of ``referent`` traits class is
as follows::
if (Value is use_default) then
typedef remove_const<pointee<V>::type>::type value_type;
else
typedef remove_const<Value>::type value_type;
if (Dereferenceable is a class and has member element_type)
Dereferenceable::element_type
else
iterator_traits<Dereferenceable>::value_type
if (Reference is use_default) then
if (Value is use_default) then
typedef indirect_reference<V>::type reference;
else
typedef Value& reference;
else
typedef Reference reference;
if (Value is use_default) then
typedef pointee<V>::type\* pointer;
else
typedef Value\* pointer;
if (Difference is use_default)
typedef iterator_traits<Iterator>::difference_type difference_type;
else
typedef Difference difference_type;
if (CategoryOrTraversal is use_default)
typedef *iterator-category* (
iterator_traversal<Iterator>::type,``reference``,``value_type``
) iterator_category;
else
typedef *iterator-category* (
CategoryOrTraversal,``reference``,``value_type``
) iterator_category;
``indirect_iterator`` requirements
..................................
The ``CategoryOrTraversal`` argument shall be one of the standard
iterator tags or ``use_default``. If ``CategoryOrTraversal`` is an
iterator tag, ``indirect_iterator`` satisfies the requirements
corresponding to the iterator tag. The template parameter
``Iterator`` argument shall meet the traversal requirements
corresponding to the iterator tag and the requirements of Readable
Iterator. If ``CategoryOrTraversal`` is ``use_default`` then
``indirect_iterator`` satisfies the requirements of the most refined
standard traversal concept that is satisfied by the ``Iterator``
argument. In this case the ``Iterator`` argument shall meet the
requirements of Readable Iterator.
The expression ``*v``, where ``v`` is an object of
``iterator_traits<Iterator>::value_type``, shall be valid
expression and convertible to ``reference``. ``Iterator`` shall
model the traversal concept indicated by ``iterator_category``.
``Value``, ``Reference``, and ``Difference`` shall be chosen so
that ``value_type``, ``reference``, and ``difference_type`` meet
the requirements indicated by ``iterator_category``.
The expression ``*v``, where ``v`` is an object of type
``iterator_traits<Iterator>::value_type``, must be a valid expression
and must be convertible to ``iterator_adaptor::reference`` Also, there
are further requirements on the
``iterator_traits<Iterator>::value_type`` if the ``Value`` parameter
is not ``use_default``, as implied by the algorithm for deducing the
default.
[Note: there are further requirements on the
``iterator_traits<Iterator>::value_type`` if the ``Value``
parameter is not ``use_default``, as implied by the algorithm for
deducing the default for the ``value_type`` member.]
``indirect_iterator`` models
............................
In addition to the concepts indicated by ``iterator_category``
and by ``iterator_traversal<indirect_iterator>::type``, a
specialization of ``indirect_iterator`` models the following
concepts, Where ``v`` is an object of
``iterator_traits<Iterator>::value_type``:
* Readable Iterator if ``reference(*v)`` is convertible to
``value_type``.
* Writable Iterator if ``reference(*v) = t`` is a valid
expression (where ``t`` is an object of type
``indirect_iterator::value_type``)
* Lvalue Iterator if ``reference`` is a reference type.
``indirect_iterator<X,V1,C1,R1,D1>`` is interoperable with
``indirect_iterator<Y,V2,C2,R2,D2>`` if and only if ``X`` is
interoperable with ``Y``.
``indirect_iterator`` operations
................................
In addition to the operations required by the concepts described
above, specializations of ``indirect_iterator`` provide the
following operations.
``indirect_iterator();``
:Requires: ``Iterator`` must be Default Constructible.
:Returns: An instance of ``indirect_iterator`` with
a default-constructed ``iterator_adaptor`` subobject.
:Effects: Constructs an instance of ``indirect_iterator`` with
a default-constructed ``m_iterator``.
``indirect_iterator(Iterator x);``
:Returns: An instance of ``indirect_iterator`` with
the ``iterator_adaptor`` subobject copy constructed from ``x``.
:Effects: Constructs an instance of ``indirect_iterator`` with
``m_iterator`` copy constructed from ``x``.
::
@ -121,7 +151,27 @@ default.
);
:Requires: ``Iterator2`` is implicitly convertible to ``Iterator``.
:Returns: An instance of ``indirect_iterator`` whose
``iterator_adaptor`` subobject is constructed from ``y.base()``.
:Effects: Constructs an instance of ``indirect_iterator`` whose
``m_iterator`` subobject is constructed from ``y.base()``.
``Iterator const& base() const;``
:Returns: ``m_iterator``
``reference operator*() const;``
:Returns: ``**m_iterator``
``indirect_iterator& operator++();``
:Effects: ``++m_iterator``
:Returns: ``*this``
``indirect_iterator& operator--();``
:Effects: ``--m_iterator``
:Returns: ``*this``

File diff suppressed because it is too large Load Diff

View File

@ -7,200 +7,9 @@
<title>Iterator Adaptor</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="date" content="2004-01-12" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="iterator-adaptor">
@ -218,7 +27,7 @@ ul.auto-toc {
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>
<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>
@ -248,19 +57,20 @@ core interface functions of <tt class="literal"><span class="pre">iterator_facad
<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="#introduction" id="id3" name="id3">Introduction</a></li>
<li><a class="reference" href="#reference" id="id4" name="id4">Reference</a><ul>
<li><a class="reference" href="#iterator-adaptor-base-class-parameters" id="id5" name="id5"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class parameters</a></li>
<li><a class="reference" href="#iterator-adaptor-usage" id="id6" name="id6"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> usage</a></li>
<li><a class="reference" href="#iterator-adaptor-public-operations" id="id7" name="id7"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></li>
<li><a class="reference" href="#iterator-adaptor-protected-member-functions" id="id8" name="id8"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></li>
<li><a class="reference" href="#iterator-adaptor-private-member-functions" id="id9" name="id9"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></li>
<li><a class="reference" href="#overview" id="id6" name="id6">Overview</a></li>
<li><a class="reference" href="#reference" id="id7" name="id7">Reference</a><ul>
<li><a class="reference" href="#iterator-adaptor-requirements" id="id8" name="id8"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> requirements</a></li>
<li><a class="reference" href="#iterator-adaptor-base-class-parameters" id="id9" name="id9"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class parameters</a></li>
<li><a class="reference" href="#iterator-adaptor-public-operations" id="id10" name="id10"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></li>
<li><a class="reference" href="#iterator-adaptor-protected-member-functions" id="id11" name="id11"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></li>
<li><a class="reference" href="#iterator-adaptor-private-member-functions" id="id12" name="id12"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></li>
</ul>
</li>
<li><a class="reference" href="#tutorial-example" id="id13" name="id13">Tutorial Example</a></li>
</ul>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id3" name="introduction">Introduction</a></h1>
<div class="section" id="overview">
<h1><a class="toc-backref" href="#id6" name="overview">Overview</a></h1>
<!-- Version 1.2 of this ReStructuredText document corresponds to
n1530_, the paper accepted by the LWG for TR1. -->
<!-- Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All
@ -274,7 +84,7 @@ instance of the <tt class="literal"><span class="pre">Base</span></tt> type, whi
<table class="footnote" frame="void" id="base" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1" name="base">[1]</a></td><td>The term &quot;Base&quot; here does not refer to a base class and is
<tr><td class="label"><a name="base">[1]</a></td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id3">2</a>)</em> The term &quot;Base&quot; here does not refer to a base class and is
not meant to imply the use of derivation. We have followed the lead
of the standard library, which provides a base() function to access
the underlying iterator object of a <tt class="literal"><span class="pre">reverse_iterator</span></tt> adaptor.</td></tr>
@ -301,7 +111,7 @@ template parameter may not always be identical to the iterator's
that assumption.</p>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id4" name="reference">Reference</a></h1>
<h1><a class="toc-backref" href="#id7" name="reference">Reference</a></h1>
<!-- Version 1.4 of this ReStructuredText document corresponds to
n1530_, the paper accepted by the LWG for TR1. -->
<!-- Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All
@ -310,19 +120,19 @@ rights reserved. -->
template &lt;
class Derived
, class Base
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Difference = use_default
&gt;
class iterator_adaptor
: public iterator_facade&lt;Derived, <em>V</em>, <em>C</em>, <em>R</em>, <em>D</em>&gt; // see <a class="reference" href="#base-parameters">details</a>
: public iterator_facade&lt;Derived, <em>V'</em>, <em>C'</em>, <em>R'</em>, <em>D'</em>&gt; // see <a class="reference" href="#base-parameters">details</a>
{
friend class iterator_core_access;
public:
iterator_adaptor();
explicit iterator_adaptor(Base iter);
Base base() const;
Base const&amp; base() const;
protected:
Base const&amp; base_reference() const;
Base&amp; base_reference();
@ -348,23 +158,28 @@ class iterator_adaptor
Base m_iterator; // exposition only
};
</pre>
<a class="target" id="base-parameters" name="base-parameters"></a><div class="section" id="iterator-adaptor-base-class-parameters">
<h2><a class="toc-backref" href="#id5" name="iterator-adaptor-base-class-parameters"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class parameters</a></h2>
<p>The <em>V</em>, <em>C</em>, <em>R</em>, and <em>D</em> parameters of the <tt class="literal"><span class="pre">iterator_facade</span></tt>
<a class="target" id="requirements" name="requirements"></a><div class="section" id="iterator-adaptor-requirements">
<h2><a class="toc-backref" href="#id8" name="iterator-adaptor-requirements"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> requirements</a></h2>
<p><tt class="literal"><span class="pre">static_cast&lt;Derived*&gt;(iterator_adaptor*)</span></tt> shall be well-formed.
The <tt class="literal"><span class="pre">Base</span></tt> argument shall be Assignable and Copy Constructible.</p>
<a class="target" id="base-parameters" name="base-parameters"></a></div>
<div class="section" id="iterator-adaptor-base-class-parameters">
<h2><a class="toc-backref" href="#id9" name="iterator-adaptor-base-class-parameters"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> base class parameters</a></h2>
<p>The <em>V'</em>, <em>C'</em>, <em>R'</em>, and <em>D'</em> parameters of the <tt class="literal"><span class="pre">iterator_facade</span></tt>
used as a base class in the summary of <tt class="literal"><span class="pre">iterator_adaptor</span></tt>
above are defined as follows:</p>
<pre class="literal-block">
<em>V</em> = if (Value is use_default)
<em>V'</em> = if (Value is use_default)
return iterator_traits&lt;Base&gt;::value_type
else
return Value
<em>C</em> = if (CategoryOrTraversal is use_default)
<em>C'</em> = if (CategoryOrTraversal is use_default)
return iterator_traversal&lt;Base&gt;::type
else
return CategoryOrTraversal
<em>R</em> = if (Reference is use_default)
<em>R'</em> = if (Reference is use_default)
if (Value is use_default)
return iterator_traits&lt;Base&gt;::reference
else
@ -372,26 +187,25 @@ above are defined as follows:</p>
else
return Reference
<em>D</em> = if (Difference is use_default)
<em>D'</em> = if (Difference is use_default)
return iterator_traits&lt;Base&gt;::difference_type
else
return Difference
</pre>
</div>
<div class="section" id="iterator-adaptor-usage">
<h2><a class="toc-backref" href="#id6" name="iterator-adaptor-usage"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> usage</a></h2>
<p>The <tt class="literal"><span class="pre">Derived</span></tt> template parameter must be a publicly derived from
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. In order for <tt class="literal"><span class="pre">Derived</span></tt> to model the
iterator concepts corresponding to
<tt class="literal"><span class="pre">iterator_traits&lt;Derived&gt;::iterator_category</span></tt>, the expressions
involving <tt class="literal"><span class="pre">m_iterator</span></tt> in the specifications of those private
member functions of <tt class="literal"><span class="pre">iterator_adaptor</span></tt> that may be called by
<tt class="literal"><span class="pre">iterator_facade&lt;Derived,</span> <span class="pre">``\</span> <span class="pre">*V*\</span></tt>, <tt class="literal"><span class="pre">\</span> <span class="pre">*C*\</span></tt>, <tt class="literal"><span class="pre">\</span> <span class="pre">*R*\</span></tt>, <tt class="literal"><span class="pre">\</span>
<span class="pre">*D*\</span></tt>&gt;`` in evaluating any valid expression involving <tt class="literal"><span class="pre">Derived</span></tt>
in those concepts' requirements.</p>
<!-- ``iterator_adaptor`` models
- - - - - - - - - - - - - - - - - - - - - - - - - - -
In order for ``Derived`` to model the iterator concepts corresponding
to ``iterator_traits<Derived>::iterator_category``, the expressions
involving ``m_iterator`` in the specifications of those private member
functions of ``iterator_adaptor`` that may be called by
``iterator_facade<Derived, V, C, R, D>`` in evaluating any valid
expression involving ``Derived`` in those concepts' requirements. -->
<!-- The above is confusing and needs a rewrite. -JGS -->
<!-- That's why it's removed. We're embracing inheritance, remember? -->
</div>
<div class="section" id="iterator-adaptor-public-operations">
<h2><a class="toc-backref" href="#id7" name="iterator-adaptor-public-operations"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></h2>
<h2><a class="toc-backref" href="#id10" name="iterator-adaptor-public-operations"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> public operations</a></h2>
<p><tt class="literal"><span class="pre">iterator_adaptor();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -414,7 +228,7 @@ in those concepts' requirements.</p>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">base()</span> <span class="pre">const;</span></tt></p>
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">const&amp;</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" />
@ -425,7 +239,7 @@ in those concepts' requirements.</p>
</table>
</div>
<div class="section" id="iterator-adaptor-protected-member-functions">
<h2><a class="toc-backref" href="#id8" name="iterator-adaptor-protected-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></h2>
<h2><a class="toc-backref" href="#id11" name="iterator-adaptor-protected-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> protected member functions</a></h2>
<p><tt class="literal"><span class="pre">Base</span> <span class="pre">const&amp;</span> <span class="pre">base_reference()</span> <span class="pre">const;</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -446,7 +260,7 @@ in those concepts' requirements.</p>
</table>
</div>
<div class="section" id="iterator-adaptor-private-member-functions">
<h2><a class="toc-backref" href="#id9" name="iterator-adaptor-private-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></h2>
<h2><a class="toc-backref" href="#id12" name="iterator-adaptor-private-member-functions"><tt class="literal"><span class="pre">iterator_adaptor</span></tt> private member functions</a></h2>
<p><tt class="literal"><span class="pre">typename</span> <span class="pre">iterator_adaptor::reference</span> <span class="pre">dereference()</span> <span class="pre">const;</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -514,11 +328,117 @@ typename iterator_adaptor::difference_type distance_to(
</table>
</div>
</div>
<div class="section" id="tutorial-example">
<h1><a class="toc-backref" href="#id13" name="tutorial-example">Tutorial Example</a></h1>
<!-- Copyright David Abrahams 2004. Use, modification and distribution is -->
<!-- subject to the Boost Software License, Version 1.0. (See accompanying -->
<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
<p>In this section we'll further refine the <tt class="literal"><span class="pre">node_iter</span></tt> class
template we developed in the <a class="reference" href="iterator_facade.html#tutorial-example"><tt class="literal"><span class="pre">iterator_facade</span></tt> tutorial</a>. If you haven't already
read that material, you should go back now and check it out because
we're going to pick up right where it left off.</p>
<div class="sidebar">
<p class="sidebar-title"><tt class="literal"><span class="pre">node_base*</span></tt> really <em>is</em> an iterator</p>
<p>It's not really a very interesting iterator, since <tt class="literal"><span class="pre">node_base</span></tt>
is an abstract class: a pointer to a <tt class="literal"><span class="pre">node_base</span></tt> just points
at some base subobject of an instance of some other class, and
incrementing a <tt class="literal"><span class="pre">node_base*</span></tt> moves it past this base subobject
to who-knows-where? The most we can do with that incremented
position is to compare another <tt class="literal"><span class="pre">node_base*</span></tt> to it. In other
words, the original iterator traverses a one-element array.</p>
</div>
<p>You probably didn't think of it this way, but the <tt class="literal"><span class="pre">node_base*</span></tt>
object which underlies <tt class="literal"><span class="pre">node_iterator</span></tt> is itself an iterator,
just like all other pointers. If we examine that pointer closely
from an iterator perspective, we can see that it has much in common
with the <tt class="literal"><span class="pre">node_iterator</span></tt> we're building. First, they share most
of the same associated types (<tt class="literal"><span class="pre">value_type</span></tt>, <tt class="literal"><span class="pre">reference</span></tt>,
<tt class="literal"><span class="pre">pointer</span></tt>, and <tt class="literal"><span class="pre">difference_type</span></tt>). Second, even some of the
core functionality is the same: <tt class="literal"><span class="pre">operator*</span></tt> and <tt class="literal"><span class="pre">operator==</span></tt> on
the <tt class="literal"><span class="pre">node_iterator</span></tt> return the result of invoking the same
operations on the underlying pointer, via the <tt class="literal"><span class="pre">node_iterator</span></tt>'s
<a class="reference" href="iterator_facade.html#implementing-the-core-operations"><tt class="literal"><span class="pre">dereference</span></tt> and <tt class="literal"><span class="pre">equal</span></tt> member functions</a>). However, the <tt class="literal"><span class="pre">operator++</span></tt> for
<tt class="literal"><span class="pre">node_iterator</span></tt> behaves differently than for <tt class="literal"><span class="pre">node_base*</span></tt>
since it follows the <tt class="literal"><span class="pre">m_next</span></tt> pointer.</p>
<p>It turns out that the pattern of building an iterator on another
iterator-like type (the <tt class="literal"><span class="pre">Base</span></tt> <a class="footnote-reference" href="#base" id="id3" name="id3"><sup>1</sup></a> type) while modifying
just a few aspects of the underlying type's behavior is an
extremely common one, and it's the pattern addressed by
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. Using <tt class="literal"><span class="pre">iterator_adaptor</span></tt> is very much like
using <tt class="literal"><span class="pre">iterator_facade</span></tt>, but because iterator_adaptor tries to
mimic as much of the <tt class="literal"><span class="pre">Base</span></tt> type's behavior as possible, we
neither have to supply a <tt class="literal"><span class="pre">Value</span></tt> argument, nor implement any core
behaviors other than <tt class="literal"><span class="pre">increment</span></tt>. The implementation of
<tt class="literal"><span class="pre">node_iter</span></tt> is thus reduced to:</p>
<pre class="literal-block">
template &lt;class Value&gt;
class node_iter
: public boost::iterator_adaptor&lt;
node_iter&lt;Value&gt; // Derived
, Value* // Base
, boost::use_default // Value
, boost::forward_traversal_tag // CategoryOrTraversal
&gt;
{
private:
struct enabler {}; // a private type avoids misuse
typedef boost::iterator_adaptor&lt;
node_iter&lt;Value&gt;, Value*, boost::use_default, boost::forward_traversal_tag
&gt; super_t;
public:
node_iter()
: super_t(0) {}
explicit node_iter(Value* p)
: super_t(p) {}
template &lt;class OtherValue&gt;
node_iter(
node_iter&lt;OtherValue&gt; const&amp; other
, typename boost::enable_if&lt;
boost::is_convertible&lt;OtherValue*,Value*&gt;
, enabler
&gt;::type = enabler()
)
: super_t(other.base()) {}
private:
friend class boost::iterator_core_access;
void increment() { this-&gt;base_reference() = this-&gt;base()-&gt;next(); }
};
</pre>
<p>You can see an example program which exercises this version of the
node iterators <a class="reference" href="../example/node_iterator3.cpp">here</a>.</p>
<p>In the case of <tt class="literal"><span class="pre">node_iter</span></tt>, it's not very compelling to pass
<tt class="literal"><span class="pre">boost::use_default</span></tt> as <tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">Value</span></tt>
argument; we could have just passed <tt class="literal"><span class="pre">node_iter</span></tt>'s <tt class="literal"><span class="pre">Value</span></tt>
along to <tt class="literal"><span class="pre">iterator_adaptor</span></tt>, and that'd even be shorter! Most
iterator class templates built with <tt class="literal"><span class="pre">iterator_adaptor</span></tt> are
parameterized on another iterator type, rather than on its
<tt class="literal"><span class="pre">value_type</span></tt>. For example, <tt class="literal"><span class="pre">boost::reverse_iterator</span></tt> takes an
iterator type argument and reverses its direction of traversal,
since the original iterator and the reversed one have all the same
associated types, <tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s delegation of default
types to its <tt class="literal"><span class="pre">Base</span></tt> saves the implementor of
<tt class="literal"><span class="pre">boost::reverse_iterator</span></tt> from writing</p>
<pre class="literal-block">
std::iterator_traits&lt;Iterator&gt;::<em>some-associated-type</em>
</pre>
<p>at least four times.</p>
<p>We urge you to review the documentation and implementations of
<a class="reference" href="reverse_iterator.html"><tt class="literal"><span class="pre">reverse_iterator</span></tt></a> and the other Boost <a class="reference" href="index.html#specialized-adaptors">specialized iterator
adaptors</a> to get an idea of the sorts of things you can do with
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>. In particular, have a look at
<a class="reference" href="transform_iterator.html"><tt class="literal"><span class="pre">transform_iterator</span></tt></a>, which is perhaps the most straightforward
adaptor, and also <a class="reference" href="counting_iterator.html"><tt class="literal"><span class="pre">counting_iterator</span></tt></a>, which demonstrates that
<tt class="literal"><span class="pre">iterator_adaptor</span></tt>'s <tt class="literal"><span class="pre">Base</span></tt> type needn't be an iterator.</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="iterator_adaptor.rst">View document source</a>.
Generated on: 2003-11-24 05:11 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>

View File

@ -20,8 +20,8 @@
.. contents:: Table of Contents
Introduction
============
Overview
========
.. include:: iterator_adaptor_body.rst
@ -30,3 +30,8 @@ Reference
=========
.. include:: iterator_adaptor_ref.rst
Tutorial Example
================
.. include:: iterator_adaptor_tutorial.rst

View File

@ -9,19 +9,19 @@
template <
class Derived
, class Base
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Value = use_default
, class CategoryOrTraversal = use_default
, class Reference = use_default
, class Difference = use_default
>
class iterator_adaptor
: public iterator_facade<Derived, *V*, *C*, *R*, *D*> // see details__
: public iterator_facade<Derived, *V'*, *C'*, *R'*, *D'*> // see details__
{
friend class iterator_core_access;
public:
iterator_adaptor();
explicit iterator_adaptor(Base iter);
Base base() const;
Base const& base() const;
protected:
Base const& base_reference() const;
Base& base_reference();
@ -49,28 +49,37 @@
__ base_parameters_
.. _requirements:
``iterator_adaptor`` requirements
---------------------------------
``static_cast<Derived*>(iterator_adaptor*)`` shall be well-formed.
The ``Base`` argument shall be Assignable and Copy Constructible.
.. _base_parameters:
``iterator_adaptor`` base class parameters
------------------------------------------
The *V*, *C*, *R*, and *D* parameters of the ``iterator_facade``
The *V'*, *C'*, *R'*, and *D'* parameters of the ``iterator_facade``
used as a base class in the summary of ``iterator_adaptor``
above are defined as follows:
.. parsed-literal::
*V* = if (Value is use_default)
*V'* = if (Value is use_default)
return iterator_traits<Base>::value_type
else
return Value
*C* = if (CategoryOrTraversal is use_default)
*C'* = if (CategoryOrTraversal is use_default)
return iterator_traversal<Base>::type
else
return CategoryOrTraversal
*R* = if (Reference is use_default)
*R'* = if (Reference is use_default)
if (Value is use_default)
return iterator_traits<Base>::reference
else
@ -78,23 +87,23 @@ above are defined as follows:
else
return Reference
*D* = if (Difference is use_default)
*D'* = if (Difference is use_default)
return iterator_traits<Base>::difference_type
else
return Difference
``iterator_adaptor`` usage
--------------------------
.. ``iterator_adaptor`` models
---------------------------
The ``Derived`` template parameter must be a publicly derived from
``iterator_adaptor``. In order for ``Derived`` to model the
iterator concepts corresponding to
``iterator_traits<Derived>::iterator_category``, the expressions
involving ``m_iterator`` in the specifications of those private
member functions of ``iterator_adaptor`` that may be called by
``iterator_facade<Derived, ``\ *V*\``, ``\ *C*\``, ``\ *R*\``, ``\
*D*\``>`` in evaluating any valid expression involving ``Derived``
in those concepts' requirements.
In order for ``Derived`` to model the iterator concepts corresponding
to ``iterator_traits<Derived>::iterator_category``, the expressions
involving ``m_iterator`` in the specifications of those private member
functions of ``iterator_adaptor`` that may be called by
``iterator_facade<Derived, V, C, R, D>`` in evaluating any valid
expression involving ``Derived`` in those concepts' requirements.
.. The above is confusing and needs a rewrite. -JGS
.. That's why it's removed. We're embracing inheritance, remember?
``iterator_adaptor`` public operations
--------------------------------------
@ -111,11 +120,10 @@ in those concepts' requirements.
:Returns: An instance of ``iterator_adaptor`` with
``m_iterator`` copy constructed from ``iter``.
``Base base() const;``
``Base const& base() const;``
:Returns: ``m_iterator``
``iterator_adaptor`` protected member functions
-----------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -16,20 +16,25 @@
:abstract:
.. include:: iterator_facade_abstract.rst
.. include:: iterator_facade_abstract.rst
.. contents:: Table of Contents
Motivation
----------
Overview
========
.. include:: iterator_facade_body.rst
Reference
---------
=========
.. include:: iterator_facade_ref.rst
.. _counting: counting_iterator.html
Tutorial Example
================
.. include:: iterator_facade_tutorial.rst

View File

@ -21,11 +21,11 @@ include the associated types exposed through iterator traits:
``value_type``, ``reference``, ``difference_type``, and
``iterator_category``.
Iterator facade uses the Curiously Recurring Template Pattern (CRTP)
[Cop95]_ so that the user can specify the behavior of
``iterator_facade`` in a derived class. Former designs used policy
objects to specify the behavior. ``iterator_facade`` does not use policy
objects for several reasons:
Iterator facade uses the Curiously Recurring Template
Pattern (CRTP) [Cop95]_ so that the user can specify the behavior
of ``iterator_facade`` in a derived class. Former designs used
policy objects to specify the behavior, but that approach was
discarded for several reasons:
1. the creation and eventual copying of the policy object may create
overhead that can be avoided with the current approach.
@ -36,9 +36,11 @@ objects for several reasons:
implementations.
3. Without the use of CRTP, the standard requirement that an
iterator's ``operator++`` returns the iterator type itself means
that all iterators generated by ``iterator_facade`` would be
specializations of ``iterator_facade``. Cumbersome type generator
iterator's ``operator++`` returns the iterator type itself
would mean that all iterators built with the library would
have to be specializations of ``iterator_facade<...>``, rather
than something more descriptive like
``indirect_iterator<T*>``. Cumbersome type generator
metafunctions would be needed to build new parameterized
iterators, and a separate ``iterator_adaptor`` layer would be
impossible.
@ -180,10 +182,10 @@ through ``operator->``. Therefore, an iterator whose ``reference``
type is not in fact a reference must return a proxy containing a copy
of the referenced value from its ``operator->``.
The return type for ``operator->`` and ``operator[]`` is not
explicitly specified. Instead it requires each ``iterator_facade``
specialization to meet the requirements of its ``iterator_category``.
The return types for ``iterator_facade``\ 's ``operator->`` and
``operator[]`` are not explicitly specified. Instead, those types
are described in terms of a set of requirements, which must be
satisfied by the ``iterator_facade`` implementation.
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template
Patterns, C++ Report, February 1995, pp. 24-27.

View File

@ -18,7 +18,7 @@
public:
typedef remove_const<Value>::type value_type;
typedef Reference reference;
typedef Value* pointer;
typedef Value\* pointer;
typedef Difference difference_type;
typedef /* see below__ \*/ iterator_category;
@ -37,67 +37,78 @@
// Comparison operators
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type // exposition
operator ==(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
typename enable_if_interoperable<Dr1,Dr2,bool>::type // exposition
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator !=(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator <(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator <=(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator >(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator >=(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator >=(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
// Iterator difference
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1, Dr2, bool>::type
operator -(iterator_facade<Dr1, V1, TC1, R1, D1> const& lhs,
iterator_facade<Dr2, V2, TC2, R2, D2> const& rhs);
/* see below__ \*/
operator-(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
// Iterator addition
template <class Derived, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Derived, V, TC, R, D> const&,
typename Derived::difference_type n)
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
typename Derived::difference_type n);
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (typename Derived::difference_type n,
iterator_facade<Dr,V,TC,R,D> const&);
__ `facade iterator category`_
__ `iterator category`_
__ `operator arrow`_
__ brackets_
__ minus_
.. _`iterator category`:
The ``iterator_category`` member of ``iterator_facade`` is
.. parsed-literal::
*iterator-category*\ (CategoryOrTraversal, value_type, reference)
where *iterator-category* is defined as follows:
.. include:: facade_iterator_category.rst
The ``enable_if_interoperable`` template used above is for exposition
purposes. The member operators should be only be in an overload set
purposes. The member operators should only be in an overload set
provided the derived types ``Dr1`` and ``Dr2`` are interoperable,
meaning that at least one of the types is convertible to the other. The
``enable_if_interoperable`` approach uses SFINAE to take the operators
@ -120,14 +131,15 @@ were defined to be::
{};
``iterator_facade`` usage
.........................
``iterator_facade`` Requirements
--------------------------------
The following table describes the typical valid expressions on
``iterator_facade``\ 's ``Derived`` parameter, depending on the
iterator concept(s) it will model. The operations in the first
column must be made accessible to member functions of class
``iterator_core_access``.
``iterator_core_access``. In addition,
``static_cast<Derived*>(iterator_facade*)`` shall be well-formed.
In the table below, ``F`` is ``iterator_facade<X,V,C,R,D>``, ``a`` is an
object of type ``X``, ``b`` and ``c`` are objects of type ``const X``,
@ -136,88 +148,37 @@ object of a single pass iterator type interoperable with ``X``, and ``z``
is a constant object of a random access traversal iterator type
interoperable with ``X``.
+--------------------+----------------------+-------------------------------------+---------------------------+
|Expression |Return Type |Assertion/Note |Used to implement Iterator |
| | | |Concept(s) |
+====================+======================+=====================================+===========================+
|``c.dereference()`` |``F::reference`` | |Readable Iterator, Writable|
| | | |Iterator |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``c.equal(b)`` |convertible to bool |true iff ``b`` and ``c`` are |Single Pass Iterator |
| | |equivalent. | |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``c.equal(y)`` |convertible to bool |true iff ``c`` and ``y`` refer to the|Single Pass Iterator |
| | |same position. Implements ``c == y``| |
| | |and ``c != y``. | |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``a.advance(n)`` |unused | |Random Access Traversal |
| | | |Iterator |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``a.increment()`` |unused | |Incrementable Iterator |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``a.decrement()`` |unused | |Bidirectional Traversal |
| | | |Iterator |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``c.distance_to(b)``|convertible to |equivalent to ``distance(c, b)`` |Random Access Traversal |
| |``F::difference_type``| |Iterator |
+--------------------+----------------------+-------------------------------------+---------------------------+
|``c.distance_to(z)``|convertible to |equivalent to ``distance(c, z)``. |Random Access Traversal |
| |``F::difference_type``|Implements ``c - z``, ``c < z``, ``c |Iterator |
| | |<= z``, ``c > z``, and ``c >= c``. | |
+--------------------+----------------------+-------------------------------------+---------------------------+
.. _`core operations`:
.. _facade iterator category:
.. topic:: ``iterator_facade`` Core Operations
``iterator_facade`` iterator category
.....................................
+--------------------+----------------------+-------------------------+---------------------------+
|Expression |Return Type |Assertion/Note |Used to implement Iterator |
| | | |Concept(s) |
+====================+======================+=========================+===========================+
|``c.dereference()`` |``F::reference`` | |Readable Iterator, Writable|
| | | |Iterator |
+--------------------+----------------------+-------------------------+---------------------------+
|``c.equal(y)`` |convertible to bool |true iff ``c`` and ``y`` |Single Pass Iterator |
| | |refer to the same | |
| | |position. | |
+--------------------+----------------------+-------------------------+---------------------------+
|``a.increment()`` |unused | |Incrementable Iterator |
+--------------------+----------------------+-------------------------+---------------------------+
|``a.decrement()`` |unused | |Bidirectional Traversal |
| | | |Iterator |
+--------------------+----------------------+-------------------------+---------------------------+
|``a.advance(n)`` |unused | |Random Access Traversal |
| | | |Iterator |
+--------------------+----------------------+-------------------------+---------------------------+
|``c.distance_to(z)``|convertible to |equivalent to |Random Access Traversal |
| |``F::difference_type``|``distance(c, X(z))``. |Iterator |
+--------------------+----------------------+-------------------------+---------------------------+
The ``iterator_category`` member of ``iterator_facade<X,V,R,C,D>``
is a type which satisfies the following conditions:
* if ``C`` is convertible to ``std::input_iterator_tag`` or
``C`` is convertible to ``std::output_iterator_tag``,
``iterator_category`` is the same as ``C``.
* Otherwise, if ``C`` is not convertible to
``incrementable_traversal_tag``, the program is ill-formed
* Otherwise:
- ``iterator_category`` is convertible to the iterator
category tag or tags given by the following algorithm, and
not to any more-derived iterator category tag or tags::
if (R is a reference type
&& C is convertible to forward_traversal_tag)
{
if (C is convertible to random_access_traversal_tag)
return random_access_iterator_tag
else if (C is convertible to bidirectional_traversal_tag)
return bidirectional_iterator_tag
else
return forward_traversal_tag
}
else
{
if (C is convertible to single_pass_traversal_tag
&& R is convertible to V)
{
if (V is const)
return input_iterator_tag
else
return input_iterator_tag and output_iterator_tag
}
else
return output_iterator_tag
}
- ``iterator_traversal<X>::type`` is convertible to the most
derived traversal tag type to which ``C`` is also
convertible, and not to any more-derived traversal tag type.
``iterator_facade`` operations
..............................
------------------------------
The operations in this section are described in terms of operations on
the core interface of ``Derived`` which may be inaccessible
@ -247,11 +208,10 @@ __ `operator arrow`_
:Returns: an object convertible to ``value_type``. For constant
objects ``v`` of type ``value_type``, and ``n`` of type
``difference_type``, and reference ``p`` equal to
``*static_cast<Derived const*>(this)``, ``(*this)[n] = v`` is
equivalent to ``*(p+ n) = v``, and ``static_cast<value_type
``difference_type``, ``(*this)[n] = v`` is equivalent to
``*(*this + n) = v``, and ``static_cast<value_type
const&>((*this)[n])`` is equivalent to
``static_cast<value_type const&>(*(p+n))``
``static_cast<value_type const&>(*(*this + n))``
@ -282,7 +242,7 @@ __ `operator arrow`_
::
static_cast<Derived*>(this)->decrement();
return static_cast<Derived*>(this);
return *static_cast<Derived*>(this);
``Derived operator--(int);``
@ -303,7 +263,7 @@ __ `operator arrow`_
::
static_cast<Derived*>(this)->advance(n);
return static_cast<Derived*>(this);
return *static_cast<Derived*>(this);
``Derived& operator-=(difference_type n);``
@ -313,7 +273,7 @@ __ `operator arrow`_
::
static_cast<Derived*>(this)->advance(-n);
return static_cast<Derived*>(this);
return *static_cast<Derived*>(this);
``Derived operator-(difference_type n) const;``
@ -322,8 +282,155 @@ __ `operator arrow`_
::
Derived tmp(static_cast<Derived const*>(this));
return tmp -= n;
Derived tmp(static_cast<Derived const*>(this));
return tmp -= n;
::
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (iterator_facade<Dr,V,TC,R,D> const&,
typename Derived::difference_type n);
template <class Dr, class V, class TC, class R, class D>
Derived operator+ (typename Derived::difference_type n,
iterator_facade<Dr,V,TC,R,D> const&);
:Effects:
::
Derived tmp(static_cast<Derived const*>(this));
return tmp += n;
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator ==(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``((Dr1 const&)lhs).equal((Dr2 const&)rhs)``.
Otherwise,
``((Dr2 const&)rhs).equal((Dr1 const&)lhs)``.
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator !=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``!((Dr1 const&)lhs).equal((Dr2 const&)rhs)``.
Otherwise,
``!((Dr2 const&)rhs).equal((Dr1 const&)lhs)``.
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) < 0``.
Otherwise,
``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) > 0``.
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator <=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) <= 0``.
Otherwise,
``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) >= 0``.
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) > 0``.
Otherwise,
``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) < 0``.
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,bool>::type
operator >=(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``((Dr1 const&)lhs).distance_to((Dr2 const&)rhs) >= 0``.
Otherwise,
``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs) <= 0``.
.. _minus:
::
template <class Dr1, class V1, class TC1, class R1, class D1,
class Dr2, class V2, class TC2, class R2, class D2>
typename enable_if_interoperable<Dr1,Dr2,difference>::type
operator -(iterator_facade<Dr1,V1,TC1,R1,D1> const& lhs,
iterator_facade<Dr2,V2,TC2,R2,D2> const& rhs);
:Return Type:
if ``is_convertible<Dr2,Dr1>::value``
then
``difference`` shall be
``iterator_traits<Dr1>::difference_type``.
Otherwise
``difference`` shall be ``iterator_traits<Dr2>::difference_type``
:Returns:
if ``is_convertible<Dr2,Dr1>::value``
then
``-((Dr1 const&)lhs).distance_to((Dr2 const&)rhs)``.
Otherwise,
``((Dr2 const&)rhs).distance_to((Dr1 const&)lhs)``.

View File

@ -6,201 +6,10 @@
<meta name="generator" content="Docutils 0.3.1: 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-12-02" />
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab, Zephyr Associates, Inc." />
<meta name="date" content="2004-01-19" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="new-iterator-concepts">
@ -212,13 +21,12 @@ ul.auto-toc {
<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;acm.org">witt&#64;acm.org</a></td></tr>
<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;styleadvisor.com">witt&#64;styleadvisor.com</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>
<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>, <a class="last reference" href="http://www.styleadvisor.com">Zephyr Associates, Inc.</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2003-12-02</td></tr>
<td>2004-01-19</td></tr>
<tr class="field"><th class="docinfo-name">Number:</th><td class="field-body">This is a revised version of <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1550.html">n1550</a>=03-0133, which was
accepted for Technical Report 1 by the C++ standard
committee's library working group. This proposal is a
@ -272,15 +80,16 @@ of iterators that are used in practice.</td>
<li><a class="reference" href="#forward-traversal-iterators-lib-forward-traversal-iterators" id="id18" name="id18">Forward Traversal Iterators [lib.forward.traversal.iterators]</a></li>
<li><a class="reference" href="#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators" id="id19" name="id19">Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]</a></li>
<li><a class="reference" href="#random-access-traversal-iterators-lib-random-access-traversal-iterators" id="id20" name="id20">Random Access Traversal Iterators [lib.random.access.traversal.iterators]</a></li>
<li><a class="reference" href="#interoperable-iterators-lib-interoperable-iterators" id="id21" name="id21">Interoperable Iterators [lib.interoperable.iterators]</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference" href="#addition-to-lib-iterator-synopsis" id="id21" name="id21">Addition to [lib.iterator.synopsis]</a></li>
<li><a class="reference" href="#addition-to-lib-iterator-traits" id="id22" name="id22">Addition to [lib.iterator.traits]</a></li>
<li><a class="reference" href="#addition-to-lib-iterator-synopsis" id="id22" name="id22">Addition to [lib.iterator.synopsis]</a></li>
<li><a class="reference" href="#addition-to-lib-iterator-traits" id="id23" name="id23">Addition to [lib.iterator.traits]</a></li>
</ul>
</li>
<li><a class="reference" href="#footnotes" id="id23" name="id23">Footnotes</a></li>
<li><a class="reference" href="#footnotes" id="id24" name="id24">Footnotes</a></li>
</ul>
</div>
<div class="section" id="motivation">
@ -380,11 +189,6 @@ made it). -DWA -->
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>Note that as currently specified, <tt class="literal"><span class="pre">istreambuf_iterator</span></tt> doesn't
meet the Readable Iterator requirements because its <tt class="literal"><span class="pre">value_type</span></tt>
is not convertible to its <tt class="literal"><span class="pre">reference</span></tt> type. We believe this to
be a defect in the standard; it should be fixed by changing its
<tt class="literal"><span class="pre">reference</span></tt> type from <tt class="literal"><span class="pre">value_type&amp;</span></tt> to <tt class="literal"><span class="pre">value_type</span> <span class="pre">const&amp;</span></tt>.</p>
<div class="section" id="possible-but-not-proposed-changes-to-the-working-paper">
<h2><a class="toc-backref" href="#id3" name="possible-but-not-proposed-changes-to-the-working-paper">Possible (but not proposed) Changes to the Working Paper</a></h2>
<p>The extensions in this paper suggest several changes we might make
@ -502,6 +306,12 @@ position comparison such as <tt class="literal"><span class="pre">operator==</sp
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>This proposal also includes a concept for specifying when an iterator
is interoperable with another iterator, in the sense that <tt class="literal"><span class="pre">int*</span></tt> is
interoperable with <tt class="literal"><span class="pre">int</span> <span class="pre">const*</span></tt>.</p>
<ul class="simple">
<li>Interoperable Iterators</li>
</ul>
<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>
@ -551,17 +361,18 @@ 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="#id11" 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>
for value type <tt class="literal"><span class="pre">T</span></tt> if, in addition to <tt class="literal"><span class="pre">X</span></tt> being Assignable and
Copy Constructible, 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>
<table border class="table">
<colgroup>
<col width="42%" />
<col width="29%" />
<col width="30%" />
<col width="28%" />
<col width="20%" />
<col width="52%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Readable Iterator Requirements (in addition to CopyConstructible)</th>
<tr><th colspan="3">Readable Iterator Requirements (in addition to Assignable and Copy Constructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
@ -574,43 +385,28 @@ member of type <tt class="literal"><span class="pre">T</span></tt>.</p>
<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><tt class="literal"><span class="pre">R</span></tt>, Convertible to
<tt class="literal"><span class="pre">T</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">*a</span></tt></td>
<td>Convertible to <tt class="literal"><span class="pre">R</span></tt>,
Convertible to <tt class="literal"><span class="pre">T</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">static_cast&lt;T&gt;(</span>
<span class="pre">static_cast&lt;R&gt;(*a)</span> <span class="pre">)</span></tt></td>
<td><tt class="literal"><span class="pre">T</span></tt></td>
<td>equivalent to
<tt class="literal"><span class="pre">static_cast&lt;T&gt;(*a)</span></tt></td>
<td>Convertible to <tt class="literal"><span class="pre">T</span></tt></td>
<td><dl class="first last">
<dt>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></dt>
<dd>is equivalent to <tt class="literal"><span class="pre">*b</span></tt>.</dd>
</dl>
</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>
<td>pre: <tt class="literal"><span class="pre">pre:</span> <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>
<!-- TR1: the originally-proposed requirement that typeof(*a) == R
was too restrictive. Now we just require that it's
convertible to R and that accessing a T through that conversion
is equivalent to accessing a T directly. -->
<!-- We won't say anything about iterator_traits<X>::reference until the DR is resolved. -JGS -->
<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="#id12" 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. Writable Iterators have an associated <em>set of value types</em>.</p>
if, in addition to <tt class="literal"><span class="pre">X</span></tt> being Copy Constructible, the following
expressions are valid and respect the stated semantics. Writable
Iterators have an associated <em>set of value types</em>.</p>
<table border class="table">
<colgroup>
<col width="37%" />
@ -618,7 +414,7 @@ semantics. Writable Iterators have an associated <em>set of value types</em>.</
<col width="42%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Writable Iterator Requirements (in addition to CopyConstructible)</th>
<tr><th colspan="3">Writable Iterator Requirements (in addition to Copy Constructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
@ -638,8 +434,8 @@ value types of <tt class="literal"><span class="pre">X</span></tt></td>
<div class="section" id="swappable-iterators-lib-swappable-iterators">
<h4><a class="toc-backref" href="#id13" 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>
if, in addition to <tt class="literal"><span class="pre">X</span></tt> being Copy Constructible, the following
expressions are valid and respect the stated semantics.</p>
<table border class="table">
<colgroup>
<col width="37%" />
@ -647,7 +443,7 @@ semantics.</p>
<col width="43%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Swappable Iterator Requirements (in addition to CopyConstructible)</th>
<tr><th colspan="3">Swappable Iterator Requirements (in addition to Copy Constructible)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
@ -669,29 +465,34 @@ exchanged</td>
</div>
<div class="section" id="lvalue-iterators-lib-lvalue-iterators">
<h4><a class="toc-backref" href="#id14" name="lvalue-iterators-lib-lvalue-iterators">Lvalue Iterators [lib.lvalue.iterators]</a></h4>
<p>The <em>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>
<p>The <em>Lvalue Iterator</em> concept adds the requirement that the return
type of <tt class="literal"><span class="pre">operator*</span></tt> type be a reference to the value type of the
iterator.</p>
<table border class="table">
<colgroup>
<col width="42%" />
<col width="14%" />
<col width="44%" />
<col width="22%" />
<col width="19%" />
<col width="59%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Lvalue Iterator Requirements</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion</th>
<th>Note/Assertion</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::reference</span></tt></td>
<tr><td><tt class="literal"><span class="pre">*a</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>
cv-qualification.
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>
</tbody>
</table>
@ -706,8 +507,9 @@ type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><s
<div class="section" id="incrementable-iterators-lib-incrementable-iterators">
<h4><a class="toc-backref" href="#id16" 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>
concept if, in addition to <tt class="literal"><span class="pre">X</span></tt> being Assignable and Copy
Constructible, the following expressions are valid and respect the
stated semantics.</p>
<table border class="table">
<colgroup>
<col width="39%" />
@ -738,7 +540,7 @@ semantics.</p>
</pre>
</td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<tr><td><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">incrementable_traversal_tag</span></tt></td>
<td>&nbsp;</td>
@ -786,7 +588,7 @@ relation over its domain</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>
<tr><td><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">single_pass_traversal_tag</span></tt></td>
<td>&nbsp;</td>
@ -799,16 +601,17 @@ single_pass_traversal_tag for consistency -->
<div class="section" id="forward-traversal-iterators-lib-forward-traversal-iterators">
<h4><a class="toc-backref" href="#id18" 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>
concept if, in addition to <tt class="literal"><span class="pre">X</span></tt> meeting the requirements of Default
Constructible and Single Pass Iterator, the following expressions are
valid and respect the stated semantics.</p>
<table border class="table">
<colgroup>
<col width="44%" />
<col width="39%" />
<col width="17%" />
<col width="38%" />
<col width="34%" />
<col width="27%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Forward Traversal Iterator Requirements (in addition to Single Pass Iterator)</th>
<tr><th colspan="3">Forward Traversal Iterator Requirements (in addition to Default Constructible and Single Pass Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
@ -818,24 +621,21 @@ semantics.</p>
<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>note: <tt class="literal"><span class="pre">u</span></tt> may
have a singular
value.</td>
<td>note: <tt class="literal"><span class="pre">u</span></tt> may have a
singular value.</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>
<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>
<tr><td><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">forward_traversal_tag</span></tt></td>
<td>&nbsp;</td>
@ -848,16 +648,18 @@ forward_traversal_tag for consistency -->
<div class="section" id="bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators">
<h4><a class="toc-backref" href="#id19" 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>
Iterator</em> concept if, in addition to <tt class="literal"><span class="pre">X</span></tt> meeting the requirements of
Forward Traversal Iterator, the following expressions are valid and
respect the stated semantics.</p>
<table border class="table">
<colgroup>
<col width="35%" />
<col width="44%" />
<col width="21%" />
<col width="38%" />
<col width="37%" />
<col width="25%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="3">Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator)</th>
<tr><th colspan="3">Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal
Iterator)</th>
</tr>
<tr><th>Expression</th>
<th>Return Type</th>
@ -889,7 +691,7 @@ implies <tt class="literal"><span class="pre">r</span> <span class="pre">==</spa
</pre>
</td>
</tr>
<tr><td><tt class="literal"><span class="pre">traversal_category&lt;X&gt;::type</span></tt></td>
<tr><td><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">bidirectional_traversal_tag</span></tt></td>
<td>&nbsp;</td>
@ -908,10 +710,10 @@ the stated semantics. In the table below, <tt class="literal"><span class="pre"
constant object of type <tt class="literal"><span class="pre">Distance</span></tt>.</p>
<table border class="table">
<colgroup>
<col width="31%" />
<col width="35%" />
<col width="18%" />
<col width="16%" />
<col width="28%" />
<col width="30%" />
<col width="23%" />
<col width="20%" />
</colgroup>
<thead valign="bottom">
<tr><th colspan="4">Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator)</th>
@ -1002,7 +804,7 @@ ordering relation</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>
<tr><td><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt></td>
<td>Convertible to
<tt class="literal"><span class="pre">random_access_traversal_tag</span></tt></td>
<td>&nbsp;</td>
@ -1013,10 +815,132 @@ ordering relation</td>
<!-- TR1: random_access_traversal_iterator_tag changed to
random_access_traversal_tag for consistency -->
</div>
<div class="section" id="interoperable-iterators-lib-interoperable-iterators">
<h4><a class="toc-backref" href="#id21" name="interoperable-iterators-lib-interoperable-iterators">Interoperable Iterators [lib.interoperable.iterators]</a></h4>
<p>A class or built-in type <tt class="literal"><span class="pre">X</span></tt> that models Single Pass Iterator is
<em>interoperable with</em> a class or built-in type <tt class="literal"><span class="pre">Y</span></tt> that also models
Single Pass Iterator if the following expressions are valid and
respect the stated semantics. In the tables below, <tt class="literal"><span class="pre">x</span></tt> is an object
of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">y</span></tt> is an object of type <tt class="literal"><span class="pre">Y</span></tt>, <tt class="literal"><span class="pre">Distance</span></tt> is
<tt class="literal"><span class="pre">iterator_traits&lt;Y&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>
<table border class="table">
<colgroup>
<col width="13%" />
<col width="27%" />
<col width="60%" />
</colgroup>
<thead valign="bottom">
<tr><th>Expression</th>
<th>Return Type</th>
<th>Assertion/Precondition/Postcondition</th>
</tr>
</thead>
<tbody valign="top">
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">=</span> <span class="pre">x</span></tt></td>
<td><tt class="literal"><span class="pre">Y</span></tt></td>
<td>post: <tt class="literal"><span class="pre">y</span> <span class="pre">==</span> <span class="pre">x</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">Y(x)</span></tt></td>
<td><tt class="literal"><span class="pre">Y</span></tt></td>
<td>post: <tt class="literal"><span class="pre">Y(x)</span> <span class="pre">==</span> <span class="pre">x</span></tt></td>
</tr>
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</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">y</span> <span class="pre">==</span> <span class="pre">x</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">x</span> <span class="pre">!=</span> <span class="pre">y</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">bool(a==b)</span> <span class="pre">!=</span> <span class="pre">bool(a!=b)</span></tt> over its domain.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">!=</span> <span class="pre">x</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">bool(a==b)</span> <span class="pre">!=</span> <span class="pre">bool(a!=b)</span></tt> over its domain.</td>
</tr>
</tbody>
</table>
<p>If <tt class="literal"><span class="pre">X</span></tt> and <tt class="literal"><span class="pre">Y</span></tt> both model Random Access Traversal Iterator then
the following additional requirements must be met.</p>
<table border class="table">
<colgroup>
<col width="12%" />
<col width="25%" />
<col width="23%" />
<col width="41%" />
</colgroup>
<thead valign="bottom">
<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">x</span> <span class="pre">&lt;</span> <span class="pre">y</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">y</span> <span class="pre">-</span> <span class="pre">x</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">y</span> <span class="pre">&lt;</span> <span class="pre">x</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">y</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">x</span> <span class="pre">&gt;</span> <span class="pre">y</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">y</span> <span class="pre">&lt;</span> <span class="pre">x</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">y</span> <span class="pre">&gt;</span> <span class="pre">x</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</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">x</span> <span class="pre">&gt;=</span> <span class="pre">y</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(x</span> <span class="pre">&lt;</span> <span class="pre">y)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">&gt;=</span> <span class="pre">x</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(y</span> <span class="pre">&lt;</span> <span class="pre">x)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">&lt;=</span> <span class="pre">y</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(x</span> <span class="pre">&gt;</span> <span class="pre">y)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">&lt;=</span> <span class="pre">x</span></tt></td>
<td>convertible to <tt class="literal"><span class="pre">bool</span></tt></td>
<td><tt class="literal"><span class="pre">!(y</span> <span class="pre">&gt;</span> <span class="pre">x)</span></tt></td>
<td>&nbsp;</td>
</tr>
<tr><td><tt class="literal"><span class="pre">y</span> <span class="pre">-</span> <span class="pre">x</span></tt></td>
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
<td><tt class="literal"><span class="pre">distance(Y(x),y)</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">x</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">y</span></tt>.
<tt class="literal"><span class="pre">y</span> <span class="pre">==</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">(y</span> <span class="pre">-</span> <span class="pre">x)</span></tt>.</td>
</tr>
<tr><td><tt class="literal"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">y</span></tt></td>
<td><tt class="literal"><span class="pre">Distance</span></tt></td>
<td><tt class="literal"><span class="pre">distance(y,Y(x))</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">y</span> <span class="pre">+</span> <span class="pre">n</span> <span class="pre">==</span> <span class="pre">x</span></tt>.
<tt class="literal"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span> <span class="pre">+</span> <span class="pre">(x</span> <span class="pre">-</span> <span class="pre">y)</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="section" id="addition-to-lib-iterator-synopsis">
<h2><a class="toc-backref" href="#id21" name="addition-to-lib-iterator-synopsis">Addition to [lib.iterator.synopsis]</a></h2>
<h2><a class="toc-backref" href="#id22" 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 is_readable_iterator;
@ -1030,28 +954,31 @@ struct random_access_traversal_tag : bidirectional_traversal_tag { };
</pre>
</div>
<div class="section" id="addition-to-lib-iterator-traits">
<h2><a class="toc-backref" href="#id22" name="addition-to-lib-iterator-traits">Addition to [lib.iterator.traits]</a></h2>
<p>The <tt class="literal"><span class="pre">is_readable_iterator</span></tt> and <tt class="literal"><span class="pre">iterator_traversal</span></tt> class
templates satisfy the <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">UnaryTypeTrait</a> requirements.</p>
<h2><a class="toc-backref" href="#id23" name="addition-to-lib-iterator-traits">Addition to [lib.iterator.traits]</a></h2>
<p>The <tt class="literal"><span class="pre">is_readable_iterator</span></tt> class
template satisfies the <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">UnaryTypeTrait</a> requirements.</p>
<p>Given an iterator type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">is_readable_iterator&lt;X&gt;::value</span></tt>
yields <tt class="literal"><span class="pre">true</span></tt> if, for an object <tt class="literal"><span class="pre">a</span></tt> of type <tt class="literal"><span class="pre">X</span></tt>, <tt class="literal"><span class="pre">*a</span></tt> is
convertible to <tt class="literal"><span class="pre">iterator_traits&lt;X&gt;::value_type</span></tt>, and <tt class="literal"><span class="pre">false</span></tt>
otherwise.</p>
<p><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::value_type</span></tt> is defined to be:</p>
<p><tt class="literal"><span class="pre">iterator_traversal&lt;X&gt;::type</span></tt> is</p>
<pre class="literal-block">
traversal-category(X) =
cat = iterator_traits&lt;X&gt;::iterator_category;
if (cat is convertible to incrementable_traversal_tag)
return cat;
else if (cat is convertible to random_access_iterator_tag)
<em>category-to-traversal</em>(iterator_traits&lt;X&gt;::iterator_category)
</pre>
<p>where <em>category-to-traversal</em> is defined as follows</p>
<a class="target" id="category-to-traversal" name="category-to-traversal"></a><pre class="literal-block">
<em>category-to-traversal</em>(C) =
if (C is convertible to incrementable_traversal_tag)
return C;
else if (C is convertible to random_access_iterator_tag)
return random_access_traversal_tag;
else if (cat is convertible to bidirectional_iterator_tag)
else if (C is convertible to bidirectional_iterator_tag)
return bidirectional_traversal_tag;
else if (cat is convertible to forward_iterator_tag)
else if (C is convertible to forward_iterator_tag)
return forward_traversal_tag;
else if (cat is convertible to input_iterator_tag)
else if (C is convertible to input_iterator_tag)
return single_pass_traversal_tag;
else if (cat is convertible to output_iterator_tag)
else if (C is convertible to output_iterator_tag)
return incrementable_traversal_tag;
else
<em>the program is ill-formed</em>
@ -1059,10 +986,10 @@ traversal-category(X) =
</div>
</div>
<div class="section" id="footnotes">
<h1><a class="toc-backref" href="#id23" name="footnotes">Footnotes</a></h1>
<p>The UnaryTypeTrait concept is defined in <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">n1519</a>; the LWG added the
requirement that specializations are derived from their nested
<tt class="literal"><span class="pre">::type</span></tt>.</p>
<h1><a class="toc-backref" href="#id24" name="footnotes">Footnotes</a></h1>
<p>The UnaryTypeTrait concept is defined in <a class="reference" href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm">n1519</a>; the LWG is
considering adding the requirement that specializations are derived
from their nested <tt class="literal"><span class="pre">::type</span></tt>.</p>
<!-- 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
@ -1075,7 +1002,6 @@ LocalWords: TraversalTag typename lvalues DWA Hmm JGS mis enum -->
<hr class="footer" />
<div class="footer">
<a class="reference" href="new-iter-concepts.rst">View document source</a>.
Generated on: 2003-12-02 14:41 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>

View File

@ -6,10 +6,9 @@
n1550_, the paper accepted by the LWG.
:Author: David Abrahams, Jeremy Siek, Thomas Witt
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@acm.org
:organization: `Boost Consulting`_, Indiana University `Open
Systems Lab`_, University of Hanover `Institute for
Transport Railway Operation and Construction`_
:Contact: dave@boost-consulting.com, jsiek@osl.iu.edu, witt@styleadvisor.com
:organization: `Boost Consulting`_, Indiana University `Open Systems
Lab`_, `Zephyr Associates, Inc.`_
:date: $Date$
:Number: This is a revised version of n1550_\ =03-0133, which was
@ -22,6 +21,7 @@
.. _`Boost Consulting`: http://www.boost-consulting.com
.. _`Open Systems Lab`: http://www.osl.iu.edu
.. _`Zephyr Associates, Inc.`: http://www.styleadvisor.com
.. _`Institute for Transport Railway Operation and Construction`:
http://www.ive.uni-hannover.de
@ -147,12 +147,6 @@ old requirements.
a tag that is not input_iterator_tag but that
is convertible to input_iterator_tag? -JGS
Note that as currently specified, ``istreambuf_iterator`` doesn't
meet the Readable Iterator requirements because its ``value_type``
is not convertible to its ``reference`` type. We believe this to
be a defect in the standard; it should be fixed by changing its
``reference`` type from ``value_type&`` to ``value_type const&``.
Possible (but not proposed) Changes to the Working Paper
========================================================
@ -291,6 +285,13 @@ 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.
This proposal also includes a concept for specifying when an iterator
is interoperable with another iterator, in the sense that ``int*`` is
interoperable with ``int const*``.
- Interoperable Iterators
The relationship between the new iterator concepts and the old are
given in the following diagram.
@ -355,38 +356,26 @@ Readable Iterators [lib.readable.iterators]
-------------------------------------------
A class or built-in type ``X`` models the *Readable Iterator* concept
for the value type ``T`` if the following expressions are valid and
respect the stated semantics. ``U`` is the type of any specified
member of type ``T``.
for value type ``T`` if, in addition to ``X`` being Assignable and
Copy Constructible, the following expressions are valid and respect
the stated semantics. ``U`` is the type of any specified member of
type ``T``.
+--------------------------------------------------------------------------------------+
|Readable Iterator Requirements (in addition to CopyConstructible) |
+-----------------------------------+------------------------+-------------------------+
|Expression |Return Type |Note/Precondition |
+===================================+========================+=========================+
|``iterator_traits<X>::value_type`` |``T`` |Any non-reference, |
| | |non-cv-qualified type |
+-----------------------------------+------------------------+-------------------------+
|``iterator_traits<X>::reference`` |``R``, Convertible to | |
| |``T`` | |
+-----------------------------------+------------------------+-------------------------+
|``*a`` |Convertible to ``R``, |pre: ``a`` is |
| |Convertible to ``T`` |dereferenceable. If ``a |
| | |== b`` then ``*a`` is |
| | |equivalent to ``*b`` |
+-----------------------------------+------------------------+-------------------------+
|``static_cast<T>( |``T`` |equivalent to |
|static_cast<R>(*a) )`` | |``static_cast<T>(*a)`` |
+-----------------------------------+------------------------+-------------------------+
|``a->m`` |``U&`` |pre: ``(*a).m`` is |
| | |well-defined. Equivalent|
| | |to ``(*a).m`` |
+-----------------------------------+------------------------+-------------------------+
+-----------------------------------------------------------------------------------------------------------------------------+
|Readable Iterator Requirements (in addition to Assignable and Copy Constructible) |
+-----------------------------------+------------------------+----------------------------------------------------------------+
|Expression |Return Type |Note/Precondition |
+===================================+========================+================================================================+
|``iterator_traits<X>::value_type`` |``T`` |Any non-reference, |
| | |non-cv-qualified type |
+-----------------------------------+------------------------+----------------------------------------------------------------+
|``*a`` | Convertible to ``T`` |pre: ``a`` is dereferenceable. If ``a == b`` then ``*a`` |
| | | is equivalent to ``*b``. |
+-----------------------------------+------------------------+----------------------------------------------------------------+
|``a->m`` |``U&`` |pre: ``pre: (*a).m`` is well-defined. Equivalent to ``(*a).m``. |
+-----------------------------------+------------------------+----------------------------------------------------------------+
.. TR1: the originally-proposed requirement that typeof(*a) == R
was too restrictive. Now we just require that it's
convertible to R and that accessing a T through that conversion
is equivalent to accessing a T directly.
.. We won't say anything about iterator_traits<X>::reference until the DR is resolved. -JGS
.. _Writable Iterator:
@ -394,11 +383,12 @@ Writable Iterators [lib.writable.iterators]
-------------------------------------------
A class or built-in type ``X`` models the *Writable Iterator* concept
if the following expressions are valid and respect the stated
semantics. Writable Iterators have an associated *set of value types*.
if, in addition to ``X`` being Copy Constructible, the following
expressions are valid and respect the stated semantics. Writable
Iterators have an associated *set of value types*.
+---------------------------------------------------------------------+
|Writable Iterator Requirements (in addition to CopyConstructible) |
|Writable Iterator Requirements (in addition to Copy Constructible) |
+-------------------------+--------------+----------------------------+
|Expression |Return Type |Precondition |
+=========================+==============+============================+
@ -411,11 +401,11 @@ Swappable Iterators [lib.swappable.iterators]
---------------------------------------------
A class or built-in type ``X`` models the *Swappable Iterator* concept
if the following expressions are valid and respect the stated
semantics.
if, in addition to ``X`` being Copy Constructible, the following
expressions are valid and respect the stated semantics.
+---------------------------------------------------------------------+
|Swappable Iterator Requirements (in addition to CopyConstructible) |
|Swappable Iterator Requirements (in addition to Copy Constructible) |
+-------------------------+-------------+-----------------------------+
|Expression |Return Type |Postcondition |
+=========================+=============+=============================+
@ -430,19 +420,25 @@ semantics.
Lvalue Iterators [lib.lvalue.iterators]
---------------------------------------
The *Lvalue Iterator* concept adds the requirement that the
``reference`` type be a reference to the value type of the iterator.
The *Lvalue Iterator* concept adds the requirement that the return
type of ``operator*`` type be a reference to the value type of the
iterator.
+-------------------------------------------------------------+
| Lvalue Iterator Requirements |
+-------------+-----------+-----------------------------------+
|Expression |Return Type|Note/Assertion |
+=============+===========+===================================+
|``*a`` | ``T&`` |``T`` is *cv* |
| | |``iterator_traits<X>::value_type`` |
| | |where *cv* is an optional |
| | |cv-qualification. |
| | |pre: ``a`` is |
| | |dereferenceable. If ``a |
| | |== b`` then ``*a`` is |
| | |equivalent to ``*b``. |
+-------------+-----------+-----------------------------------+
+---------------------------------------------------------------------------------+
| Lvalue Iterator Requirements |
+---------------------------------+-----------+-----------------------------------+
|Expression |Return Type|Assertion |
+=================================+===========+===================================+
|``iterator_traits<X>::reference``|``T&`` |``T`` is *cv* |
| | |``iterator_traits<X>::value_type`` |
| | |where *cv* is an optional |
| | |cv-qualification |
+---------------------------------+-----------+-----------------------------------+
Iterator Traversal Concepts [lib.iterator.traversal]
@ -458,8 +454,9 @@ Incrementable Iterators [lib.incrementable.iterators]
-----------------------------------------------------
A class or built-in type ``X`` models the *Incrementable Iterator*
concept if the following expressions are valid and respect the stated
semantics.
concept if, in addition to ``X`` being Assignable and Copy
Constructible, the following expressions are valid and respect the
stated semantics.
+-------------------------------------------------------------------------------------+
@ -478,7 +475,7 @@ semantics.
| | | return tmp; |
| | | } |
+--------------------------------+-------------------------------+--------------------+
|``traversal_category<X>::type`` |Convertible to | |
|``iterator_traversal<X>::type`` |Convertible to | |
| |``incrementable_traversal_tag``| |
+--------------------------------+-------------------------------+--------------------+
@ -510,7 +507,7 @@ semantics.
+--------------------------------+-----------------------------+---------------------------+
|``a != b`` |convertible to ``bool`` |``!(a == b)`` |
+--------------------------------+-----------------------------+---------------------------+
|``traversal_category<X>::type`` |Convertible to | |
|``iterator_traversal<X>::type`` |Convertible to | |
| |``single_pass_traversal_tag``| |
+--------------------------------+-----------------------------+---------------------------+
@ -522,31 +519,29 @@ Forward Traversal Iterators [lib.forward.traversal.iterators]
-------------------------------------------------------------
A class or built-in type ``X`` models the *Forward Traversal Iterator*
concept if the following expressions are valid and respect the stated
semantics.
concept if, in addition to ``X`` meeting the requirements of Default
Constructible and Single Pass Iterator, the following expressions are
valid and respect the stated semantics.
+-------------------------------------------------------------------------------------------+
|Forward Traversal Iterator Requirements (in addition to Single Pass Iterator) |
+---------------------------------------+-----------------------------------+---------------+
|Expression |Return Type |Assertion/Note |
+=======================================+===================================+===============+
|``X u;`` |``X&`` |note: ``u`` may|
| | |have a singular|
| | |value. |
+---------------------------------------+-----------------------------------+---------------+
|``++r`` |``X&`` |``r == s`` and |
| | |``r`` is |
| | |dereferenceable|
| | |implies ``++r |
| | |== ++s.`` |
+---------------------------------------+-----------------------------------+---------------+
|``iterator_traits<X>::difference_type``|A signed integral type representing| |
| |the distance between iterators | |
| | | |
+---------------------------------------+-----------------------------------+---------------+
|``traversal_category<X>::type`` |Convertible to | |
| |``forward_traversal_tag`` | |
+---------------------------------------+-----------------------------------+---------------+
+--------------------------------------------------------------------------------------------------------+
|Forward Traversal Iterator Requirements (in addition to Default Constructible and Single Pass Iterator) |
+---------------------------------------+-----------------------------------+----------------------------+
|Expression |Return Type |Assertion/Note |
+=======================================+===================================+============================+
|``X u;`` |``X&`` |note: ``u`` may have a |
| | |singular value. |
+---------------------------------------+-----------------------------------+----------------------------+
|``++r`` |``X&`` |``r == s`` and ``r`` is |
| | |dereferenceable implies |
| | |``++r == ++s.`` |
+---------------------------------------+-----------------------------------+----------------------------+
|``iterator_traits<X>::difference_type``|A signed integral type representing| |
| |the distance between iterators | |
| | | |
+---------------------------------------+-----------------------------------+----------------------------+
|``iterator_traversal<X>::type`` |Convertible to | |
| |``forward_traversal_tag`` | |
+---------------------------------------+-----------------------------------+----------------------------+
.. TR1: forward_traversal_iterator_tag changed to
forward_traversal_tag for consistency
@ -556,37 +551,39 @@ Bidirectional Traversal Iterators [lib.bidirectional.traversal.iterators]
-------------------------------------------------------------------------
A class or built-in type ``X`` models the *Bidirectional Traversal
Iterator* concept if the following expressions are valid and respect
the stated semantics.
Iterator* concept if, in addition to ``X`` meeting the requirements of
Forward Traversal Iterator, the following expressions are valid and
respect the stated semantics.
+--------------------------------------------------------------------------------------------------------+
|Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal Iterator) |
+------------------------------------+---------------------------------------------+---------------------+
|Expression |Return Type |Assertion/Semantics /|
| | |Pre-/Post-condition |
+====================================+=============================================+=====================+
|``--r`` |``X&`` |pre: there exists |
| | |``s`` such that ``r |
| | |== ++s``. post: |
| | |``s`` is |
| | |dereferenceable. |
| | |``--(++r) == r``. |
| | |``--r == --s`` |
| | |implies ``r == |
| | |s``. ``&r == &--r``. |
+------------------------------------+---------------------------------------------+---------------------+
|``r--`` |convertible to ``const X&`` |:: |
| | | |
| | | { |
| | | X tmp = r; |
| | | --r; |
| | | return tmp; |
| | | } |
+------------------------------------+---------------------------------------------+---------------------+
|``traversal_category<X>::type`` |Convertible to | |
| |``bidirectional_traversal_tag`` | |
| | | |
+------------------------------------+---------------------------------------------+---------------------+
+--------------------------------------------------------------------------------------+
|Bidirectional Traversal Iterator Requirements (in addition to Forward Traversal |
|Iterator) |
+--------------------------------+-------------------------------+---------------------+
|Expression |Return Type |Assertion/Semantics /|
| | |Pre-/Post-condition |
+================================+===============================+=====================+
|``--r`` |``X&`` |pre: there exists |
| | |``s`` such that ``r |
| | |== ++s``. post: |
| | |``s`` is |
| | |dereferenceable. |
| | |``--(++r) == r``. |
| | |``--r == --s`` |
| | |implies ``r == |
| | |s``. ``&r == &--r``. |
+--------------------------------+-------------------------------+---------------------+
|``r--`` |convertible to ``const X&`` |:: |
| | | |
| | | { |
| | | X tmp = r; |
| | | --r; |
| | | return tmp; |
| | | } |
+--------------------------------+-------------------------------+---------------------+
|``iterator_traversal<X>::type`` |Convertible to | |
| |``bidirectional_traversal_tag``| |
| | | |
+--------------------------------+-------------------------------+---------------------+
.. TR1: bidirectional_traversal_iterator_tag changed to
bidirectional_traversal_tag for consistency
@ -600,65 +597,125 @@ the stated semantics. In the table below, ``Distance`` is
``iterator_traits<X>::difference_type`` and ``n`` represents a
constant object of type ``Distance``.
+----------------------------------------------------------------------------------------------------------------------------------------------+
|Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator) |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|Expression |Return Type |Operational Semantics |Assertion/ |
| | | |Precondition |
+===========================================+=================================================+=========================+======================+
|``r += n`` |``X&`` |:: | |
| | | | |
| | | { | |
| | | Distance m = n; | |
| | | if (m >= 0) | |
| | | while (m--) | |
| | | ++r; | |
| | | else | |
| | | while (m++) | |
| | | --r; | |
| | | return r; | |
| | | } | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a + n``, ``n + a`` |``X`` |``{ X tmp = a; return tmp| |
| | |+= n; }`` | |
| | | | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``r -= n`` |``X&`` |``return r += -n`` | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a - n`` |``X`` |``{ X tmp = a; return tmp| |
| | |-= n; }`` | |
| | | | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``b - a`` |``Distance`` |``a < b ? distance(a,b) |pre: there exists a |
| | |: -distance(b,a)`` |value ``n`` of |
| | | |``Distance`` such that|
| | | |``a + n == b``. ``b |
| | | |== a + (b - a)``. |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a[n]`` |convertible to T |``*(a + n)`` |pre: a is a `readable |
| | | |iterator`_ |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a[n] = v`` |convertible to T |``*(a + n) = v`` |pre: a is a `writable |
| | | |iterator`_ |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a < b`` |convertible to ``bool`` |``b - a > 0`` |``<`` is a total |
| | | |ordering relation |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a > b`` |convertible to ``bool`` |``b < a`` |``>`` is a total |
| | | |ordering relation |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a >= b`` |convertible to ``bool`` |``!(a < b)`` | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``a <= b`` |convertible to ``bool`` |``!(a > b)`` | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
|``traversal_category<X>::type`` |Convertible to | | |
| |``random_access_traversal_tag`` | | |
+-------------------------------------------+-------------------------------------------------+-------------------------+----------------------+
+------------------------------------------------------------------------------------------------------------------+
|Random Access Traversal Iterator Requirements (in addition to Bidirectional Traversal Iterator) |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|Expression |Return Type |Operational Semantics |Assertion/ |
| | | |Precondition |
+===============================+=================================+=========================+======================+
|``r += n`` |``X&`` |:: | |
| | | | |
| | | { | |
| | | Distance m = n; | |
| | | if (m >= 0) | |
| | | while (m--) | |
| | | ++r; | |
| | | else | |
| | | while (m++) | |
| | | --r; | |
| | | return r; | |
| | | } | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a + n``, ``n + a`` |``X`` |``{ X tmp = a; return tmp| |
| | |+= n; }`` | |
| | | | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``r -= n`` |``X&`` |``return r += -n`` | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a - n`` |``X`` |``{ X tmp = a; return tmp| |
| | |-= n; }`` | |
| | | | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``b - a`` |``Distance`` |``a < b ? distance(a,b) |pre: there exists a |
| | |: -distance(b,a)`` |value ``n`` of |
| | | |``Distance`` such that|
| | | |``a + n == b``. ``b |
| | | |== a + (b - a)``. |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a[n]`` |convertible to T |``*(a + n)`` |pre: a is a `readable |
| | | |iterator`_ |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a[n] = v`` |convertible to T |``*(a + n) = v`` |pre: a is a `writable |
| | | |iterator`_ |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a < b`` |convertible to ``bool`` |``b - a > 0`` |``<`` is a total |
| | | |ordering relation |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a > b`` |convertible to ``bool`` |``b < a`` |``>`` is a total |
| | | |ordering relation |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a >= b`` |convertible to ``bool`` |``!(a < b)`` | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``a <= b`` |convertible to ``bool`` |``!(a > b)`` | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
|``iterator_traversal<X>::type``|Convertible to | | |
| |``random_access_traversal_tag`` | | |
+-------------------------------+---------------------------------+-------------------------+----------------------+
.. TR1: random_access_traversal_iterator_tag changed to
random_access_traversal_tag for consistency
Interoperable Iterators [lib.interoperable.iterators]
-----------------------------------------------------
A class or built-in type ``X`` that models Single Pass Iterator is
*interoperable with* a class or built-in type ``Y`` that also models
Single Pass Iterator if the following expressions are valid and
respect the stated semantics. In the tables below, ``x`` is an object
of type ``X``, ``y`` is an object of type ``Y``, ``Distance`` is
``iterator_traits<Y>::difference_type``, and ``n`` represents a
constant object of type ``Distance``.
+-----------+-----------------------+---------------------------------------------------+
|Expression |Return Type |Assertion/Precondition/Postcondition |
+===========+=======================+===================================================+
|``y = x`` |``Y`` |post: ``y == x`` |
+-----------+-----------------------+---------------------------------------------------+
|``Y(x)`` |``Y`` |post: ``Y(x) == x`` |
+-----------+-----------------------+---------------------------------------------------+
|``x == y`` |convertible to ``bool``|``==`` is an equivalence relation over its domain. |
+-----------+-----------------------+---------------------------------------------------+
|``y == x`` |convertible to ``bool``|``==`` is an equivalence relation over its domain. |
+-----------+-----------------------+---------------------------------------------------+
|``x != y`` |convertible to ``bool``|``bool(a==b) != bool(a!=b)`` over its domain. |
+-----------+-----------------------+---------------------------------------------------+
|``y != x`` |convertible to ``bool``|``bool(a==b) != bool(a!=b)`` over its domain. |
+-----------+-----------------------+---------------------------------------------------+
If ``X`` and ``Y`` both model Random Access Traversal Iterator then
the following additional requirements must be met.
+-----------+-----------------------+---------------------+--------------------------------------+
|Expression |Return Type |Operational Semantics|Assertion/ Precondition |
+===========+=======================+=====================+======================================+
|``x < y`` |convertible to ``bool``|``y - x > 0`` |``<`` is a total ordering relation |
+-----------+-----------------------+---------------------+--------------------------------------+
|``y < x`` |convertible to ``bool``|``x - y > 0`` |``<`` is a total ordering relation |
+-----------+-----------------------+---------------------+--------------------------------------+
|``x > y`` |convertible to ``bool``|``y < x`` |``>`` is a total ordering relation |
+-----------+-----------------------+---------------------+--------------------------------------+
|``y > x`` |convertible to ``bool``|``x < y`` |``>`` is a total ordering relation |
+-----------+-----------------------+---------------------+--------------------------------------+
|``x >= y`` |convertible to ``bool``|``!(x < y)`` | |
+-----------+-----------------------+---------------------+--------------------------------------+
|``y >= x`` |convertible to ``bool``|``!(y < x)`` | |
+-----------+-----------------------+---------------------+--------------------------------------+
|``x <= y`` |convertible to ``bool``|``!(x > y)`` | |
+-----------+-----------------------+---------------------+--------------------------------------+
|``y <= x`` |convertible to ``bool``|``!(y > x)`` | |
+-----------+-----------------------+---------------------+--------------------------------------+
|``y - x`` |``Distance`` |``distance(Y(x),y)`` |pre: there exists a value ``n`` of |
| | | |``Distance`` such that ``x + n == y``.|
| | | |``y == x + (y - x)``. |
+-----------+-----------------------+---------------------+--------------------------------------+
|``x - y`` |``Distance`` |``distance(y,Y(x))`` |pre: there exists a value ``n`` of |
| | | |``Distance`` such that ``y + n == x``.|
| | | |``x == y + (x - y)``. |
+-----------+-----------------------+---------------------+--------------------------------------+
Addition to [lib.iterator.synopsis]
===================================
@ -678,31 +735,38 @@ Addition to [lib.iterator.synopsis]
Addition to [lib.iterator.traits]
=================================
The ``is_readable_iterator`` and ``iterator_traversal`` class
templates satisfy the UnaryTypeTrait_ requirements.
The ``is_readable_iterator`` class
template satisfies the UnaryTypeTrait_ requirements.
Given an iterator type ``X``, ``is_readable_iterator<X>::value``
yields ``true`` if, for an object ``a`` of type ``X``, ``*a`` is
convertible to ``iterator_traits<X>::value_type``, and ``false``
otherwise.
``iterator_traversal<X>::value_type`` is defined to be:
``iterator_traversal<X>::type`` is
.. parsed-literal::
traversal-category(X) =
cat = iterator_traits<X>::iterator_category;
if (cat is convertible to incrementable_traversal_tag)
return cat;
else if (cat is convertible to random_access_iterator_tag)
*category-to-traversal*\ (iterator_traits<X>::iterator_category)
where *category-to-traversal* is defined as follows
.. _`category-to-traversal`:
.. parsed-literal::
*category-to-traversal*\ (C) =
if (C is convertible to incrementable_traversal_tag)
return C;
else if (C is convertible to random_access_iterator_tag)
return random_access_traversal_tag;
else if (cat is convertible to bidirectional_iterator_tag)
else if (C is convertible to bidirectional_iterator_tag)
return bidirectional_traversal_tag;
else if (cat is convertible to forward_iterator_tag)
else if (C is convertible to forward_iterator_tag)
return forward_traversal_tag;
else if (cat is convertible to input_iterator_tag)
else if (C is convertible to input_iterator_tag)
return single_pass_traversal_tag;
else if (cat is convertible to output_iterator_tag)
else if (C is convertible to output_iterator_tag)
return incrementable_traversal_tag;
else
*the program is ill-formed*
@ -714,9 +778,9 @@ otherwise.
.. _UnaryTypeTrait: n1519_
The UnaryTypeTrait concept is defined in n1519_; the LWG added the
requirement that specializations are derived from their nested
``::type``.
The UnaryTypeTrait concept is defined in n1519_; the LWG is
considering adding the requirement that specializations are derived
from their nested ``::type``.
.. _n1519: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1519.htm

View File

@ -7,200 +7,9 @@
<title>Permutation Iterator</title>
<meta name="author" content="Toon Knapen, David Abrahams, Roland Richter, Jeremy Siek" />
<meta name="organization" content="Boost Consulting, Indiana University Open Systems Lab" />
<meta name="date" content="2003-09-14" />
<meta name="date" content="2004-01-13" />
<meta name="copyright" content="Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved" />
<style type="text/css"><!--
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date$
:version: $Revision$
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
--></style>
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="permutation-iterator">
@ -217,7 +26,7 @@ ul.auto-toc {
<td><a class="first reference" href="http://www.boost-consulting.com">Boost Consulting</a>, Indiana University <a class="last reference" href="http://www.osl.iu.edu">Open Systems
Lab</a></td></tr>
<tr><th class="docinfo-name">Date:</th>
<td>2003-09-14</td></tr>
<td>2004-01-13</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright Toon Knapen, David Abrahams, Roland Richter, and Jeremy Siek 2003. All rights reserved</td></tr>
</tbody>
@ -226,26 +35,27 @@ Lab</a></td></tr>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">The permutation iterator adaptor provides a permuted view of a given
range. That is, the view includes every element of the given range but
in a potentially different order.</td>
</tr>
</tbody>
</table>
<p>The permutation iterator adaptor provides a permuted view of a given
range. That is, the view includes every element of the given range but
in a potentially different order.</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="#introduction" id="id4" name="id4">Introduction</a></li>
<li><a class="reference" href="#reference" id="id5" name="id5">Reference</a><ul>
<li><a class="reference" href="#permutation-iterator-requirements" id="id6" name="id6"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#permutation-iterator-operations" id="id7" name="id7"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></li>
<li><a class="reference" href="#introduction" id="id2" name="id2">Introduction</a></li>
<li><a class="reference" href="#reference" id="id3" name="id3">Reference</a><ul>
<li><a class="reference" href="#permutation-iterator-requirements" id="id4" name="id4"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#permutation-iterator-models" id="id5" name="id5"><tt class="literal"><span class="pre">permutation_iterator</span></tt> models</a></li>
<li><a class="reference" href="#permutation-iterator-operations" id="id6" name="id6"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></li>
</ul>
</li>
<li><a class="reference" href="#example" id="id7" name="id7">Example</a></li>
</ul>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id4" name="introduction">Introduction</a></h1>
<h1><a class="toc-backref" href="#id2" name="introduction">Introduction</a></h1>
<p>The adaptor takes two arguments:</p>
<blockquote>
<ul class="simple">
@ -265,20 +75,16 @@ end permutation iterator is completely defined by means of the
past-the-end iterator to the indices.</p>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id5" name="reference">Reference</a></h1>
<h1><a class="toc-backref" href="#id3" name="reference">Reference</a></h1>
<pre class="literal-block">
template&lt; class ElementIterator
, class IndexIterator
, class ValueT = use_default
, unsigned access = use_default_access
, class Traversal = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default &gt;
class permutation_iterator
: public iterator_adaptor&lt;...&gt;
{
typedef iterator_adaptor&lt;...&gt;
friend class iterator_core_access;
public:
permutation_iterator();
explicit permutation_iterator(ElementIterator x, IndexIterator y);
@ -289,31 +95,200 @@ public:
, typename enable_if_convertible&lt;OEIter, ElementIterator&gt;::type* = 0
, typename enable_if_convertible&lt;OIIter, IndexIterator&gt;::type* = 0
);
reference operator*() const;
permutation_iterator&amp; operator++();
ElementIterator const&amp; base() const;
private:
ElementIterator m_elt; // exposition only
IndexIterator m_order; // exposition only
};
template &lt;class ElementIterator, class IndexIterator&gt;
permutation_iterator&lt;ElementIterator, IndexIterator&gt;
make_permutation_iterator( ElementIterator e, IndexIterator i);
</pre>
<div class="section" id="permutation-iterator-requirements">
<h2><a class="toc-backref" href="#id6" name="permutation-iterator-requirements"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></h2>
<p><tt class="literal"><span class="pre">ElementIterator</span></tt> must be a model of <a class="reference" href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>.
<tt class="literal"><span class="pre">IndexIterator</span></tt> must at least be a model <a class="reference" href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>. The
value type of the <tt class="literal"><span class="pre">IndexIterator</span></tt> must be convertible to the
difference type of <tt class="literal"><span class="pre">ElementIterator</span></tt>.</p>
<h2><a class="toc-backref" href="#id4" name="permutation-iterator-requirements"><tt class="literal"><span class="pre">permutation_iterator</span></tt> requirements</a></h2>
<p><tt class="literal"><span class="pre">ElementIterator</span></tt> shall model Random Access Traversal Iterator.
<tt class="literal"><span class="pre">IndexIterator</span></tt> shall model Readable Iterator. The value type of
the <tt class="literal"><span class="pre">IndexIterator</span></tt> must be convertible to the difference type of
<tt class="literal"><span class="pre">ElementIterator</span></tt>.</p>
</div>
<div class="section" id="permutation-iterator-models">
<h2><a class="toc-backref" href="#id5" name="permutation-iterator-models"><tt class="literal"><span class="pre">permutation_iterator</span></tt> models</a></h2>
<p><tt class="literal"><span class="pre">permutation_iterator</span></tt> models the same iterator traversal concepts
as <tt class="literal"><span class="pre">IndexIterator</span></tt> and the same iterator access concepts as
<tt class="literal"><span class="pre">ElementIterator</span></tt>.</p>
<p>If <tt class="literal"><span class="pre">IndexIterator</span></tt> models Single Pass Iterator and
<tt class="literal"><span class="pre">ElementIterator</span></tt> models Readable Iterator then
<tt class="literal"><span class="pre">permutation_iterator</span></tt> models Input Iterator.</p>
<p>If <tt class="literal"><span class="pre">IndexIterator</span></tt> models Forward Traversal Iterator and
<tt class="literal"><span class="pre">ElementIterator</span></tt> models Readable Lvalue Iterator then
<tt class="literal"><span class="pre">permutation_iterator</span></tt> models Forward Iterator.</p>
<p>If <tt class="literal"><span class="pre">IndexIterator</span></tt> models Bidirectional Traversal Iterator and
<tt class="literal"><span class="pre">ElementIterator</span></tt> models Readable Lvalue Iterator then
<tt class="literal"><span class="pre">permutation_iterator</span></tt> models Bidirectional Iterator.</p>
<p>If <tt class="literal"><span class="pre">IndexIterator</span></tt> models Random Access Traversal Iterator and
<tt class="literal"><span class="pre">ElementIterator</span></tt> models Readable Lvalue Iterator then
<tt class="literal"><span class="pre">permutation_iterator</span></tt> models Random Access Iterator.</p>
<p><tt class="literal"><span class="pre">permutation_iterator&lt;E1,</span> <span class="pre">X,</span> <span class="pre">V1,</span> <span class="pre">C2,</span> <span class="pre">R1,</span> <span class="pre">D1&gt;</span></tt> is interoperable
with <tt class="literal"><span class="pre">permutation_iterator&lt;E2,</span> <span class="pre">Y,</span> <span class="pre">V2,</span> <span class="pre">C2,</span> <span class="pre">R2,</span> <span class="pre">D2&gt;</span></tt> if and only if
<tt class="literal"><span class="pre">X</span></tt> is interoperable with <tt class="literal"><span class="pre">Y</span></tt> and <tt class="literal"><span class="pre">E1</span></tt> is convertible
to <tt class="literal"><span class="pre">E2</span></tt>.</p>
</div>
<div class="section" id="permutation-iterator-operations">
<h2><a class="toc-backref" href="#id7" name="permutation-iterator-operations"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></h2>
<p>The permutation iterator implements the member functions and operators
required for the <a class="reference" href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a> concept. However, the
permutation iterator can only meet the complexity guarantees of the
same concept as the IndexIterator. Thus for instance, although the
permutation iterator provides <tt class="literal"><span class="pre">operator+=(distance)</span></tt>, this operation
will take linear time in case the IndexIterator is a model of
ForwardIterator instead of amortized constant time.</p>
<h2><a class="toc-backref" href="#id6" name="permutation-iterator-operations"><tt class="literal"><span class="pre">permutation_iterator</span></tt> operations</a></h2>
<p>In addition to those operations required by the concepts that
<tt class="literal"><span class="pre">permutation_iterator</span></tt> models, <tt class="literal"><span class="pre">permutation_iterator</span></tt> provides the
following operations.</p>
<p><tt class="literal"><span class="pre">permutation_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">Effects:</th><td class="field-body">Default constructs <tt class="literal"><span class="pre">m_elt</span></tt> and <tt class="literal"><span class="pre">m_order</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">explicit</span> <span class="pre">permutation_iterator(ElementIterator</span> <span class="pre">x,</span> <span class="pre">IndexIterator</span> <span class="pre">y);</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">Constructs <tt class="literal"><span class="pre">m_elt</span></tt> from <tt class="literal"><span class="pre">x</span></tt> and <tt class="literal"><span class="pre">m_order</span></tt> from <tt class="literal"><span class="pre">y</span></tt>.</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template&lt; class OEIter, class OIIter, class V, class C, class R, class D &gt;
permutation_iterator(
permutation_iterator&lt;OEIter, OIIter, V, C, R, D&gt; const&amp; r
, typename enable_if_convertible&lt;OEIter, ElementIterator&gt;::type* = 0
, typename enable_if_convertible&lt;OIIter, IndexIterator&gt;::type* = 0
);
</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">Effects:</th><td class="field-body">Constructs <tt class="literal"><span class="pre">m_elt</span></tt> from <tt class="literal"><span class="pre">r.m_elt</span></tt> and
<tt class="literal"><span class="pre">m_order</span></tt> from <tt class="literal"><span class="pre">y.m_order</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_elt</span> <span class="pre">+</span> <span class="pre">*m_order)</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">permutation_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_order</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">ElementIterator</span> <span class="pre">const&amp;</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_order</span></tt></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class ElementIterator, class IndexIterator&gt;
permutation_iterator&lt;ElementIterator, IndexIterator&gt;
make_permutation_iterator(ElementIterator e, IndexIterator i);
</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"><tt class="literal"><span class="pre">permutation_iterator&lt;ElementIterator,</span> <span class="pre">IndexIterator&gt;(e,</span> <span class="pre">i)</span></tt></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section" id="example">
<h1><a class="toc-backref" href="#id7" name="example">Example</a></h1>
<pre class="literal-block">
using namespace boost;
int i = 0;
typedef std::vector&lt; int &gt; element_range_type;
typedef std::list&lt; int &gt; index_type;
static const int element_range_size = 10;
static const int index_size = 4;
element_range_type elements( element_range_size );
for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.end() ; ++el_it)
*el_it = std::distance(elements.begin(), el_it);
index_type indices( index_size );
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it )
*i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
std::reverse( indices.begin(), indices.end() );
typedef permutation_iterator&lt; element_range_type::iterator, index_type::iterator &gt; permutation_type;
permutation_type begin = make_permutation_iterator( elements.begin(), indices.begin() );
permutation_type it = begin;
permutation_type end = make_permutation_iterator( elements.begin(), indices.end() );
std::cout &lt;&lt; &quot;The original range is : &quot;;
std::copy( elements.begin(), elements.end(), std::ostream_iterator&lt; int &gt;( std::cout, &quot; &quot; ) );
std::cout &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;The reindexing scheme is : &quot;;
std::copy( indices.begin(), indices.end(), std::ostream_iterator&lt; int &gt;( std::cout, &quot; &quot; ) );
std::cout &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;The permutated range is : &quot;;
std::copy( begin, end, std::ostream_iterator&lt; int &gt;( std::cout, &quot; &quot; ) );
std::cout &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;Elements at even indices in the permutation : &quot;;
it = begin;
for(i = 0; i &lt; index_size / 2 ; ++i, it+=2 ) std::cout &lt;&lt; *it &lt;&lt; &quot; &quot;;
std::cout &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;Permutation backwards : &quot;;
it = begin + (index_size);
assert( it != begin );
for( ; it-- != begin ; ) std::cout &lt;&lt; *it &lt;&lt; &quot; &quot;;
std::cout &lt;&lt; &quot;\n&quot;;
std::cout &lt;&lt; &quot;Iterate backward with stride 2 : &quot;;
it = begin + (index_size - 1);
for(i = 0 ; i &lt; index_size / 2 ; ++i, it-=2 ) std::cout &lt;&lt; *it &lt;&lt; &quot; &quot;;
std::cout &lt;&lt; &quot;\n&quot;;
</pre>
<p>The output is:</p>
<pre class="literal-block">
The original range is : 0 1 2 3 4 5 6 7 8 9
The reindexing scheme is : 9 8 7 6
The permutated range is : 9 8 7 6
Elements at even indices in the permutation : 9 7
Permutation backwards : 6 7 8 9
Iterate backward with stride 2 : 6 8
</pre>
<p>The source code for this example can be found <a class="reference" href="../example/permutation_iterator_example.cpp">here</a>.</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="permutation_iterator.rst">View document source</a>.
Generated on: 2003-11-24 05:00 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>

View File

@ -14,7 +14,7 @@
:abstract:
.. include:: permutation_iterator_abstract.rst
.. include:: permutation_iterator_abstract.rst
.. contents:: Table of Contents
@ -29,3 +29,9 @@ Reference
=========
.. include:: permutation_iterator_ref.rst
Example
=======
.. include:: permutation_iterator_eg.rst

View File

@ -3,15 +3,11 @@
template< class ElementIterator
, class IndexIterator
, class ValueT = use_default
, unsigned access = use_default_access
, class Traversal = use_default
, class CategoryT = use_default
, class ReferenceT = use_default
, class DifferenceT = use_default >
class permutation_iterator
: public iterator_adaptor<...>
{
typedef iterator_adaptor<...>
friend class iterator_core_access;
public:
permutation_iterator();
explicit permutation_iterator(ElementIterator x, IndexIterator y);
@ -22,34 +18,109 @@
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
reference operator*() const;
permutation_iterator& operator++();
ElementIterator const& base() const;
private:
ElementIterator m_elt; // exposition only
IndexIterator m_order; // exposition only
};
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator( ElementIterator e, IndexIterator i);
``permutation_iterator`` requirements
-------------------------------------
``ElementIterator`` must be a model of RandomAccessIterator__.
``IndexIterator`` must at least be a model ForwardIterator__. The
value type of the ``IndexIterator`` must be convertible to the
difference type of ``ElementIterator``.
__ http://www.sgi.com/tech/stl/RandomAccessIterator.html
__ http://www.sgi.com/tech/stl/ForwardIterator.html
``ElementIterator`` shall model Random Access Traversal Iterator.
``IndexIterator`` shall model Readable Iterator. The value type of
the ``IndexIterator`` must be convertible to the difference type of
``ElementIterator``.
``permutation_iterator`` models
-------------------------------
``permutation_iterator`` models the same iterator traversal concepts
as ``IndexIterator`` and the same iterator access concepts as
``ElementIterator``.
If ``IndexIterator`` models Single Pass Iterator and
``ElementIterator`` models Readable Iterator then
``permutation_iterator`` models Input Iterator.
If ``IndexIterator`` models Forward Traversal Iterator and
``ElementIterator`` models Readable Lvalue Iterator then
``permutation_iterator`` models Forward Iterator.
If ``IndexIterator`` models Bidirectional Traversal Iterator and
``ElementIterator`` models Readable Lvalue Iterator then
``permutation_iterator`` models Bidirectional Iterator.
If ``IndexIterator`` models Random Access Traversal Iterator and
``ElementIterator`` models Readable Lvalue Iterator then
``permutation_iterator`` models Random Access Iterator.
``permutation_iterator<E1, X, V1, C2, R1, D1>`` is interoperable
with ``permutation_iterator<E2, Y, V2, C2, R2, D2>`` if and only if
``X`` is interoperable with ``Y`` and ``E1`` is convertible
to ``E2``.
``permutation_iterator`` operations
-----------------------------------
The permutation iterator implements the member functions and operators
required for the `Random Access Iterator`__ concept. However, the
permutation iterator can only meet the complexity guarantees of the
same concept as the IndexIterator. Thus for instance, although the
permutation iterator provides ``operator+=(distance)``, this operation
will take linear time in case the IndexIterator is a model of
ForwardIterator instead of amortized constant time.
In addition to those operations required by the concepts that
``permutation_iterator`` models, ``permutation_iterator`` provides the
following operations.
``permutation_iterator();``
:Effects: Default constructs ``m_elt`` and ``m_order``.
``explicit permutation_iterator(ElementIterator x, IndexIterator y);``
:Effects: Constructs ``m_elt`` from ``x`` and ``m_order`` from ``y``.
::
template< class OEIter, class OIIter, class V, class C, class R, class D >
permutation_iterator(
permutation_iterator<OEIter, OIIter, V, C, R, D> const& r
, typename enable_if_convertible<OEIter, ElementIterator>::type* = 0
, typename enable_if_convertible<OIIter, IndexIterator>::type* = 0
);
:Effects: Constructs ``m_elt`` from ``r.m_elt`` and
``m_order`` from ``y.m_order``.
``reference operator*() const;``
:Returns: ``*(m_elt + *m_order)``
``permutation_iterator& operator++();``
:Effects: ``++m_order``
:Returns: ``*this``
``ElementIterator const& base() const;``
:Returns: ``m_order``
::
template <class ElementIterator, class IndexIterator>
permutation_iterator<ElementIterator, IndexIterator>
make_permutation_iterator(ElementIterator e, IndexIterator i);
:Returns: ``permutation_iterator<ElementIterator, IndexIterator>(e, i)``
__ http://www.sgi.com/tech/stl/RandomAccessIterator.html

View File

@ -7,9 +7,9 @@
<title>Reverse 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="2003-09-14" />
<meta name="date" content="2004-01-13" />
<meta name="copyright" content="Copyright David Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<link rel="stylesheet" href="../../../rst.css" type="text/css" />
<link rel="stylesheet" href="default.css" type="text/css" />
</head>
<body>
<div class="document" id="reverse-iterator">
@ -27,7 +27,7 @@
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>
<td>2004-01-13</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>
@ -36,27 +36,34 @@ Railway Operation and Construction</a></td></tr>
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">abstract:</th><td class="field-body"></td>
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">The reverse iterator adaptor iterates through the adapted iterator
range in the opposite direction.</td>
</tr>
</tbody>
</table>
<!-- I think we'd better strike the old reverse_iterator text from the standard, eh? -->
<p>The reverse iterator adaptor flips the direction of a base iterator's
motion. Invoking <tt class="literal"><span class="pre">operator++()</span></tt> moves the base iterator backward and
invoking <tt class="literal"><span class="pre">operator--()</span></tt> moves the base iterator forward.</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="#reverse-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#reverse-iterator-synopsis" id="id2" name="id2"><tt class="literal"><span class="pre">reverse_iterator</span></tt> synopsis</a></li>
<li><a class="reference" href="#reverse-iterator-requirements" id="id3" name="id3"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#reverse-iterator-models" id="id4" name="id4"><tt class="literal"><span class="pre">reverse_iterator</span></tt> models</a></li>
<li><a class="reference" href="#reverse-iterator-operations" id="id5" name="id5"><tt class="literal"><span class="pre">reverse_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="reverse-iterator-synopsis">
<h1><a class="toc-backref" href="#id2" name="reverse-iterator-synopsis"><tt class="literal"><span class="pre">reverse_iterator</span></tt> synopsis</a></h1>
<pre class="literal-block">
template &lt;class Iterator&gt;
class reverse_iterator :
public iterator_adaptor&lt; reverse_iterator&lt;Iterator&gt;, Iterator &gt;
class reverse_iterator
{
friend class iterator_core_access;
public:
typedef iterator_traits&lt;Iterator&gt;::value_type value_type;
typedef iterator_traits&lt;Iterator&gt;::reference reference;
typedef iterator_traits&lt;Iterator&gt;::pointer pointer;
typedef iterator_traits&lt;Iterator&gt;::difference_type difference_type;
typedef /* see below */ iterator_category;
reverse_iterator() {}
explicit reverse_iterator(Iterator x) ;
@ -65,33 +72,72 @@ public:
reverse_iterator&lt;OtherIterator&gt; const&amp; r
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
private: // as-if specification
typename reverse_iterator::reference dereference() const { return *prior(this-&gt;base()); }
void increment() { --this-&gt;base_reference(); }
void decrement() { ++this-&gt;base_reference(); }
void advance(typename reverse_iterator::difference_type n)
{
this-&gt;base_reference() += -n;
}
template &lt;class OtherIterator&gt;
typename reverse_iterator::difference_type
distance_to(reverse_iterator&lt;OtherIterator&gt; const&amp; y) const
{
return this-&gt;base_reference() - y.base();
}
Iterator const&amp; base() const;
reference operator*() const;
reverse_iterator&amp; operator++();
reverse_iterator&amp; operator--();
private:
Iterator m_iterator; // exposition
};
</pre>
<p>If <tt class="literal"><span class="pre">Iterator</span></tt> models Random Access Traversal Iterator and Readable
Lvalue Iterator, then <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>. Otherwise, if
<tt class="literal"><span class="pre">Iterator</span></tt> models Bidirectional Traversal Iterator and Readable
Lvalue Iterator, then <tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
<tt class="literal"><span class="pre">bidirectional_iterator_tag</span></tt>. Otherwise, <tt class="literal"><span class="pre">iterator_category</span></tt> is
convertible to <tt class="literal"><span class="pre">input_iterator_tag</span></tt>.</p>
</div>
<div class="section" id="reverse-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="reverse-iterator-requirements"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></h1>
<p>The base <tt class="literal"><span class="pre">Iterator</span></tt> must be a model of Bidirectional Traversal
Iterator. The resulting <tt class="literal"><span class="pre">reverse_iterator</span></tt> will be a model of the
most refined standard traversal and access concepts that are modeled
by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<h1><a class="toc-backref" href="#id3" name="reverse-iterator-requirements"><tt class="literal"><span class="pre">reverse_iterator</span></tt> requirements</a></h1>
<p><tt class="literal"><span class="pre">Iterator</span></tt> must be a model of Bidirectional Traversal Iterator. The
type <tt class="literal"><span class="pre">iterator_traits&lt;Iterator&gt;::reference</span></tt> must be the type of
<tt class="literal"><span class="pre">*i</span></tt>, where <tt class="literal"><span class="pre">i</span></tt> is an object of type <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
</div>
<div class="section" id="reverse-iterator-models">
<h1><a class="toc-backref" href="#id4" name="reverse-iterator-models"><tt class="literal"><span class="pre">reverse_iterator</span></tt> models</a></h1>
<p>A specialization of <tt class="literal"><span class="pre">reverse_iterator</span></tt> models the same iterator
traversal and iterator access concepts modeled by its <tt class="literal"><span class="pre">Iterator</span></tt>
argument. In addition, it may model old iterator concepts
specified in the following table:</p>
<table border class="table">
<colgroup>
<col width="53%" />
<col width="47%" />
</colgroup>
<thead valign="bottom">
<tr><th>If <tt class="literal"><span class="pre">I</span></tt> models</th>
<th>then <tt class="literal"><span class="pre">reverse_iterator&lt;I&gt;</span></tt> models</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Readable Lvalue Iterator,
Bidirectional Traversal Iterator</td>
<td>Bidirectional Iterator</td>
</tr>
<tr><td>Writable Lvalue Iterator,
Bidirectional Traversal Iterator</td>
<td>Mutable Bidirectional Iterator</td>
</tr>
<tr><td>Readable Lvalue Iterator,
Random Access Traversal Iterator</td>
<td>Random Access Iterator</td>
</tr>
<tr><td>Writable Lvalue Iterator,
Random Access Traversal Iterator</td>
<td>Mutable Random Access Iterator</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">reverse_iterator&lt;X&gt;</span></tt> is interoperable with
<tt class="literal"><span class="pre">reverse_iterator&lt;Y&gt;</span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is interoperable with
<tt class="literal"><span class="pre">Y</span></tt>.</p>
</div>
<div class="section" id="reverse-iterator-operations">
<h1><a class="toc-backref" href="#id5" name="reverse-iterator-operations"><tt class="literal"><span class="pre">reverse_iterator</span></tt> operations</a></h1>
<p>In addition to the operations required by the concepts modeled by
<tt class="literal"><span class="pre">reverse_iterator</span></tt>, <tt class="literal"><span class="pre">reverse_iterator</span></tt> provides the following
operations.</p>
<p><tt class="literal"><span class="pre">reverse_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -99,8 +145,8 @@ by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">Iterator</span></tt> must be Default Constructible.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with a
default constructed base object.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with <tt class="literal"><span class="pre">m_iterator</span></tt>
default constructed.</td>
</tr>
</tbody>
</table>
@ -109,8 +155,8 @@ default constructed base object.</td>
<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">reverse_iterator</span></tt> with a
base object copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs an instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> with
<tt class="literal"><span class="pre">m_iterator</span></tt> copy constructed from <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
@ -127,16 +173,108 @@ reverse_iterator(
<tbody valign="top">
<tr class="field"><th class="field-name">Requires:</th><td class="field-body"><tt class="literal"><span class="pre">OtherIterator</span></tt> is implicitly convertible to <tt class="literal"><span class="pre">Iterator</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body">An instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> that is a copy of <tt class="literal"><span class="pre">r</span></tt>.</td>
<tr class="field"><th class="field-name">Effects:</th><td class="field-body">Constructs instance of <tt class="literal"><span class="pre">reverse_iterator</span></tt> whose
<tt class="literal"><span class="pre">m_iterator</span></tt> subobject is constructed from <tt class="literal"><span class="pre">y.base()</span></tt>.</td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">const&amp;</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_iterator</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">Effects:</th><td class="field-body"></td>
</tr>
</tbody>
</table>
<pre class="literal-block">
Iterator tmp = m_iterator;
return *--tmp;
</pre>
<p><tt class="literal"><span class="pre">reverse_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_iterator</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">reverse_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_iterator</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>
<pre class="literal-block">
template &lt;class BidirectionalIterator&gt;
reverse_iterator&lt;BidirectionalIterator&gt;n
make_reverse_iterator(BidirectionalIterator 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">reverse_iterator&lt;BidirectionalIterator&gt;</span></tt>
with a <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>The following example prints an array of characters in reverse order
using <tt class="literal"><span class="pre">reverse_iterator</span></tt>.</p>
<pre class="literal-block">
char letters_[] = &quot;hello world!&quot;;
const int N = sizeof(letters_)/sizeof(char) - 1;
typedef char* base_iterator;
base_iterator letters(letters_);
std::cout &lt;&lt; &quot;original sequence of letters:\t\t\t&quot; &lt;&lt; letters_ &lt;&lt; std::endl;
boost::reverse_iterator&lt;base_iterator&gt;
reverse_letters_first(letters + N),
reverse_letters_last(letters);
std::cout &lt;&lt; &quot;sequence in reverse order:\t\t\t&quot;;
std::copy(reverse_letters_first, reverse_letters_last,
std::ostream_iterator&lt;char&gt;(std::cout));
std::cout &lt;&lt; std::endl;
std::cout &lt;&lt; &quot;sequence in double-reversed (normal) order:\t&quot;;
std::copy(boost::make_reverse_iterator(reverse_letters_last),
boost::make_reverse_iterator(reverse_letters_first),
std::ostream_iterator&lt;char&gt;(std::cout));
std::cout &lt;&lt; std::endl;
</pre>
<p>The output is:</p>
<pre class="literal-block">
original sequence of letters: hello world!
sequence in reverse order: !dlrow olleh
sequence in double-reversed (normal) order: hello world!
</pre>
<p>The source code for this example can be found <a class="reference" href="../example/reverse_iterator_example.cpp">here</a>.</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="reverse_iterator.rst">View document source</a>.
Generated on: 2003-09-21 09:35 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>

View File

@ -16,8 +16,14 @@
:abstract:
.. include:: reverse_iterator_abstract.rst
.. include:: reverse_iterator_abstract.rst
.. contents:: Table of Contents
``reverse_iterator`` synopsis
.............................
.. include:: reverse_iterator_ref.rst
.. include:: make_reverse_iterator.rst
.. include:: reverse_iterator_eg.rst

View File

@ -1,6 +1,9 @@
.. I think we'd better strike the old reverse_iterator text from the standard, eh?
The reverse iterator adaptor flips the direction of a base iterator's
motion. Invoking ``operator++()`` moves the base iterator backward and
invoking ``operator--()`` moves the base iterator forward.
The reverse iterator adaptor iterates through the adapted iterator
range in the opposite direction.

View File

@ -1,11 +1,15 @@
::
template <class Iterator>
class reverse_iterator :
public iterator_adaptor< reverse_iterator<Iterator>, Iterator >
class reverse_iterator
{
friend class iterator_core_access;
public:
typedef iterator_traits<Iterator>::value_type value_type;
typedef iterator_traits<Iterator>::reference reference;
typedef iterator_traits<Iterator>::pointer pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
reverse_iterator() {}
explicit reverse_iterator(Iterator x) ;
@ -14,47 +18,82 @@
reverse_iterator<OtherIterator> const& r
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0 // exposition
);
private: // as-if specification
typename reverse_iterator::reference dereference() const { return *prior(this->base()); }
void increment() { --this->base_reference(); }
void decrement() { ++this->base_reference(); }
void advance(typename reverse_iterator::difference_type n)
{
this->base_reference() += -n;
}
template <class OtherIterator>
typename reverse_iterator::difference_type
distance_to(reverse_iterator<OtherIterator> const& y) const
{
return this->base_reference() - y.base();
}
Iterator const& base() const;
reference operator*() const;
reverse_iterator& operator++();
reverse_iterator& operator--();
private:
Iterator m_iterator; // exposition
};
If ``Iterator`` models Random Access Traversal Iterator and Readable
Lvalue Iterator, then ``iterator_category`` is convertible to
``random_access_iterator_tag``. Otherwise, if
``Iterator`` models Bidirectional Traversal Iterator and Readable
Lvalue Iterator, then ``iterator_category`` is convertible to
``bidirectional_iterator_tag``. Otherwise, ``iterator_category`` is
convertible to ``input_iterator_tag``.
``reverse_iterator`` requirements
.................................
The base ``Iterator`` must be a model of Bidirectional Traversal
Iterator. The resulting ``reverse_iterator`` will be a model of the
most refined standard traversal and access concepts that are modeled
by ``Iterator``.
``Iterator`` must be a model of Bidirectional Traversal Iterator. The
type ``iterator_traits<Iterator>::reference`` must be the type of
``*i``, where ``i`` is an object of type ``Iterator``.
``reverse_iterator`` models
...........................
A specialization of ``reverse_iterator`` models the same iterator
traversal and iterator access concepts modeled by its ``Iterator``
argument. In addition, it may model old iterator concepts
specified in the following table:
+---------------------------------------+-----------------------------------+
| If ``I`` models |then ``reverse_iterator<I>`` models|
+=======================================+===================================+
| Readable Lvalue Iterator, | Bidirectional Iterator |
| Bidirectional Traversal Iterator | |
+---------------------------------------+-----------------------------------+
| Writable Lvalue Iterator, | Mutable Bidirectional Iterator |
| Bidirectional Traversal Iterator | |
+---------------------------------------+-----------------------------------+
| Readable Lvalue Iterator, | Random Access Iterator |
| Random Access Traversal Iterator | |
+---------------------------------------+-----------------------------------+
| Writable Lvalue Iterator, | Mutable Random Access Iterator |
| Random Access Traversal Iterator | |
+---------------------------------------+-----------------------------------+
``reverse_iterator<X>`` is interoperable with
``reverse_iterator<Y>`` if and only if ``X`` is interoperable with
``Y``.
``reverse_iterator`` operations
...............................
In addition to the operations required by the concepts modeled by
``reverse_iterator``, ``reverse_iterator`` provides the following
operations.
``reverse_iterator();``
:Requires: ``Iterator`` must be Default Constructible.
:Returns: An instance of ``reverse_iterator`` with a
default constructed base object.
:Effects: Constructs an instance of ``reverse_iterator`` with ``m_iterator``
default constructed.
``explicit reverse_iterator(Iterator x);``
:Returns: An instance of ``reverse_iterator`` with a
base object copy constructed from ``x``.
:Effects: Constructs an instance of ``reverse_iterator`` with
``m_iterator`` copy constructed from ``x``.
::
@ -66,4 +105,33 @@ by ``Iterator``.
);
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
:Returns: An instance of ``reverse_iterator`` that is a copy of ``r``.
:Effects: Constructs instance of ``reverse_iterator`` whose
``m_iterator`` subobject is constructed from ``y.base()``.
``Iterator const& base() const;``
:Returns: ``m_iterator``
``reference operator*() const;``
:Effects:
::
Iterator tmp = m_iterator;
return *--tmp;
``reverse_iterator& operator++();``
:Effects: ``--m_iterator``
:Returns: ``*this``
``reverse_iterator& operator--();``
:Effects: ``++m_iterator``
:Returns: ``*this``

View File

@ -9,10 +9,14 @@ sources = [
'function_output_iterator.rst',
'index.rst',
'indirect_iterator.rst',
'pointee.rst',
'iterator_adaptor.rst',
'iterator_facade.rst',
'new-iter-concepts.rst',
'permutation_iterator.rst',
'reverse_iterator.rst'
'reverse_iterator.rst',
'transform_iterator.rst',
'zip_iterator.rst',
'iterator_archetypes.rst'
]

View File

@ -3,12 +3,12 @@
<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.3.0: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.3.1: http://docutils.sourceforge.net/" />
<title>Transform 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="2003-08-05" />
<meta name="copyright" content="Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved" />
<meta name="date" content="2004-01-13" />
<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>
@ -27,84 +27,145 @@
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-08-05</td></tr>
<td>2004-01-13</td></tr>
<tr><th class="docinfo-name">Copyright:</th>
<td>Copyright Dave Abrahams, Jeremy Siek, and Thomas Witt 2003. All rights reserved</td></tr>
<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"></td>
<tr class="field"><th class="field-name">abstract:</th><td class="field-body">The transform iterator adapts an iterator by modifying the
<tt class="literal"><span class="pre">operator*</span></tt> to apply a function object to the result of
dereferencing the iterator and returning the result.</td>
</tr>
</tbody>
</table>
<p>The transform iterator adapts an iterator by applying some function
object to the result of dereferencing the iterator. In other words,
the <tt class="literal"><span class="pre">operator*</span></tt> of the transform iterator first dereferences the
base iterator, passes the result of this to the function object, and
then returns the result.</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="#transform-iterator-requirements" id="id1" name="id1"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#transform-iterator-public-operations" id="id2" name="id2"><tt class="literal"><span class="pre">transform_iterator</span></tt> public operations</a></li>
<li><a class="reference" href="#transform-iterator-private-operations" id="id3" name="id3"><tt class="literal"><span class="pre">transform_iterator</span></tt> private operations</a></li>
<li><a class="reference" href="#transform-iterator-synopsis" id="id2" name="id2"><tt class="literal"><span class="pre">transform_iterator</span></tt> synopsis</a></li>
<li><a class="reference" href="#transform-iterator-requirements" id="id3" name="id3"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></li>
<li><a class="reference" href="#transform-iterator-models" id="id4" name="id4"><tt class="literal"><span class="pre">transform_iterator</span></tt> models</a></li>
<li><a class="reference" href="#transform-iterator-operations" id="id5" name="id5"><tt class="literal"><span class="pre">transform_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="transform-iterator-synopsis">
<h1><a class="toc-backref" href="#id2" name="transform-iterator-synopsis"><tt class="literal"><span class="pre">transform_iterator</span></tt> synopsis</a></h1>
<!-- Version 1.3 of this document was accepted for TR1 -->
<pre class="literal-block">
template &lt;class AdaptableUnaryFunction,
template &lt;class UnaryFunction,
class Iterator,
class Reference = use_default,
class Value = use_default&gt;
class transform_iterator
: public iterator_adaptor&lt;/* see discussion */&gt;
{
friend class iterator_core_access;
public:
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef iterator_traits&lt;Iterator&gt;::difference_type difference_type;
typedef /* see below */ iterator_category;
transform_iterator();
transform_iterator(Iterator const&amp; x, AdaptableUnaryFunction f);
transform_iterator(Iterator const&amp; x, UnaryFunction f);
template&lt;class OtherIterator, class R2, class V2&gt;
template&lt;class F2, class I2, class R2, class V2&gt;
transform_iterator(
transform_iterator&lt;AdaptableUnaryFunction, OtherIterator, R2, V2&gt; const&amp; t
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
transform_iterator&lt;F2, I2, R2, V2&gt; const&amp; t
, typename enable_if_convertible&lt;I2, Iterator&gt;::type* = 0 // exposition only
, typename enable_if_convertible&lt;F2, UnaryFunction&gt;::type* = 0 // exposition only
);
AdaptableUnaryFunction functor() const;
UnaryFunction functor() const;
Iterator const&amp; base() const;
reference operator*() const;
transform_iterator&amp; operator++();
transform_iterator&amp; operator--();
private:
typename transform_iterator::value_type dereference() const;
AdaptableUnaryFunction m_f;
Iterator m_iterator; // exposition only
UnaryFunction m_f; // exposition only
};
</pre>
<p>If <tt class="literal"><span class="pre">Reference</span></tt> is <tt class="literal"><span class="pre">use_default</span></tt> then the <tt class="literal"><span class="pre">reference</span></tt> member of
<tt class="literal"><span class="pre">transform_iterator</span></tt> is
<tt class="literal"><span class="pre">result_of&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.
Otherwise, <tt class="literal"><span class="pre">reference</span></tt> is <tt class="literal"><span class="pre">Reference</span></tt>.</p>
<p>If <tt class="literal"><span class="pre">Value</span></tt> is <tt class="literal"><span class="pre">use_default</span></tt> then the <tt class="literal"><span class="pre">value_type</span></tt> member is
<tt class="literal"><span class="pre">remove_cv&lt;remove_reference&lt;reference&gt;</span> <span class="pre">&gt;::type</span></tt>. Otherwise,
<tt class="literal"><span class="pre">value_type</span></tt> is <tt class="literal"><span class="pre">Value</span></tt>.</p>
<p>If <tt class="literal"><span class="pre">Iterator</span></tt> models Readable Lvalue Iterator and if <tt class="literal"><span class="pre">Iterator</span></tt>
models Random Access Traversal Iterator, then <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>. Otherwise, if
<tt class="literal"><span class="pre">Iterator</span></tt> models Bidirectional Traversal Iterator, then
<tt class="literal"><span class="pre">iterator_category</span></tt> is convertible to
<tt class="literal"><span class="pre">bidirectional_iterator_tag</span></tt>. Otherwise <tt class="literal"><span class="pre">iterator_category</span></tt> is
convertible to <tt class="literal"><span class="pre">forward_iterator_tag</span></tt>. If <tt class="literal"><span class="pre">Iterator</span></tt> does not
model Readable Lvalue Iterator then <tt class="literal"><span class="pre">iterator_category</span></tt> is
convertible to <tt class="literal"><span class="pre">input_iterator_tag</span></tt>.</p>
</div>
<div class="section" id="transform-iterator-requirements">
<h1><a class="toc-backref" href="#id1" name="transform-iterator-requirements"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
<p>The type <tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt> must be Assignable, Copy
Constructible, and the expression <tt class="literal"><span class="pre">f(x)</span></tt> must be valid where <tt class="literal"><span class="pre">f</span></tt>
is an object of type <tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt>, <tt class="literal"><span class="pre">x</span></tt> is an object of
type <tt class="literal"><span class="pre">AdaptableUnaryFunction::argument_type</span></tt>, and where the type of
<tt class="literal"><span class="pre">f(x)</span></tt> must be <tt class="literal"><span class="pre">AdaptableUnaryFunction::result_type</span></tt>.</p>
<p>The type <tt class="literal"><span class="pre">Iterator</span></tt> must at least model Readable Iterator. The
resulting <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined of the
following options that is also modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<h1><a class="toc-backref" href="#id3" name="transform-iterator-requirements"><tt class="literal"><span class="pre">transform_iterator</span></tt> requirements</a></h1>
<p>The type <tt class="literal"><span class="pre">UnaryFunction</span></tt> must be Assignable, Copy Constructible, and
the expression <tt class="literal"><span class="pre">f(*i)</span></tt> must be valid where <tt class="literal"><span class="pre">f</span></tt> is an object of
type <tt class="literal"><span class="pre">UnaryFunction</span></tt>, <tt class="literal"><span class="pre">i</span></tt> is an object of type <tt class="literal"><span class="pre">Iterator</span></tt>, and
where the type of <tt class="literal"><span class="pre">f(*i)</span></tt> must be
<tt class="literal"><span class="pre">result_of&lt;UnaryFunction(iterator_traits&lt;Iterator&gt;::reference)&gt;::type</span></tt>.</p>
<p>The argument <tt class="literal"><span class="pre">Iterator</span></tt> shall model Readable Iterator.</p>
</div>
<div class="section" id="transform-iterator-models">
<h1><a class="toc-backref" href="#id4" name="transform-iterator-models"><tt class="literal"><span class="pre">transform_iterator</span></tt> models</a></h1>
<p>The resulting <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined of the
following that is also modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<blockquote>
<ul class="simple">
<li>Writable Lvalue Iterator if the <tt class="literal"><span class="pre">result_type</span></tt> of the
<tt class="literal"><span class="pre">AdaptableUnaryFunction</span></tt> is a non-const reference.</li>
<li>Readable Lvalue Iterator if the <tt class="literal"><span class="pre">result_type</span></tt> is a const
reference.</li>
<li>Writable Lvalue Iterator if <tt class="literal"><span class="pre">transform_iterator::reference</span></tt> is a non-const reference.</li>
<li>Readable Lvalue Iterator if <tt class="literal"><span class="pre">transform_iterator::reference</span></tt> is a const reference.</li>
<li>Readable Iterator otherwise.</li>
</ul>
</blockquote>
<p>The <tt class="literal"><span class="pre">transform_iterator</span></tt> models the most refined standard traversal
concept that is modeled by <tt class="literal"><span class="pre">Iterator</span></tt>.</p>
<p>The <tt class="literal"><span class="pre">value_type</span></tt> of <tt class="literal"><span class="pre">transform_iterator</span></tt> is
<tt class="literal"><span class="pre">remove_reference&lt;result_type&gt;::type</span></tt>. The <tt class="literal"><span class="pre">reference</span></tt> type is
<tt class="literal"><span class="pre">result_type</span></tt>.</p>
concept that is modeled by the <tt class="literal"><span class="pre">Iterator</span></tt> argument.</p>
<p>If <tt class="literal"><span class="pre">transform_iterator</span></tt> is a model of Readable Lvalue Iterator then
it models the following original iterator concepts depending on what
the <tt class="literal"><span class="pre">Iterator</span></tt> argument models.</p>
<table border class="table">
<colgroup>
<col width="47%" />
<col width="53%" />
</colgroup>
<thead valign="bottom">
<tr><th>If <tt class="literal"><span class="pre">Iterator</span></tt> models</th>
<th>then <tt class="literal"><span class="pre">transform_iterator</span></tt> models</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Single Pass Iterator</td>
<td>Input Iterator</td>
</tr>
<tr><td>Forward Traversal Iterator</td>
<td>Forward Iterator</td>
</tr>
<tr><td>Bidirectional Traversal Iterator</td>
<td>Bidirectional Iterator</td>
</tr>
<tr><td>Random Access Traversal Iterator</td>
<td>Random Access Iterator</td>
</tr>
</tbody>
</table>
<p>If <tt class="literal"><span class="pre">transform_iterator</span></tt> models Writable Lvalue Iterator then it is a
mutable iterator (as defined in the old iterator requirements).</p>
<p><tt class="literal"><span class="pre">transform_iterator&lt;F1,</span> <span class="pre">X,</span> <span class="pre">R1,</span> <span class="pre">V1&gt;</span></tt> is interoperable with
<tt class="literal"><span class="pre">transform_iterator&lt;F2,</span> <span class="pre">Y,</span> <span class="pre">R2,</span> <span class="pre">V2&gt;</span></tt> if and only if <tt class="literal"><span class="pre">X</span></tt> is
interoperable with <tt class="literal"><span class="pre">Y</span></tt>.</p>
</div>
<div class="section" id="transform-iterator-public-operations">
<h1><a class="toc-backref" href="#id2" name="transform-iterator-public-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> public operations</a></h1>
<div class="section" id="transform-iterator-operations">
<h1><a class="toc-backref" href="#id5" name="transform-iterator-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> operations</a></h1>
<p>In addition to the operations required by the concepts modeled by
<tt class="literal"><span class="pre">transform_iterator</span></tt>, <tt class="literal"><span class="pre">transform_iterator</span></tt> provides the following
operations.</p>
<p><tt class="literal"><span class="pre">transform_iterator();</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
@ -115,7 +176,7 @@ and <tt class="literal"><span class="pre">m_iterator</span></tt> default constru
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">transform_iterator(Iterator</span> <span class="pre">const&amp;</span> <span class="pre">x,</span> <span class="pre">AdaptableUnaryFunction</span> <span class="pre">f);</span></tt></p>
<p><tt class="literal"><span class="pre">transform_iterator(Iterator</span> <span class="pre">const&amp;</span> <span class="pre">x,</span> <span class="pre">UnaryFunction</span> <span class="pre">f);</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
@ -128,7 +189,7 @@ initialized to <tt class="literal"><span class="pre">f</span></tt> and <tt class
<pre class="literal-block">
template&lt;class OtherIterator, class R2, class V2&gt;
transform_iterator(
transform_iterator&lt;AdaptableUnaryFunction, OtherIterator, R2, V2&gt; const&amp; t
transform_iterator&lt;UnaryFunction, OtherIterator, R2, V2&gt; const&amp; t
, typename enable_if_convertible&lt;OtherIterator, Iterator&gt;::type* = 0 // exposition
);
</pre>
@ -142,7 +203,7 @@ transform_iterator(
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">AdaptableUnaryFunction</span> <span class="pre">functor()</span> <span class="pre">const;</span></tt></p>
<p><tt class="literal"><span class="pre">UnaryFunction</span> <span class="pre">functor()</span> <span class="pre">const;</span></tt></p>
<table class="field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
@ -151,19 +212,116 @@ transform_iterator(
</tr>
</tbody>
</table>
</div>
<div class="section" id="transform-iterator-private-operations">
<h1><a class="toc-backref" href="#id3" name="transform-iterator-private-operations"><tt class="literal"><span class="pre">transform_iterator</span></tt> private operations</a></h1>
<p><tt class="literal"><span class="pre">typename</span> <span class="pre">transform_iterator::value_type</span> <span class="pre">dereference()</span> <span class="pre">const;</span></tt></p>
<p><tt class="literal"><span class="pre">Iterator</span> <span class="pre">const&amp;</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_f(transform_iterator::dereference());</span></tt></td>
<tr class="field"><th class="field-name">Returns:</th><td class="field-body"><tt class="literal"><span class="pre">m_iterator</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_f(*m_iterator)</span></tt></td>
</tr>
</tbody>
</table>
<p><tt class="literal"><span class="pre">transform_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_iterator</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">transform_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_iterator</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>
<pre class="literal-block">
template &lt;class UnaryFunction, class Iterator&gt;
transform_iterator&lt;UnaryFunction, Iterator&gt;
make_transform_iterator(Iterator it, UnaryFunction fun);
</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">transform_iterator&lt;UnaryFunction,</span> <span class="pre">Iterator&gt;</span></tt> with <tt class="literal"><span class="pre">m_f</span></tt>
initialized to <tt class="literal"><span class="pre">f</span></tt> and <tt class="literal"><span class="pre">m_iterator</span></tt> initialized to <tt class="literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
<pre class="literal-block">
template &lt;class UnaryFunction, class Iterator&gt;
transform_iterator&lt;UnaryFunction, Iterator&gt;
make_transform_iterator(Iterator it);
</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">transform_iterator&lt;UnaryFunction,</span> <span class="pre">Iterator&gt;</span></tt> with <tt class="literal"><span class="pre">m_f</span></tt>
default constructed and <tt class="literal"><span class="pre">m_iterator</span></tt> initialized to <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 is a simple example of using the transform_iterators class to
generate iterators that multiply (or add to) the value returned by
dereferencing the iterator. It would be cooler to use lambda library
in this example.</p>
<pre class="literal-block">
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
const int N = sizeof(x)/sizeof(int);
typedef boost::binder1st&lt; std::multiplies&lt;int&gt; &gt; Function;
typedef boost::transform_iterator&lt;Function, int*&gt; doubling_iterator;
doubling_iterator i(x, boost::bind1st(std::multiplies&lt;int&gt;(), 2)),
i_end(x + N, boost::bind1st(std::multiplies&lt;int&gt;(), 2));
std::cout &lt;&lt; &quot;multiplying the array by 2:&quot; &lt;&lt; std::endl;
while (i != i_end)
std::cout &lt;&lt; *i++ &lt;&lt; &quot; &quot;;
std::cout &lt;&lt; std::endl;
std::cout &lt;&lt; &quot;adding 4 to each element in the array:&quot; &lt;&lt; std::endl;
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus&lt;int&gt;(), 4)),
boost::make_transform_iterator(x + N, boost::bind1st(std::plus&lt;int&gt;(), 4)),
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">
multiplying the array by 2:
2 4 6 8 10 12 14 16
adding 4 to each element in the array:
5 6 7 8 9 10 11 12
</pre>
<p>The source code for this example can be found <a class="reference" href="../example/transform_iterator_example.cpp">here</a>.</p>
</div>
</div>
<hr class="footer" />
<div class="footer">
<a class="reference" href="transform_iterator.rst">View document source</a>.
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>

View File

@ -16,8 +16,13 @@
:abstract:
.. include:: transform_iterator_abstract.rst
.. include:: transform_iterator_abstract.rst
.. contents:: Table of Contents
``transform_iterator`` synopsis
...............................
.. include:: transform_iterator_ref.rst
.. include:: make_transform_iterator.rst
.. include:: transform_iterator_eg.rst

View File

@ -1,5 +1,3 @@
The transform iterator adapts an iterator by applying some function
object to the result of dereferencing the iterator. In other words,
the ``operator*`` of the transform iterator first dereferences the
base iterator, passes the result of this to the function object, and
then returns the result.
The transform iterator adapts an iterator by modifying the
``operator*`` to apply a function object to the result of
dereferencing the iterator and returning the result.

View File

@ -7,27 +7,55 @@
class Reference = use_default,
class Value = use_default>
class transform_iterator
: public iterator_adaptor</* see discussion */>
{
friend class iterator_core_access;
public:
typedef /* see below */ value_type;
typedef /* see below */ reference;
typedef /* see below */ pointer;
typedef iterator_traits<Iterator>::difference_type difference_type;
typedef /* see below */ iterator_category;
transform_iterator();
transform_iterator(Iterator const& x, UnaryFunction f);
template<class F2, class I2, class R2, class V2>
transform_iterator(
transform_iterator<F2, I2, R2, V2> const& t
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition
, typename enable_if_convertible<I2, Iterator>::type* = 0 // exposition only
, typename enable_if_convertible<F2, UnaryFunction>::type* = 0 // exposition only
);
UnaryFunction functor() const;
Iterator const& base() const;
reference operator*() const;
transform_iterator& operator++();
transform_iterator& operator--();
private:
typename transform_iterator::value_type dereference() const;
UnaryFunction m_f;
Iterator m_iterator; // exposition only
UnaryFunction m_f; // exposition only
};
If ``Reference`` is ``use_default`` then the ``reference`` member of
``transform_iterator`` is
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
Otherwise, ``reference`` is ``Reference``.
If ``Value`` is ``use_default`` then the ``value_type`` member is
``remove_cv<remove_reference<reference> >::type``. Otherwise,
``value_type`` is ``Value``.
If ``Iterator`` models Readable Lvalue Iterator and if ``Iterator``
models Random Access Traversal Iterator, then ``iterator_category`` is
convertible to ``random_access_iterator_tag``. Otherwise, if
``Iterator`` models Bidirectional Traversal Iterator, then
``iterator_category`` is convertible to
``bidirectional_iterator_tag``. Otherwise ``iterator_category`` is
convertible to ``forward_iterator_tag``. If ``Iterator`` does not
model Readable Lvalue Iterator then ``iterator_category`` is
convertible to ``input_iterator_tag``.
``transform_iterator`` requirements
...................................
@ -37,27 +65,55 @@ type ``UnaryFunction``, ``i`` is an object of type ``Iterator``, and
where the type of ``f(*i)`` must be
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
The type ``Iterator`` must at least model Readable Iterator. The
resulting ``transform_iterator`` models the most refined of the
following options that is also modeled by ``Iterator``.
The argument ``Iterator`` shall model Readable Iterator.
* Writable Lvalue Iterator if ``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`` is a non-const reference.
* Readable Lvalue Iterator if ``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type`` is a const
reference.
``transform_iterator`` models
.............................
The resulting ``transform_iterator`` models the most refined of the
following that is also modeled by ``Iterator``.
* Writable Lvalue Iterator if ``transform_iterator::reference`` is a non-const reference.
* Readable Lvalue Iterator if ``transform_iterator::reference`` is a const reference.
* Readable Iterator otherwise.
The ``transform_iterator`` models the most refined standard traversal
concept that is modeled by ``Iterator``.
concept that is modeled by the ``Iterator`` argument.
The ``reference`` type of ``transform_iterator`` is
``result_of<UnaryFunction(iterator_traits<Iterator>::reference)>::type``.
The ``value_type`` is ``remove_cv<remove_reference<reference> >::type``.
If ``transform_iterator`` is a model of Readable Lvalue Iterator then
it models the following original iterator concepts depending on what
the ``Iterator`` argument models.
``transform_iterator`` public operations
........................................
+-----------------------------------+---------------------------------------+
| If ``Iterator`` models | then ``transform_iterator`` models |
+===================================+=======================================+
| Single Pass Iterator | Input Iterator |
+-----------------------------------+---------------------------------------+
| Forward Traversal Iterator | Forward Iterator |
+-----------------------------------+---------------------------------------+
| Bidirectional Traversal Iterator | Bidirectional Iterator |
+-----------------------------------+---------------------------------------+
| Random Access Traversal Iterator | Random Access Iterator |
+-----------------------------------+---------------------------------------+
If ``transform_iterator`` models Writable Lvalue Iterator then it is a
mutable iterator (as defined in the old iterator requirements).
``transform_iterator<F1, X, R1, V1>`` is interoperable with
``transform_iterator<F2, Y, R2, V2>`` if and only if ``X`` is
interoperable with ``Y``.
``transform_iterator`` operations
.................................
In addition to the operations required by the concepts modeled by
``transform_iterator``, ``transform_iterator`` provides the following
operations.
``transform_iterator();``
@ -83,14 +139,30 @@ The ``value_type`` is ``remove_cv<remove_reference<reference> >::type``.
:Returns: An instance of ``transform_iterator`` that is a copy of ``t``.
:Requires: ``OtherIterator`` is implicitly convertible to ``Iterator``.
``UnaryFunction functor() const;``
:Returns: ``m_f``
``transform_iterator`` private operations
.........................................
``typename transform_iterator::value_type dereference() const;``
``Iterator const& base() const;``
:Returns: ``m_f(transform_iterator::dereference());``
:Returns: ``m_iterator``
``reference operator*() const;``
:Returns: ``m_f(*m_iterator)``
``transform_iterator& operator++();``
:Effects: ``++m_iterator``
:Returns: ``*this``
``transform_iterator& operator--();``
:Effects: ``--m_iterator``
:Returns: ``*this``