• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Tutorial: view_interface</title>
6<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="../stl_interfaces.html" title="Chapter 38. Boost.STLInterfaces">
10<link rel="prev" href="tutorial___iterator_interface_.html" title="Tutorial: iterator_interface">
11<link rel="next" href="tutorial___sequence_container_interface_.html" title="Tutorial: sequence_container_interface">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
16<td align="center"><a href="../../../index.html">Home</a></td>
17<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<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>
25</div>
26<div class="section">
27<div class="titlepage"><div><div><h2 class="title" style="clear: both">
28<a name="boost_stlinterfaces.tutorial___view_interface_"></a><a class="link" href="tutorial___view_interface_.html" title="Tutorial: view_interface">Tutorial:
29    <code class="computeroutput"><span class="identifier">view_interface</span></code></a>
30</h2></div></div></div>
31<div class="note"><table border="0" summary="Note">
32<tr>
33<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
34<th align="left">Note</th>
35</tr>
36<tr><td align="left" valign="top"><p>
37        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
38        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
39        can therefore be hidden if you define a member function with the same name
40        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
41        function, feel free to replace it.
42      </p></td></tr>
43</table></div>
44<h4>
45<a name="boost_stlinterfaces.tutorial___view_interface_.h0"></a>
46      <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
47      <code class="computeroutput"><span class="identifier">view_interface</span></code> Template</a>
48    </h4>
49<p>
50      C++20 contains a <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" target="_top">CRTP</a>
51      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,
52      and adds all the operations that view types have, using only the range's/view's
53      <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code>
54      and <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>.
55      This is a C++14-compatible version of that template.
56    </p>
57<p>
58      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>
59      makes it possible to write very few operations — only <code class="computeroutput"><span class="identifier">begin</span><span class="special">()</span></code> and
60      <code class="computeroutput"><span class="identifier">end</span><span class="special">()</span></code>
61      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
62      all the other operations that go with view types. The operations added depend
63      on what kinds of iterator and/or sentinel types your derived view type defines.
64    </p>
65<p>
66      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>:
67    </p>
68<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>
69<span class="keyword">struct</span> <span class="identifier">view_interface</span><span class="special">;</span>
70</pre>
71<p>
72      <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>
73      only requires the derived type and an optional non-type template parameter
74      that indicates whether <code class="computeroutput"><span class="identifier">Derived</span></code>'s
75      iterators are contiguous. The non-type parameter is necessary to support pre-C++20
76      code.
77    </p>
78<div class="note"><table border="0" summary="Note">
79<tr>
80<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
81<th align="left">Note</th>
82</tr>
83<tr><td align="left" valign="top"><p>
84        Proxy iterators are inherently discontiguous.
85      </p></td></tr>
86</table></div>
87<p>
88      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>.
89      First, we need helper view types <code class="computeroutput"><span class="identifier">subrange</span></code>
90      and <code class="computeroutput"><span class="identifier">all_view</span></code>, and a function
91      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>:
92    </p>
93<p>
94</p>
95<pre class="programlisting"><span class="comment">// A subrange is simply an iterator-sentinel pair.  This one is a bit simpler</span>
96<span class="comment">// than the one in std::ranges; its missing a bunch of constructors, prev(),</span>
97<span class="comment">// next(), and advance().</span>
98<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>
99<span class="keyword">struct</span> <span class="identifier">subrange</span>
100    <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>
101<span class="special">{</span>
102    <span class="identifier">subrange</span><span class="special">()</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
103    <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>
104
105    <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>
106    <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>
107
108<span class="keyword">private</span><span class="special">:</span>
109    <span class="identifier">Iterator</span> <span class="identifier">first_</span><span class="special">;</span>
110    <span class="identifier">Sentinel</span> <span class="identifier">last_</span><span class="special">;</span>
111<span class="special">};</span>
112
113<span class="comment">// std::view::all() returns one of several types, depending on what you pass</span>
114<span class="comment">// it.  Here, we're keeping it simple; all() always returns a subrange.</span>
115<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>
116<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>
117<span class="special">{</span>
118    <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>
119        <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>
120<span class="special">}</span>
121
122<span class="comment">// A template alias that denotes the type of all(r) for some Range r.</span>
123<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>
124<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>
125</pre>
126<p>
127    </p>
128<p>
129      Note that <code class="computeroutput"><span class="identifier">subrange</span></code> is derived
130      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
131      all the view-like operations that are appropriate to its <code class="computeroutput"><span class="identifier">Iterator</span></code>
132      and <code class="computeroutput"><span class="identifier">Sentinel</span></code> types.
133    </p>
134<p>
135      With the helpers available, we can define <code class="computeroutput"><span class="identifier">drop_while_view</span></code>:
136    </p>
137<p>
138</p>
139<pre class="programlisting"><span class="comment">// Perhaps its clear now why we defined subrange, all(), etc. above.</span>
140<span class="comment">// drop_while_view contains a view data member.  If we just took any old range</span>
141<span class="comment">// that was passed to drop_while_view's constructor, we'd copy the range</span>
142<span class="comment">// itself, which may be a std::vector.  So, we want to make a view out of</span>
143<span class="comment">// whatever Range we're given so that this copy of an owning range does not</span>
144<span class="comment">// happen.</span>
145<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>
146<span class="keyword">struct</span> <span class="identifier">drop_while_view</span>
147    <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>
148<span class="special">{</span>
149    <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>
150
151    <span class="identifier">drop_while_view</span><span class="special">()</span> <span class="special">=</span> <span class="keyword">default</span><span class="special">;</span>
152
153    <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>
154        <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>
155        <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>
156    <span class="special">{}</span>
157
158    <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>
159    <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>
160
161    <span class="comment">// A more robust implementation should probably cache the value computed</span>
162    <span class="comment">// by this function, so that subsequent calls can just return the cached</span>
163    <span class="comment">// iterator.</span>
164    <span class="keyword">constexpr</span> <span class="keyword">auto</span> <span class="identifier">begin</span><span class="special">()</span>
165    <span class="special">{</span>
166        <span class="comment">// We're forced to write this out as a raw loop, since no</span>
167        <span class="comment">// std::-namespace algorithms accept a sentinel.</span>
168        <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>
169        <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>
170        <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>
171            <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>
172                <span class="keyword">break</span><span class="special">;</span>
173        <span class="special">}</span>
174        <span class="keyword">return</span> <span class="identifier">first</span><span class="special">;</span>
175    <span class="special">}</span>
176
177    <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>
178
179<span class="keyword">private</span><span class="special">:</span>
180    <span class="identifier">base_type</span> <span class="identifier">base_</span><span class="special">;</span>
181    <span class="identifier">Pred</span> <span class="identifier">pred_</span><span class="special">;</span>
182<span class="special">};</span>
183
184<span class="comment">// Since this is a C++14 and later library, we're not using CTAD; we therefore</span>
185<span class="comment">// need a make-function.</span>
186<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>
187<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>
188<span class="special">{</span>
189    <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>
190<span class="special">}</span>
191</pre>
192<p>
193    </p>
194<p>
195      Now, let's look at code using these types, including operations defined by
196      <code class="computeroutput"><a class="link" href="../boost/stl_interfaces/v1/view_interface.html" title="Struct template view_interface">view_interface</a></code>
197      that we did not have to write:
198    </p>
199<p>
200</p>
201<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>
202
203<span class="comment">// all() returns a subrange, which is a view type containing ints.begin()</span>
204<span class="comment">// and ints.end().</span>
205<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>
206
207<span class="comment">// This works using just the used-defined members of subrange: begin() and</span>
208<span class="comment">// end().</span>
209<span class="identifier">assert</span><span class="special">(</span>
210    <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>
211
212<span class="comment">// These are available because subrange is derived from view_interface.</span>
213<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>
214<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>
215
216<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>
217<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>
218
219<span class="comment">// Available via begin()/end()...</span>
220<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>
221    <span class="identifier">ints_after_even_prefix</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span>
222    <span class="identifier">ints_after_even_prefix</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span>
223    <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>
224    <span class="identifier">ints</span><span class="special">.</span><span class="identifier">end</span><span class="special">()));</span>
225
226<span class="comment">// ... and via view_interface.</span>
227<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>
228<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>
229<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>
230</pre>
231<p>
232    </p>
233<p>
234      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
235      it wherever you usually find reference documentation on the standard library.
236      We won't cover it here for that reason. See <a href="http://eel.is/c++draft/view.interface" target="_top">[view.interface</a>
237      on eel.is] or <a href="https://cppreference.com" target="_top">https://cppreference.com</a>
238      for details.
239    </p>
240</div>
241<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
242<td align="left"></td>
243<td align="right"><div class="copyright-footer">Copyright © 2019 T. Zachary Laine<p>
244        Distributed under the Boost Software License, Version 1.0. (See accompanying
245        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>)
246      </p>
247</div></td>
248</tr></table>
249<hr>
250<div class="spirit-nav">
251<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>
252</div>
253</body>
254</html>
255