[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,540 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Examples</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="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="prev" href="tutorial___reverse_iterator_.html" title="Tutorial: reverse_iterator">
<link rel="next" href="../stl_interfaces/compiler_support.html" title="Compiler Support">
</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="tutorial___reverse_iterator_.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="../stl_interfaces/compiler_support.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="boost_stlinterfaces.examples"></a><a class="link" href="examples.html" title="Examples">Examples</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="examples.html#boost_stlinterfaces.examples.random_access_iterator">Random
Access Iterator</a></span></dt>
<dt><span class="section"><a href="examples.html#boost_stlinterfaces.examples.mutable_and_constant_iterator_interoperability">Mutable
and Constant Iterator Interoperability</a></span></dt>
<dt><span class="section"><a href="examples.html#boost_stlinterfaces.examples.zip_iterator___proxy_iterator">Zip
Iterator / Proxy Iterator</a></span></dt>
<dt><span class="section"><a href="examples.html#boost_stlinterfaces.examples.reimplementing__back_insert_iterator_">Reimplementing
<code class="computeroutput"><span class="identifier">back_insert_iterator</span></code></a></span></dt>
<dt><span class="section"><a href="examples.html#boost_stlinterfaces.examples.reimplementing__reverse_iterator_">Reimplementing
<code class="computeroutput"><span class="identifier">reverse_iterator</span></code></a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stlinterfaces.examples.random_access_iterator"></a><a class="link" href="examples.html#boost_stlinterfaces.examples.random_access_iterator" title="Random Access Iterator">Random
Access Iterator</a>
</h3></div></div></div>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stl_interfaces</span><span class="special">/</span><span class="identifier">iterator_interface</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">// This is a minimal random access iterator. It uses default template</span>
<span class="comment">// parameters for most stl_interfaces template parameters.</span>
<span class="keyword">struct</span> <span class="identifier">simple_random_access_iterator</span>
<span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">simple_random_access_iterator</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">random_access_iterator_tag</span><span class="special">,</span>
<span class="keyword">int</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="comment">// This default constructor does not initialize it_, since that's how int *</span>
<span class="comment">// works as well. This allows optimum performance in code paths where</span>
<span class="comment">// initializing a single pointer may be measurable. It is also a</span>
<span class="comment">// reasonable choice to initialize with nullptr.</span>
<span class="identifier">simple_random_access_iterator</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{}</span>
<span class="identifier">simple_random_access_iterator</span><span class="special">(</span><span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">(</span><span class="identifier">it</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">int</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span>
<span class="identifier">simple_random_access_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="identifier">it_</span> <span class="special">+=</span> <span class="identifier">i</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">simple_random_access_iterator</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">it_</span> <span class="special">-</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">it_</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it_</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">}};</span>
<span class="identifier">simple_random_access_iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
<span class="identifier">simple_random_access_iterator</span> <span class="identifier">last</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;{{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">}}));</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stlinterfaces.examples.mutable_and_constant_iterator_interoperability"></a><a class="link" href="examples.html#boost_stlinterfaces.examples.mutable_and_constant_iterator_interoperability" title="Mutable and Constant Iterator Interoperability">Mutable
and Constant Iterator Interoperability</a>
</h3></div></div></div>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stl_interfaces</span><span class="special">/</span><span class="identifier">iterator_interface</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">numeric</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">// This is a random access iterator templated on a value type. The ValueType</span>
<span class="comment">// template parameter allows us easily to define const and non-const iterators</span>
<span class="comment">// from the same template.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">ValueType</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">random_access_iterator</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">random_access_iterator</span><span class="special">&lt;</span><span class="identifier">ValueType</span><span class="special">&gt;,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">random_access_iterator_tag</span><span class="special">,</span>
<span class="identifier">ValueType</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="keyword">static_assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">is_object</span><span class="special">&lt;</span><span class="identifier">ValueType</span><span class="special">&gt;::</span><span class="identifier">value</span><span class="special">,</span> <span class="string">""</span><span class="special">);</span>
<span class="comment">// Default constructor.</span>
<span class="keyword">constexpr</span> <span class="identifier">random_access_iterator</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{}</span>
<span class="comment">// Construction from an underlying pointer.</span>
<span class="keyword">constexpr</span> <span class="identifier">random_access_iterator</span><span class="special">(</span><span class="identifier">ValueType</span> <span class="special">*</span> <span class="identifier">it</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">(</span><span class="identifier">it</span><span class="special">)</span> <span class="special">{}</span>
<span class="comment">// Implicit conversion from an existing random_access_iterator with a</span>
<span class="comment">// possibly different value type. The enable_if logic here just enforces</span>
<span class="comment">// that this constructor only participates in overload resolution when the</span>
<span class="comment">// expression it_ = other.it_ is well-formed.</span>
<span class="keyword">template</span><span class="special">&lt;</span>
<span class="keyword">typename</span> <span class="identifier">ValueType2</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">E</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">enable_if_t</span><span class="special">&lt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">ValueType2</span> <span class="special">*,</span> <span class="identifier">ValueType</span> <span class="special">*&gt;::</span><span class="identifier">value</span><span class="special">&gt;&gt;</span>
<span class="keyword">constexpr</span> <span class="identifier">random_access_iterator</span><span class="special">(</span>
<span class="identifier">random_access_iterator</span><span class="special">&lt;</span><span class="identifier">ValueType2</span><span class="special">&gt;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">:</span>
<span class="identifier">it_</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">it_</span><span class="special">)</span>
<span class="special">{}</span>
<span class="keyword">constexpr</span> <span class="identifier">ValueType</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">constexpr</span> <span class="identifier">random_access_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="identifier">it_</span> <span class="special">+=</span> <span class="identifier">i</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">random_access_iterator</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">it_</span> <span class="special">-</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">it_</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">ValueType</span> <span class="special">*</span> <span class="identifier">it_</span><span class="special">;</span>
<span class="comment">// This friendship is necessary to enable the implicit conversion</span>
<span class="comment">// constructor above to work.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">ValueType2</span><span class="special">&gt;</span>
<span class="keyword">friend</span> <span class="keyword">struct</span> <span class="identifier">random_access_iterator</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">using</span> <span class="identifier">iterator</span> <span class="special">=</span> <span class="identifier">random_access_iterator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">const_iterator</span> <span class="special">=</span> <span class="identifier">random_access_iterator</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="keyword">const</span><span class="special">&gt;;</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">}};</span>
<span class="comment">// Create and use two mutable iterators.</span>
<span class="identifier">iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
<span class="identifier">iterator</span> <span class="identifier">last</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;{{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">}}));</span>
<span class="comment">// Create and use two constant iterators, one from an existing mutable</span>
<span class="comment">// iterator.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="identifier">int_sums</span><span class="special">;</span>
<span class="identifier">const_iterator</span> <span class="identifier">cfirst</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
<span class="identifier">const_iterator</span> <span class="identifier">clast</span> <span class="special">=</span> <span class="identifier">last</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">partial_sum</span><span class="special">(</span><span class="identifier">cfirst</span><span class="special">,</span> <span class="identifier">clast</span><span class="special">,</span> <span class="identifier">int_sums</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">int_sums</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;{{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">10</span><span class="special">,</span> <span class="number">15</span><span class="special">,</span> <span class="number">21</span><span class="special">,</span> <span class="number">28</span><span class="special">,</span> <span class="number">36</span><span class="special">,</span> <span class="number">45</span><span class="special">}}));</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stlinterfaces.examples.zip_iterator___proxy_iterator"></a><a class="link" href="examples.html#boost_stlinterfaces.examples.zip_iterator___proxy_iterator" title="Zip Iterator / Proxy Iterator">Zip
Iterator / Proxy Iterator</a>
</h3></div></div></div>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stl_interfaces</span><span class="special">/</span><span class="identifier">iterator_interface</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">array</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">tuple</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">// This is a zip iterator, meaning that it iterates over a notional sequence</span>
<span class="comment">// of pairs that is formed from two actual sequences of scalars. To make this</span>
<span class="comment">// iterator writable, it needs to have a reference type that is not actually a</span>
<span class="comment">// reference -- the reference type is a pair of references, std::tuple&lt;int &amp;,</span>
<span class="comment">// int &amp;&gt;.</span>
<span class="keyword">struct</span> <span class="identifier">zip_iterator</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">proxy_iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">zip_iterator</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">random_access_iterator_tag</span><span class="special">,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="special">&amp;,</span> <span class="keyword">int</span> <span class="special">&amp;&gt;&gt;</span>
<span class="special">{</span>
<span class="keyword">constexpr</span> <span class="identifier">zip_iterator</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">:</span> <span class="identifier">it1_</span><span class="special">(),</span> <span class="identifier">it2_</span><span class="special">()</span> <span class="special">{}</span>
<span class="keyword">constexpr</span> <span class="identifier">zip_iterator</span><span class="special">(</span><span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it1</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it2</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">:</span> <span class="identifier">it1_</span><span class="special">(</span><span class="identifier">it1</span><span class="special">),</span> <span class="identifier">it2_</span><span class="special">(</span><span class="identifier">it2</span><span class="special">)</span>
<span class="special">{}</span>
<span class="keyword">constexpr</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="special">&amp;,</span> <span class="keyword">int</span> <span class="special">&amp;&gt;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="special">&amp;,</span> <span class="keyword">int</span> <span class="special">&amp;&gt;{*</span><span class="identifier">it1_</span><span class="special">,</span> <span class="special">*</span><span class="identifier">it2_</span><span class="special">};</span>
<span class="special">}</span>
<span class="keyword">constexpr</span> <span class="identifier">zip_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">+=</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span> <span class="identifier">i</span><span class="special">)</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="identifier">it1_</span> <span class="special">+=</span> <span class="identifier">i</span><span class="special">;</span>
<span class="identifier">it2_</span> <span class="special">+=</span> <span class="identifier">i</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">zip_iterator</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">it1_</span> <span class="special">-</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">it1_</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it1_</span><span class="special">;</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it2_</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">namespace</span> <span class="identifier">std</span> <span class="special">{</span>
<span class="comment">// Required for std::sort to work with zip_iterator. Without this</span>
<span class="comment">// overload, std::sort eventually tries to call std::swap(*it1, *it2),</span>
<span class="comment">// *it1 and *it2 are rvalues, and std::swap() takes mutable lvalue</span>
<span class="comment">// references. That makes std::swap(*it1, *it2) ill-formed.</span>
<span class="comment">//</span>
<span class="comment">// Note that this overload does not conflict with any other swap()</span>
<span class="comment">// overloads, since this one takes rvalue reference parameters.</span>
<span class="comment">//</span>
<span class="comment">// Also note that this overload has to be in namespace std only because</span>
<span class="comment">// ADL cannot find it anywhere else. If</span>
<span class="comment">// zip_iterator::reference/std::tuple's template parameters were not</span>
<span class="comment">// builtins, this overload could be in whatever namespace those template</span>
<span class="comment">// parameters were declared in.</span>
<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">zip_iterator</span><span class="special">::</span><span class="identifier">reference</span> <span class="special">&amp;&amp;</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">zip_iterator</span><span class="special">::</span><span class="identifier">reference</span> <span class="special">&amp;&amp;</span> <span class="identifier">rhs</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">swap</span><span class="special">;</span>
<span class="identifier">swap</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">lhs</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">0</span><span class="special">&gt;(</span><span class="identifier">rhs</span><span class="special">));</span>
<span class="identifier">swap</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">lhs</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span><span class="number">1</span><span class="special">&gt;(</span><span class="identifier">rhs</span><span class="special">));</span>
<span class="special">}</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{{</span><span class="number">2</span><span class="special">,</span> <span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">9</span><span class="special">,</span> <span class="number">7</span><span class="special">}};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="identifier">ones</span> <span class="special">=</span> <span class="special">{{</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">}};</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">{{</span>
<span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">5</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">6</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">8</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">4</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">9</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">7</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">}};</span>
<span class="identifier">zip_iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">ones</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
<span class="identifier">zip_iterator</span> <span class="identifier">last</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">(),</span> <span class="identifier">ones</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ones</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">end</span><span class="special">()));</span>
<span class="special">}</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">int</span><span class="special">&gt;,</span> <span class="number">10</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">result</span> <span class="special">=</span> <span class="special">{{</span>
<span class="special">{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">1</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">3</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">4</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">5</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">6</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">7</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">8</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">{</span><span class="number">9</span><span class="special">,</span> <span class="number">1</span><span class="special">},</span>
<span class="special">}};</span>
<span class="identifier">zip_iterator</span> <span class="identifier">first</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">ones</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span>
<span class="identifier">zip_iterator</span> <span class="identifier">last</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">(),</span> <span class="identifier">ones</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ones</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">end</span><span class="special">()));</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">sort</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">end</span><span class="special">()));</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stlinterfaces.examples.reimplementing__back_insert_iterator_"></a><a class="link" href="examples.html#boost_stlinterfaces.examples.reimplementing__back_insert_iterator_" title="Reimplementing back_insert_iterator">Reimplementing
<code class="computeroutput"><span class="identifier">back_insert_iterator</span></code></a>
</h3></div></div></div>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stl_interfaces</span><span class="special">/</span><span class="identifier">iterator_interface</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">// This is an output iterator that holds a reference to a container, and calls</span>
<span class="comment">// push_back() on that container when it is written to, just like</span>
<span class="comment">// std::back_insert_iterator. This is not a lot less code to write than the</span>
<span class="comment">// implementation of std::back_insert_iterator, but it demonstrates that</span>
<span class="comment">// iterator_interface is flexible enough to handle this odd kind of iterator.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">back_insert_iterator</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">back_insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">output_iterator_tag</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">,</span>
<span class="identifier">back_insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;</span> <span class="special">&amp;&gt;</span>
<span class="special">{</span>
<span class="comment">// For concept requirements.</span>
<span class="identifier">back_insert_iterator</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">c_</span><span class="special">(</span><span class="keyword">nullptr</span><span class="special">)</span> <span class="special">{}</span>
<span class="comment">// Construct from a container.</span>
<span class="keyword">explicit</span> <span class="identifier">back_insert_iterator</span><span class="special">(</span><span class="identifier">Container</span> <span class="special">&amp;</span> <span class="identifier">c</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">c_</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">addressof</span><span class="special">(</span><span class="identifier">c</span><span class="special">))</span> <span class="special">{}</span>
<span class="comment">// When writing to *this, copy v into the container via push_back().</span>
<span class="identifier">back_insert_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">::</span><span class="identifier">value_type</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">v</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">c_</span><span class="special">-&gt;</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// When writing to *this, move v into the container via push_back().</span>
<span class="identifier">back_insert_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">::</span><span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">c_</span><span class="special">-&gt;</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">v</span><span class="special">));</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// Dereferencing *this just returns a reference to *this, so that the</span>
<span class="comment">// expression *it = value uses the operator=() overloads above.</span>
<span class="identifier">back_insert_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span>
<span class="comment">// There is no underlying sequence over which we are iterating, so there's</span>
<span class="comment">// nowhere to go in next(). Do nothing.</span>
<span class="identifier">back_insert_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">++()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">using</span> <span class="identifier">base_type</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">back_insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">output_iterator_tag</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">::</span><span class="identifier">value_type</span><span class="special">,</span>
<span class="identifier">back_insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;</span> <span class="special">&amp;&gt;;</span>
<span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">++;</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">Container</span> <span class="special">*</span> <span class="identifier">c_</span><span class="special">;</span>
<span class="special">};</span>
<span class="comment">// A convenience function that creates a back_insert_iterator&lt;Container&gt;.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Container</span><span class="special">&gt;</span>
<span class="identifier">back_insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;</span> <span class="identifier">back_inserter</span><span class="special">(</span><span class="identifier">Container</span> <span class="special">&amp;</span> <span class="identifier">c</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">back_insert_iterator</span><span class="special">&lt;</span><span class="identifier">Container</span><span class="special">&gt;(</span><span class="identifier">c</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">7</span><span class="special">,</span> <span class="number">8</span><span class="special">,</span> <span class="number">9</span><span class="special">}};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints_copy</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="special">::</span><span class="identifier">back_inserter</span><span class="special">(</span><span class="identifier">ints_copy</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints_copy</span> <span class="special">==</span> <span class="identifier">ints</span><span class="special">);</span>
<span class="special">}</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_stlinterfaces.examples.reimplementing__reverse_iterator_"></a><a class="link" href="examples.html#boost_stlinterfaces.examples.reimplementing__reverse_iterator_" title="Reimplementing reverse_iterator">Reimplementing
<code class="computeroutput"><span class="identifier">reverse_iterator</span></code></a>
</h3></div></div></div>
<p>
</p>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">stl_interfaces</span><span class="special">/</span><span class="identifier">iterator_interface</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">algorithm</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">list</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">vector</span><span class="special">&gt;</span>
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</span>
<span class="comment">// In all the previous examples, we only had to implement a subset of the six</span>
<span class="comment">// possible user-defined basis operations that was needed for one particular</span>
<span class="comment">// iterator concept. For reverse_iterator, we want to support bidirectional,</span>
<span class="comment">// random access, and contiguous iterators. We therefore need to provide all</span>
<span class="comment">// the basis operations that might be needed.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">BidiIter</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">reverse_iterator</span>
<span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">reverse_iterator</span><span class="special">&lt;</span><span class="identifier">BidiIter</span><span class="special">&gt;,</span>
<span class="preprocessor">#if</span> <span class="number">201703L</span> <span class="special">&lt;</span> <span class="identifier">__cplusplus</span> <span class="special">&amp;&amp;</span> <span class="identifier">defined</span><span class="special">(</span><span class="identifier">__cpp_lib_ranges</span><span class="special">)</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">v2</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">iter_concept_t</span><span class="special">&lt;</span><span class="identifier">BidiIter</span><span class="special">&gt;,</span>
<span class="preprocessor">#else</span>
<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special">&lt;</span><span class="identifier">BidiIter</span><span class="special">&gt;::</span><span class="identifier">iterator_category</span><span class="special">,</span>
<span class="preprocessor">#endif</span>
<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special">&lt;</span><span class="identifier">BidiIter</span><span class="special">&gt;::</span><span class="identifier">value_type</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="identifier">reverse_iterator</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">()</span> <span class="special">{}</span>
<span class="identifier">reverse_iterator</span><span class="special">(</span><span class="identifier">BidiIter</span> <span class="identifier">it</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">(</span><span class="identifier">it</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">using</span> <span class="identifier">ref_t</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special">&lt;</span><span class="identifier">BidiIter</span><span class="special">&gt;::</span><span class="identifier">reference</span><span class="special">;</span>
<span class="keyword">using</span> <span class="identifier">diff_t</span> <span class="special">=</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special">&lt;</span><span class="identifier">BidiIter</span><span class="special">&gt;::</span><span class="identifier">difference_type</span><span class="special">;</span>
<span class="identifier">ref_t</span> <span class="keyword">operator</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">std</span><span class="special">::</span><span class="identifier">prev</span><span class="special">(</span><span class="identifier">it_</span><span class="special">);</span> <span class="special">}</span>
<span class="comment">// These three are used only when BidiIter::iterator_category is</span>
<span class="comment">// std::bidirectional_iterator_tag.</span>
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">reverse_iterator</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="identifier">it_</span> <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span>
<span class="comment">// Even though iterator_interface-derived bidirectional iterators are</span>
<span class="comment">// usually given operator++() and operator--() members, it turns out that</span>
<span class="comment">// operator+=() below amounts to the same thing. That's good, since</span>
<span class="comment">// having operator++() and operator+=() in this class would have lead to</span>
<span class="comment">// ambiguities in iterator_interface.</span>
<span class="comment">// These two are only used when BidiIter::iterator_category is</span>
<span class="comment">// std::random_access_iterator_tag or std::contiguous_iterator_tag. Even</span>
<span class="comment">// so, they need to compile even when BidiIter::iterator_category is</span>
<span class="comment">// std::bidirectional_iterator_tag. That means we have to use</span>
<span class="comment">// std::distance() and std::advance() instead of operator-() and</span>
<span class="comment">// operator+=().</span>
<span class="comment">//</span>
<span class="comment">// Don't worry, the O(n) bidirectional implementations of std::distance()</span>
<span class="comment">// and std::advance() are dead code, because compare() and advance() are</span>
<span class="comment">// never even called when BidiIter::iterator_category is</span>
<span class="comment">// std::bidirectional_iterator_tag.</span>
<span class="identifier">diff_t</span> <span class="keyword">operator</span><span class="special">-(</span><span class="identifier">reverse_iterator</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="special">-</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">distance</span><span class="special">(</span><span class="identifier">other</span><span class="special">.</span><span class="identifier">it_</span><span class="special">,</span> <span class="identifier">it_</span><span class="special">);</span>
<span class="special">}</span>
<span class="identifier">reverse_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">+=(</span><span class="identifier">diff_t</span> <span class="identifier">n</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">advance</span><span class="special">(</span><span class="identifier">it_</span><span class="special">,</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">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// No need for a using declaration to make</span>
<span class="comment">// iterator_interface::operator++(int) visible, because we're not defining</span>
<span class="comment">// operator++() in this template.</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">BidiIter</span> <span class="identifier">it_</span><span class="special">;</span>
<span class="special">};</span>
<span class="keyword">using</span> <span class="identifier">rev_bidi_iter</span> <span class="special">=</span> <span class="identifier">reverse_iterator</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">iterator</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">rev_ra_iter</span> <span class="special">=</span> <span class="identifier">reverse_iterator</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;::</span><span class="identifier">iterator</span><span class="special">&gt;;</span>
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
<span class="special">{</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{</span><span class="number">4</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints_copy</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span>
<span class="identifier">rev_bidi_iter</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">()),</span>
<span class="identifier">rev_bidi_iter</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">back_inserter</span><span class="special">(</span><span class="identifier">ints_copy</span><span class="special">));</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints_copy</span> <span class="special">==</span> <span class="identifier">ints</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{</span><span class="number">4</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints_copy</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span>
<span class="identifier">rev_ra_iter</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">()),</span>
<span class="identifier">rev_ra_iter</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()),</span>
<span class="identifier">ints_copy</span><span class="special">.</span><span class="identifier">begin</span><span class="special">());</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">(</span><span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints_copy</span> <span class="special">==</span> <span class="identifier">ints</span><span class="special">);</span>
<span class="special">}</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="identifier">rev_ptr_iter</span> <span class="special">=</span> <span class="identifier">reverse_iterator</span><span class="special">&lt;</span><span class="keyword">int</span> <span class="special">*&gt;;</span>
<span class="keyword">int</span> <span class="identifier">ints</span><span class="special">[</span><span class="number">3</span><span class="special">]</span> <span class="special">=</span> <span class="special">{</span><span class="number">4</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">2</span><span class="special">};</span>
<span class="keyword">int</span> <span class="identifier">ints_copy</span><span class="special">[</span><span class="number">3</span><span class="special">];</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span>
<span class="identifier">rev_ptr_iter</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">ints</span><span class="special">)),</span>
<span class="identifier">rev_ptr_iter</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">ints</span><span class="special">)),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">ints_copy</span><span class="special">));</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">ints</span><span class="special">),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">ints</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">ints_copy</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">ints_copy</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">ints</span><span class="special">),</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">ints</span><span class="special">)));</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
</p>
</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 © 2019 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial___reverse_iterator_.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="../stl_interfaces/compiler_support.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,177 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Rationale</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="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="prev" href="../boost/stl_interfaces/v2/view_interface.html" title="Type definition view_interface">
<link rel="next" href="../thread.html" title="Chapter 40. Thread 4.8.0">
</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="../boost/stl_interfaces/v2/view_interface.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="../thread.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="boost_stlinterfaces.rationale"></a><a class="link" href="rationale.html" title="Rationale">Rationale</a>
</h2></div></div></div>
<h4>
<a name="boost_stlinterfaces.rationale.h0"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale.there_are_minimal_derived_type_contraints"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale.there_are_minimal_derived_type_contraints">There
Are Minimal Derived-Type Contraints</a>
</h4>
<p>
This is the constraint on the <code class="computeroutput"><span class="identifier">Derived</span></code>
template parameter to <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>, <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>
and <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>:
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">enable_if_t</span><span class="special">&lt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">is_class</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">&gt;::</span><span class="identifier">value</span> <span class="special">&amp;&amp;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">is_same</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">remove_cv_t</span><span class="special">&lt;</span><span class="identifier">Derived</span><span class="special">&gt;&gt;::</span><span class="identifier">value</span><span class="special">&gt;</span>
</pre>
<p>
This prevents instantiating an interface template with an <code class="computeroutput"><span class="keyword">int</span></code>,
a <code class="computeroutput"><span class="keyword">const</span></code> type, a reference type,
etc.
</p>
<p>
Further constraints are not possible (for instance, that <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code> is given a <code class="computeroutput"><span class="identifier">Derived</span></code> template parameter for a type that
has a <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>),
because <code class="computeroutput"><span class="identifier">Derived</span></code> is an incomplete
type within each *<code class="computeroutput"><span class="identifier">_interface</span></code>
template.
</p>
<h4>
<a name="boost_stlinterfaces.rationale.h1"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale.using_a_special_access_granting__code__phrase_role__keyword__struct__phrase___code_"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale.using_a_special_access_granting__code__phrase_role__keyword__struct__phrase___code_">Using
a Special Access-Granting <code class="computeroutput"><span class="keyword">struct</span></code></a>
</h4>
<p>
The interface templates rely mostly on public members provided by their <code class="computeroutput"><span class="identifier">Derived</span></code> template parameter. However, <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>
requires you to supply <code class="computeroutput"><span class="identifier">base_reference</span><span class="special">()</span></code> functions if you want it to act like an adaptor.
Since at least the non-<code class="computeroutput"><span class="keyword">const</span></code> overload
provides a non-<code class="computeroutput"><span class="keyword">const</span></code> lvalue reference
to one of your types data members, it will break the encapsulation of many
types to leave <code class="computeroutput"><span class="identifier">base_reference</span><span class="special">()</span></code> a public member. To allow users to keep these
overloads private, <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/access.html" title="Struct access">access</a></code> exists.
</p>
<h4>
<a name="boost_stlinterfaces.rationale.h2"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__iterator_interface___code__phrase_role__identifier__iterator_interface__phrase___code___classname__can_act_like_an_adaptor__and_the_other_interface_templates_can_t"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__iterator_interface___code__phrase_role__identifier__iterator_interface__phrase___code___classname__can_act_like_an_adaptor__and_the_other_interface_templates_can_t">iterator_interface
Can Act Like an Adaptor, And the Other Interface Templates Can't</a>
</h4>
<p>
There wouldn't be much point in adding this functionality to <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>, because it only
uses the <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>
of the <code class="computeroutput"><span class="identifier">Derived</span></code> type anyway.
</p>
<p>
For <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>
it also does not make much sense. Consider how many container adaptors you've
written. That's a use case that does not come up often.
</p>
<h4>
<a name="boost_stlinterfaces.rationale.h3"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__iterator_interface___code__phrase_role__identifier__iterator_interface__phrase___code___classname__takes_a_lot_of_template_parameters__and_the_other_interface_templates_don_t"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__iterator_interface___code__phrase_role__identifier__iterator_interface__phrase___code___classname__takes_a_lot_of_template_parameters__and_the_other_interface_templates_don_t">iterator_interface
Takes a Lot of Template Parameters, And the Other Interface Templates Don't</a>
</h4>
<p>
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> does in fact
take a lot of template parameters. However, it usually only takes three: the
<code class="computeroutput"><span class="identifier">Derived</span></code> type, the iterator
category, and the iterator's <code class="computeroutput"><span class="identifier">value_type</span></code>.
</p>
<p>
When you make a proxy iterator, you typically use the <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/proxy_iterator_interface.html" title="Type definition proxy_iterator_interface">proxy_iterator_interface</a></code> alias,
and you again only need the same three template parameters. Though you can
opt into more template parameters, the rest are seldom necessary.
</p>
<p>
By contrast, the <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code> and <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>
templates have very few template parameters. For <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>, this is because
there are no member typedefs in the <code class="computeroutput"><span class="identifier">view</span></code>
concept. For <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>,
it was deemed ridiculous to create a template whose purpose is to reduce code
size, which takes 14 template parameters.
</p>
<h4>
<a name="boost_stlinterfaces.rationale.h4"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__sequence_container_interface___code__phrase_role__identifier__sequence_container_interface__phrase___code___classname__does_not_deduce_nested_types_like__code__phrase_role__identifier__iterator__phrase___code_"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__sequence_container_interface___code__phrase_role__identifier__sequence_container_interface__phrase___code___classname__does_not_deduce_nested_types_like__code__phrase_role__identifier__iterator__phrase___code_">sequence_container_interface
Does not Deduce Nested Types Like <code class="computeroutput"><span class="identifier">iterator</span></code></a>
</h4>
<p>
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>
could deduce some of the nested types required for a standard sequence container.
For instance, <code class="computeroutput"><span class="identifier">iterator</span></code> can
be deduced as <code class="computeroutput"><span class="keyword">decltype</span><span class="special">(*</span><span class="identifier">begin</span><span class="special">())</span></code>.
However, a type <code class="computeroutput"><span class="identifier">D</span></code> derived from
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>
may need to use some of these nested types — like <code class="computeroutput"><span class="identifier">iterator</span></code>
— in its interface or implementation. If this is the case, those nested
types are not available early enough in the parse to be used in <code class="computeroutput"><span class="identifier">D</span></code>, if they come from deductions in <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>.
This leaves the user in the awkward position of defining the same nested type
with a different name that can be used within <code class="computeroutput"><span class="identifier">D</span></code>.
It seems better to leave these types for the user to define.
</p>
<h4>
<a name="boost_stlinterfaces.rationale.h5"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__sequence_container_interface___code__phrase_role__identifier__sequence_container_interface__phrase___code___classname__does_not_support_associative_or_unordered_associative_containers"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__sequence_container_interface___code__phrase_role__identifier__sequence_container_interface__phrase___code___classname__does_not_support_associative_or_unordered_associative_containers">sequence_container_interface
Does not Support Associative or Unordered Associative Containers</a>
</h4>
<p>
That's right. Associative containers have an interface that assumes that they
are node-based containers. On modern hardware, node-based containers are not
very efficient, and I don't want to encourage people to write more of them.
Unordered associative containers have an interface that precludes open addressing.
I don't want to encourage more of that either.
</p>
<h4>
<a name="boost_stlinterfaces.rationale.h6"></a>
<span class="phrase"><a name="boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__sequence_container_interface___code__phrase_role__identifier__sequence_container_interface__phrase___code___classname__does_not_satisfy_the_allocator_aware_container_requirements"></a></span><a class="link" href="rationale.html#boost_stlinterfaces.rationale._classname_alt__boost__stl_interfaces__v1__sequence_container_interface___code__phrase_role__identifier__sequence_container_interface__phrase___code___classname__does_not_satisfy_the_allocator_aware_container_requirements">sequence_container_interface
Does not Satisfy the Allocator-Aware Container Requirements</a>
</h4>
<p>
It may not be immediately obvious, but <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>
simply cannot help with the allocator-aware requirements. All of the allocator-aware
requirements but 3 are special members and constructors. A <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" target="_top">CRTP</a>
base template is unable to provide those, based on the language rules. That
leaves the <code class="computeroutput"><span class="identifier">allocator_type</span></code> typedef,
which the user must provide; member <code class="computeroutput"><span class="identifier">swap</span><span class="special">()</span></code>, which is already a container requirement
(the allocator-aware table entry just specifies that member <code class="computeroutput"><span class="identifier">swap</span><span class="special">()</span></code> must be constant-time); and <code class="computeroutput"><span class="identifier">get_allocator</span><span class="special">()</span></code>,
which again is something the user must provide.
</p>
<p>
Most of the difficulty of dealing with allocators has to do with the implementation
details of their use within your container. <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/sequ_1_3_40_11_2_5_1_1_1_1.html" title="Struct template sequence_container_interface">sequence_container_interface</a></code>
provides missing elements of a sequence container's interface, by calling user-provided
members of that same interface. It cannot help you with your container's implementation.
</p>
</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 © 2019 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/stl_interfaces/v2/view_interface.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="../thread.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,93 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>This Library's Relationship to Boost.Iterator</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="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="prev" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="next" href="tutorial___iterator_interface_.html" title="Tutorial: iterator_interface">
</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="../stl_interfaces.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="tutorial___iterator_interface_.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="boost_stlinterfaces.this_library_s_relationship_to_boost_iterator"></a><a class="link" href="this_library_s_relationship_to_boost_iterator.html" title="This Library's Relationship to Boost.Iterator">This
Library's Relationship to Boost.Iterator</a>
</h2></div></div></div>
<p>
<a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>
is a library that is already in Boost, and it has been around for a long time.
</p>
<p>
However, it was attempting to solve a lot of problems related to iterators,
not just how to write them from scratch. It is also not easy to modernize it
for use in C++11 and later. Specifically:
</p>
<p>
- <a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>
contains a large number of iterator adaptors; those have since been rendered
moot by C++20 ranges.
</p>
<p>
- <a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>'s
<code class="computeroutput"><span class="identifier">iterator_facade</span></code> template is
not limited just to the existing standard C++ iterator categories; that was
an experiment that never landed in standard C++, so it adds needless complexity.
</p>
<p>
- <a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>'s
<code class="computeroutput"><span class="identifier">iterator_facade</span></code> was written
against C++98, so it is not <code class="computeroutput"><span class="keyword">constexpr</span></code>-
and <code class="computeroutput"><span class="keyword">noexcept</span></code>-friendly.
</p>
<p>
- <a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>'s
<code class="computeroutput"><span class="identifier">iterator_facade</span></code> does not support
proxy iterators, which are fully supported by the C++20 iterator concepts.
</p>
<p>
- There is opportunity to reduce the amount of code the user must write in
order to use <code class="computeroutput"><span class="identifier">iterator_facade</span></code>.
</p>
<p>
- <a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>
contains two templates, <code class="computeroutput"><span class="identifier">iterator_facade</span></code>
and <code class="computeroutput"><span class="identifier">iterator_adaptor</span></code>, that
represent two ways of writing a new iterator while writing as little code as
possible. It would be nice to have the functionality for both available in
one template, but it is difficult to unify those two templates as written.
</p>
<p>
For these reasons, it seems more appropriate to introduce a new Boost library
than to try and address the shortcomings of <a href="https://www.boost.org/doc/libs/release/libs/iterator" target="_top">Boost.Iterator</a>'s
<code class="computeroutput"><span class="identifier">iterator_facade</span></code> and <code class="computeroutput"><span class="identifier">iterator_adaptor</span></code> templates directly.
</p>
</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 © 2019 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../stl_interfaces.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="tutorial___iterator_interface_.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,862 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial: iterator_interface</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="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="prev" href="this_library_s_relationship_to_boost_iterator.html" title="This Library's Relationship to Boost.Iterator">
<link rel="next" href="tutorial___view_interface_.html" title="Tutorial: view_interface">
</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="this_library_s_relationship_to_boost_iterator.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="tutorial___view_interface_.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="boost_stlinterfaces.tutorial___iterator_interface_"></a><a class="link" href="tutorial___iterator_interface_.html" title="Tutorial: iterator_interface">Tutorial:
<code class="computeroutput"><span class="identifier">iterator_interface</span></code></a>
</h2></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
All the member functions provided by <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> are in your
iterator's base class — <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>
and can therefore be hidden if you define a member function with the same
name in your derived iterator. If you don't like the semantics of any <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>-provided
member function, feel free to replace it.
</p></td></tr>
</table></div>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h0"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.the__code__phrase_role__identifier__iterator_interface__phrase___code__template"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.the__code__phrase_role__identifier__iterator_interface__phrase___code__template">The
<code class="computeroutput"><span class="identifier">iterator_interface</span></code> Template</a>
</h4>
<p>
Though a given iterator may have a large number of operations associated with
it, there are only a few basis operations that the iterator needs to define;
the full set of operations it supports can be defined in terms of that much
smaller basis.
</p>
<p>
It is possible to define any iterator <code class="computeroutput"><span class="identifier">Iter</span></code>
in terms of a subset of user-defined operations. By deriving <code class="computeroutput"><span class="identifier">Iter</span></code> from <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> using <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" target="_top">CRTP</a>,
we can generate the full set of operations. Here is the declaration of <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
<span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">IteratorConcept</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">ValueType</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Reference</span> <span class="special">=</span> <span class="identifier">ValueType</span> <span class="special">&amp;,</span>
<span class="keyword">typename</span> <span class="identifier">Pointer</span> <span class="special">=</span> <span class="identifier">ValueType</span> <span class="special">*,</span>
<span class="keyword">typename</span> <span class="identifier">DifferenceType</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">iterator_interface</span><span class="special">;</span>
</pre>
<p>
Let's break that down.
</p>
<p>
<code class="computeroutput"><span class="identifier">Derived</span></code> is the type that you're
deriving <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> from.
</p>
<p>
<code class="computeroutput"><span class="identifier">IteratorConcept</span></code> defines the
iterator category/concept. This must be one of the C++ standard iterator tag
types, like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span></code>. In C++20 and later,
<code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">contiguous_iterator_tag</span></code> is a valid tag to
use.
</p>
<p>
<code class="computeroutput"><span class="identifier">ValueType</span></code> is used to define
the iterator's <code class="computeroutput"><span class="identifier">value_type</span></code> typedef.
Likewise, <code class="computeroutput"><span class="identifier">Reference</span></code> and <code class="computeroutput"><span class="identifier">Pointer</span></code> are used to define the iterator's
<code class="computeroutput"><span class="identifier">reference</span></code> and <code class="computeroutput"><span class="identifier">pointer</span></code> typedefs, respectively.
</p>
<div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">Reference</span></code> does not need to
be a reference type, and <code class="computeroutput"><span class="identifier">Pointer</span></code>
does not need to be a pointer type. This fact is very useful when making
proxy iterators.
</p></td></tr>
</table></div>
<p>
<code class="computeroutput"><span class="identifier">DifferenceType</span></code> is used to define
the iterator's <code class="computeroutput"><span class="identifier">difference_type</span></code>.
Don't be a weirdo; just leave this as the default type, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span></code>.
</p>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h1"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.proxy_iterators"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.proxy_iterators">Proxy
Iterators</a>
</h4>
<p>
Sometimes you need to create an iterator <code class="computeroutput"><span class="identifier">I</span></code>
such that <code class="computeroutput"><span class="identifier">I</span><span class="special">::</span><span class="identifier">reference_type</span></code> is not a (possibly <code class="computeroutput"><span class="keyword">const</span></code>) reference to <code class="computeroutput"><span class="identifier">I</span><span class="special">::</span><span class="identifier">value_type</span></code>.
For instance, let's say you want to make a zip-iterator that produces pairs
of values from two separate underlying sequences. For sequences <code class="computeroutput"><span class="identifier">A</span></code> and <code class="computeroutput"><span class="identifier">B</span></code>,
with respective <code class="computeroutput"><span class="identifier">value_type</span></code>s
<code class="computeroutput"><span class="identifier">T</span></code> and <code class="computeroutput"><span class="identifier">U</span></code>,
one possible <code class="computeroutput"><span class="identifier">reference_type</span></code>
for a zip iterator would be <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span> <span class="special">&amp;,</span> <span class="identifier">U</span> <span class="special">&amp;&gt;</span></code>
(this is distinct from a reference to a pair, such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="special">&amp;</span></code>).
Each such pair would contain a reference to one element from <code class="computeroutput"><span class="identifier">A</span></code> and a reference to the corresponding element
from <code class="computeroutput"><span class="identifier">B</span></code>.
</p>
<p>
As another example, if you wanted an iterator <code class="computeroutput"><span class="identifier">I</span></code>
that represents the infinite sequence 0, 1, 2, ..., you'd be unable to form
a reference to most or all of those values; you'd instead produce a temporary
for each value as it is needed. This implies that <code class="computeroutput"><span class="identifier">I</span><span class="special">::</span><span class="identifier">value_type</span></code>
does not involve references at all; it may instead by <code class="computeroutput"><span class="keyword">int</span></code>
or <code class="computeroutput"><span class="keyword">double</span></code>.
</p>
<p>
When defining a proxy iterator, you can use a template alias that provides
reasonable defaults for <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>'s parameters:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span>
<span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">IteratorConcept</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">ValueType</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">Reference</span> <span class="special">=</span> <span class="identifier">ValueType</span><span class="special">,</span>
<span class="keyword">typename</span> <span class="identifier">DifferenceType</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span><span class="special">&gt;</span>
<span class="keyword">using</span> <span class="identifier">proxy_iterator_interface</span> <span class="special">=</span> <span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">Derived</span><span class="special">,</span>
<span class="identifier">IteratorConcept</span><span class="special">,</span>
<span class="identifier">ValueType</span><span class="special">,</span>
<span class="identifier">Reference</span><span class="special">,</span>
<span class="identifier">proxy_arrow_result</span><span class="special">&lt;</span><span class="identifier">Reference</span><span class="special">&gt;,</span>
<span class="identifier">DifferenceType</span><span class="special">&gt;;</span>
</pre>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
As shown above, <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/proxy_iterator_interface.html" title="Type definition proxy_iterator_interface">proxy_iterator_interface</a></code> uses
a template called <code class="computeroutput"><span class="identifier">proxy_arrow_result</span></code>
as its pointer-type. This template makes a copy of whatever value is obtained
by <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>,
and then returns a pointer to the copy in its <code class="computeroutput"><span class="keyword">operator</span><span class="special">-&gt;</span></code>. You may want to use something else
if this is a performance concern.
</p></td></tr>
</table></div>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h2"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.user_defined_iterator_operations"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.user_defined_iterator_operations">User-Defined
Iterator Operations</a>
</h4>
<p>
Now, let's get back to the user-defined basis operations.
</p>
<p>
In the table below, <code class="computeroutput"><span class="identifier">Iter</span></code> is
a user-defined type derived from <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>; <code class="computeroutput"><span class="identifier">i</span></code> and <code class="computeroutput"><span class="identifier">i2</span></code>
are objects of type <code class="computeroutput"><span class="identifier">Iter</span></code>;
<code class="computeroutput"><span class="identifier">reference</span></code> is the type passed
as the <code class="computeroutput"><span class="identifier">Reference</span></code> template parameter
to <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>; <code class="computeroutput"><span class="identifier">pointer</span></code> is the type passed as the <code class="computeroutput"><span class="identifier">Pointer</span></code> template parameter to <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>;
and <code class="computeroutput"><span class="identifier">n</span></code> is a value of type <code class="computeroutput"><span class="identifier">difference_type</span></code>.
</p>
<div class="table">
<a name="boost_stlinterfaces.tutorial___iterator_interface_.t0"></a><p class="title"><b>Table 39.1. User-Defined Operations</b></p>
<div class="table-contents"><table class="table" summary="User-Defined Operations">
<colgroup>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Expression
</p>
</th>
<th>
<p>
Return Type
</p>
</th>
<th>
<p>
Semantics
</p>
</th>
<th>
<p>
Assertion/note/pre-/post-condition
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="special">*</span><span class="identifier">i</span></code>
</p>
</td>
<td>
<p>
Convertible to <code class="computeroutput"><span class="identifier">reference</span></code>.
</p>
</td>
<td>
<p>
Dereferences <code class="computeroutput"><span class="identifier">i</span></code> and
returns the result.
</p>
</td>
<td>
<p>
<span class="emphasis"><em>Expects:</em></span> i is dereferenceable.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">i</span> <span class="special">==</span>
<span class="identifier">i2</span></code>
</p>
</td>
<td>
<p>
Contextually convertible to <code class="computeroutput"><span class="keyword">bool</span></code>.
</p>
</td>
<td>
<p>
Returns true if and only if <code class="computeroutput"><span class="identifier">i</span></code>
and <code class="computeroutput"><span class="identifier">i2</span></code> refer to the
same value.
</p>
</td>
<td>
<p>
<span class="emphasis"><em>Expects:</em></span> <code class="computeroutput"><span class="special">(</span><span class="identifier">i</span><span class="special">,</span> <span class="identifier">i2</span><span class="special">)</span></code>
is in the domain of <code class="computeroutput"><span class="special">==</span></code>.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">i2</span> <span class="special">-</span>
<span class="identifier">i</span></code>
</p>
</td>
<td>
<p>
Convertible to <code class="computeroutput"><span class="identifier">difference_type</span></code>.
</p>
</td>
<td>
<p>
Returns <code class="computeroutput"><span class="identifier">n</span></code>.
</p>
</td>
<td>
<p>
<span class="emphasis"><em>Expects:</em></span> there exists a value <code class="computeroutput"><span class="identifier">n</span></code> of type <code class="computeroutput"><span class="identifier">difference_type</span></code>
such that <code class="computeroutput"><span class="identifier">i</span> <span class="special">+</span>
<span class="identifier">n</span> <span class="special">==</span>
<span class="identifier">i2</span></code>. <code class="computeroutput"><span class="identifier">i2</span>
<span class="special">==</span> <span class="identifier">i</span>
<span class="special">+</span> <span class="special">(</span><span class="identifier">i2</span> <span class="special">-</span>
<span class="identifier">i</span><span class="special">)</span></code>.
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="special">++</span><span class="identifier">i</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">Iter</span> <span class="special">&amp;</span></code>
</p>
</td>
<td>
<p>
Increments <code class="computeroutput"><span class="identifier">i</span></code>.
</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="special">--</span><span class="identifier">i</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">Iter</span> <span class="special">&amp;</span></code>
</p>
</td>
<td>
<p>
Decrements <code class="computeroutput"><span class="identifier">i</span></code>.
</p>
</td>
<td>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">i</span> <span class="special">+=</span>
<span class="identifier">n</span></code>
</p>
</td>
<td>
<p>
<code class="computeroutput"><span class="identifier">Iter</span> <span class="special">&amp;</span></code>
</p>
</td>
<td>
<p>
</p>
<pre class="programlisting"><span class="identifier">difference_type</span> <span class="identifier">m</span> <span class="special">=</span> <span class="identifier">n</span><span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">m</span> <span class="special">&gt;=</span> <span class="number">0</span><span class="special">)</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">m</span><span class="special">--)</span> <span class="special">++</span><span class="identifier">i</span><span class="special">;</span>
<span class="keyword">else</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">m</span><span class="special">++)</span> <span class="special">--</span><span class="identifier">i</span><span class="special">;</span></pre>
<p>
</p>
</td>
<td>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="tip"><table border="0" summary="Tip">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td>
<th align="left">Tip</th>
</tr>
<tr><td align="left" valign="top"><p>
The table above leaves a lot of implementation freedom. In <code class="computeroutput"><span class="keyword">operator</span><span class="special">+=()</span></code>,
you could take <code class="computeroutput"><span class="identifier">n</span></code> as a value
or as a reference; <code class="computeroutput"><span class="keyword">operator</span><span class="special">-()</span></code> can return a <code class="computeroutput"><span class="identifier">difference_type</span></code>
or just something convertible to one; etc. In particular, your operations
can be <code class="computeroutput"><span class="keyword">constexpr</span></code> or <code class="computeroutput"><span class="keyword">noexcept</span></code> as you see fit.
</p></td></tr>
</table></div>
<p>
Not all the iterator concepts require all the operations above. Here are the
operations used with each iterator concept:
</p>
<div class="table">
<a name="boost_stlinterfaces.tutorial___iterator_interface_.t1"></a><p class="title"><b>Table 39.2. Operations Required for Each Concept</b></p>
<div class="table-contents"><table class="table" summary="Operations Required for Each Concept">
<colgroup>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
Concept
</p>
</th>
<th>
<p>
Operations
</p>
</th>
</tr></thead>
<tbody>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">input_iterator</span></code>
</p>
</td>
<td>
<p>
</p>
<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span>
<span class="identifier">i</span> <span class="special">==</span> <span class="identifier">i2</span>
<span class="special">++</span><span class="identifier">i</span></pre>
<p>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">output_iterator</span></code>
</p>
</td>
<td>
<p>
</p>
<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span>
<span class="special">++</span><span class="identifier">i</span></pre>
<p>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">forward_iterator</span></code>
</p>
</td>
<td>
<p>
</p>
<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span>
<span class="identifier">i</span> <span class="special">==</span> <span class="identifier">i2</span>
<span class="special">++</span><span class="identifier">i</span></pre>
<p>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">bidirectional_iterator</span></code>
</p>
</td>
<td>
<p>
</p>
<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span>
<span class="identifier">i</span> <span class="special">==</span> <span class="identifier">i2</span>
<span class="special">++</span><span class="identifier">i</span>
<span class="special">--</span><span class="identifier">i</span></pre>
<p>
</p>
</td>
</tr>
<tr>
<td>
<p>
<code class="computeroutput"><span class="identifier">random_access_iterator</span></code>/<code class="computeroutput"><span class="identifier">continguous_iterator</span></code>
</p>
</td>
<td>
<p>
</p>
<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span>
<span class="identifier">i</span> <span class="special">-</span> <span class="identifier">i2</span>
<span class="identifier">i</span> <span class="special">+=</span> <span class="identifier">n</span></pre>
<p>
</p>
</td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
For <code class="computeroutput"><span class="identifier">random_access_iterator</span></code>s,
the operation <code class="computeroutput"><span class="identifier">i</span> <span class="special">-</span>
<span class="identifier">i2</span></code> is used to provide all the relational
operators, including <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>. If you are defining an iterator over
a discontiguous sequence (e.g. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span></code>),
this implementation of <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code> may not be optimal. In this case, provide
your own <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code>.
<code class="computeroutput"><span class="keyword">operator</span><span class="special">!=()</span></code>
will be provided if <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> is available.
</p></td></tr>
</table></div>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h3"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.an_important_note_about__code__phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code__and__code__phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code_"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.an_important_note_about__code__phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code__and__code__phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code_">An
Important Note About <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></a>
</h4>
<p>
There's a wrinkle in this way of doing things. When you define <code class="computeroutput"><span class="keyword">operator</span><span class="special">++()</span></code>
in your iterator type <code class="computeroutput"><span class="identifier">Derived</span></code>,
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> defines post-increment,
<code class="computeroutput"><span class="keyword">operator</span><span class="special">++(</span><span class="keyword">int</span><span class="special">)</span></code>. But since
<code class="computeroutput"><span class="identifier">Derived</span></code> has an <code class="computeroutput"><span class="keyword">operator</span><span class="special">++</span></code> and
so does its base class <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>, the one in
<code class="computeroutput"><span class="identifier">Derived</span></code> <span class="bold"><strong>hides</strong></span>
the one in <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>.
</p>
<p>
So, you need to add a using declaration that makes the <code class="computeroutput"><span class="keyword">operator</span><span class="special">++</span></code> from the base class visible in the derived
class. For instance, in the <code class="computeroutput"><span class="identifier">node_iterator</span></code>
example there are these lines:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">base_type</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span>
<span class="identifier">iterator_interface</span><span class="special">&lt;</span><span class="identifier">node_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">++;</span>
</pre>
<p>
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
All of the above applies to <code class="computeroutput"><span class="keyword">operator</span><span class="special">--</span></code>. So, for bidirectional iterators, you need
to add a line like <code class="computeroutput"><span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">--;</span></code> as well.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
These using declarations are not necessary for a random access iterator,
because <code class="computeroutput"><span class="identifier">Derived</span></code> does not
have an <code class="computeroutput"><span class="keyword">operator</span><span class="special">++()</span></code>
in that case.
</p></td></tr>
</table></div>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h4"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.putting_it_all_together"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.putting_it_all_together">Putting
it All Together</a>
</h4>
<p>
Ok, let's actually define a simple iterator. Let's say you need to interact
with some legacy code that has a hand-written linked list:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">node</span>
<span class="special">{</span>
<span class="identifier">T</span> <span class="identifier">value_</span><span class="special">;</span>
<span class="identifier">node</span> <span class="special">*</span> <span class="identifier">next_</span><span class="special">;</span> <span class="comment">// == nullptr in the tail node</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
We can't change this code to use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span></code>, but
it would be nice to be able to reuse all of the standard algorithms with this
type. Defining an iterator will get us there.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">node_iterator</span>
<span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span>
<span class="identifier">iterator_interface</span><span class="special">&lt;</span><span class="identifier">node_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;</span>
</pre>
<p>
</p>
<p>
We are deriving <code class="computeroutput"><span class="identifier">node_iterator</span></code>
from <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>, and because
we're using <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" target="_top">CRTP</a>,
we first have to pass <code class="computeroutput"><span class="identifier">node_iterator</span></code>
for the <code class="computeroutput"><span class="identifier">Derived</span></code> template parameter,
so that <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> knows what
derived type to cast to in order to get at the user-defined operations. Then,
we pass <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span></code> for <code class="computeroutput"><span class="identifier">IteratorConcept</span></code>,
since that's appropriate for a singly-linked list. Finally, we pass <code class="computeroutput"><span class="identifier">T</span></code> to let <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> know what
the <code class="computeroutput"><span class="identifier">value_type</span></code> is for our iterator.
</p>
<p>
We leave the rest of the template parameters at their defaults: <code class="computeroutput"><span class="identifier">T</span> <span class="special">&amp;</span></code> for
<code class="computeroutput"><span class="identifier">Reference</span></code>, <code class="computeroutput"><span class="identifier">T</span>
<span class="special">*</span></code> for <code class="computeroutput"><span class="identifier">Pointer</span></code>,
and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ptrdiff_t</span></code> for <code class="computeroutput"><span class="identifier">DifferenceType</span></code>.
This is what you will do for almost all iterators. The most common exceptions
to this are usually some kind of proxy iterator. Another exception is when
for better code generation you want to return builtin values instead of references
for constant iterators. To see an example of the latter, see the <code class="computeroutput"><span class="identifier">repeated_chars_iterator</span></code> in the introduction;
it's <code class="computeroutput"><span class="identifier">Reference</span></code> template parameter
is <code class="computeroutput"><span class="keyword">char</span></code> for this reason.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="identifier">node_iterator</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">(</span><span class="keyword">nullptr</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">constexpr</span> <span class="identifier">node_iterator</span><span class="special">(</span><span class="identifier">node</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">*</span> <span class="identifier">it</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">(</span><span class="identifier">it</span><span class="special">)</span> <span class="special">{}</span>
</pre>
<p>
</p>
<p>
Next, we define two constructors: a default constructor, and one that takes
a <code class="computeroutput"><span class="identifier">node</span></code> pointer. A default constructor
is required by the <code class="computeroutput"><span class="identifier">forward_iterator</span></code>
concept, but <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> cannot supply
this, since constructors are not visible in derived types without user intervention.
</p>
<div class="important"><table border="0" summary="Important">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td>
<th align="left">Important</th>
</tr>
<tr><td align="left" valign="top"><p>
A default constructor is required for every iterator concept.
</p></td></tr>
</table></div>
<p>
</p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="identifier">T</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">it_</span><span class="special">-&gt;</span><span class="identifier">value_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">constexpr</span> <span class="identifier">node_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">++()</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="identifier">it_</span> <span class="special">=</span> <span class="identifier">it_</span><span class="special">-&gt;</span><span class="identifier">next_</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">friend</span> <span class="keyword">constexpr</span> <span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">==(</span><span class="identifier">node_iterator</span> <span class="identifier">lhs</span><span class="special">,</span> <span class="identifier">node_iterator</span> <span class="identifier">rhs</span><span class="special">)</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">lhs</span><span class="special">.</span><span class="identifier">it_</span> <span class="special">==</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">it_</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
Next, we define the user-defined operations that <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> requires to
do its work. As you might expect, the three required operations are very straightforward.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top">
<p>
Here, I implement <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code>
as a hidden friend function. it would have worked just as well if I had instead
implemented it as a member function, like this:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">constexpr</span> <span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">==(</span><span class="identifier">node_iterator</span> <span class="identifier">rhs</span><span class="special">)</span> <span class="keyword">const</span> <span class="keyword">noexcept</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">it_</span> <span class="special">==</span> <span class="identifier">rhs</span><span class="special">.</span><span class="identifier">it_</span><span class="special">;</span>
<span class="special">}</span></pre>
<p>
</p>
<p>
Either of these forms works, since <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> is concept-based
— the appropriate expressions need to be well-formed for the <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>
tempalte to do its work.
</p>
</td></tr>
</table></div>
<p>
Finally, we need a using declaration to make <code class="computeroutput"><span class="identifier">iterator_interface</span><span class="special">::</span><span class="keyword">operator</span><span class="special">++(</span><span class="keyword">int</span><span class="special">)</span></code> visible:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="identifier">base_type</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span>
<span class="identifier">iterator_interface</span><span class="special">&lt;</span><span class="identifier">node_iterator</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator_tag</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&gt;;</span>
<span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">++;</span>
</pre>
<p>
</p>
<p>
Here's how we might use the forward iterator we just defined:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">node_iterator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">first</span><span class="special">(&amp;</span><span class="identifier">nodes</span><span class="special">[</span><span class="number">0</span><span class="special">]);</span>
<span class="identifier">node_iterator</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">last</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">first</span><span class="special">;</span> <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">;</span> <span class="identifier">it</span><span class="special">++)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="special">*</span><span class="identifier">it</span> <span class="special">&lt;&lt;</span> <span class="string">" "</span><span class="special">;</span> <span class="comment">// Prints 0 1 2 3 4</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"\n"</span><span class="special">;</span>
</pre>
<p>
</p>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h5"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.what_about_adapting_an_existing_iterator_"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.what_about_adapting_an_existing_iterator_">What
About Adapting an Existing Iterator?</a>
</h4>
<p>
So glad you asked. If you want to make something like a filtering iterator,
or say a UTF-8 to UTF-32 transcoding iterator, you are starting with an existing
iterator and adapting it. There's a way to avoid having to write all of the
user-defined basis functions, as long as there's a base iterator that already
has the right operations with the right semantics.
</p>
<p>
For example, consider an iterator that contains a pointer to an array of <code class="computeroutput"><span class="keyword">int</span></code>, and predicate of type <code class="computeroutput"><span class="identifier">Pred</span></code>.
It filters out integers that do not meet the predicate. Since we are using
an existing iterator (the pointer to <code class="computeroutput"><span class="keyword">int</span></code>),
we already have all the operations we need for a bidirectional iterator (and
more), except that <code class="computeroutput"><span class="keyword">operator</span><span class="special">++</span></code>
on an <code class="computeroutput"><span class="keyword">int</span> <span class="special">*</span></code>
does not skip over elements as we'd like. Here's the code:
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Pred</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">filtered_int_iterator</span> <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">iterator_interface</span><span class="special">&lt;</span>
<span class="identifier">filtered_int_iterator</span><span class="special">&lt;</span><span class="identifier">Pred</span><span class="special">&gt;,</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">bidirectional_iterator_tag</span><span class="special">,</span>
<span class="keyword">int</span><span class="special">&gt;</span>
<span class="special">{</span>
<span class="identifier">filtered_int_iterator</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">it_</span><span class="special">(</span><span class="keyword">nullptr</span><span class="special">)</span> <span class="special">{}</span>
<span class="identifier">filtered_int_iterator</span><span class="special">(</span><span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">*</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">it_</span><span class="special">(</span><span class="identifier">it</span><span class="special">),</span>
<span class="identifier">last_</span><span class="special">(</span><span class="identifier">last</span><span class="special">),</span>
<span class="identifier">pred_</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pred</span><span class="special">))</span>
<span class="special">{</span>
<span class="comment">// We need to do this in the constructor so that operator== works</span>
<span class="comment">// properly on two filtered_int_iterators, when they bound a sequence</span>
<span class="comment">// in which none of the ints meets the predicate.</span>
<span class="identifier">it_</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find_if</span><span class="special">(</span><span class="identifier">it_</span><span class="special">,</span> <span class="identifier">last_</span><span class="special">,</span> <span class="identifier">pred_</span><span class="special">);</span>
<span class="special">}</span>
<span class="comment">// A bidirectional iterator based on iterator_interface usually required</span>
<span class="comment">// four user-defined operations. since we are adapting an existing</span>
<span class="comment">// iterator (an int *), we only need to define this one. The others are</span>
<span class="comment">// implemented by iterator_interface, using the underlying int *.</span>
<span class="identifier">filtered_int_iterator</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">++()</span>
<span class="special">{</span>
<span class="identifier">it_</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find_if</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">next</span><span class="special">(</span><span class="identifier">it_</span><span class="special">),</span> <span class="identifier">last_</span><span class="special">,</span> <span class="identifier">pred_</span><span class="special">);</span>
<span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span>
<span class="special">}</span>
<span class="comment">// It is really common for iterator adaptors to have a base() member</span>
<span class="comment">// function that returns the adapted iterator.</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="identifier">base</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="comment">// Provide access to these private members.</span>
<span class="keyword">friend</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">access</span><span class="special">;</span>
<span class="comment">// These functions are picked up by iterator_interface, and used to</span>
<span class="comment">// implement any operations that you don't define above. They're not</span>
<span class="comment">// called base() so that they do not collide with the base() member above.</span>
<span class="comment">//</span>
<span class="comment">// Note that the const overload does not strictly speaking need to be a</span>
<span class="comment">// reference, as demonstrated here.</span>
<span class="keyword">constexpr</span> <span class="keyword">int</span> <span class="special">*&amp;</span> <span class="identifier">base_reference</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">constexpr</span> <span class="keyword">int</span> <span class="special">*</span> <span class="identifier">base_reference</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it_</span><span class="special">;</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="identifier">last_</span><span class="special">;</span>
<span class="identifier">Pred</span> <span class="identifier">pred_</span><span class="special">;</span>
<span class="special">};</span>
<span class="comment">// A make-function makes it easier to deal with the Pred parameter.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Pred</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">make_filtered_int_iterator</span><span class="special">(</span><span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">*</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">filtered_int_iterator</span><span class="special">&lt;</span><span class="identifier">Pred</span><span class="special">&gt;(</span><span class="identifier">it</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pred</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
So, all we had to do was let <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> know that
there was an underlying iterator it could use — by implementing <code class="computeroutput"><span class="identifier">base_reference</span><span class="special">()</span></code>
— and the operations that we did not define got defined for us by <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>.
</p>
<p>
Here is the iterator in action:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span> <span class="number">8</span><span class="special">&gt;</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{{</span><span class="number">0</span><span class="special">,</span> <span class="number">1</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">,</span> <span class="number">7</span><span class="special">}};</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="keyword">const</span> <span class="identifier">ints_first</span> <span class="special">=</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">();</span>
<span class="keyword">int</span> <span class="special">*</span> <span class="keyword">const</span> <span class="identifier">ints_last</span> <span class="special">=</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">data</span><span class="special">()</span> <span class="special">+</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span>
<span class="keyword">auto</span> <span class="identifier">even</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="special">(</span><span class="identifier">x</span> <span class="special">%</span> <span class="number">2</span><span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">make_filtered_int_iterator</span><span class="special">(</span><span class="identifier">ints_first</span><span class="special">,</span> <span class="identifier">ints_last</span><span class="special">,</span> <span class="identifier">even</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">last</span> <span class="special">=</span> <span class="identifier">make_filtered_int_iterator</span><span class="special">(</span><span class="identifier">ints_last</span><span class="special">,</span> <span class="identifier">ints_last</span><span class="special">,</span> <span class="identifier">even</span><span class="special">);</span>
<span class="comment">// This is an example only. Obviously, we could have called</span>
<span class="comment">// std::copy_if() here.</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ints_copy</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">copy</span><span class="special">(</span><span class="identifier">first</span><span class="special">,</span> <span class="identifier">last</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">back_inserter</span><span class="special">(</span><span class="identifier">ints_copy</span><span class="special">));</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints_copy</span> <span class="special">==</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;{</span><span class="number">0</span><span class="special">,</span> <span class="number">2</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">6</span><span class="special">}));</span>
</pre>
<p>
</p>
<h4>
<a name="boost_stlinterfaces.tutorial___iterator_interface_.h6"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___iterator_interface_.checking_your_work"></a></span><a class="link" href="tutorial___iterator_interface_.html#boost_stlinterfaces.tutorial___iterator_interface_.checking_your_work">Checking
Your Work</a>
</h4>
<p>
Boost.STLInterfaces is able to check that some of the code that you write is
compatible with the concept for the iterator you're writing. It cannot check
everything. For instance, Boost.STLInterfaces does not know if your derived
type includes a default constructor, which is required by all the iterators.
In particular, <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> cannot <code class="computeroutput"><span class="keyword">static_assert</span></code> on the wellformedness of <code class="computeroutput"><span class="identifier">Derived</span><span class="special">()</span></code>,
since <code class="computeroutput"><span class="identifier">Derived</span></code> is an incomplete
type within the body of <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> is the base
class for <code class="computeroutput"><span class="identifier">Derived</span></code>, not the
other way round.
</p>
<p>
Since you can easily <code class="computeroutput"><span class="keyword">static_assert</span></code>
that a type models a given concept, a good practice is to put such a <code class="computeroutput"><span class="keyword">static_assert</span></code> after you define your iterator
type.
</p>
<p>
For instance, after <code class="computeroutput"><span class="identifier">node_iterator</span></code>
you'll find this code:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// static_assert(std::forward_iterator&lt;node_iterator&gt;, ""), or nothing in</span>
<span class="comment">// C++17 and earlier.</span>
<span class="identifier">BOOST_STL_INTERFACES_STATIC_ASSERT_CONCEPT</span><span class="special">(</span><span class="identifier">node_iterator</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward_iterator</span><span class="special">)</span>
</pre>
<p>
</p>
<p>
Consider this good code hygiene. Without this simple check, you'll probably
eventually find yourself looking at an error message with a very long template
instantiation stack.
</p>
<p>
There's also a macro that can help you check that <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">iterator_traits</span></code>
is well-formed and provides the correct types. See <code class="computeroutput"><a class="link" href="../BOOST_STL__1_3_40_11_2_3_3.html" title="Macro BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS">BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS</a></code>.
</p>
</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 © 2019 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="this_library_s_relationship_to_boost_iterator.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="tutorial___view_interface_.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,54 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial: reverse_iterator</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="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="prev" href="tutorial___sequence_container_interface_.html" title="Tutorial: sequence_container_interface">
<link rel="next" href="examples.html" title="Examples">
</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="tutorial___sequence_container_interface_.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="examples.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="boost_stlinterfaces.tutorial___reverse_iterator_"></a><a class="link" href="tutorial___reverse_iterator_.html" title="Tutorial: reverse_iterator">Tutorial:
<code class="computeroutput"><span class="identifier">reverse_iterator</span></code></a>
</h2></div></div></div>
<p>
There is a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse_iterator</span></code> template that has been around
since C++98. In C++20 it is compatible with proxy iterators, and is <code class="computeroutput"><span class="keyword">constexpr</span></code>- and <code class="computeroutput"><span class="keyword">noexcept</span></code>-friendly.
If you are using C++20 or later, just use <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse_iterator</span></code>.
For code built against earlier versions of C++, you can use <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/reverse_iterator.html" title="Struct template reverse_iterator">reverse_iterator</a></code>.
</p>
<p>
There's nothing much to document about it; it works just like <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">reverse_iterator</span></code>.
</p>
</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 © 2019 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial___sequence_container_interface_.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="examples.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,254 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial: view_interface</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="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../stl_interfaces.html" title="Chapter 39. Boost.STLInterfaces">
<link rel="prev" href="tutorial___iterator_interface_.html" title="Tutorial: iterator_interface">
<link rel="next" href="tutorial___sequence_container_interface_.html" title="Tutorial: sequence_container_interface">
</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="tutorial___iterator_interface_.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="tutorial___sequence_container_interface_.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="boost_stlinterfaces.tutorial___view_interface_"></a><a class="link" href="tutorial___view_interface_.html" title="Tutorial: view_interface">Tutorial:
<code class="computeroutput"><span class="identifier">view_interface</span></code></a>
</h2></div></div></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
All the member functions provided by <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code> are in your
view's base class — <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code> — and
can therefore be hidden if you define a member function with the same name
in your derived view. If you don't like the semantics of any <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>-provided member
function, feel free to replace it.
</p></td></tr>
</table></div>
<h4>
<a name="boost_stlinterfaces.tutorial___view_interface_.h0"></a>
<span class="phrase"><a name="boost_stlinterfaces.tutorial___view_interface_.the__code__phrase_role__identifier__view_interface__phrase___code__template"></a></span><a class="link" href="tutorial___view_interface_.html#boost_stlinterfaces.tutorial___view_interface_.the__code__phrase_role__identifier__view_interface__phrase___code__template">The
<code class="computeroutput"><span class="identifier">view_interface</span></code> Template</a>
</h4>
<p>
C++20 contains a <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" target="_top">CRTP</a>
template, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">view_interface</span></code>, which takes a range or view,
and adds all the operations that view types have, using only the range's/view's
<code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code>
and <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>.
This is a C++14-compatible version of that template.
</p>
<p>
As with <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code>, <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>
makes it possible to write very few operations — only <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code> and
<code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>
are actually used by <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code> — and get
all the other operations that go with view types. The operations added depend
on what kinds of iterator and/or sentinel types your derived view type defines.
</p>
<p>
Here is the declaration of <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>:
</p>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">,</span> <span class="identifier">element_layout</span> <span class="identifier">Contiguity</span> <span class="special">=</span> <span class="identifier">element_layout</span><span class="special">::</span><span class="identifier">discontiguous</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">view_interface</span><span class="special">;</span>
</pre>
<p>
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>
only requires the derived type and an optional non-type template parameter
that indicates whether <code class="computeroutput"><span class="identifier">Derived</span></code>'s
iterators are contiguous. The non-type parameter is necessary to support pre-C++20
code.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Proxy iterators are inherently discontiguous.
</p></td></tr>
</table></div>
<p>
In this example, we're implementing something very similar to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">ranges</span><span class="special">::</span><span class="identifier">drop_while_view</span></code>.
First, we need helper view types <code class="computeroutput"><span class="identifier">subrange</span></code>
and <code class="computeroutput"><span class="identifier">all_view</span></code>, and a function
that takes a range and returns a view of the entire range, <code class="computeroutput"><span class="identifier">all</span><span class="special">()</span></code>:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// A subrange is simply an iterator-sentinel pair. This one is a bit simpler</span>
<span class="comment">// than the one in std::ranges; its missing a bunch of constructors, prev(),</span>
<span class="comment">// next(), and advance().</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Iterator</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Sentinel</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">subrange</span>
<span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">view_interface</span><span class="special">&lt;</span><span class="identifier">subrange</span><span class="special">&lt;</span><span class="identifier">Iterator</span><span class="special">,</span> <span class="identifier">Sentinel</span><span class="special">&gt;&gt;</span>
<span class="special">{</span>
<span class="identifier">subrange</span><span class="special">()</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="identifier">subrange</span><span class="special">(</span><span class="identifier">Iterator</span> <span class="identifier">it</span><span class="special">,</span> <span class="identifier">Sentinel</span> <span class="identifier">s</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">first_</span><span class="special">(</span><span class="identifier">it</span><span class="special">),</span> <span class="identifier">last_</span><span class="special">(</span><span class="identifier">s</span><span class="special">)</span> <span class="special">{}</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">first_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">last_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">Iterator</span> <span class="identifier">first_</span><span class="special">;</span>
<span class="identifier">Sentinel</span> <span class="identifier">last_</span><span class="special">;</span>
<span class="special">};</span>
<span class="comment">// std::view::all() returns one of several types, depending on what you pass</span>
<span class="comment">// it. Here, we're keeping it simple; all() always returns a subrange.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">all</span><span class="special">(</span><span class="identifier">Range</span> <span class="special">&amp;&amp;</span> <span class="identifier">range</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">subrange</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">range</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()),</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">range</span><span class="special">.</span><span class="identifier">end</span><span class="special">())&gt;(</span>
<span class="identifier">range</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">range</span><span class="special">.</span><span class="identifier">end</span><span class="special">());</span>
<span class="special">}</span>
<span class="comment">// A template alias that denotes the type of all(r) for some Range r.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">&gt;</span>
<span class="keyword">using</span> <span class="identifier">all_view</span> <span class="special">=</span> <span class="keyword">decltype</span><span class="special">(</span><span class="identifier">all</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">declval</span><span class="special">&lt;</span><span class="identifier">Range</span><span class="special">&gt;()));</span>
</pre>
<p>
</p>
<p>
Note that <code class="computeroutput"><span class="identifier">subrange</span></code> is derived
from <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>, so it will have
all the view-like operations that are appropriate to its <code class="computeroutput"><span class="identifier">Iterator</span></code>
and <code class="computeroutput"><span class="identifier">Sentinel</span></code> types.
</p>
<p>
With the helpers available, we can define <code class="computeroutput"><span class="identifier">drop_while_view</span></code>:
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">// Perhaps its clear now why we defined subrange, all(), etc. above.</span>
<span class="comment">// drop_while_view contains a view data member. If we just took any old range</span>
<span class="comment">// that was passed to drop_while_view's constructor, we'd copy the range</span>
<span class="comment">// itself, which may be a std::vector. So, we want to make a view out of</span>
<span class="comment">// whatever Range we're given so that this copy of an owning range does not</span>
<span class="comment">// happen.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">drop_while_view</span>
<span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span><span class="identifier">view_interface</span><span class="special">&lt;</span><span class="identifier">drop_while_view</span><span class="special">&lt;</span><span class="identifier">Range</span><span class="special">,</span> <span class="identifier">Pred</span><span class="special">&gt;&gt;</span>
<span class="special">{</span>
<span class="keyword">using</span> <span class="identifier">base_type</span> <span class="special">=</span> <span class="identifier">all_view</span><span class="special">&lt;</span><span class="identifier">Range</span><span class="special">&gt;;</span>
<span class="identifier">drop_while_view</span><span class="special">()</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
<span class="keyword">constexpr</span> <span class="identifier">drop_while_view</span><span class="special">(</span><span class="identifier">Range</span> <span class="special">&amp;</span> <span class="identifier">base</span><span class="special">,</span> <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">)</span> <span class="special">:</span>
<span class="identifier">base_</span><span class="special">(</span><span class="identifier">all</span><span class="special">(</span><span class="identifier">base</span><span class="special">)),</span>
<span class="identifier">pred_</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pred</span><span class="special">))</span>
<span class="special">{}</span>
<span class="keyword">constexpr</span> <span class="identifier">base_type</span> <span class="identifier">base</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">base_</span><span class="special">;</span> <span class="special">}</span>
<span class="keyword">constexpr</span> <span class="identifier">Pred</span> <span class="keyword">const</span> <span class="special">&amp;</span> <span class="identifier">pred</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">pred_</span><span class="special">;</span> <span class="special">}</span>
<span class="comment">// A more robust implementation should probably cache the value computed</span>
<span class="comment">// by this function, so that subsequent calls can just return the cached</span>
<span class="comment">// iterator.</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">begin</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">// We're forced to write this out as a raw loop, since no</span>
<span class="comment">// std::-namespace algorithms accept a sentinel.</span>
<span class="keyword">auto</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">base_</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
<span class="keyword">auto</span> <span class="keyword">const</span> <span class="identifier">last</span> <span class="special">=</span> <span class="identifier">base_</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span>
<span class="keyword">for</span> <span class="special">(;</span> <span class="identifier">first</span> <span class="special">!=</span> <span class="identifier">last</span><span class="special">;</span> <span class="special">++</span><span class="identifier">first</span><span class="special">)</span> <span class="special">{</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">pred_</span><span class="special">(*</span><span class="identifier">first</span><span class="special">))</span>
<span class="keyword">break</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">return</span> <span class="identifier">first</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">end</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">base_</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span> <span class="special">}</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">base_type</span> <span class="identifier">base_</span><span class="special">;</span>
<span class="identifier">Pred</span> <span class="identifier">pred_</span><span class="special">;</span>
<span class="special">};</span>
<span class="comment">// Since this is a C++14 and later library, we're not using CTAD; we therefore</span>
<span class="comment">// need a make-function.</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Range</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span><span class="special">&gt;</span>
<span class="keyword">auto</span> <span class="identifier">make_drop_while_view</span><span class="special">(</span><span class="identifier">Range</span> <span class="special">&amp;</span> <span class="identifier">base</span><span class="special">,</span> <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">return</span> <span class="identifier">drop_while_view</span><span class="special">&lt;</span><span class="identifier">Range</span><span class="special">,</span> <span class="identifier">Pred</span><span class="special">&gt;(</span><span class="identifier">base</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pred</span><span class="special">));</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
Now, let's look at code using these types, including operations defined by
<code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>
that we did not have to write:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="keyword">const</span> <span class="identifier">ints</span> <span class="special">=</span> <span class="special">{</span><span class="number">2</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">3</span><span class="special">,</span> <span class="number">4</span><span class="special">,</span> <span class="number">5</span><span class="special">,</span> <span class="number">6</span><span class="special">};</span>
<span class="comment">// all() returns a subrange, which is a view type containing ints.begin()</span>
<span class="comment">// and ints.end().</span>
<span class="keyword">auto</span> <span class="identifier">all_ints</span> <span class="special">=</span> <span class="identifier">all</span><span class="special">(</span><span class="identifier">ints</span><span class="special">);</span>
<span class="comment">// This works using just the used-defined members of subrange: begin() and</span>
<span class="comment">// end().</span>
<span class="identifier">assert</span><span class="special">(</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">equal</span><span class="special">(</span><span class="identifier">all_ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">all_ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">()));</span>
<span class="comment">// These are available because subrange is derived from view_interface.</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">all_ints</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">==</span> <span class="number">3</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">all_ints</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">==</span> <span class="number">6u</span><span class="special">);</span>
<span class="keyword">auto</span> <span class="identifier">even</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">int</span> <span class="identifier">x</span><span class="special">)</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">x</span> <span class="special">%</span> <span class="number">2</span> <span class="special">==</span> <span class="number">0</span><span class="special">;</span> <span class="special">};</span>
<span class="keyword">auto</span> <span class="identifier">ints_after_even_prefix</span> <span class="special">=</span> <span class="identifier">make_drop_while_view</span><span class="special">(</span><span class="identifier">ints</span><span class="special">,</span> <span class="identifier">even</span><span class="special">);</span>
<span class="comment">// Available via begin()/end()...</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">equal</span><span class="special">(</span>
<span class="identifier">ints_after_even_prefix</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span>
<span class="identifier">ints_after_even_prefix</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span>
<span class="identifier">ints</span><span class="special">.</span><span class="identifier">begin</span><span class="special">()</span> <span class="special">+</span> <span class="number">2</span><span class="special">,</span>
<span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">()));</span>
<span class="comment">// ... and via view_interface.</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">ints_after_even_prefix</span><span class="special">.</span><span class="identifier">empty</span><span class="special">());</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints_after_even_prefix</span><span class="special">[</span><span class="number">2</span><span class="special">]</span> <span class="special">==</span> <span class="number">5</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ints_after_even_prefix</span><span class="special">.</span><span class="identifier">back</span><span class="special">()</span> <span class="special">==</span> <span class="number">6</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
If you want more details on <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>, you can find
it wherever you usually find reference documentation on the standard library.
We won't cover it here for that reason. See <a href="http://eel.is/c++draft/view.interface" target="_top">[view.interface</a>
on eel.is] or <a href="https://cppreference.com" target="_top">https://cppreference.com</a>
for details.
</p>
</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 © 2019 T. Zachary Laine<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial___iterator_interface_.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../stl_interfaces.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="tutorial___sequence_container_interface_.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>