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: iterator_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="this_library_s_relationship_to_boost_iterator.html" title="This Library's Relationship to Boost.Iterator"> 11<link rel="next" href="tutorial___view_interface_.html" title="Tutorial: view_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="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> 25</div> 26<div class="section"> 27<div class="titlepage"><div><div><h2 class="title" style="clear: both"> 28<a name="boost_stlinterfaces.tutorial___iterator_interface_"></a><a class="link" href="tutorial___iterator_interface_.html" title="Tutorial: iterator_interface">Tutorial: 29 <code class="computeroutput"><span class="identifier">iterator_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/iterator_interface.html" title="Struct template iterator_interface">iterator_interface</a></code> are in your 38 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> — 39 and can therefore be hidden if you define a member function with the same 40 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 41 member function, feel free to replace it. 42 </p></td></tr> 43</table></div> 44<h4> 45<a name="boost_stlinterfaces.tutorial___iterator_interface_.h0"></a> 46 <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 47 <code class="computeroutput"><span class="identifier">iterator_interface</span></code> Template</a> 48 </h4> 49<p> 50 Though a given iterator may have a large number of operations associated with 51 it, there are only a few basis operations that the iterator needs to define; 52 the full set of operations it supports can be defined in terms of that much 53 smaller basis. 54 </p> 55<p> 56 It is possible to define any iterator <code class="computeroutput"><span class="identifier">Iter</span></code> 57 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>, 58 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>: 59 </p> 60<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> 61 <span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">,</span> 62 <span class="keyword">typename</span> <span class="identifier">IteratorConcept</span><span class="special">,</span> 63 <span class="keyword">typename</span> <span class="identifier">ValueType</span><span class="special">,</span> 64 <span class="keyword">typename</span> <span class="identifier">Reference</span> <span class="special">=</span> <span class="identifier">ValueType</span> <span class="special">&,</span> 65 <span class="keyword">typename</span> <span class="identifier">Pointer</span> <span class="special">=</span> <span class="identifier">ValueType</span> <span class="special">*,</span> 66 <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">></span> 67<span class="keyword">struct</span> <span class="identifier">iterator_interface</span><span class="special">;</span> 68</pre> 69<p> 70 Let's break that down. 71 </p> 72<p> 73 <code class="computeroutput"><span class="identifier">Derived</span></code> is the type that you're 74 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. 75 </p> 76<p> 77 <code class="computeroutput"><span class="identifier">IteratorConcept</span></code> defines the 78 iterator category/concept. This must be one of the C++ standard iterator tag 79 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, 80 <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 81 use. 82 </p> 83<p> 84 <code class="computeroutput"><span class="identifier">ValueType</span></code> is used to define 85 the iterator's <code class="computeroutput"><span class="identifier">value_type</span></code> typedef. 86 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 87 <code class="computeroutput"><span class="identifier">reference</span></code> and <code class="computeroutput"><span class="identifier">pointer</span></code> typedefs, respectively. 88 </p> 89<div class="tip"><table border="0" summary="Tip"> 90<tr> 91<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td> 92<th align="left">Tip</th> 93</tr> 94<tr><td align="left" valign="top"><p> 95 <code class="computeroutput"><span class="identifier">Reference</span></code> does not need to 96 be a reference type, and <code class="computeroutput"><span class="identifier">Pointer</span></code> 97 does not need to be a pointer type. This fact is very useful when making 98 proxy iterators. 99 </p></td></tr> 100</table></div> 101<p> 102 <code class="computeroutput"><span class="identifier">DifferenceType</span></code> is used to define 103 the iterator's <code class="computeroutput"><span class="identifier">difference_type</span></code>. 104 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>. 105 </p> 106<h4> 107<a name="boost_stlinterfaces.tutorial___iterator_interface_.h1"></a> 108 <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 109 Iterators</a> 110 </h4> 111<p> 112 Sometimes you need to create an iterator <code class="computeroutput"><span class="identifier">I</span></code> 113 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>. 114 For instance, let's say you want to make a zip-iterator that produces pairs 115 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>, 116 with respective <code class="computeroutput"><span class="identifier">value_type</span></code>s 117 <code class="computeroutput"><span class="identifier">T</span></code> and <code class="computeroutput"><span class="identifier">U</span></code>, 118 one possible <code class="computeroutput"><span class="identifier">reference_type</span></code> 119 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"><</span><span class="identifier">T</span> <span class="special">&,</span> <span class="identifier">U</span> <span class="special">&></span></code> 120 (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"><</span><span class="identifier">T</span><span class="special">,</span> <span class="identifier">U</span><span class="special">></span> <span class="special">&</span></code>). 121 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 122 from <code class="computeroutput"><span class="identifier">B</span></code>. 123 </p> 124<p> 125 As another example, if you wanted an iterator <code class="computeroutput"><span class="identifier">I</span></code> 126 that represents the infinite sequence 0, 1, 2, ..., you'd be unable to form 127 a reference to most or all of those values; you'd instead produce a temporary 128 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> 129 does not involve references at all; it may instead by <code class="computeroutput"><span class="keyword">int</span></code> 130 or <code class="computeroutput"><span class="keyword">double</span></code>. 131 </p> 132<p> 133 When defining a proxy iterator, you can use a template alias that provides 134 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: 135 </p> 136<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> 137 <span class="keyword">typename</span> <span class="identifier">Derived</span><span class="special">,</span> 138 <span class="keyword">typename</span> <span class="identifier">IteratorConcept</span><span class="special">,</span> 139 <span class="keyword">typename</span> <span class="identifier">ValueType</span><span class="special">,</span> 140 <span class="keyword">typename</span> <span class="identifier">Reference</span> <span class="special">=</span> <span class="identifier">ValueType</span><span class="special">,</span> 141 <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">></span> 142<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"><</span> 143 <span class="identifier">Derived</span><span class="special">,</span> 144 <span class="identifier">IteratorConcept</span><span class="special">,</span> 145 <span class="identifier">ValueType</span><span class="special">,</span> 146 <span class="identifier">Reference</span><span class="special">,</span> 147 <span class="identifier">proxy_arrow_result</span><span class="special"><</span><span class="identifier">Reference</span><span class="special">>,</span> 148 <span class="identifier">DifferenceType</span><span class="special">>;</span> 149</pre> 150<div class="note"><table border="0" summary="Note"> 151<tr> 152<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 153<th align="left">Note</th> 154</tr> 155<tr><td align="left" valign="top"><p> 156 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 157 a template called <code class="computeroutput"><span class="identifier">proxy_arrow_result</span></code> 158 as its pointer-type. This template makes a copy of whatever value is obtained 159 by <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>, 160 and then returns a pointer to the copy in its <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code>. You may want to use something else 161 if this is a performance concern. 162 </p></td></tr> 163</table></div> 164<h4> 165<a name="boost_stlinterfaces.tutorial___iterator_interface_.h2"></a> 166 <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 167 Iterator Operations</a> 168 </h4> 169<p> 170 Now, let's get back to the user-defined basis operations. 171 </p> 172<p> 173 In the table below, <code class="computeroutput"><span class="identifier">Iter</span></code> is 174 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> 175 are objects of type <code class="computeroutput"><span class="identifier">Iter</span></code>; 176 <code class="computeroutput"><span class="identifier">reference</span></code> is the type passed 177 as the <code class="computeroutput"><span class="identifier">Reference</span></code> template parameter 178 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>; 179 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>. 180 </p> 181<div class="table"> 182<a name="boost_stlinterfaces.tutorial___iterator_interface_.t0"></a><p class="title"><b>Table 38.1. User-Defined Operations</b></p> 183<div class="table-contents"><table class="table" summary="User-Defined Operations"> 184<colgroup> 185<col> 186<col> 187<col> 188<col> 189</colgroup> 190<thead><tr> 191<th> 192 <p> 193 Expression 194 </p> 195 </th> 196<th> 197 <p> 198 Return Type 199 </p> 200 </th> 201<th> 202 <p> 203 Semantics 204 </p> 205 </th> 206<th> 207 <p> 208 Assertion/note/pre-/post-condition 209 </p> 210 </th> 211</tr></thead> 212<tbody> 213<tr> 214<td> 215 <p> 216 <code class="computeroutput"><span class="special">*</span><span class="identifier">i</span></code> 217 </p> 218 </td> 219<td> 220 <p> 221 Convertible to <code class="computeroutput"><span class="identifier">reference</span></code>. 222 </p> 223 </td> 224<td> 225 <p> 226 Dereferences <code class="computeroutput"><span class="identifier">i</span></code> and 227 returns the result. 228 </p> 229 </td> 230<td> 231 <p> 232 <span class="emphasis"><em>Expects:</em></span> i is dereferenceable. 233 </p> 234 </td> 235</tr> 236<tr> 237<td> 238 <p> 239 <code class="computeroutput"><span class="identifier">i</span> <span class="special">==</span> 240 <span class="identifier">i2</span></code> 241 </p> 242 </td> 243<td> 244 <p> 245 Contextually convertible to <code class="computeroutput"><span class="keyword">bool</span></code>. 246 </p> 247 </td> 248<td> 249 <p> 250 Returns true if and only if <code class="computeroutput"><span class="identifier">i</span></code> 251 and <code class="computeroutput"><span class="identifier">i2</span></code> refer to the 252 same value. 253 </p> 254 </td> 255<td> 256 <p> 257 <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> 258 is in the domain of <code class="computeroutput"><span class="special">==</span></code>. 259 </p> 260 </td> 261</tr> 262<tr> 263<td> 264 <p> 265 <code class="computeroutput"><span class="identifier">i2</span> <span class="special">-</span> 266 <span class="identifier">i</span></code> 267 </p> 268 </td> 269<td> 270 <p> 271 Convertible to <code class="computeroutput"><span class="identifier">difference_type</span></code>. 272 </p> 273 </td> 274<td> 275 <p> 276 Returns <code class="computeroutput"><span class="identifier">n</span></code>. 277 </p> 278 </td> 279<td> 280 <p> 281 <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> 282 such that <code class="computeroutput"><span class="identifier">i</span> <span class="special">+</span> 283 <span class="identifier">n</span> <span class="special">==</span> 284 <span class="identifier">i2</span></code>. <code class="computeroutput"><span class="identifier">i2</span> 285 <span class="special">==</span> <span class="identifier">i</span> 286 <span class="special">+</span> <span class="special">(</span><span class="identifier">i2</span> <span class="special">-</span> 287 <span class="identifier">i</span><span class="special">)</span></code>. 288 </p> 289 </td> 290</tr> 291<tr> 292<td> 293 <p> 294 <code class="computeroutput"><span class="special">++</span><span class="identifier">i</span></code> 295 </p> 296 </td> 297<td> 298 <p> 299 <code class="computeroutput"><span class="identifier">Iter</span> <span class="special">&</span></code> 300 </p> 301 </td> 302<td> 303 <p> 304 Increments <code class="computeroutput"><span class="identifier">i</span></code>. 305 </p> 306 </td> 307<td> 308 </td> 309</tr> 310<tr> 311<td> 312 <p> 313 <code class="computeroutput"><span class="special">--</span><span class="identifier">i</span></code> 314 </p> 315 </td> 316<td> 317 <p> 318 <code class="computeroutput"><span class="identifier">Iter</span> <span class="special">&</span></code> 319 </p> 320 </td> 321<td> 322 <p> 323 Decrements <code class="computeroutput"><span class="identifier">i</span></code>. 324 </p> 325 </td> 326<td> 327 </td> 328</tr> 329<tr> 330<td> 331 <p> 332 <code class="computeroutput"><span class="identifier">i</span> <span class="special">+=</span> 333 <span class="identifier">n</span></code> 334 </p> 335 </td> 336<td> 337 <p> 338 <code class="computeroutput"><span class="identifier">Iter</span> <span class="special">&</span></code> 339 </p> 340 </td> 341<td> 342 <p> 343</p> 344<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> 345<span class="keyword">if</span> <span class="special">(</span><span class="identifier">m</span> <span class="special">>=</span> <span class="number">0</span><span class="special">)</span> 346 <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> 347<span class="keyword">else</span> 348 <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> 349<p> 350 </p> 351 </td> 352<td> 353 </td> 354</tr> 355</tbody> 356</table></div> 357</div> 358<br class="table-break"><div class="tip"><table border="0" summary="Tip"> 359<tr> 360<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../doc/src/images/tip.png"></td> 361<th align="left">Tip</th> 362</tr> 363<tr><td align="left" valign="top"><p> 364 The table above leaves a lot of implementation freedom. In <code class="computeroutput"><span class="keyword">operator</span><span class="special">+=()</span></code>, 365 you could take <code class="computeroutput"><span class="identifier">n</span></code> as a value 366 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> 367 or just something convertible to one; etc. In particular, your operations 368 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. 369 </p></td></tr> 370</table></div> 371<p> 372 Not all the iterator concepts require all the operations above. Here are the 373 operations used with each iterator concept: 374 </p> 375<div class="table"> 376<a name="boost_stlinterfaces.tutorial___iterator_interface_.t1"></a><p class="title"><b>Table 38.2. Operations Required for Each Concept</b></p> 377<div class="table-contents"><table class="table" summary="Operations Required for Each Concept"> 378<colgroup> 379<col> 380<col> 381</colgroup> 382<thead><tr> 383<th> 384 <p> 385 Concept 386 </p> 387 </th> 388<th> 389 <p> 390 Operations 391 </p> 392 </th> 393</tr></thead> 394<tbody> 395<tr> 396<td> 397 <p> 398 <code class="computeroutput"><span class="identifier">input_iterator</span></code> 399 </p> 400 </td> 401<td> 402 <p> 403</p> 404<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span> 405<span class="identifier">i</span> <span class="special">==</span> <span class="identifier">i2</span> 406<span class="special">++</span><span class="identifier">i</span></pre> 407<p> 408 </p> 409 </td> 410</tr> 411<tr> 412<td> 413 <p> 414 <code class="computeroutput"><span class="identifier">output_iterator</span></code> 415 </p> 416 </td> 417<td> 418 <p> 419</p> 420<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span> 421<span class="special">++</span><span class="identifier">i</span></pre> 422<p> 423 </p> 424 </td> 425</tr> 426<tr> 427<td> 428 <p> 429 <code class="computeroutput"><span class="identifier">forward_iterator</span></code> 430 </p> 431 </td> 432<td> 433 <p> 434</p> 435<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span> 436<span class="identifier">i</span> <span class="special">==</span> <span class="identifier">i2</span> 437<span class="special">++</span><span class="identifier">i</span></pre> 438<p> 439 </p> 440 </td> 441</tr> 442<tr> 443<td> 444 <p> 445 <code class="computeroutput"><span class="identifier">bidirectional_iterator</span></code> 446 </p> 447 </td> 448<td> 449 <p> 450</p> 451<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span> 452<span class="identifier">i</span> <span class="special">==</span> <span class="identifier">i2</span> 453<span class="special">++</span><span class="identifier">i</span> 454<span class="special">--</span><span class="identifier">i</span></pre> 455<p> 456 </p> 457 </td> 458</tr> 459<tr> 460<td> 461 <p> 462 <code class="computeroutput"><span class="identifier">random_access_iterator</span></code>/<code class="computeroutput"><span class="identifier">continguous_iterator</span></code> 463 </p> 464 </td> 465<td> 466 <p> 467</p> 468<pre class="programlisting"><span class="special">*</span><span class="identifier">i</span> 469<span class="identifier">i</span> <span class="special">-</span> <span class="identifier">i2</span> 470<span class="identifier">i</span> <span class="special">+=</span> <span class="identifier">n</span></pre> 471<p> 472 </p> 473 </td> 474</tr> 475</tbody> 476</table></div> 477</div> 478<br class="table-break"><div class="note"><table border="0" summary="Note"> 479<tr> 480<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 481<th align="left">Note</th> 482</tr> 483<tr><td align="left" valign="top"><p> 484 For <code class="computeroutput"><span class="identifier">random_access_iterator</span></code>s, 485 the operation <code class="computeroutput"><span class="identifier">i</span> <span class="special">-</span> 486 <span class="identifier">i2</span></code> is used to provide all the relational 487 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 488 a discontiguous sequence (e.g. <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">deque</span></code>), 489 this implementation of <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code> may not be optimal. In this case, provide 490 your own <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code>. 491 <code class="computeroutput"><span class="keyword">operator</span><span class="special">!=()</span></code> 492 will be provided if <code class="computeroutput"><span class="keyword">operator</span><span class="special">==</span></code> is available. 493 </p></td></tr> 494</table></div> 495<h4> 496<a name="boost_stlinterfaces.tutorial___iterator_interface_.h3"></a> 497 <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 498 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> 499 </h4> 500<p> 501 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> 502 in your iterator type <code class="computeroutput"><span class="identifier">Derived</span></code>, 503 <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, 504 <code class="computeroutput"><span class="keyword">operator</span><span class="special">++(</span><span class="keyword">int</span><span class="special">)</span></code>. But since 505 <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 506 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 507 <code class="computeroutput"><span class="identifier">Derived</span></code> <span class="bold"><strong>hides</strong></span> 508 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>. 509 </p> 510<p> 511 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 512 class. For instance, in the <code class="computeroutput"><span class="identifier">node_iterator</span></code> 513 example there are these lines: 514 </p> 515<p> 516</p> 517<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> 518 <span class="identifier">iterator_interface</span><span class="special"><</span><span class="identifier">node_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</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">>;</span> 519<span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">++;</span> 520</pre> 521<p> 522 </p> 523<div class="important"><table border="0" summary="Important"> 524<tr> 525<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td> 526<th align="left">Important</th> 527</tr> 528<tr><td align="left" valign="top"><p> 529 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 530 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. 531 </p></td></tr> 532</table></div> 533<div class="note"><table border="0" summary="Note"> 534<tr> 535<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 536<th align="left">Note</th> 537</tr> 538<tr><td align="left" valign="top"><p> 539 These using declarations are not necessary for a random access iterator, 540 because <code class="computeroutput"><span class="identifier">Derived</span></code> does not 541 have an <code class="computeroutput"><span class="keyword">operator</span><span class="special">++()</span></code> 542 in that case. 543 </p></td></tr> 544</table></div> 545<h4> 546<a name="boost_stlinterfaces.tutorial___iterator_interface_.h4"></a> 547 <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 548 it All Together</a> 549 </h4> 550<p> 551 Ok, let's actually define a simple iterator. Let's say you need to interact 552 with some legacy code that has a hand-written linked list: 553 </p> 554<p> 555</p> 556<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 557<span class="keyword">struct</span> <span class="identifier">node</span> 558<span class="special">{</span> 559 <span class="identifier">T</span> <span class="identifier">value_</span><span class="special">;</span> 560 <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> 561<span class="special">};</span> 562</pre> 563<p> 564 </p> 565<p> 566 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 567 it would be nice to be able to reuse all of the standard algorithms with this 568 type. Defining an iterator will get us there. 569 </p> 570<p> 571</p> 572<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">></span> 573<span class="keyword">struct</span> <span class="identifier">node_iterator</span> 574 <span class="special">:</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">stl_interfaces</span><span class="special">::</span> 575 <span class="identifier">iterator_interface</span><span class="special"><</span><span class="identifier">node_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</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">></span> 576</pre> 577<p> 578 </p> 579<p> 580 We are deriving <code class="computeroutput"><span class="identifier">node_iterator</span></code> 581 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 582 we're using <a href="https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern" target="_top">CRTP</a>, 583 we first have to pass <code class="computeroutput"><span class="identifier">node_iterator</span></code> 584 for the <code class="computeroutput"><span class="identifier">Derived</span></code> template parameter, 585 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 586 derived type to cast to in order to get at the user-defined operations. Then, 587 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>, 588 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 589 the <code class="computeroutput"><span class="identifier">value_type</span></code> is for our iterator. 590 </p> 591<p> 592 We leave the rest of the template parameters at their defaults: <code class="computeroutput"><span class="identifier">T</span> <span class="special">&</span></code> for 593 <code class="computeroutput"><span class="identifier">Reference</span></code>, <code class="computeroutput"><span class="identifier">T</span> 594 <span class="special">*</span></code> for <code class="computeroutput"><span class="identifier">Pointer</span></code>, 595 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>. 596 This is what you will do for almost all iterators. The most common exceptions 597 to this are usually some kind of proxy iterator. Another exception is when 598 for better code generation you want to return builtin values instead of references 599 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; 600 it's <code class="computeroutput"><span class="identifier">Reference</span></code> template parameter 601 is <code class="computeroutput"><span class="keyword">char</span></code> for this reason. 602 </p> 603<p> 604</p> 605<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> 606<span class="keyword">constexpr</span> <span class="identifier">node_iterator</span><span class="special">(</span><span class="identifier">node</span><span class="special"><</span><span class="identifier">T</span><span class="special">></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> 607</pre> 608<p> 609 </p> 610<p> 611 Next, we define two constructors: a default constructor, and one that takes 612 a <code class="computeroutput"><span class="identifier">node</span></code> pointer. A default constructor 613 is required by the <code class="computeroutput"><span class="identifier">forward_iterator</span></code> 614 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 615 this, since constructors are not visible in derived types without user intervention. 616 </p> 617<div class="important"><table border="0" summary="Important"> 618<tr> 619<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../../doc/src/images/important.png"></td> 620<th align="left">Important</th> 621</tr> 622<tr><td align="left" valign="top"><p> 623 A default constructor is required for every iterator concept. 624 </p></td></tr> 625</table></div> 626<p> 627</p> 628<pre class="programlisting"><span class="keyword">constexpr</span> <span class="identifier">T</span> <span class="special">&</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">-></span><span class="identifier">value_</span><span class="special">;</span> <span class="special">}</span> 629<span class="keyword">constexpr</span> <span class="identifier">node_iterator</span> <span class="special">&</span> <span class="keyword">operator</span><span class="special">++()</span> <span class="keyword">noexcept</span> 630<span class="special">{</span> 631 <span class="identifier">it_</span> <span class="special">=</span> <span class="identifier">it_</span><span class="special">-></span><span class="identifier">next_</span><span class="special">;</span> 632 <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> 633<span class="special">}</span> 634<span class="keyword">friend</span> <span class="keyword">constexpr</span> <span class="keyword">bool</span> 635<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> 636<span class="special">{</span> 637 <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> 638<span class="special">}</span> 639</pre> 640<p> 641 </p> 642<p> 643 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 644 do its work. As you might expect, the three required operations are very straightforward. 645 </p> 646<div class="note"><table border="0" summary="Note"> 647<tr> 648<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td> 649<th align="left">Note</th> 650</tr> 651<tr><td align="left" valign="top"> 652<p> 653 Here, I implement <code class="computeroutput"><span class="keyword">operator</span><span class="special">==()</span></code> 654 as a hidden friend function. it would have worked just as well if I had instead 655 implemented it as a member function, like this: 656 </p> 657<p> 658</p> 659<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> 660<span class="special">{</span> 661 <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> 662<span class="special">}</span></pre> 663<p> 664 </p> 665<p> 666 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 667 — 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> 668 tempalte to do its work. 669 </p> 670</td></tr> 671</table></div> 672<p> 673 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: 674 </p> 675<p> 676</p> 677<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> 678 <span class="identifier">iterator_interface</span><span class="special"><</span><span class="identifier">node_iterator</span><span class="special"><</span><span class="identifier">T</span><span class="special">>,</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">>;</span> 679<span class="keyword">using</span> <span class="identifier">base_type</span><span class="special">::</span><span class="keyword">operator</span><span class="special">++;</span> 680</pre> 681<p> 682 </p> 683<p> 684 Here's how we might use the forward iterator we just defined: 685 </p> 686<p> 687</p> 688<pre class="programlisting"><span class="identifier">node_iterator</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">first</span><span class="special">(&</span><span class="identifier">nodes</span><span class="special">[</span><span class="number">0</span><span class="special">]);</span> 689<span class="identifier">node_iterator</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="keyword">const</span> <span class="identifier">last</span><span class="special">;</span> 690<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> 691 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">it</span> <span class="special"><<</span> <span class="string">" "</span><span class="special">;</span> <span class="comment">// Prints 0 1 2 3 4</span> 692<span class="special">}</span> 693<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span> 694</pre> 695<p> 696 </p> 697<h4> 698<a name="boost_stlinterfaces.tutorial___iterator_interface_.h5"></a> 699 <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 700 About Adapting an Existing Iterator?</a> 701 </h4> 702<p> 703 So glad you asked. If you want to make something like a filtering iterator, 704 or say a UTF-8 to UTF-32 transcoding iterator, you are starting with an existing 705 iterator and adapting it. There's a way to avoid having to write all of the 706 user-defined basis functions, as long as there's a base iterator that already 707 has the right operations with the right semantics. 708 </p> 709<p> 710 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>. 711 It filters out integers that do not meet the predicate. Since we are using 712 an existing iterator (the pointer to <code class="computeroutput"><span class="keyword">int</span></code>), 713 we already have all the operations we need for a bidirectional iterator (and 714 more), except that <code class="computeroutput"><span class="keyword">operator</span><span class="special">++</span></code> 715 on an <code class="computeroutput"><span class="keyword">int</span> <span class="special">*</span></code> 716 does not skip over elements as we'd like. Here's the code: 717 </p> 718<p> 719</p> 720<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Pred</span><span class="special">></span> 721<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"><</span> 722 <span class="identifier">filtered_int_iterator</span><span class="special"><</span><span class="identifier">Pred</span><span class="special">>,</span> 723 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bidirectional_iterator_tag</span><span class="special">,</span> 724 <span class="keyword">int</span><span class="special">></span> 725<span class="special">{</span> 726 <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> 727 <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> 728 <span class="identifier">it_</span><span class="special">(</span><span class="identifier">it</span><span class="special">),</span> 729 <span class="identifier">last_</span><span class="special">(</span><span class="identifier">last</span><span class="special">),</span> 730 <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> 731 <span class="special">{</span> 732 <span class="comment">// We need to do this in the constructor so that operator== works</span> 733 <span class="comment">// properly on two filtered_int_iterators, when they bound a sequence</span> 734 <span class="comment">// in which none of the ints meets the predicate.</span> 735 <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> 736 <span class="special">}</span> 737 738 <span class="comment">// A bidirectional iterator based on iterator_interface usually required</span> 739 <span class="comment">// four user-defined operations. since we are adapting an existing</span> 740 <span class="comment">// iterator (an int *), we only need to define this one. The others are</span> 741 <span class="comment">// implemented by iterator_interface, using the underlying int *.</span> 742 <span class="identifier">filtered_int_iterator</span> <span class="special">&</span> <span class="keyword">operator</span><span class="special">++()</span> 743 <span class="special">{</span> 744 <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> 745 <span class="keyword">return</span> <span class="special">*</span><span class="keyword">this</span><span class="special">;</span> 746 <span class="special">}</span> 747 748 <span class="comment">// It is really common for iterator adaptors to have a base() member</span> 749 <span class="comment">// function that returns the adapted iterator.</span> 750 <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> 751 752<span class="keyword">private</span><span class="special">:</span> 753 <span class="comment">// Provide access to these private members.</span> 754 <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> 755 756 <span class="comment">// These functions are picked up by iterator_interface, and used to</span> 757 <span class="comment">// implement any operations that you don't define above. They're not</span> 758 <span class="comment">// called base() so that they do not collide with the base() member above.</span> 759 <span class="comment">//</span> 760 <span class="comment">// Note that the const overload does not strictly speaking need to be a</span> 761 <span class="comment">// reference, as demonstrated here.</span> 762 <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">noexcept</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">it_</span><span class="special">;</span> <span class="special">}</span> 763 <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> 764 765 <span class="keyword">int</span> <span class="special">*</span> <span class="identifier">it_</span><span class="special">;</span> 766 <span class="keyword">int</span> <span class="special">*</span> <span class="identifier">last_</span><span class="special">;</span> 767 <span class="identifier">Pred</span> <span class="identifier">pred_</span><span class="special">;</span> 768<span class="special">};</span> 769 770<span class="comment">// A make-function makes it easier to deal with the Pred parameter.</span> 771<span class="keyword">template</span><span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Pred</span><span class="special">></span> 772<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> 773<span class="special">{</span> 774 <span class="keyword">return</span> <span class="identifier">filtered_int_iterator</span><span class="special"><</span><span class="identifier">Pred</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">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pred</span><span class="special">));</span> 775<span class="special">}</span> 776</pre> 777<p> 778 </p> 779<p> 780 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 781 there was an underlying iterator it could use — by implementing <code class="computeroutput"><span class="identifier">base_reference</span><span class="special">()</span></code> 782 — 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>. 783 </p> 784<p> 785 Here is the iterator in action: 786 </p> 787<p> 788</p> 789<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="keyword">int</span><span class="special">,</span> <span class="number">8</span><span class="special">></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> 790<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> 791<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> 792 793<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> 794<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> 795<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> 796 797<span class="comment">// This is an example only. Obviously, we could have called</span> 798<span class="comment">// std::copy_if() here.</span> 799<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">ints_copy</span><span class="special">;</span> 800<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> 801<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"><</span><span class="keyword">int</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">4</span><span class="special">,</span> <span class="number">6</span><span class="special">}));</span> 802</pre> 803<p> 804 </p> 805<h4> 806<a name="boost_stlinterfaces.tutorial___iterator_interface_.h6"></a> 807 <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 808 Your Work</a> 809 </h4> 810<p> 811 Boost.STLInterfaces is able to check that some of the code that you write is 812 compatible with the concept for the iterator you're writing. It cannot check 813 everything. For instance, Boost.STLInterfaces does not know if your derived 814 type includes a default constructor, which is required by all the iterators. 815 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>, 816 since <code class="computeroutput"><span class="identifier">Derived</span></code> is an incomplete 817 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> — 818 <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 819 class for <code class="computeroutput"><span class="identifier">Derived</span></code>, not the 820 other way round. 821 </p> 822<p> 823 Since you can easily <code class="computeroutput"><span class="keyword">static_assert</span></code> 824 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 825 type. 826 </p> 827<p> 828 For instance, after <code class="computeroutput"><span class="identifier">node_iterator</span></code> 829 you'll find this code: 830 </p> 831<p> 832</p> 833<pre class="programlisting"><span class="comment">// static_assert(std::forward_iterator<node_iterator>, ""), or nothing in</span> 834<span class="comment">// C++17 and earlier.</span> 835<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> 836</pre> 837<p> 838 </p> 839<p> 840 Consider this good code hygiene. Without this simple check, you'll probably 841 eventually find yourself looking at an error message with a very long template 842 instantiation stack. 843 </p> 844<p> 845 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> 846 is well-formed and provides the correct types. See <code class="computeroutput"><a class="link" href="../BOOST_STL__1_3_39_11_2_3_3.html" title="Macro BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS">BOOST_STL_INTERFACES_STATIC_ASSERT_ITERATOR_TRAITS</a></code>. 847 </p> 848</div> 849<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 850<td align="left"></td> 851<td align="right"><div class="copyright-footer">Copyright © 2019 T. Zachary Laine<p> 852 Distributed under the Boost Software License, Version 1.0. (See accompanying 853 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>) 854 </p> 855</div></td> 856</tr></table> 857<hr> 858<div class="spirit-nav"> 859<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> 860</div> 861</body> 862</html> 863