mirror of
https://github.com/saitohirga/WSJT-X.git
synced 2025-07-05 19:35:16 -04:00
1547 lines
163 KiB
HTML
1547 lines
163 KiB
HTML
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
|
<title>Generic Iterators</title>
|
|
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
|
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
|
|
<link rel="home" href="../index.html" title="Chapter 1. Boost.Iterator">
|
|
<link rel="up" href="../index.html" title="Chapter 1. Boost.Iterator">
|
|
<link rel="prev" href="concepts/concepts_traversal.html" title="Traversal">
|
|
<link rel="next" href="generic/adaptor.html" title="Iterator Adaptor">
|
|
</head>
|
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
|
<table cellpadding="2" width="100%"><tr>
|
|
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
|
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
|
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
|
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
|
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
|
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="concepts/concepts_traversal.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="generic/adaptor.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
|
</div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
|
<a name="iterator.generic"></a><a class="link" href="generic.html" title="Generic Iterators">Generic Iterators</a>
|
|
</h2></div></div></div>
|
|
<div class="toc"><dl class="toc">
|
|
<dt><span class="section"><a href="generic.html#iterator.generic.facade">Iterator Facade</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="generic.html#iterator.generic.facade.facade_reference">Reference</a></span></dt>
|
|
<dt><span class="section"><a href="generic.html#iterator.generic.facade.facade_tutorial">Tutorial</a></span></dt>
|
|
</dl></dd>
|
|
<dt><span class="section"><a href="generic/adaptor.html">Iterator Adaptor</a></span></dt>
|
|
<dd><dl>
|
|
<dt><span class="section"><a href="generic/adaptor.html#iterator.generic.adaptor.adaptor_reference">Reference</a></span></dt>
|
|
<dt><span class="section"><a href="generic/adaptor/adaptor_tutorial.html">Tutorial</a></span></dt>
|
|
</dl></dd>
|
|
</dl></div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h3 class="title">
|
|
<a name="iterator.generic.facade"></a><a class="link" href="generic.html#iterator.generic.facade" title="Iterator Facade">Iterator Facade</a>
|
|
</h3></div></div></div>
|
|
<div class="toc"><dl class="toc">
|
|
<dt><span class="section"><a href="generic.html#iterator.generic.facade.facade_reference">Reference</a></span></dt>
|
|
<dt><span class="section"><a href="generic.html#iterator.generic.facade.facade_tutorial">Tutorial</a></span></dt>
|
|
</dl></div>
|
|
<p>
|
|
While the iterator interface is rich, there is a core subset of the interface
|
|
that is necessary for all the functionality. We have identified the following
|
|
core behaviors for iterators:
|
|
</p>
|
|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
|
<li class="listitem">
|
|
dereferencing
|
|
</li>
|
|
<li class="listitem">
|
|
incrementing
|
|
</li>
|
|
<li class="listitem">
|
|
decrementing
|
|
</li>
|
|
<li class="listitem">
|
|
equality comparison
|
|
</li>
|
|
<li class="listitem">
|
|
random-access motion
|
|
</li>
|
|
<li class="listitem">
|
|
distance measurement
|
|
</li>
|
|
</ul></div>
|
|
<p>
|
|
In addition to the behaviors listed above, the core interface elements include
|
|
the associated types exposed through iterator traits: <code class="computeroutput"><span class="identifier">value_type</span></code>,
|
|
<code class="computeroutput"><span class="identifier">reference</span></code>, <code class="computeroutput"><span class="identifier">difference_type</span></code>, and <code class="computeroutput"><span class="identifier">iterator_category</span></code>.
|
|
</p>
|
|
<p>
|
|
Iterator facade uses the Curiously Recurring Template Pattern (CRTP) [Cop95]_
|
|
so that the user can specify the behavior of <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
in a derived class. Former designs used policy objects to specify the behavior,
|
|
but that approach was discarded for several reasons:
|
|
</p>
|
|
<p>
|
|
1. the creation and eventual copying of the policy object may create overhead
|
|
that can be avoided with the current approach.
|
|
</p>
|
|
<p>
|
|
2. The policy object approach does not allow for custom constructors on the
|
|
created iterator types, an essential feature if <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
should be used in other library implementations.
|
|
</p>
|
|
<p>
|
|
3. Without the use of CRTP, the standard requirement that an iterator's
|
|
<code class="computeroutput"><span class="keyword">operator</span><span class="special">++</span></code>
|
|
returns the iterator type itself would mean that all iterators built with
|
|
the library would have to be specializations of <code class="computeroutput"><span class="identifier">iterator_facade</span><span class="special"><...></span></code>, rather than something more descriptive
|
|
like <code class="computeroutput"><span class="identifier">indirect_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">*></span></code>.
|
|
Cumbersome type generator metafunctions would be needed to build new parameterized
|
|
iterators, and a separate <code class="computeroutput"><span class="identifier">iterator_adaptor</span></code>
|
|
layer would be impossible.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.h0"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.usage"></a></span><a class="link" href="generic.html#iterator.generic.facade.usage">Usage</a>
|
|
</h3>
|
|
<p>
|
|
The user of <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
derives his iterator class from a specialization of <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
and passes the derived iterator class as <code class="computeroutput"><span class="identifier">iterator_facade</span></code>'s
|
|
first template parameter. The order of the other template parameters have
|
|
been carefully chosen to take advantage of useful defaults. For example,
|
|
when defining a constant lvalue iterator, the user can pass a const-qualified
|
|
version of the iterator's <code class="computeroutput"><span class="identifier">value_type</span></code>
|
|
as <code class="computeroutput"><span class="identifier">iterator_facade</span></code>'s <code class="computeroutput"><span class="identifier">Value</span></code> parameter and omit the <code class="computeroutput"><span class="identifier">Reference</span></code> parameter which follows.
|
|
</p>
|
|
<p>
|
|
The derived iterator class must define member functions implementing the
|
|
iterator's core behaviors. The following table describes expressions which
|
|
are required to be valid depending on the category of the derived iterator
|
|
type. These member functions are described briefly below and in more detail
|
|
in the iterator facade requirements.
|
|
</p>
|
|
<div class="table">
|
|
<a name="iterator.generic.facade.core_interface"></a><p class="title"><b>Table 1.10. Core Interface</b></p>
|
|
<div class="table-contents"><table class="table" summary="Core Interface">
|
|
<colgroup>
|
|
<col>
|
|
<col>
|
|
</colgroup>
|
|
<thead><tr>
|
|
<th>
|
|
<p>
|
|
Expression
|
|
</p>
|
|
</th>
|
|
<th>
|
|
<p>
|
|
Effects
|
|
</p>
|
|
</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">i</span><span class="special">.</span><span class="identifier">dereference</span><span class="special">()</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Access the value referred to
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">i</span><span class="special">.</span><span class="identifier">equal</span><span class="special">(</span><span class="identifier">j</span><span class="special">)</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Compare for equality with <code class="computeroutput"><span class="identifier">j</span></code>
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">i</span><span class="special">.</span><span class="identifier">increment</span><span class="special">()</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Advance by one position
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">i</span><span class="special">.</span><span class="identifier">decrement</span><span class="special">()</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Retreat by one position
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">i</span><span class="special">.</span><span class="identifier">advance</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Advance by <code class="computeroutput"><span class="identifier">n</span></code> positions
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">i</span><span class="special">.</span><span class="identifier">distance_to</span><span class="special">(</span><span class="identifier">j</span><span class="special">)</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Measure the distance to <code class="computeroutput"><span class="identifier">j</span></code>
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table></div>
|
|
</div>
|
|
<br class="table-break"><p>
|
|
In addition to implementing the core interface functions, an iterator derived
|
|
from <code class="computeroutput"><span class="identifier">iterator_facade</span></code> typically
|
|
defines several constructors. To model any of the standard iterator concepts,
|
|
the iterator must at least have a copy constructor. Also, if the iterator
|
|
type <code class="computeroutput"><span class="identifier">X</span></code> is meant to be automatically
|
|
interoperate with another iterator type <code class="computeroutput"><span class="identifier">Y</span></code>
|
|
(as with constant and mutable iterators) then there must be an implicit conversion
|
|
from <code class="computeroutput"><span class="identifier">X</span></code> to <code class="computeroutput"><span class="identifier">Y</span></code>
|
|
or from <code class="computeroutput"><span class="identifier">Y</span></code> to <code class="computeroutput"><span class="identifier">X</span></code> (but not both), typically implemented
|
|
as a conversion constructor. Finally, if the iterator is to model Forward
|
|
Traversal Iterator or a more-refined iterator concept, a default constructor
|
|
is required.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.h1"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.iterator_core_access"></a></span><a class="link" href="generic.html#iterator.generic.facade.iterator_core_access">Iterator
|
|
Core Access</a>
|
|
</h3>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">iterator_facade</span></code> and the operator
|
|
implementations need to be able to access the core member functions in the
|
|
derived class. Making the core member functions public would expose an implementation
|
|
detail to the user. The design used here ensures that implementation details
|
|
do not appear in the public interface of the derived iterator type.
|
|
</p>
|
|
<p>
|
|
Preventing direct access to the core member functions has two advantages.
|
|
First, there is no possibility for the user to accidently use a member function
|
|
of the iterator when a member of the value_type was intended. This has been
|
|
an issue with smart pointer implementations in the past. The second and main
|
|
advantage is that library implementers can freely exchange a hand-rolled
|
|
iterator implementation for one based on <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
without fear of breaking code that was accessing the public core member functions
|
|
directly.
|
|
</p>
|
|
<p>
|
|
In a naive implementation, keeping the derived class' core member functions
|
|
private would require it to grant friendship to <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
and each of the seven operators. In order to reduce the burden of limiting
|
|
access, <code class="computeroutput"><span class="identifier">iterator_core_access</span></code>
|
|
is provided, a class that acts as a gateway to the core member functions
|
|
in the derived iterator class. The author of the derived class only needs
|
|
to grant friendship to <code class="computeroutput"><span class="identifier">iterator_core_access</span></code>
|
|
to make his core member functions available to the library.
|
|
</p>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">iterator_core_access</span></code> will
|
|
be typically implemented as an empty class containing only private static
|
|
member functions which invoke the iterator core member functions. There is,
|
|
however, no need to standardize the gateway protocol. Note that even if
|
|
<code class="computeroutput"><span class="identifier">iterator_core_access</span></code> used
|
|
public member functions it would not open a safety loophole, as every core
|
|
member function preserves the invariants of the iterator.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.h2"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.operator"></a></span><a class="link" href="generic.html#iterator.generic.facade.operator"><code class="computeroutput"><span class="keyword">operator</span><span class="special">\[\]</span></code></a>
|
|
</h3>
|
|
<p>
|
|
The indexing operator for a generalized iterator presents special challenges.
|
|
A random access iterator's <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code> is only required to return something convertible
|
|
to its <code class="computeroutput"><span class="identifier">value_type</span></code>. Requiring
|
|
that it return an lvalue would rule out currently-legal random-access iterators
|
|
which hold the referenced value in a data member (e.g. |counting|_), because
|
|
<code class="computeroutput"><span class="special">*(</span><span class="identifier">p</span><span class="special">+</span><span class="identifier">n</span><span class="special">)</span></code>
|
|
is a reference into the temporary iterator <code class="computeroutput"><span class="identifier">p</span><span class="special">+</span><span class="identifier">n</span></code>, which
|
|
is destroyed when <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>
|
|
returns.
|
|
</p>
|
|
<p>
|
|
.. |counting| replace:: <code class="computeroutput"><span class="identifier">counting_iterator</span></code>
|
|
</p>
|
|
<p>
|
|
Writable iterators built with <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
implement the semantics required by the preferred resolution to <code class="computeroutput"><span class="identifier">issue</span> <span class="number">299</span></code>_
|
|
and adopted by proposal n1550_: the result of <code class="computeroutput"><span class="identifier">p</span><span class="special">[</span><span class="identifier">n</span><span class="special">]</span></code>
|
|
is an object convertible to the iterator's <code class="computeroutput"><span class="identifier">value_type</span></code>,
|
|
and <code class="computeroutput"><span class="identifier">p</span><span class="special">[</span><span class="identifier">n</span><span class="special">]</span> <span class="special">=</span>
|
|
<span class="identifier">x</span></code> is equivalent to <code class="computeroutput"><span class="special">*(</span><span class="identifier">p</span> <span class="special">+</span>
|
|
<span class="identifier">n</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">x</span></code> (Note:
|
|
This result object may be implemented as a proxy containing a copy of <code class="computeroutput"><span class="identifier">p</span><span class="special">+</span><span class="identifier">n</span></code>).
|
|
This approach will work properly for any random-access iterator regardless
|
|
of the other details of its implementation. A user who knows more about the
|
|
implementation of her iterator is free to implement an <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code> that returns an lvalue in the derived iterator
|
|
class; it will hide the one supplied by <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
from clients of her iterator.
|
|
</p>
|
|
<p>
|
|
.. _n1550: http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1550.htm
|
|
</p>
|
|
<p>
|
|
.. _<code class="computeroutput"><span class="identifier">issue</span> <span class="number">299</span></code>:
|
|
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299
|
|
</p>
|
|
<p>
|
|
.. _<code class="computeroutput"><span class="keyword">operator</span> <span class="identifier">arrow</span></code>:
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.h3"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.operator0"></a></span><a class="link" href="generic.html#iterator.generic.facade.operator0"><code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code></a>
|
|
</h3>
|
|
<p>
|
|
The <code class="computeroutput"><span class="identifier">reference</span></code> type of a readable
|
|
iterator (and today's input iterator) need not in fact be a reference, so
|
|
long as it is convertible to the iterator's <code class="computeroutput"><span class="identifier">value_type</span></code>.
|
|
When the <code class="computeroutput"><span class="identifier">value_type</span></code> is a
|
|
class, however, it must still be possible to access members through <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code>.
|
|
Therefore, an iterator whose <code class="computeroutput"><span class="identifier">reference</span></code>
|
|
type is not in fact a reference must return a proxy containing a copy of
|
|
the referenced value from its <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code>.
|
|
</p>
|
|
<p>
|
|
The return types for <code class="computeroutput"><span class="identifier">iterator_facade</span></code>'s
|
|
<code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code>
|
|
and <code class="computeroutput"><span class="keyword">operator</span><span class="special">[]</span></code>
|
|
are not explicitly specified. Instead, those types are described in terms
|
|
of a set of requirements, which must be satisfied by the <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
implementation.
|
|
</p>
|
|
<p>
|
|
.. [Cop95] [Coplien, 1995] Coplien, J., Curiously Recurring Template Patterns,
|
|
C++ Report, February 1995, pp. 24-27.
|
|
</p>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h4 class="title">
|
|
<a name="iterator.generic.facade.facade_reference"></a><a class="link" href="generic.html#iterator.generic.facade.facade_reference" title="Reference">Reference</a>
|
|
</h4></div></div></div>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span>
|
|
<span class="keyword">class</span> <span class="identifier">Derived</span>
|
|
<span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Value</span>
|
|
<span class="special">,</span> <span class="keyword">class</span> <span class="identifier">CategoryOrTraversal</span>
|
|
<span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Reference</span> <span class="special">=</span> <span class="identifier">Value</span><span class="special">&</span>
|
|
<span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Difference</span> <span class="special">=</span> <span class="identifier">ptrdiff_t</span>
|
|
<span class="special">></span>
|
|
<span class="keyword">class</span> <span class="identifier">iterator_facade</span> <span class="special">{</span>
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">remove_const</span><span class="special"><</span><span class="identifier">Value</span><span class="special">>::</span><span class="identifier">type</span> <span class="identifier">value_type</span><span class="special">;</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">Reference</span> <span class="identifier">reference</span><span class="special">;</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">Value</span><span class="special">\*</span> <span class="identifier">pointer</span><span class="special">;</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">Difference</span> <span class="identifier">difference_type</span><span class="special">;</span>
|
|
<span class="keyword">typedef</span> <span class="comment">/* see below__ \*/</span> <span class="identifier">iterator_category</span><span class="special">;</span>
|
|
|
|
<span class="identifier">reference</span> <span class="keyword">operator</span><span class="special">\*()</span> <span class="keyword">const</span><span class="special">;</span>
|
|
<span class="comment">/* see below__ \*/</span> <span class="keyword">operator</span><span class="special">->()</span> <span class="keyword">const</span><span class="special">;</span>
|
|
<span class="comment">/* see below__ \*/</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">++();</span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">++(</span><span class="keyword">int</span><span class="special">);</span>
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">--();</span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">--(</span><span class="keyword">int</span><span class="special">);</span>
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">);</span>
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">);</span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
<span class="keyword">protected</span><span class="special">:</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">iterator_facade</span> <span class="identifier">iterator_facade</span><span class="special">\</span><span class="identifier">_</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
|
|
<span class="comment">// Comparison operators</span>
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span> <span class="comment">// exposition</span>
|
|
<span class="keyword">operator</span> <span class="special">==(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">!=(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special"><(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special"><=(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">>(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">>=(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="comment">// Iterator difference</span>
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="comment">/* see below__ \*/</span>
|
|
<span class="keyword">operator</span><span class="special">-(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
|
|
<span class="comment">// Iterator addition</span>
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D</span><span class="special">></span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">+</span> <span class="special">(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr</span><span class="special">,</span><span class="identifier">V</span><span class="special">,</span><span class="identifier">TC</span><span class="special">,</span><span class="identifier">R</span><span class="special">,</span><span class="identifier">D</span><span class="special">></span> <span class="keyword">const</span><span class="special">&,</span>
|
|
<span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">::</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D</span><span class="special">></span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">+</span> <span class="special">(</span><span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">::</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr</span><span class="special">,</span><span class="identifier">V</span><span class="special">,</span><span class="identifier">TC</span><span class="special">,</span><span class="identifier">R</span><span class="special">,</span><span class="identifier">D</span><span class="special">></span> <span class="keyword">const</span><span class="special">&);</span>
|
|
</pre>
|
|
<p>
|
|
__ <code class="computeroutput"><span class="identifier">iterator</span> <span class="identifier">category</span></code>_
|
|
</p>
|
|
<p>
|
|
__ <code class="computeroutput"><span class="keyword">operator</span> <span class="identifier">arrow</span></code>_
|
|
</p>
|
|
<p>
|
|
__ brackets_
|
|
</p>
|
|
<p>
|
|
__ minus_
|
|
</p>
|
|
<p>
|
|
.. _<code class="computeroutput"><span class="identifier">iterator</span> <span class="identifier">category</span></code>:
|
|
</p>
|
|
<p>
|
|
The <code class="computeroutput"><span class="identifier">iterator_category</span></code> member
|
|
of <code class="computeroutput"><span class="identifier">iterator_facade</span></code> is
|
|
</p>
|
|
<p>
|
|
.. parsed-literal::
|
|
</p>
|
|
<pre class="programlisting"><span class="special">*</span><span class="identifier">iterator</span><span class="special">-</span><span class="identifier">category</span><span class="special">*\</span> <span class="special">(</span><span class="identifier">CategoryOrTraversal</span><span class="special">,</span> <span class="identifier">value_type</span><span class="special">,</span> <span class="identifier">reference</span><span class="special">)</span>
|
|
</pre>
|
|
<p>
|
|
where <span class="bold"><strong>iterator-category</strong></span> is defined as
|
|
follows:
|
|
</p>
|
|
<p>
|
|
.. include:: facade_iterator_category.rst
|
|
</p>
|
|
<p>
|
|
The <code class="computeroutput"><span class="identifier">enable_if_interoperable</span></code>
|
|
template used above is for exposition purposes. The member operators should
|
|
only be in an overload set provided the derived types <code class="computeroutput"><span class="identifier">Dr1</span></code>
|
|
and <code class="computeroutput"><span class="identifier">Dr2</span></code> are interoperable,
|
|
meaning that at least one of the types is convertible to the other. The
|
|
<code class="computeroutput"><span class="identifier">enable_if_interoperable</span></code>
|
|
approach uses SFINAE to take the operators out of the overload set when
|
|
the types are not interoperable. The operators should behave <span class="bold"><strong>as-if</strong></span> <code class="computeroutput"><span class="identifier">enable_if_interoperable</span></code>
|
|
were defined to be:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">bool</span><span class="special">,</span> <span class="keyword">typename</span><span class="special">></span> <span class="identifier">enable_if_interoperable_impl</span>
|
|
<span class="special">{};</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> <span class="identifier">enable_if_interoperable_impl</span><span class="special"><</span><span class="keyword">true</span><span class="special">,</span><span class="identifier">T</span><span class="special">></span>
|
|
<span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span> <span class="special">};</span>
|
|
|
|
<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="keyword">struct</span> <span class="identifier">enable_if_interoperable</span>
|
|
<span class="special">:</span> <span class="identifier">enable_if_interoperable_impl</span><span class="special"><</span>
|
|
<span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">>::</span><span class="identifier">value</span> <span class="special">||</span> <span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span>
|
|
<span class="special">,</span> <span class="identifier">T</span>
|
|
<span class="special">></span>
|
|
<span class="special">{};</span>
|
|
</pre>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_reference.h0"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_reference.requirements"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_reference.requirements">Requirements</a>
|
|
</h3>
|
|
<p>
|
|
The following table describes the typical valid expressions on <code class="computeroutput"><span class="identifier">iterator_facade</span></code>'s <code class="computeroutput"><span class="identifier">Derived</span></code>
|
|
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
|
|
<code class="computeroutput"><span class="identifier">iterator_core_access</span></code>. In
|
|
addition, <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="identifier">iterator_facade</span><span class="special">*)</span></code>
|
|
shall be well-formed.
|
|
</p>
|
|
<p>
|
|
In the table below, <code class="computeroutput"><span class="identifier">F</span></code> is
|
|
<code class="computeroutput"><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">X</span><span class="special">,</span><span class="identifier">V</span><span class="special">,</span><span class="identifier">C</span><span class="special">,</span><span class="identifier">R</span><span class="special">,</span><span class="identifier">D</span><span class="special">></span></code>, <code class="computeroutput"><span class="identifier">a</span></code>
|
|
is an object of type <code class="computeroutput"><span class="identifier">X</span></code>,
|
|
<code class="computeroutput"><span class="identifier">b</span></code> and <code class="computeroutput"><span class="identifier">c</span></code>
|
|
are objects of type <code class="computeroutput"><span class="keyword">const</span> <span class="identifier">X</span></code>, <code class="computeroutput"><span class="identifier">n</span></code>
|
|
is an object of <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">difference_type</span></code>, <code class="computeroutput"><span class="identifier">y</span></code>
|
|
is a constant object of a single pass iterator type interoperable with
|
|
<code class="computeroutput"><span class="identifier">X</span></code>, and <code class="computeroutput"><span class="identifier">z</span></code>
|
|
is a constant object of a random access traversal iterator type interoperable
|
|
with <code class="computeroutput"><span class="identifier">X</span></code>.
|
|
</p>
|
|
<p>
|
|
.. _<code class="computeroutput"><span class="identifier">core</span> <span class="identifier">operations</span></code>:
|
|
</p>
|
|
<p>
|
|
.. topic:: <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
Core Operations
|
|
</p>
|
|
<div class="table">
|
|
<a name="iterator.generic.facade.facade_reference.core_operations"></a><p class="title"><b>Table 1.11. Core Operations</b></p>
|
|
<div class="table-contents"><table class="table" summary="Core Operations">
|
|
<colgroup>
|
|
<col>
|
|
<col>
|
|
<col>
|
|
<col>
|
|
</colgroup>
|
|
<thead><tr>
|
|
<th>
|
|
<p>
|
|
Expression
|
|
</p>
|
|
</th>
|
|
<th>
|
|
<p>
|
|
Return Type
|
|
</p>
|
|
</th>
|
|
<th>
|
|
<p>
|
|
Assertion/Note
|
|
</p>
|
|
</th>
|
|
<th>
|
|
<p>
|
|
Used to implement Iterator Concept(s)
|
|
</p>
|
|
</th>
|
|
</tr></thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">dereference</span><span class="special">()</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">reference</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Readable Iterator, Writable Iterator
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">equal</span><span class="special">(</span><span class="identifier">y</span><span class="special">)</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
convertible to bool
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
true iff <code class="computeroutput"><span class="identifier">c</span></code> and
|
|
<code class="computeroutput"><span class="identifier">y</span></code> refer to the
|
|
same position
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Single Pass Iterator
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">increment</span><span class="special">()</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
unused
|
|
</p>
|
|
</td>
|
|
<td>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Incrementable Iterator
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">decrement</span><span class="special">()</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
unused
|
|
</p>
|
|
</td>
|
|
<td>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Bidirectional Traversal Iterator
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">a</span><span class="special">.</span><span class="identifier">advance</span><span class="special">(</span><span class="identifier">n</span><span class="special">)</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
unused
|
|
</p>
|
|
</td>
|
|
<td>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Random Access Traversal Iterator
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">c</span><span class="special">.</span><span class="identifier">distance_to</span><span class="special">(</span><span class="identifier">z</span><span class="special">)</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
convertible to <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">difference_type</span></code>
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
equivalent to <code class="computeroutput"><span class="identifier">distance</span><span class="special">(</span><span class="identifier">c</span><span class="special">,</span> <span class="identifier">X</span><span class="special">(</span><span class="identifier">z</span><span class="special">))</span></code>.
|
|
</p>
|
|
</td>
|
|
<td>
|
|
<p>
|
|
Random Access Traversal Iterator
|
|
</p>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table></div>
|
|
</div>
|
|
<br class="table-break"><h3>
|
|
<a name="iterator.generic.facade.facade_reference.h1"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_reference.operations"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_reference.operations">Operations</a>
|
|
</h3>
|
|
<p>
|
|
The operations in this section are described in terms of operations on
|
|
the core interface of <code class="computeroutput"><span class="identifier">Derived</span></code>
|
|
which may be inaccessible (i.e. private). The implementation should access
|
|
these operations through member functions of class <code class="computeroutput"><span class="identifier">iterator_core_access</span></code>.
|
|
</p>
|
|
<pre class="programlisting"><span class="identifier">reference</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span><span class="special">;</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span> <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span>
|
|
<span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">)-></span><span class="identifier">dereference</span><span class="special">()</span></code>
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">operator</span><span class="special">->()</span> <span class="keyword">const</span><span class="special">;</span> <span class="special">(</span><span class="identifier">see</span> <span class="identifier">below__</span><span class="special">)</span>
|
|
</pre>
|
|
<p>
|
|
__ <code class="computeroutput"><span class="keyword">operator</span> <span class="identifier">arrow</span></code>_
|
|
</p>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span> If <code class="computeroutput"><span class="identifier">reference</span></code>
|
|
is a reference type, an object of type <code class="computeroutput"><span class="identifier">pointer</span></code>
|
|
equal to: <code class="computeroutput"><span class="special">&</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span>
|
|
<span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">)-></span><span class="identifier">dereference</span><span class="special">()</span></code>
|
|
Otherwise returns an object of unspecified type such that, <code class="computeroutput"><span class="special">(*</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span>
|
|
<span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">))-></span><span class="identifier">m</span></code> is equivalent to <code class="computeroutput"><span class="special">(</span><span class="identifier">w</span> <span class="special">=</span> <span class="special">**</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span>
|
|
<span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">),</span> <span class="identifier">w</span><span class="special">.</span><span class="identifier">m</span><span class="special">)</span></code> for some temporary object <code class="computeroutput"><span class="identifier">w</span></code> of type <code class="computeroutput"><span class="identifier">value_type</span></code>.
|
|
</p>
|
|
<p>
|
|
.. _brackets:
|
|
</p>
|
|
<pre class="programlisting"><span class="special">*</span><span class="identifier">unspecified</span><span class="special">*</span> <span class="keyword">operator</span><span class="special">[](</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span> an object convertible to <code class="computeroutput"><span class="identifier">value_type</span></code>. For constant objects <code class="computeroutput"><span class="identifier">v</span></code> of type <code class="computeroutput"><span class="identifier">value_type</span></code>,
|
|
and <code class="computeroutput"><span class="identifier">n</span></code> of type <code class="computeroutput"><span class="identifier">difference_type</span></code>, <code class="computeroutput"><span class="special">(*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">n</span><span class="special">]</span> <span class="special">=</span> <span class="identifier">v</span></code>
|
|
is equivalent to <code class="computeroutput"><span class="special">*(*</span><span class="keyword">this</span>
|
|
<span class="special">+</span> <span class="identifier">n</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">v</span></code>,
|
|
and <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&>((*</span><span class="keyword">this</span><span class="special">)[</span><span class="identifier">n</span><span class="special">])</span></code>
|
|
is equivalent to <code class="computeroutput"><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">value_type</span>
|
|
<span class="keyword">const</span><span class="special">&>(*(*</span><span class="keyword">this</span> <span class="special">+</span> <span class="identifier">n</span><span class="special">))</span></code>
|
|
</p>
|
|
<pre class="programlisting"><span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">++();</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">)-></span><span class="identifier">increment</span><span class="special">();</span>
|
|
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">);</span>
|
|
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">++(</span><span class="keyword">int</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="identifier">Derived</span> <span class="identifier">tmp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span> <span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">));</span>
|
|
<span class="special">++*</span><span class="keyword">this</span><span class="special">;</span>
|
|
<span class="keyword">return</span> <span class="identifier">tmp</span><span class="special">;</span>
|
|
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">--();</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">)-></span><span class="identifier">decrement</span><span class="special">();</span>
|
|
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">);</span>
|
|
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">--(</span><span class="keyword">int</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="identifier">Derived</span> <span class="identifier">tmp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span> <span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">));</span>
|
|
<span class="special">--*</span><span class="keyword">this</span><span class="special">;</span>
|
|
<span class="keyword">return</span> <span class="identifier">tmp</span><span class="special">;</span>
|
|
|
|
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">)-></span><span class="identifier">advance</span><span class="special">(</span><span class="identifier">n</span><span class="special">);</span>
|
|
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">);</span>
|
|
|
|
|
|
<span class="identifier">Derived</span><span class="special">&</span> <span class="keyword">operator</span><span class="special">-=(</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">)-></span><span class="identifier">advance</span><span class="special">(-</span><span class="identifier">n</span><span class="special">);</span>
|
|
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">);</span>
|
|
|
|
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="identifier">Derived</span> <span class="identifier">tmp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span> <span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">));</span>
|
|
<span class="keyword">return</span> <span class="identifier">tmp</span> <span class="special">-=</span> <span class="identifier">n</span><span class="special">;</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D</span><span class="special">></span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">+</span> <span class="special">(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr</span><span class="special">,</span><span class="identifier">V</span><span class="special">,</span><span class="identifier">TC</span><span class="special">,</span><span class="identifier">R</span><span class="special">,</span><span class="identifier">D</span><span class="special">></span> <span class="keyword">const</span><span class="special">&,</span>
|
|
<span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">::</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">);</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D</span><span class="special">></span>
|
|
<span class="identifier">Derived</span> <span class="keyword">operator</span><span class="special">+</span> <span class="special">(</span><span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">::</span><span class="identifier">difference_type</span> <span class="identifier">n</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr</span><span class="special">,</span><span class="identifier">V</span><span class="special">,</span><span class="identifier">TC</span><span class="special">,</span><span class="identifier">R</span><span class="special">,</span><span class="identifier">D</span><span class="special">></span> <span class="keyword">const</span><span class="special">&);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Effects:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> <span class="identifier">Derived</span> <span class="identifier">tmp</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">Derived</span> <span class="keyword">const</span><span class="special">*>(</span><span class="keyword">this</span><span class="special">));</span>
|
|
<span class="keyword">return</span> <span class="identifier">tmp</span> <span class="special">+=</span> <span class="identifier">n</span><span class="special">;</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">==(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">equal</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">equal</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span></code>.
|
|
</pre>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">!=(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">!((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">equal</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">!((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">equal</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span></code>.
|
|
</pre>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special"><(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special"><</span> <span class="number">0</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span> <span class="special">></span> <span class="number">0</span></code>.
|
|
</pre>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special"><=(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special"><=</span> <span class="number">0</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span> <span class="special">>=</span> <span class="number">0</span></code>.
|
|
</pre>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">>(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">></span> <span class="number">0</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span> <span class="special"><</span> <span class="number">0</span></code>.
|
|
</pre>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="keyword">bool</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">>=(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span> <span class="special">>=</span> <span class="number">0</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span> <span class="special"><=</span> <span class="number">0</span></code>.
|
|
</pre>
|
|
<p>
|
|
.. _minus:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Dr1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D1</span><span class="special">,</span>
|
|
<span class="keyword">class</span> <span class="identifier">Dr2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">V2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">TC2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">R2</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">D2</span><span class="special">></span>
|
|
<span class="keyword">typename</span> <span class="identifier">enable_if_interoperable</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">difference</span><span class="special">>::</span><span class="identifier">type</span>
|
|
<span class="keyword">operator</span> <span class="special">-(</span><span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">,</span><span class="identifier">V1</span><span class="special">,</span><span class="identifier">TC1</span><span class="special">,</span><span class="identifier">R1</span><span class="special">,</span><span class="identifier">D1</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">lhs</span><span class="special">,</span>
|
|
<span class="identifier">iterator_facade</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">V2</span><span class="special">,</span><span class="identifier">TC2</span><span class="special">,</span><span class="identifier">R2</span><span class="special">,</span><span class="identifier">D2</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Return Type:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="identifier">difference</span></code> shall be
|
|
<code class="computeroutput"><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">difference_type</span></code>.
|
|
|
|
Otherwise
|
|
<code class="computeroutput"><span class="identifier">difference</span></code> shall be <code class="computeroutput"><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">>::</span><span class="identifier">difference_type</span></code>
|
|
</pre>
|
|
<p>
|
|
<span class="bold"><strong>Returns:</strong></span>
|
|
</p>
|
|
<pre class="programlisting"> if <code class="computeroutput"><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">Dr2</span><span class="special">,</span><span class="identifier">Dr1</span><span class="special">>::</span><span class="identifier">value</span></code>
|
|
|
|
then
|
|
<code class="computeroutput"><span class="special">-((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">)</span></code>.
|
|
|
|
Otherwise,
|
|
<code class="computeroutput"><span class="special">((</span><span class="identifier">Dr2</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">rhs</span><span class="special">).</span><span class="identifier">distance_to</span><span class="special">((</span><span class="identifier">Dr1</span> <span class="keyword">const</span><span class="special">&)</span><span class="identifier">lhs</span><span class="special">)</span></code>.
|
|
</pre>
|
|
</div>
|
|
<div class="section">
|
|
<div class="titlepage"><div><div><h4 class="title">
|
|
<a name="iterator.generic.facade.facade_tutorial"></a><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial" title="Tutorial">Tutorial</a>
|
|
</h4></div></div></div>
|
|
<p>
|
|
In this section we'll walk through the implementation of a few iterators
|
|
using <code class="computeroutput"><span class="identifier">iterator_facade</span></code>,
|
|
based around the simple example of a linked list of polymorphic objects.
|
|
This example was inspired by a <a href="http://thread.gmane.org/gmane.comp.lib.boost.user/5100" target="_top"><code class="computeroutput"><span class="identifier">posting</span></code></a> by Keith Macdonald on
|
|
the <a href="http://www.boost.org/more/mailing_lists.htm#users" target="_top"><code class="computeroutput"><span class="identifier">Boost</span><span class="special">-</span><span class="identifier">Users</span></code></a> mailing list.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h0"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.the_problem"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.the_problem">The Problem</a>
|
|
</h3>
|
|
<p>
|
|
Say we've written a polymorphic linked list node base class:
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span>
|
|
|
|
<span class="keyword">struct</span> <span class="identifier">node_base</span>
|
|
<span class="special">{</span>
|
|
<span class="identifier">node_base</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">m_next</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="comment">// Each node manages all of its tail nodes</span>
|
|
<span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">node_base</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">delete</span> <span class="identifier">m_next</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="comment">// Access the rest of the list</span>
|
|
<span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">next</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">m_next</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="comment">// print to the stream</span>
|
|
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
|
|
|
<span class="comment">// double the value</span>
|
|
<span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">double_me</span><span class="special">()</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
|
|
|
<span class="keyword">void</span> <span class="identifier">append</span><span class="special">(</span><span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">m_next</span><span class="special">)</span>
|
|
<span class="identifier">m_next</span><span class="special">-></span><span class="identifier">append</span><span class="special">(</span><span class="identifier">p</span><span class="special">);</span>
|
|
<span class="keyword">else</span>
|
|
<span class="identifier">m_next</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">m_next</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<p>
|
|
Lists can hold objects of different types by linking together specializations
|
|
of the following template:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
|
<span class="keyword">struct</span> <span class="identifier">node</span> <span class="special">:</span> <span class="identifier">node_base</span>
|
|
<span class="special">{</span>
|
|
<span class="identifier">node</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">x</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_value</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
|
|
<span class="special">{}</span>
|
|
|
|
<span class="keyword">void</span> <span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">s</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span> <span class="identifier">s</span> <span class="special"><<</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">m_value</span><span class="special">;</span> <span class="special">}</span>
|
|
<span class="keyword">void</span> <span class="identifier">double_me</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">m_value</span> <span class="special">+=</span> <span class="identifier">m_value</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="identifier">T</span> <span class="identifier">m_value</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<p>
|
|
And we can print any node using the following streaming operator:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">inline</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="keyword">operator</span><span class="special"><<(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&</span> <span class="identifier">s</span><span class="special">,</span> <span class="identifier">node_base</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">n</span><span class="special">)</span>
|
|
<span class="special">{</span>
|
|
<span class="identifier">n</span><span class="special">.</span><span class="identifier">print</span><span class="special">(</span><span class="identifier">s</span><span class="special">);</span>
|
|
<span class="keyword">return</span> <span class="identifier">s</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
</pre>
|
|
<p>
|
|
Our first challenge is to build an appropriate iterator over these lists.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h1"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.a_basic_iterator_using_iterator_"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.a_basic_iterator_using_iterator_">A
|
|
Basic Iterator Using <code class="computeroutput"><span class="identifier">iterator_facade</span></code></a>
|
|
</h3>
|
|
<p>
|
|
We will construct a <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
class using inheritance from <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
to implement most of the iterator's operations.
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor"># include</span> <span class="string">"node.hpp"</span>
|
|
<span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">iterator_facade</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="keyword">class</span> <span class="identifier">node_iterator</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><...></span>
|
|
<span class="special">{</span>
|
|
<span class="special">...</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h2"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.template_arguments_for_iterator_"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.template_arguments_for_iterator_">Template
|
|
Arguments for <code class="computeroutput"><span class="identifier">iterator_facade</span></code></a>
|
|
</h3>
|
|
<p>
|
|
<code class="computeroutput"><span class="identifier">iterator_facade</span></code> has several
|
|
template parameters, so we must decide what types to use for the arguments.
|
|
The parameters are <code class="computeroutput"><span class="identifier">Derived</span></code>,
|
|
<code class="computeroutput"><span class="identifier">Value</span></code>, <code class="computeroutput"><span class="identifier">CategoryOrTraversal</span></code>,
|
|
<code class="computeroutput"><span class="identifier">Reference</span></code>, and <code class="computeroutput"><span class="identifier">Difference</span></code>.
|
|
</p>
|
|
<h4>
|
|
<a name="iterator.generic.facade.facade_tutorial.h3"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.derived"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.derived"><code class="computeroutput"><span class="identifier">Derived</span></code></a>
|
|
</h4>
|
|
<p>
|
|
Because <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
is meant to be used with the CRTP [Cop95]_ the first parameter is the iterator
|
|
class name itself, <code class="computeroutput"><span class="identifier">node_iterator</span></code>.
|
|
</p>
|
|
<h4>
|
|
<a name="iterator.generic.facade.facade_tutorial.h4"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.value"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.value"><code class="computeroutput"><span class="identifier">Value</span></code></a>
|
|
</h4>
|
|
<p>
|
|
The <code class="computeroutput"><span class="identifier">Value</span></code> parameter determines
|
|
the <code class="computeroutput"><span class="identifier">node_iterator</span></code>'s <code class="computeroutput"><span class="identifier">value_type</span></code>. In this case, we are iterating
|
|
over <code class="computeroutput"><span class="identifier">node_base</span></code> objects,
|
|
so <code class="computeroutput"><span class="identifier">Value</span></code> will be <code class="computeroutput"><span class="identifier">node_base</span></code>.
|
|
</p>
|
|
<h4>
|
|
<a name="iterator.generic.facade.facade_tutorial.h5"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.categoryortraversal"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.categoryortraversal"><code class="computeroutput"><span class="identifier">CategoryOrTraversal</span></code></a>
|
|
</h4>
|
|
<p>
|
|
Now we have to determine which <code class="computeroutput"><span class="identifier">iterator</span>
|
|
<span class="identifier">traversal</span> <span class="identifier">concept</span></code>_
|
|
our <code class="computeroutput"><span class="identifier">node_iterator</span></code> is going
|
|
to model. Singly-linked lists only have forward links, so our iterator
|
|
can't can't be a <code class="computeroutput"><span class="identifier">bidirectional</span>
|
|
<span class="identifier">traversal</span> <span class="identifier">iterator</span></code>_.
|
|
Our iterator should be able to make multiple passes over the same linked
|
|
list (unlike, say, an <code class="computeroutput"><span class="identifier">istream_iterator</span></code>
|
|
which consumes the stream it traverses), so it must be a <code class="computeroutput"><span class="identifier">forward</span> <span class="identifier">traversal</span>
|
|
<span class="identifier">iterator</span></code>_. Therefore, we'll pass
|
|
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span></code> in this position
|
|
<a name="category"></a>_.
|
|
</p>
|
|
<p>
|
|
.. <a name="category0"></a><code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
also supports old-style category tags, so we could have passed <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span></code> here; either way,
|
|
the resulting iterator's <code class="computeroutput"><span class="identifier">iterator_category</span></code>
|
|
will end up being <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span></code>.
|
|
</p>
|
|
<h4>
|
|
<a name="iterator.generic.facade.facade_tutorial.h6"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.reference"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.reference"><code class="computeroutput"><span class="identifier">Reference</span></code></a>
|
|
</h4>
|
|
<p>
|
|
The <code class="computeroutput"><span class="identifier">Reference</span></code> argument
|
|
becomes the type returned by <code class="computeroutput"><span class="identifier">node_iterator</span></code>'s
|
|
dereference operation, and will also be the same as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">node_iterator</span><span class="special">>::</span><span class="identifier">reference</span></code>.
|
|
The library's default for this parameter is <code class="computeroutput"><span class="identifier">Value</span><span class="special">&</span></code>; since <code class="computeroutput"><span class="identifier">node_base</span><span class="special">&</span></code> is a good choice for the iterator's
|
|
<code class="computeroutput"><span class="identifier">reference</span></code> type, we can
|
|
omit this argument, or pass <code class="computeroutput"><span class="identifier">use_default</span></code>.
|
|
</p>
|
|
<h4>
|
|
<a name="iterator.generic.facade.facade_tutorial.h7"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.difference"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.difference"><code class="computeroutput"><span class="identifier">Difference</span></code></a>
|
|
</h4>
|
|
<p>
|
|
The <code class="computeroutput"><span class="identifier">Difference</span></code> argument
|
|
determines how the distance between two <code class="computeroutput"><span class="identifier">node_iterator</span></code>s
|
|
will be measured and will also be the same as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special"><</span><span class="identifier">node_iterator</span><span class="special">>::</span><span class="identifier">difference_type</span></code>.
|
|
The library's default for <code class="computeroutput"><span class="identifier">Difference</span></code>
|
|
is <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span></code>, an appropriate type for measuring
|
|
the distance between any two addresses in memory, and one that works for
|
|
almost any iterator, so we can omit this argument, too.
|
|
</p>
|
|
<p>
|
|
The declaration of <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
will therefore look something like:
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor"># include</span> <span class="string">"node.hpp"</span>
|
|
<span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">iterator_facade</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="keyword">class</span> <span class="identifier">node_iterator</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><</span>
|
|
<span class="identifier">node_iterator</span>
|
|
<span class="special">,</span> <span class="identifier">node_base</span>
|
|
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span>
|
|
<span class="special">></span>
|
|
<span class="special">{</span>
|
|
<span class="special">...</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h8"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.constructors_and_data_members"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.constructors_and_data_members">Constructors
|
|
and Data Members</a>
|
|
</h3>
|
|
<p>
|
|
Next we need to decide how to represent the iterator's position. This representation
|
|
will take the form of data members, so we'll also need to write constructors
|
|
to initialize them. The <code class="computeroutput"><span class="identifier">node_iterator</span></code>'s
|
|
position is quite naturally represented using a pointer to a <code class="computeroutput"><span class="identifier">node_base</span></code>. We'll need a constructor to
|
|
build an iterator from a <code class="computeroutput"><span class="identifier">node_base</span><span class="special">*</span></code>, and a default constructor to satisfy
|
|
the <code class="computeroutput"><span class="identifier">forward</span> <span class="identifier">traversal</span>
|
|
<span class="identifier">iterator</span></code>_ requirements <a name="default"></a>_. Our <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
then becomes:
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor"># include</span> <span class="string">"node.hpp"</span>
|
|
<span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">iterator_facade</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="keyword">class</span> <span class="identifier">node_iterator</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><</span>
|
|
<span class="identifier">node_iterator</span>
|
|
<span class="special">,</span> <span class="identifier">node_base</span>
|
|
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span>
|
|
<span class="special">></span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="identifier">node_iterator</span><span class="special">()</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="number">0</span><span class="special">)</span>
|
|
<span class="special">{}</span>
|
|
|
|
<span class="keyword">explicit</span> <span class="identifier">node_iterator</span><span class="special">(</span><span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">{}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="special">...</span>
|
|
<span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<p>
|
|
.. <a name="default0"></a>Technically, the C++ standard places almost no
|
|
requirements on a default-constructed iterator, so if we were really concerned
|
|
with efficiency, we could've written the default constructor to leave
|
|
<code class="computeroutput"><span class="identifier">m_node</span></code> uninitialized.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h9"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.implementing_the_core_operations"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.implementing_the_core_operations">Implementing
|
|
the Core Operations</a>
|
|
</h3>
|
|
<p>
|
|
The last step is to implement the <code class="computeroutput"><span class="identifier">core</span>
|
|
<span class="identifier">operations</span></code>_ required by the concepts
|
|
we want our iterator to model. Referring to the table__, we can see that
|
|
the first three rows are applicable because <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
needs to satisfy the requirements for <code class="computeroutput"><span class="identifier">readable</span>
|
|
<span class="identifier">iterator</span></code>_, <code class="computeroutput"><span class="identifier">single</span>
|
|
<span class="identifier">pass</span> <span class="identifier">iterator</span></code>_,
|
|
and <code class="computeroutput"><span class="identifier">incrementable</span> <span class="identifier">iterator</span></code>_.
|
|
</p>
|
|
<p>
|
|
__ <code class="computeroutput"><span class="identifier">core</span> <span class="identifier">operations</span></code>_
|
|
</p>
|
|
<p>
|
|
We therefore need to supply <code class="computeroutput"><span class="identifier">dereference</span></code>,
|
|
<code class="computeroutput"><span class="identifier">equal</span></code>, and <code class="computeroutput"><span class="identifier">increment</span></code> members. We don't want these
|
|
members to become part of <code class="computeroutput"><span class="identifier">node_iterator</span></code>'s
|
|
public interface, so we can make them private and grant friendship to
|
|
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_core_access</span></code>, a "back-door"
|
|
that <code class="computeroutput"><span class="identifier">iterator_facade</span></code> uses
|
|
to get access to the core operations:
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor"># include</span> <span class="string">"node.hpp"</span>
|
|
<span class="preprocessor"># include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">iterator</span><span class="special">/</span><span class="identifier">iterator_facade</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="keyword">class</span> <span class="identifier">node_iterator</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><</span>
|
|
<span class="identifier">node_iterator</span>
|
|
<span class="special">,</span> <span class="identifier">node_base</span>
|
|
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span>
|
|
<span class="special">></span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="identifier">node_iterator</span><span class="special">()</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">explicit</span> <span class="identifier">node_iterator</span><span class="special">(</span><span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_core_access</span><span class="special">;</span>
|
|
|
|
<span class="keyword">void</span> <span class="identifier">increment</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">m_node</span> <span class="special">=</span> <span class="identifier">m_node</span><span class="special">-></span><span class="identifier">next</span><span class="special">();</span> <span class="special">}</span>
|
|
|
|
<span class="keyword">bool</span> <span class="identifier">equal</span><span class="special">(</span><span class="identifier">node_iterator</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">m_node</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
|
|
<span class="identifier">node_base</span><span class="special">&</span> <span class="identifier">dereference</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="identifier">m_node</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<p>
|
|
Voila; a complete and conforming readable, forward-traversal iterator!
|
|
For a working example of its use, see <a href="../../example/node_iterator1.cpp" target="_top"><code class="computeroutput"><span class="keyword">this</span> <span class="identifier">program</span></code></a>.
|
|
</p>
|
|
<p>
|
|
__ ../example/node_iterator1.cpp
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h10"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.a_constant_node_iterator"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.a_constant_node_iterator">A
|
|
constant <code class="computeroutput"><span class="identifier">node_iterator</span></code></a>
|
|
</h3>
|
|
<div class="sidebar">
|
|
<div class="titlepage"><div><div><p class="title"><b></b></p></div></div></div>
|
|
<p>
|
|
<span class="bold"><strong>Constant and Mutable iterators</strong></span><br>
|
|
<br> The term **mutable iterator** means an iterator through which the
|
|
object it references (its "referent") can be modified. A **constant
|
|
iterator** is one which doesn't allow modification of its referent.<br>
|
|
<br> The words <span class="bold"><strong>constant</strong></span> and <span class="bold"><strong>mutable</strong></span> don't refer to the ability to modify the
|
|
iterator itself. For example, an <code class="computeroutput"><span class="keyword">int</span>
|
|
<span class="keyword">const</span><span class="special">*</span></code>
|
|
is a non-<code class="computeroutput"><span class="keyword">const</span></code> <span class="bold"><strong>constant
|
|
iterator</strong></span>, which can be incremented but doesn't allow modification
|
|
of its referent, and <code class="computeroutput"><span class="keyword">int</span><span class="special">*</span>
|
|
<span class="keyword">const</span></code> is a <code class="computeroutput"><span class="keyword">const</span></code>
|
|
<span class="bold"><strong>mutable iterator</strong></span>, which cannot be modified
|
|
but which allows modification of its referent.<br> <br> Confusing?
|
|
We agree, but those are the standard terms. It probably doesn't help much
|
|
that a container's constant iterator is called <code class="computeroutput"><span class="identifier">const_iterator</span></code>.
|
|
</p>
|
|
</div>
|
|
<p>
|
|
Now, our <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
gives clients access to both <code class="computeroutput"><span class="identifier">node</span></code>\
|
|
's <code class="computeroutput"><span class="identifier">print</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&)</span>
|
|
<span class="keyword">const</span></code> member function, but also
|
|
its mutating <code class="computeroutput"><span class="identifier">double_me</span><span class="special">()</span></code> member. If we wanted to build a <span class="bold"><strong>constant</strong></span> <code class="computeroutput"><span class="identifier">node_iterator</span></code>,
|
|
we'd only have to make three changes:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">const_node_iterator</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><</span>
|
|
<span class="identifier">node_iterator</span>
|
|
<span class="special">,</span> <span class="identifier">node_base</span> <span class="special">**</span><span class="keyword">const</span><span class="special">**</span>
|
|
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span>
|
|
<span class="special">></span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="identifier">const_node_iterator</span><span class="special">()</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">explicit</span> <span class="identifier">const_node_iterator</span><span class="special">(</span><span class="identifier">node_base</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_core_access</span><span class="special">;</span>
|
|
|
|
<span class="keyword">void</span> <span class="identifier">increment</span><span class="special">()</span> <span class="special">{</span> <span class="identifier">m_node</span> <span class="special">=</span> <span class="identifier">m_node</span><span class="special">-></span><span class="identifier">next</span><span class="special">();</span> <span class="special">}</span>
|
|
|
|
<span class="keyword">bool</span> <span class="identifier">equal</span><span class="special">(</span><span class="identifier">const_node_iterator</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">m_node</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
|
|
<span class="identifier">node_base</span> <span class="special">**</span><span class="keyword">const</span><span class="special">**\</span> <span class="special">&</span> <span class="identifier">dereference</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">\*</span><span class="identifier">m_node</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="identifier">node_base</span> <span class="special">**</span><span class="keyword">const</span><span class="special">**\</span> <span class="special">*</span> <span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
</pre>
|
|
<div class="sidebar">
|
|
<div class="titlepage"><div><div><p class="title"><b></b></p></div></div></div>
|
|
<p>
|
|
<code class="computeroutput"><span class="keyword">const</span></code> and an iterator's <code class="computeroutput"><span class="identifier">value_type</span></code><br> <br> The C++ standard
|
|
requires an iterator's <code class="computeroutput"><span class="identifier">value_type</span></code>
|
|
<span class="bold"><strong>not</strong></span> be <code class="computeroutput"><span class="keyword">const</span></code>-qualified,
|
|
so <code class="computeroutput"><span class="identifier">iterator_facade</span></code> strips
|
|
the <code class="computeroutput"><span class="keyword">const</span></code> from its <code class="computeroutput"><span class="identifier">Value</span></code> parameter in order to produce the
|
|
iterator's <code class="computeroutput"><span class="identifier">value_type</span></code>.
|
|
Making the <code class="computeroutput"><span class="identifier">Value</span></code> argument
|
|
<code class="computeroutput"><span class="keyword">const</span></code> provides a useful hint
|
|
to <code class="computeroutput"><span class="identifier">iterator_facade</span></code> that
|
|
the iterator is a <span class="bold"><strong>constant iterator</strong></span>, and
|
|
the default <code class="computeroutput"><span class="identifier">Reference</span></code> argument
|
|
will be correct for all lvalue iterators.
|
|
</p>
|
|
</div>
|
|
<p>
|
|
As a matter of fact, <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
and <code class="computeroutput"><span class="identifier">const_node_iterator</span></code>
|
|
are so similar that it makes sense to factor the common code out into a
|
|
template as follows:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Value</span><span class="special">></span>
|
|
<span class="keyword">class</span> <span class="identifier">node_iter</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><</span>
|
|
<span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">Value</span><span class="special">></span>
|
|
<span class="special">,</span> <span class="identifier">Value</span>
|
|
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span>
|
|
<span class="special">></span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="identifier">node_iter</span><span class="special">()</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">explicit</span> <span class="identifier">node_iter</span><span class="special">(</span><span class="identifier">Value</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_core_access</span><span class="special">;</span>
|
|
|
|
<span class="keyword">bool</span> <span class="identifier">equal</span><span class="special">(</span><span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">Value</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">m_node</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
|
|
<span class="keyword">void</span> <span class="identifier">increment</span><span class="special">()</span>
|
|
<span class="special">{</span> <span class="identifier">m_node</span> <span class="special">=</span> <span class="identifier">m_node</span><span class="special">-></span><span class="identifier">next</span><span class="special">();</span> <span class="special">}</span>
|
|
|
|
<span class="identifier">Value</span><span class="special">&</span> <span class="identifier">dereference</span><span class="special">()</span> <span class="keyword">const</span>
|
|
<span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="identifier">m_node</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="identifier">Value</span><span class="special">*</span> <span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">node_base</span><span class="special">></span> <span class="identifier">node_iterator</span><span class="special">;</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">node_base</span> <span class="keyword">const</span><span class="special">></span> <span class="identifier">node_const_iterator</span><span class="special">;</span>
|
|
</pre>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h11"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.interoperability"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.interoperability">Interoperability</a>
|
|
</h3>
|
|
<p>
|
|
Our <code class="computeroutput"><span class="identifier">const_node_iterator</span></code>
|
|
works perfectly well on its own, but taken together with <code class="computeroutput"><span class="identifier">node_iterator</span></code> it doesn't quite meet expectations.
|
|
For example, we'd like to be able to pass a <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
where a <code class="computeroutput"><span class="identifier">node_const_iterator</span></code>
|
|
was expected, just as you can with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>'s <code class="computeroutput"><span class="identifier">iterator</span></code>
|
|
and <code class="computeroutput"><span class="identifier">const_iterator</span></code>. Furthermore,
|
|
given a <code class="computeroutput"><span class="identifier">node_iterator</span></code> and
|
|
a <code class="computeroutput"><span class="identifier">node_const_iterator</span></code> into
|
|
the same list, we should be able to compare them for equality.
|
|
</p>
|
|
<p>
|
|
This expected ability to use two different iterator types together is known
|
|
as |interoperability|_. Achieving interoperability in our case is as simple
|
|
as templatizing the <code class="computeroutput"><span class="identifier">equal</span></code>
|
|
function and adding a templatized converting constructor <a name="broken"></a>_
|
|
<a name="random"></a>_:
|
|
</p>
|
|
<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">Value</span><span class="special">></span>
|
|
<span class="keyword">class</span> <span class="identifier">node_iter</span>
|
|
<span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_facade</span><span class="special"><</span>
|
|
<span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">Value</span><span class="special">></span>
|
|
<span class="special">,</span> <span class="identifier">Value</span>
|
|
<span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_traversal_tag</span>
|
|
<span class="special">></span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="identifier">node_iter</span><span class="special">()</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="number">0</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">explicit</span> <span class="identifier">node_iter</span><span class="special">(</span><span class="identifier">Value</span><span class="special">*</span> <span class="identifier">p</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">OtherValue</span><span class="special">></span>
|
|
<span class="identifier">node_iter</span><span class="special">(</span><span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">OtherValue</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">other</span><span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">m_node</span><span class="special">)</span> <span class="special">{}</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">iterator_core_access</span><span class="special">;</span>
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span><span class="special">></span> <span class="keyword">friend</span> <span class="keyword">class</span> <span class="identifier">node_iter</span><span class="special">;</span>
|
|
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">OtherValue</span><span class="special">></span>
|
|
<span class="keyword">bool</span> <span class="identifier">equal</span><span class="special">(</span><span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">OtherValue</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span>
|
|
<span class="special">{</span>
|
|
<span class="keyword">return</span> <span class="keyword">this</span><span class="special">-></span><span class="identifier">m_node</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">}</span>
|
|
|
|
<span class="keyword">void</span> <span class="identifier">increment</span><span class="special">()</span>
|
|
<span class="special">{</span> <span class="identifier">m_node</span> <span class="special">=</span> <span class="identifier">m_node</span><span class="special">-></span><span class="identifier">next</span><span class="special">();</span> <span class="special">}</span>
|
|
|
|
<span class="identifier">Value</span><span class="special">&</span> <span class="identifier">dereference</span><span class="special">()</span> <span class="keyword">const</span>
|
|
<span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="identifier">m_node</span><span class="special">;</span> <span class="special">}</span>
|
|
|
|
<span class="identifier">Value</span><span class="special">*</span> <span class="identifier">m_node</span><span class="special">;</span>
|
|
<span class="special">};</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">impl</span><span class="special">::</span><span class="identifier">node_iterator</span><span class="special"><</span><span class="identifier">node_base</span><span class="special">></span> <span class="identifier">node_iterator</span><span class="special">;</span>
|
|
<span class="keyword">typedef</span> <span class="identifier">impl</span><span class="special">::</span><span class="identifier">node_iterator</span><span class="special"><</span><span class="identifier">node_base</span> <span class="keyword">const</span><span class="special">></span> <span class="identifier">node_const_iterator</span><span class="special">;</span>
|
|
</pre>
|
|
<p>
|
|
.. |interoperability| replace:: **interoperability** .. _interoperability:
|
|
new-iter-concepts.html#interoperable-iterators-lib-interoperable-iterators
|
|
</p>
|
|
<p>
|
|
.. <a name="broken0"></a>If you're using an older compiler and it can't
|
|
handle this example, see the <code class="computeroutput"><span class="identifier">example</span>
|
|
<span class="identifier">code</span></code>__ for workarounds.
|
|
</p>
|
|
<p>
|
|
.. <a name="random0"></a>If <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
had been a <code class="computeroutput"><span class="identifier">random</span> <span class="identifier">access</span>
|
|
<span class="identifier">traversal</span> <span class="identifier">iterator</span></code>_,
|
|
we'd have had to templatize its <code class="computeroutput"><span class="identifier">distance_to</span></code>
|
|
function as well.
|
|
</p>
|
|
<p>
|
|
__ ../example/node_iterator2.hpp
|
|
</p>
|
|
<p>
|
|
You can see an example program which exercises our interoperable iterators
|
|
<a href="../../example/node_iterator2.cpp" target="_top"><code class="computeroutput"><span class="identifier">here</span></code></a>.
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h12"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.telling_the_truth"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.telling_the_truth">Telling
|
|
the Truth</a>
|
|
</h3>
|
|
<p>
|
|
Now <code class="computeroutput"><span class="identifier">node_iterator</span></code> and
|
|
<code class="computeroutput"><span class="identifier">node_const_iterator</span></code> behave
|
|
exactly as you'd expect... almost. We can compare them and we can convert
|
|
in one direction: from <code class="computeroutput"><span class="identifier">node_iterator</span></code>
|
|
to <code class="computeroutput"><span class="identifier">node_const_iterator</span></code>.
|
|
If we try to convert from <code class="computeroutput"><span class="identifier">node_const_iterator</span></code>
|
|
to <code class="computeroutput"><span class="identifier">node_iterator</span></code>, we'll
|
|
get an error when the converting constructor tries to initialize <code class="computeroutput"><span class="identifier">node_iterator</span></code>'s <code class="computeroutput"><span class="identifier">m_node</span></code>,
|
|
a <code class="computeroutput"><span class="identifier">node</span><span class="special">*</span></code>
|
|
with a <code class="computeroutput"><span class="identifier">node</span> <span class="keyword">const</span><span class="special">*</span></code>. So what's the problem?
|
|
</p>
|
|
<p>
|
|
The problem is that <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span></code>|is_convertible|_<code class="computeroutput"><span class="special"><</span><span class="identifier">node_const_iterator</span><span class="special">,</span><span class="identifier">node_iterator</span><span class="special">>::</span><span class="identifier">value</span></code> will be <code class="computeroutput"><span class="keyword">true</span></code>,
|
|
but it should be <code class="computeroutput"><span class="keyword">false</span></code>. |is_convertible|_
|
|
lies because it can only see as far as the <span class="bold"><strong>declaration</strong></span>
|
|
of <code class="computeroutput"><span class="identifier">node_iter</span></code>'s converting
|
|
constructor, but can't look inside at the <span class="bold"><strong>definition</strong></span>
|
|
to make sure it will compile. A perfect solution would make <code class="computeroutput"><span class="identifier">node_iter</span></code>'s converting constructor disappear
|
|
when the <code class="computeroutput"><span class="identifier">m_node</span></code> conversion
|
|
would fail.
|
|
</p>
|
|
<p>
|
|
.. |is_convertible| replace:: <code class="computeroutput"><span class="identifier">is_convertible</span></code>
|
|
.. _is_convertible: ../../type_traits/index.html#relationships
|
|
</p>
|
|
<p>
|
|
In fact, that sort of magic is possible using |enable_if|__. By rewriting
|
|
the converting constructor as follows, we can remove it from the overload
|
|
set when it's not appropriate:
|
|
</p>
|
|
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">is_convertible</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">utility</span><span class="special">/</span><span class="identifier">enable_if</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
|
|
|
<span class="special">...</span>
|
|
|
|
<span class="keyword">private</span><span class="special">:</span>
|
|
<span class="keyword">struct</span> <span class="identifier">enabler</span> <span class="special">{};</span>
|
|
|
|
<span class="keyword">public</span><span class="special">:</span>
|
|
<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">OtherValue</span><span class="special">></span>
|
|
<span class="identifier">node_iter</span><span class="special">(</span>
|
|
<span class="identifier">node_iter</span><span class="special"><</span><span class="identifier">OtherValue</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">other</span>
|
|
<span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span><span class="special"><</span>
|
|
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_convertible</span><span class="special"><</span><span class="identifier">OtherValue</span><span class="special">*,</span><span class="identifier">Value</span><span class="special">*></span>
|
|
<span class="special">,</span> <span class="identifier">enabler</span>
|
|
<span class="special">>::</span><span class="identifier">type</span> <span class="special">=</span> <span class="identifier">enabler</span><span class="special">()</span>
|
|
<span class="special">)</span>
|
|
<span class="special">:</span> <span class="identifier">m_node</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">m_node</span><span class="special">)</span> <span class="special">{}</span>
|
|
</pre>
|
|
<p>
|
|
.. |enable_if| replace:: <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">enable_if</span></code>
|
|
__ ../../utility/enable_if.html
|
|
</p>
|
|
<h3>
|
|
<a name="iterator.generic.facade.facade_tutorial.h13"></a>
|
|
<span class="phrase"><a name="iterator.generic.facade.facade_tutorial.wrap_up"></a></span><a class="link" href="generic.html#iterator.generic.facade.facade_tutorial.wrap_up">Wrap
|
|
Up</a>
|
|
</h3>
|
|
<p>
|
|
This concludes our <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
|
|
tutorial, but before you stop reading we urge you to take a look at |iterator_adaptor|__.
|
|
There's another way to approach writing these iterators which might even
|
|
be superior.
|
|
</p>
|
|
<p>
|
|
.. |iterator_adaptor| replace:: <code class="computeroutput"><span class="identifier">iterator_adaptor</span></code>
|
|
__ iterator_adaptor.html
|
|
</p>
|
|
<p>
|
|
.. _<code class="computeroutput"><span class="identifier">iterator</span> <span class="identifier">traversal</span>
|
|
<span class="identifier">concept</span></code>: new-iter-concepts.html#iterator-traversal-concepts-lib-iterator-traversal
|
|
.. _<code class="computeroutput"><span class="identifier">readable</span> <span class="identifier">iterator</span></code>:
|
|
new-iter-concepts.html#readable-iterators-lib-readable-iterators .. _<code class="computeroutput"><span class="identifier">lvalue</span> <span class="identifier">iterator</span></code>:
|
|
new-iter-concepts.html#lvalue-iterators-lib-lvalue-iterators .. _<code class="computeroutput"><span class="identifier">single</span> <span class="identifier">pass</span>
|
|
<span class="identifier">iterator</span></code>: new-iter-concepts.html#single-pass-iterators-lib-single-pass-iterators
|
|
.. _<code class="computeroutput"><span class="identifier">incrementable</span> <span class="identifier">iterator</span></code>:
|
|
new-iter-concepts.html#incrementable-iterators-lib-incrementable-iterators
|
|
.. _<code class="computeroutput"><span class="identifier">forward</span> <span class="identifier">traversal</span>
|
|
<span class="identifier">iterator</span></code>: new-iter-concepts.html#forward-traversal-iterators-lib-forward-traversal-iterators
|
|
.. _<code class="computeroutput"><span class="identifier">bidirectional</span> <span class="identifier">traversal</span>
|
|
<span class="identifier">iterator</span></code>: new-iter-concepts.html#bidirectional-traversal-iterators-lib-bidirectional-traversal-iterators
|
|
.. _<code class="computeroutput"><span class="identifier">random</span> <span class="identifier">access</span>
|
|
<span class="identifier">traversal</span> <span class="identifier">iterator</span></code>:
|
|
new-iter-concepts.html#random-access-traversal-iterators-lib-random-access-traversal-iterators
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
|
<td align="left"></td>
|
|
<td align="right"><div class="copyright-footer">Copyright © 2003, 2005 David Abrahams Jeremy Siek Thomas
|
|
Witt<p>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
file LICENSE_1_0.txt or copy at <ulink url="http://www.boost.org/LICENSE_1_0.txt">
|
|
http://www.boost.org/LICENSE_1_0.txt </ulink>)
|
|
</p>
|
|
</div></td>
|
|
</tr></table>
|
|
<hr>
|
|
<div class="spirit-nav">
|
|
<a accesskey="p" href="concepts/concepts_traversal.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="generic/adaptor.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
|
</div>
|
|
</body>
|
|
</html>
|