1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>The multi pass iterator</title> 5<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css"> 6<meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> 7<link rel="home" href="../../index.html" title="Spirit 2.5.8"> 8<link rel="up" href="../support.html" title="Supporting Libraries"> 9<link rel="prev" href="../support.html" title="Supporting Libraries"> 10<link rel="next" href="line_pos_iterator.html" title="The line position iterator"> 11</head> 12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> 13<table cellpadding="2" width="100%"><tr> 14<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td> 15<td align="center"><a href="../../../../../../index.html">Home</a></td> 16<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td> 17<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td> 18<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td> 19<td align="center"><a href="../../../../../../more/index.htm">More</a></td> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="../support.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../support.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="line_pos_iterator.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="spirit.support.multi_pass"></a><a class="link" href="multi_pass.html" title="The multi pass iterator">The multi pass iterator</a> 28</h3></div></div></div> 29<p> 30 Backtracking in <span class="emphasis"><em>Spirit.Qi</em></span> requires the use of the following 31 types of iterator: forward, bidirectional, or random access. Because of backtracking, 32 input iterators cannot be used. Therefore, the standard library classes 33 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istreambuf_iterator</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span></code>, 34 that fall under the category of input iterators, cannot be used. Another 35 input iterator that is of interest is one that wraps a lexer, such as LEX. 36 </p> 37<div class="note"><table border="0" summary="Note"> 38<tr> 39<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../images/note.png"></td> 40<th align="left">Note</th> 41</tr> 42<tr><td align="left" valign="top"><p> 43 In general, <span class="emphasis"><em>Spirit.Qi</em></span> generates recursive descent 44 parser which require backtracking parsers by design. For this reason we 45 need to provide at least forward iterators to any of <span class="emphasis"><em>Spirit.Qi</em></span>'s 46 API functions. This is not an absolute requirement though. In the future, 47 we shall see more deterministic parsers that require no more than 1 character 48 (token) of lookahead. Such parsers allow us to use input iterators such 49 as the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span></code> as is. 50 </p></td></tr> 51</table></div> 52<p> 53 Backtracking can be implemented only if we are allowed to save an iterator 54 position, i.e. making a copy of the current iterator. Unfortunately, with 55 an input iterator, there is no way to do so, and thus input iterators will 56 not work with backtracking in <span class="emphasis"><em>Spirit.Qi</em></span>. One solution 57 to this problem is to simply load all the data to be parsed into a container, 58 such as a vector or deque, and then pass the begin and end of the container 59 to <span class="emphasis"><em>Spirit.Qi</em></span>. This method can be too memory intensive 60 for certain applications, which is why the <code class="computeroutput"><span class="identifier">multi_pass</span></code> 61 iterator was created. 62 </p> 63<h5> 64<a name="spirit.support.multi_pass.h0"></a> 65 <span class="phrase"><a name="spirit.support.multi_pass.using_the_multi_pass"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.using_the_multi_pass">Using 66 the multi_pass</a> 67 </h5> 68<p> 69 The <code class="computeroutput"><span class="identifier">multi_pass</span></code> iterator will 70 convert any input iterator into a forward iterator suitable for use with 71 <span class="emphasis"><em>Spirit.Qi</em></span>. <code class="computeroutput"><span class="identifier">multi_pass</span></code> 72 will buffer data when needed and will discard the buffer when its contents 73 is not needed anymore. This happens either if only one copy of the iterator 74 exists or if no backtracking can occur. 75 </p> 76<p> 77 A grammar must be designed with care if the <code class="computeroutput"><span class="identifier">multi_pass</span></code> 78 iterator is used. Any rule that may need to backtrack, such as one that contains 79 an alternative, will cause data to be buffered. The rules that are optimal 80 to use are repetition constructs (as kleene and plus). 81 </p> 82<p> 83 Sequences of the form <code class="computeroutput"><span class="identifier">a</span> <span class="special">>></span> <span class="identifier">b</span></code> 84 will buffer data as well. This is different from the behavior of <a href="../../../../../../libs/spirit/classic/index.html" target="_top"><span class="emphasis"><em>Spirit.Classic</em></span></a> 85 but for a good reason. Sequences need to reset the current iterator to its 86 initial state if one of the components of a sequence fails to match. To compensate 87 for this behavior we added functionality to the <code class="computeroutput"><span class="identifier">expect</span></code> 88 parsers (i.e. constructs like <code class="computeroutput"><span class="identifier">a</span> 89 <span class="special">></span> <span class="identifier">b</span></code>). 90 Expectation points introduce deterministic points into the grammar ensuring 91 no backtracking can occur if they match. For this reason we clear the buffers 92 of any multi_pass iterator on each expectation point, ensuring minimal buffer 93 content even for large grammars. 94 </p> 95<div class="important"><table border="0" summary="Important"> 96<tr> 97<td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="../../images/important.png"></td> 98<th align="left">Important</th> 99</tr> 100<tr><td align="left" valign="top"> 101<p> 102 If you use an error handler in conjunction with the <code class="computeroutput"><span class="identifier">expect</span></code> 103 parser while utilizing a <code class="computeroutput"><span class="identifier">multi_pass</span></code> 104 iterator and you intend to use the error handler to force a <code class="computeroutput"><span class="identifier">retry</span></code> or a <code class="computeroutput"><span class="identifier">fail</span></code> 105 (see the description of error handlers - <span class="bold"><strong>FIXME</strong></span>: 106 insert link), then you need to instantiate the error handler using <code class="computeroutput"><span class="identifier">retry</span></code> or <code class="computeroutput"><span class="identifier">fail</span></code>, 107 for instance: 108</p> 109<pre class="programlisting"><span class="identifier">rule</span> <span class="identifier">r</span><span class="special"><</span><span class="identifier">iterator_type</span><span class="special">></span> <span class="identifier">r</span><span class="special">;</span> 110<span class="identifier">on_error</span><span class="special"><</span><span class="identifier">retry</span><span class="special">>(</span><span class="identifier">r</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">phoenix</span><span class="special">::</span><span class="identifier">val</span><span class="special">(</span><span class="string">"Error!"</span><span class="special">));</span> 111</pre> 112<p> 113 If you fail to do so the resulting code will trigger an assert statement 114 at runtime. 115 </p> 116</td></tr> 117</table></div> 118<p> 119 Any rule that repeats, such as kleene_star (<code class="computeroutput"><span class="special">*</span><span class="identifier">a</span></code>) or positive such as (<code class="computeroutput"><span class="special">+</span><span class="identifier">a</span></code>), will only buffer the data for the current 120 repetition. 121 </p> 122<p> 123 In typical grammars, ambiguity and therefore lookahead is often localized. 124 In fact, many well designed languages are fully deterministic and require 125 no lookahead at all. Peeking at the first character from the input will immediately 126 determine the alternative branch to take. Yet, even with highly ambiguous 127 grammars, alternatives are often of the form <code class="computeroutput"><span class="special">*(</span><span class="identifier">a</span> <span class="special">|</span> <span class="identifier">b</span> 128 <span class="special">|</span> <span class="identifier">c</span> <span class="special">|</span> <span class="identifier">d</span><span class="special">)</span></code>. 129 The input iterator moves on and is never stuck at the beginning. Let's look 130 at a Pascal snippet for example: 131 </p> 132<pre class="programlisting"><span class="identifier">program</span> <span class="special">=</span> 133 <span class="identifier">programHeading</span> <span class="special">>></span> <span class="identifier">block</span> <span class="special">>></span> <span class="char">'.'</span> 134 <span class="special">;</span> 135 136<span class="identifier">block</span> <span class="special">=</span> 137 <span class="special">*(</span> <span class="identifier">labelDeclarationPart</span> 138 <span class="special">|</span> <span class="identifier">constantDefinitionPart</span> 139 <span class="special">|</span> <span class="identifier">typeDefinitionPart</span> 140 <span class="special">|</span> <span class="identifier">variableDeclarationPart</span> 141 <span class="special">|</span> <span class="identifier">procedureAndFunctionDeclarationPart</span> 142 <span class="special">)</span> 143 <span class="special">>></span> <span class="identifier">statementPart</span> 144 <span class="special">;</span> 145</pre> 146<p> 147 Notice the alternatives inside the Kleene star in the rule block . The rule 148 gobbles the input in a linear manner and throws away the past history with 149 each iteration. As this is fully deterministic LL(1) grammar, each failed 150 alternative only has to peek 1 character (token). The alternative that consumes 151 more than 1 character (token) is definitely a winner. After which, the Kleene 152 star moves on to the next. 153 </p> 154<p> 155 Now, after the lecture on the features to be careful with when using <code class="computeroutput"><span class="identifier">multi_pass</span></code>, you may think that <code class="computeroutput"><span class="identifier">multi_pass</span></code> is way too restrictive to use. 156 That's not the case. If your grammar is deterministic, you can make use of 157 the <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> pseudo 158 parser in your grammar to ensure that data is not buffered when unnecessary 159 (<code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> is available 160 from the <span class="emphasis"><em>Spirit.Qi</em></span> parser <a href="../../../../repository/doc/html/index.html" target="_top">Repository</a>). 161 </p> 162<p> 163 Here we present a minimal example showing a minimal use case. The <code class="computeroutput"><span class="identifier">multi_pass</span></code> iterator is highly configurable, 164 but the default policies have been chosen so that its easily usable with 165 input iterators such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istreambuf_iterator</span></code>. 166 For the complete source code of this example please refer to <a href="../../../../example/support/multi_pass.cpp" target="_top">multi_pass.cpp</a>. 167 </p> 168<p> 169</p> 170<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> 171<span class="special">{</span> 172 <span class="keyword">namespace</span> <span class="identifier">spirit</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> 173 <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">space</span><span class="special">;</span> 174 <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">ascii</span><span class="special">::</span><span class="identifier">char_</span><span class="special">;</span> 175 <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">double_</span><span class="special">;</span> 176 <span class="keyword">using</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">eol</span><span class="special">;</span> 177 178 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ifstream</span> <span class="identifier">in</span><span class="special">(</span><span class="string">"multi_pass.txt"</span><span class="special">);</span> <span class="comment">// we get our input from this file</span> 179 <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">in</span><span class="special">.</span><span class="identifier">is_open</span><span class="special">())</span> <span class="special">{</span> 180 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Could not open input file: 'multi_pass.txt'"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 181 <span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span> 182 <span class="special">}</span> 183 184 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">istreambuf_iterator</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="identifier">base_iterator_type</span><span class="special">;</span> 185 <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">multi_pass</span><span class="special"><</span><span class="identifier">base_iterator_type</span><span class="special">></span> <span class="identifier">first</span> <span class="special">=</span> 186 <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">make_default_multi_pass</span><span class="special">(</span><span class="identifier">base_iterator_type</span><span class="special">(</span><span class="identifier">in</span><span class="special">));</span> 187 188 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">double</span><span class="special">></span> <span class="identifier">v</span><span class="special">;</span> 189 <span class="keyword">bool</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">qi</span><span class="special">::</span><span class="identifier">phrase_parse</span><span class="special">(</span><span class="identifier">first</span> 190 <span class="special">,</span> <span class="identifier">spirit</span><span class="special">::</span><span class="identifier">make_default_multi_pass</span><span class="special">(</span><span class="identifier">base_iterator_type</span><span class="special">())</span> 191 <span class="special">,</span> <span class="identifier">double_</span> <span class="special">>></span> <span class="special">*(</span><span class="char">','</span> <span class="special">>></span> <span class="identifier">double_</span><span class="special">)</span> <span class="comment">// recognize list of doubles</span> 192 <span class="special">,</span> <span class="identifier">space</span> <span class="special">|</span> <span class="char">'#'</span> <span class="special">>></span> <span class="special">*(</span><span class="identifier">char_</span> <span class="special">-</span> <span class="identifier">eol</span><span class="special">)</span> <span class="special">>></span> <span class="identifier">eol</span> <span class="comment">// comment skipper</span> 193 <span class="special">,</span> <span class="identifier">v</span><span class="special">);</span> <span class="comment">// data read from file</span> 194 195 <span class="keyword">if</span> <span class="special">(!</span><span class="identifier">result</span><span class="special">)</span> <span class="special">{</span> 196 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Failed parsing input file!"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 197 <span class="keyword">return</span> <span class="special">-</span><span class="number">2</span><span class="special">;</span> 198 <span class="special">}</span> 199 200 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"Successfully parsed input file!"</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 201 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 202<span class="special">}</span> 203</pre> 204<p> 205 </p> 206<h5> 207<a name="spirit.support.multi_pass.h1"></a> 208 <span class="phrase"><a name="spirit.support.multi_pass.using_the_flush_multi_pass_parser"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.using_the_flush_multi_pass_parser">Using 209 the flush_multi_pass parser</a> 210 </h5> 211<p> 212 The <a href="http://boost-spirit.com" target="_top">Spirit</a> <a href="../../../../repository/doc/html/index.html" target="_top">Repository</a> 213 contains the <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> 214 parser component. This is usable in conjunction with the <code class="computeroutput"><span class="identifier">multi_pass</span></code> 215 iterator to minimize the buffering. It allows to insert explicit synchronization 216 points into your grammar where it is safe to clear any stored input as it 217 is ensured that no backtracking can occur at this point anymore. 218 </p> 219<p> 220 When the <code class="computeroutput"><span class="identifier">flush_multi_pass</span></code> 221 parser is used with <code class="computeroutput"><span class="identifier">multi_pass</span></code>, 222 it will call <code class="computeroutput"><span class="identifier">multi_pass</span><span class="special">::</span><span class="identifier">clear_queue</span><span class="special">()</span></code>. 223 This will cause any buffered data to be erased. This also will invalidate 224 all other copies of multi_pass and they should not be used. If they are, 225 an <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">illegal_backtracking</span></code> exception will be 226 thrown. 227 </p> 228<h5> 229<a name="spirit.support.multi_pass.h2"></a> 230 <span class="phrase"><a name="spirit.support.multi_pass.the_multi_pass_policies"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.the_multi_pass_policies">The 231 multi_pass Policies</a> 232 </h5> 233<p> 234 The <code class="computeroutput"><span class="identifier">multi_pass</span></code> iterator is 235 a templated class configurable using policies. The description of <code class="computeroutput"><span class="identifier">multi_pass</span></code> above is how it was originally 236 implemented (before it used policies), and is the default configuration now. 237 But, <code class="computeroutput"><span class="identifier">multi_pass</span></code> is capable 238 of much more. Because of the open-ended nature of policies, you can write 239 your own policy to make <code class="computeroutput"><span class="identifier">multi_pass</span></code> 240 behave in a way that we never before imagined. 241 </p> 242<p> 243 The multi_pass class has two template parameters: 244 </p> 245<div class="variablelist"> 246<p class="title"><b>The multi_pass template parameters</b></p> 247<dl class="variablelist"> 248<dt><span class="term">Input</span></dt> 249<dd><p> 250 The type multi_pass uses to acquire it's input. This is typically an 251 input iterator, or functor. 252 </p></dd> 253<dt><span class="term">Policies</span></dt> 254<dd><p> 255 The combined policies to use to create an instance of a multi_pass 256 iterator. This combined policy type is described below 257 </p></dd> 258</dl> 259</div> 260<p> 261 It is possible to implement all of the required functionality of the combined 262 policy in a single class. But it has shown to be more convenient to split 263 this into four different groups of functions, i.e. four separate, but well 264 coordinated policies. For this reason the <code class="computeroutput"><span class="identifier">multi_pass</span></code> 265 library implements a template <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">default_policy</span></code> 266 allowing to combine several different policies, each implementing one of 267 the functionality groups: 268 </p> 269<div class="table"> 270<a name="spirit.support.multi_pass.policies_needed_for_default_policy_template"></a><p class="title"><b>Table 12. Policies needed for default_policy template</b></p> 271<div class="table-contents"><table class="table" summary="Policies needed for default_policy template"> 272<colgroup> 273<col> 274<col> 275</colgroup> 276<thead><tr> 277<th> 278 <p> 279 Template Parameter 280 </p> 281 </th> 282<th> 283 <p> 284 Description 285 </p> 286 </th> 287</tr></thead> 288<tbody> 289<tr> 290<td> 291 <p> 292 <code class="computeroutput"><span class="identifier">OwnershipPolicy</span></code> 293 </p> 294 </td> 295<td> 296 <p> 297 This policy determines how <code class="computeroutput"><span class="identifier">multi_pass</span></code> 298 deals with it's shared components. 299 </p> 300 </td> 301</tr> 302<tr> 303<td> 304 <p> 305 <code class="computeroutput"><span class="identifier">CheckingPolicy</span></code> 306 </p> 307 </td> 308<td> 309 <p> 310 This policy determines how checking for invalid iterators is done. 311 </p> 312 </td> 313</tr> 314<tr> 315<td> 316 <p> 317 <code class="computeroutput"><span class="identifier">InputPolicy</span></code> 318 </p> 319 </td> 320<td> 321 <p> 322 A class that defines how <code class="computeroutput"><span class="identifier">multi_pass</span></code> 323 acquires its input. The <code class="computeroutput"><span class="identifier">InputPolicy</span></code> 324 is parameterized by the <code class="computeroutput"><span class="identifier">Input</span></code> 325 template parameter to the <code class="computeroutput"><span class="identifier">multi_pass</span></code>. 326 </p> 327 </td> 328</tr> 329<tr> 330<td> 331 <p> 332 <code class="computeroutput"><span class="identifier">StoragePolicy</span></code> 333 </p> 334 </td> 335<td> 336 <p> 337 The buffering scheme used by <code class="computeroutput"><span class="identifier">multi_pass</span></code> 338 is determined and managed by the StoragePolicy. 339 </p> 340 </td> 341</tr> 342</tbody> 343</table></div> 344</div> 345<br class="table-break"><p> 346 The <code class="computeroutput"><span class="identifier">multi_pass</span></code> library contains 347 several predefined policy implementations for each of the policy types as 348 described above. First we will describe those predefined types. Afterwards 349 we will give some guidelines how you can write your own policy implementations. 350 </p> 351<h5> 352<a name="spirit.support.multi_pass.h3"></a> 353 <span class="phrase"><a name="spirit.support.multi_pass.predefined_policies"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.predefined_policies">Predefined 354 policies</a> 355 </h5> 356<p> 357 All predefined <code class="computeroutput"><span class="identifier">multi_pass</span></code> 358 policies are defined in the namespace <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">iterator_policies</span></code>. 359 </p> 360<div class="table"> 361<a name="spirit.support.multi_pass.predefined_policy_classes"></a><p class="title"><b>Table 13. Predefined policy classes</b></p> 362<div class="table-contents"><table class="table" summary="Predefined policy classes"> 363<colgroup> 364<col> 365<col> 366</colgroup> 367<thead><tr> 368<th> 369 <p> 370 Class name 371 </p> 372 </th> 373<th> 374 <p> 375 Description 376 </p> 377 </th> 378</tr></thead> 379<tbody> 380<tr> 381<td> 382 <p> 383 <span class="bold"><strong>InputPolicy</strong></span> classes 384 </p> 385 </td> 386<td class="auto-generated"> </td> 387</tr> 388<tr> 389<td> 390 <p> 391 <code class="computeroutput"><span class="identifier">input_iterator</span></code> 392 </p> 393 </td> 394<td> 395 <p> 396 This policy directs <code class="computeroutput"><span class="identifier">multi_pass</span></code> 397 to read from an input iterator of type <code class="computeroutput"><span class="identifier">Input</span></code>. 398 </p> 399 </td> 400</tr> 401<tr> 402<td> 403 <p> 404 <code class="computeroutput"><span class="identifier">buffering_input_iterator</span></code> 405 </p> 406 </td> 407<td> 408 <p> 409 This policy directs <code class="computeroutput"><span class="identifier">multi_pass</span></code> 410 to read from an input iterator of type <code class="computeroutput"><span class="identifier">Input</span></code>. 411 Additionally it buffers the last character received from the underlying 412 iterator. This allows to wrap iterators not buffering the last 413 character on their own (as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istreambuf_iterator</span></code>). 414 </p> 415 </td> 416</tr> 417<tr> 418<td> 419 <p> 420 <code class="computeroutput"><span class="identifier">istream</span></code> 421 </p> 422 </td> 423<td> 424 <p> 425 This policy directs <code class="computeroutput"><span class="identifier">multi_pass</span></code> 426 to read from an input stream of type <code class="computeroutput"><span class="identifier">Input</span></code> 427 (usually a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_istream</span></code>). 428 </p> 429 </td> 430</tr> 431<tr> 432<td> 433 <p> 434 <code class="computeroutput"><span class="identifier">lex_input</span></code> 435 </p> 436 </td> 437<td> 438 <p> 439 This policy obtains it's input by calling yylex(), which would 440 typically be provided by a scanner generated by <a href="http://flex.sourceforge.net/" target="_top">Flex</a>. 441 If you use this policy your code must link against a <a href="http://flex.sourceforge.net/" target="_top">Flex</a> 442 generated scanner. 443 </p> 444 </td> 445</tr> 446<tr> 447<td> 448 <p> 449 <code class="computeroutput"><span class="identifier">functor_input</span></code> 450 </p> 451 </td> 452<td> 453 <p> 454 This input policy obtains it's data by calling a functor of type 455 <code class="computeroutput"><span class="identifier">Input</span></code>. The functor 456 must meet certain requirements. It must have a typedef called 457 <code class="computeroutput"><span class="identifier">result_type</span></code> which 458 should be the type returned from <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>. Also, since an input policy 459 needs a way to determine when the end of input has been reached, 460 the functor must contain a static variable named <code class="computeroutput"><span class="identifier">eof</span></code> which is comparable to a 461 variable of <code class="computeroutput"><span class="identifier">result_type</span></code>. 462 </p> 463 </td> 464</tr> 465<tr> 466<td> 467 <p> 468 <code class="computeroutput"><span class="identifier">split_functor_input</span></code> 469 </p> 470 </td> 471<td> 472 <p> 473 This is essentially the same as the <code class="computeroutput"><span class="identifier">functor_input</span></code> 474 policy except that the (user supplied) function object exposes 475 separate <code class="computeroutput"><span class="identifier">unique</span></code> 476 and <code class="computeroutput"><span class="identifier">shared</span></code> sub 477 classes, allowing to integrate the functors <span class="emphasis"><em>unique</em></span> 478 data members with the <code class="computeroutput"><span class="identifier">multi_pass</span></code> 479 data items held by each instance and its <span class="emphasis"><em>shared</em></span> 480 data members will be integrated with the <code class="computeroutput"><span class="identifier">multi_pass</span></code> 481 members shared by all copies. 482 </p> 483 </td> 484</tr> 485<tr> 486<td> 487 <p> 488 <span class="bold"><strong>OwnershipPolicy</strong></span> classes 489 </p> 490 </td> 491<td class="auto-generated"> </td> 492</tr> 493<tr> 494<td> 495 <p> 496 <code class="computeroutput"><span class="identifier">ref_counted</span></code> 497 </p> 498 </td> 499<td> 500 <p> 501 This class uses a reference counting scheme. The <code class="computeroutput"><span class="identifier">multi_pass</span></code> will delete it's shared 502 components when the count reaches zero. 503 </p> 504 </td> 505</tr> 506<tr> 507<td> 508 <p> 509 <code class="computeroutput"><span class="identifier">first_owner</span></code> 510 </p> 511 </td> 512<td> 513 <p> 514 When this policy is used, the first <code class="computeroutput"><span class="identifier">multi_pass</span></code> 515 created will be the one that deletes the shared data. Each copy 516 will not take ownership of the shared data. This works well for 517 <a href="http://boost-spirit.com" target="_top">Spirit</a>, since no dynamic 518 allocation of iterators is done. All copies are made on the stack, 519 so the original iterator has the longest lifespan. 520 </p> 521 </td> 522</tr> 523<tr> 524<td> 525 <p> 526 <span class="bold"><strong>CheckingPolicy</strong></span> classes 527 </p> 528 </td> 529<td class="auto-generated"> </td> 530</tr> 531<tr> 532<td> 533 <p> 534 <code class="computeroutput"><span class="identifier">no_check</span></code> 535 </p> 536 </td> 537<td> 538 <p> 539 This policy does no checking at all. 540 </p> 541 </td> 542</tr> 543<tr> 544<td> 545 <p> 546 <code class="computeroutput"><span class="identifier">buf_id_check</span></code> 547 </p> 548 </td> 549<td> 550 <p> 551 This policy keeps around a buffer id, or a buffer age. Every time 552 <code class="computeroutput"><span class="identifier">clear_queue</span><span class="special">()</span></code> 553 is called on a <code class="computeroutput"><span class="identifier">multi_pass</span></code> 554 iterator, it is possible that all other iterators become invalid. 555 When <code class="computeroutput"><span class="identifier">clear_queue</span><span class="special">()</span></code> is called, <code class="computeroutput"><span class="identifier">buf_id_check</span></code> 556 increments the buffer id. When an iterator is dereferenced, this 557 policy checks that the buffer id of the iterator matches the shared 558 buffer id. This policy is most effective when used together with 559 the <code class="computeroutput"><span class="identifier">split_std_deque</span></code> 560 StoragePolicy. It should not be used with the <code class="computeroutput"><span class="identifier">fixed_size_queue</span></code> 561 StoragePolicy, because it will not detect iterator dereferences 562 that are out of range. 563 </p> 564 </td> 565</tr> 566<tr> 567<td> 568 <p> 569 full_check 570 </p> 571 </td> 572<td> 573 <p> 574 This policy has not been implemented yet. When it is, it will keep 575 track of all iterators and make sure that they are all valid. This 576 will be mostly useful for debugging purposes as it will incur significant 577 overhead. 578 </p> 579 </td> 580</tr> 581<tr> 582<td> 583 <p> 584 <span class="bold"><strong>StoragePolicy</strong></span> classes 585 </p> 586 </td> 587<td class="auto-generated"> </td> 588</tr> 589<tr> 590<td> 591 <p> 592 <code class="computeroutput"><span class="identifier">split_std_deque</span></code> 593 </p> 594 </td> 595<td> 596 <p> 597 Despite its name this policy keeps all buffered data in a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>. All data is stored as 598 long as there is more than one iterator. Once the iterator count 599 goes down to one, and the queue is no longer needed, it is cleared, 600 freeing up memory. The queue can also be forcibly cleared by calling 601 <code class="computeroutput"><span class="identifier">multi_pass</span><span class="special">::</span><span class="identifier">clear_queue</span><span class="special">()</span></code>. 602 </p> 603 </td> 604</tr> 605<tr> 606<td> 607 <p> 608 <code class="computeroutput"><span class="identifier">fixed_size_queue</span><span class="special"><</span><span class="identifier">N</span><span class="special">></span></code> 609 </p> 610 </td> 611<td> 612 <p> 613 This policy keeps a circular buffer that is size <code class="computeroutput"><span class="identifier">N</span><span class="special">+</span><span class="number">1</span></code> and stores <code class="computeroutput"><span class="identifier">N</span></code> 614 elements. <code class="computeroutput"><span class="identifier">fixed_size_queue</span></code> 615 is a template with a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code> 616 parameter that specified the queue size. It is your responsibility 617 to ensure that <code class="computeroutput"><span class="identifier">N</span></code> 618 is big enough for your parser. Whenever the foremost iterator is 619 incremented, the last character of the buffer is automatically 620 erased. Currently there is no way to tell if an iterator is trailing 621 too far behind and has become invalid. No dynamic allocation is 622 done by this policy during normal iterator operation, only on initial 623 construction. The memory usage of this <code class="computeroutput"><span class="identifier">StoragePolicy</span></code> 624 is set at <code class="computeroutput"><span class="identifier">N</span><span class="special">+</span><span class="number">1</span></code> bytes, unlike <code class="computeroutput"><span class="identifier">split_std_deque</span></code>, 625 which is unbounded. 626 </p> 627 </td> 628</tr> 629</tbody> 630</table></div> 631</div> 632<br class="table-break"><h5> 633<a name="spirit.support.multi_pass.h4"></a> 634 <span class="phrase"><a name="spirit.support.multi_pass.combinations__how_to_specify_your_own_custom_multi_pass"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.combinations__how_to_specify_your_own_custom_multi_pass">Combinations: 635 How to specify your own custom multi_pass</a> 636 </h5> 637<p> 638 The beauty of policy based designs is that you can mix and match policies 639 to create your own custom iterator by selecting the policies you want. Here's 640 an example of how to specify a custom <code class="computeroutput"><span class="identifier">multi_pass</span></code> 641 that wraps an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span></code>, 642 and is slightly more efficient than the default <code class="computeroutput"><span class="identifier">multi_pass</span></code> 643 (as generated by the <code class="computeroutput"><span class="identifier">make_default_multi_pass</span><span class="special">()</span></code> API function) because it uses the <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">first_owner</span></code> OwnershipPolicy and the <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">no_check</span></code> CheckingPolicy: 644 </p> 645<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">multi_pass</span><span class="special"><</span> 646 <span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> 647 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">default_policy</span><span class="special"><</span> 648 <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">first_owner</span> 649 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">no_check</span> 650 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">buffering_input_iterator</span> 651 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">split_std_deque</span> 652 <span class="special">></span> 653<span class="special">></span> <span class="identifier">first_owner_multi_pass_type</span><span class="special">;</span> 654</pre> 655<p> 656 The default template parameters for <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">default_policy</span></code> 657 are: 658 </p> 659<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> 660<li class="listitem"> 661 <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">ref_counted</span></code> OwnershipPolicy 662 </li> 663<li class="listitem"> 664 <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">no_check</span></code> CheckingPolicy, if <code class="computeroutput"><span class="identifier">BOOST_SPIRIT_DEBUG</span></code> is defined: <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">buf_id_check</span></code> CheckingPolicy 665 </li> 666<li class="listitem"> 667 <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">buffering_input_iterator</span></code> InputPolicy, 668 and 669 </li> 670<li class="listitem"> 671 <code class="computeroutput"><span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">split_std_deque</span></code> StoragePolicy. 672 </li> 673</ul></div> 674<p> 675 So if you use <code class="computeroutput"><span class="identifier">multi_pass</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> 676 <span class="special">></span></code> you will get those pre-defined 677 behaviors while wrapping an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span></code>. 678 </p> 679<h5> 680<a name="spirit.support.multi_pass.h5"></a> 681 <span class="phrase"><a name="spirit.support.multi_pass.dealing_with_constant_look_ahead"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.dealing_with_constant_look_ahead">Dealing 682 with constant look ahead</a> 683 </h5> 684<p> 685 There is one other pre-defined class called <code class="computeroutput"><span class="identifier">look_ahead</span></code>. 686 The class <code class="computeroutput"><span class="identifier">look_ahead</span></code> is another 687 predefine <code class="computeroutput"><span class="identifier">multi_pass</span></code> iterator 688 type. It has two template parameters: <code class="computeroutput"><span class="identifier">Input</span></code>, 689 the type of the input iterator to wrap, and a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">N</span></code>, which specifies the size of the buffer 690 to the <code class="computeroutput"><span class="identifier">fixed_size_queue</span></code> policy. 691 While the default multi_pass configuration is designed for safety, <code class="computeroutput"><span class="identifier">look_ahead</span></code> is designed for speed. <code class="computeroutput"><span class="identifier">look_ahead</span></code> is derived from a multi_pass 692 with the following policies: <code class="computeroutput"><span class="identifier">input_iterator</span></code> 693 InputPolicy, <code class="computeroutput"><span class="identifier">first_owner</span></code> 694 OwnershipPolicy, <code class="computeroutput"><span class="identifier">no_check</span></code> 695 CheckingPolicy, and <code class="computeroutput"><span class="identifier">fixed_size_queue</span><span class="special"><</span><span class="identifier">N</span><span class="special">></span></code> 696 StoragePolicy. 697 </p> 698<p> 699 This iterator is defined by including the files: 700 </p> 701<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/home/support/look_ahead.hpp></span> 702<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">support_look_ahead</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 703</pre> 704<p> 705 Also, see <a class="link" href="../structure/include.html" title="Include">Include Structure</a>. 706 </p> 707<h5> 708<a name="spirit.support.multi_pass.h6"></a> 709 <span class="phrase"><a name="spirit.support.multi_pass.reading_from_standard_input_streams"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.reading_from_standard_input_streams">Reading 710 from standard input streams</a> 711 </h5> 712<p> 713 Yet another predefined iterator for wrapping standard input streams (usually 714 a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_istream</span><span class="special"><></span></code>) 715 is called <code class="computeroutput"><span class="identifier">basic_istream_iterator</span><span class="special"><</span><span class="identifier">Char</span><span class="special">,</span> <span class="identifier">Traits</span><span class="special">></span></code>. This class is usable as a drop in replacement 716 for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special"><</span><span class="identifier">Char</span><span class="special">,</span> <span class="identifier">Traits</span><span class="special">></span></code>. 717 Its only difference is that it is a forward iterator (instead of the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span></code>, 718 which is an input iterator). <code class="computeroutput"><span class="identifier">basic_istream_iterator</span></code> 719 is derived from a multi_pass with the following policies: <code class="computeroutput"><span class="identifier">istream</span></code> 720 InputPolicy, <code class="computeroutput"><span class="identifier">ref_counted</span></code> 721 OwnershipPolicy, <code class="computeroutput"><span class="identifier">no_check</span></code> 722 CheckingPolicy, and <code class="computeroutput"><span class="identifier">split_std_deque</span></code> 723 StoragePolicy. 724 </p> 725<p> 726 There exists an additional predefined typedef: 727 </p> 728<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">basic_istream_iterator</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">></span> <span class="special">></span> <span class="identifier">istream_iterator</span><span class="special">;</span> 729</pre> 730<p> 731 This iterator is defined by including the files: 732 </p> 733<pre class="programlisting"><span class="comment">// forwards to <boost/spirit/home/support/istream_iterator.hpp></span> 734<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">support_istream_iterator</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 735</pre> 736<p> 737 Also, see <a class="link" href="../structure/include.html" title="Include">Include Structure</a>. 738 </p> 739<h5> 740<a name="spirit.support.multi_pass.h7"></a> 741 <span class="phrase"><a name="spirit.support.multi_pass.how_to_write_a_functor_for_use_with_the__code__phrase_role__identifier__functor_input__phrase___code__inputpolicy"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.how_to_write_a_functor_for_use_with_the__code__phrase_role__identifier__functor_input__phrase___code__inputpolicy">How 742 to write a functor for use with the <code class="computeroutput"><span class="identifier">functor_input</span></code> 743 InputPolicy</a> 744 </h5> 745<p> 746 If you want to use the <code class="computeroutput"><span class="identifier">functor_input</span></code> 747 InputPolicy, you can write your own function object that will supply the 748 input to <code class="computeroutput"><span class="identifier">multi_pass</span></code>. The 749 function object must satisfy several requirements. It must have a typedef 750 <code class="computeroutput"><span class="identifier">result_type</span></code> which specifies 751 the return type of its <code class="computeroutput"><span class="keyword">operator</span><span class="special">()</span></code>. This is standard practice in the STL. 752 Also, it must supply a static variable called eof which is compared against 753 to know whether the input has reached the end. Last but not least the function 754 object must be default constructible. Here is an example: 755 </p> 756<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">iostream</span><span class="special">></span> 757<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">home</span><span class="special">/</span><span class="identifier">qi</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 758<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">home</span><span class="special">/</span><span class="identifier">support</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 759<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">home</span><span class="special">/</span><span class="identifier">support</span><span class="special">/</span><span class="identifier">multi_pass</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 760<span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">spirit</span><span class="special">/</span><span class="identifier">home</span><span class="special">/</span><span class="identifier">support</span><span class="special">/</span><span class="identifier">iterators</span><span class="special">/</span><span class="identifier">detail</span><span class="special">/</span><span class="identifier">functor_input_policy</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span> 761 762<span class="comment">// define the function object</span> 763<span class="keyword">class</span> <span class="identifier">iterate_a2m</span> 764<span class="special">{</span> 765<span class="keyword">public</span><span class="special">:</span> 766 <span class="keyword">typedef</span> <span class="keyword">char</span> <span class="identifier">result_type</span><span class="special">;</span> 767 768 <span class="identifier">iterate_a2m</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">c_</span><span class="special">(</span><span class="char">'A'</span><span class="special">)</span> <span class="special">{}</span> 769 <span class="identifier">iterate_a2m</span><span class="special">(</span><span class="keyword">char</span> <span class="identifier">c</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">c_</span><span class="special">(</span><span class="identifier">c</span><span class="special">)</span> <span class="special">{}</span> 770 771 <span class="identifier">result_type</span> <span class="keyword">operator</span><span class="special">()()</span> 772 <span class="special">{</span> 773 <span class="keyword">if</span> <span class="special">(</span><span class="identifier">c_</span> <span class="special">==</span> <span class="char">'M'</span><span class="special">)</span> 774 <span class="keyword">return</span> <span class="identifier">eof</span><span class="special">;</span> 775 <span class="keyword">return</span> <span class="identifier">c_</span><span class="special">++;</span> 776 <span class="special">}</span> 777 778 <span class="keyword">static</span> <span class="identifier">result_type</span> <span class="identifier">eof</span><span class="special">;</span> 779 780<span class="keyword">private</span><span class="special">:</span> 781 <span class="keyword">char</span> <span class="identifier">c_</span><span class="special">;</span> 782<span class="special">};</span> 783 784<span class="identifier">iterate_a2m</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">iterate_a2m</span><span class="special">::</span><span class="identifier">eof</span> <span class="special">=</span> <span class="identifier">iterate_a2m</span><span class="special">::</span><span class="identifier">result_type</span><span class="special">(</span><span class="char">'M'</span><span class="special">);</span> 785 786<span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">;</span> 787 788<span class="comment">// create two iterators using the define function object, one of which is </span> 789<span class="comment">// an end iterator</span> 790<span class="keyword">typedef</span> <span class="identifier">multi_pass</span><span class="special"><</span><span class="identifier">iterate_a2m</span> 791 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">first_owner</span> 792 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">no_check</span> 793 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">functor_input</span> 794 <span class="special">,</span> <span class="identifier">iterator_policies</span><span class="special">::</span><span class="identifier">split_std_deque</span><span class="special">></span> 795<span class="identifier">functor_multi_pass_type</span><span class="special">;</span> 796 797<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span> 798<span class="special">{</span> 799 <span class="identifier">functor_multi_pass_type</span> <span class="identifier">first</span> <span class="special">=</span> <span class="identifier">functor_multi_pass_type</span><span class="special">(</span><span class="identifier">iterate_a2m</span><span class="special">());</span> 800 <span class="identifier">functor_multi_pass_type</span> <span class="identifier">last</span><span class="special">;</span> 801 802 <span class="comment">// use the iterators: this will print "ABCDEFGHIJKL"</span> 803 <span class="keyword">while</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> 804 <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">first</span><span class="special">;</span> 805 <span class="special">++</span><span class="identifier">first</span><span class="special">;</span> 806 <span class="special">}</span> 807 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special"><<</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span> 808 <span class="keyword">return</span> <span class="number">0</span><span class="special">;</span> 809<span class="special">}</span> 810</pre> 811<h5> 812<a name="spirit.support.multi_pass.h8"></a> 813 <span class="phrase"><a name="spirit.support.multi_pass.how_to_write_policies_for_use_with_multi_pass"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.how_to_write_policies_for_use_with_multi_pass">How 814 to write policies for use with multi_pass</a> 815 </h5> 816<p> 817 All policies to be used with the <code class="computeroutput"><span class="identifier">default_policy</span></code> 818 template need to have two embedded classes: <code class="computeroutput"><span class="identifier">unique</span></code> 819 and <code class="computeroutput"><span class="identifier">shared</span></code>. The <code class="computeroutput"><span class="identifier">unique</span></code> class needs to implement all required 820 functions for a particular policy type. In addition it may hold all member 821 data items being <span class="emphasis"><em>unique</em></span> for a particular instance of 822 a <code class="computeroutput"><span class="identifier">multi_pass</span></code> (hence the name). 823 The <code class="computeroutput"><span class="identifier">shared</span></code> class does not 824 expose any member functions (except sometimes a constructor), but it may 825 hold all member data items to be <span class="emphasis"><em>shared</em></span> between all 826 copies of a particular <code class="computeroutput"><span class="identifier">multi_pass</span></code>. 827 </p> 828<h5> 829<a name="spirit.support.multi_pass.h9"></a> 830 <span class="phrase"><a name="spirit.support.multi_pass.inputpolicy"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.inputpolicy">InputPolicy</a> 831 </h5> 832<p> 833 An <code class="computeroutput"><span class="identifier">InputPolicy</span></code> must have 834 the following interface: 835 </p> 836<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">input_policy</span> 837<span class="special">{</span> 838 <span class="comment">// Input is the same type used as the first template parameter</span> 839 <span class="comment">// while instantiating the multi_pass</span> 840 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Input</span><span class="special">></span> 841 <span class="keyword">struct</span> <span class="identifier">unique</span> 842 <span class="special">{</span> 843 <span class="comment">// these typedef's will be exposed as the multi_pass iterator</span> 844 <span class="comment">// properties</span> 845 <span class="keyword">typedef</span> <span class="identifier">__unspecified_type__</span> <span class="identifier">value_type</span><span class="special">;</span> 846 <span class="keyword">typedef</span> <span class="identifier">__unspecified_type__</span> <span class="identifier">difference_type</span><span class="special">;</span> 847 <span class="keyword">typedef</span> <span class="identifier">__unspecified_type__</span> <span class="identifier">distance_type</span><span class="special">;</span> 848 <span class="keyword">typedef</span> <span class="identifier">__unspecified_type__</span> <span class="identifier">pointer</span><span class="special">;</span> 849 <span class="keyword">typedef</span> <span class="identifier">__unspecified_type__</span> <span class="identifier">reference</span><span class="special">;</span> 850 851 <span class="identifier">unique</span><span class="special">()</span> <span class="special">{}</span> 852 <span class="keyword">explicit</span> <span class="identifier">unique</span><span class="special">(</span><span class="identifier">Input</span><span class="special">)</span> <span class="special">{}</span> 853 854 <span class="comment">// destroy is called whenever the last copy of a multi_pass is</span> 855 <span class="comment">// destructed (ownership_policy::release() returned true)</span> 856 <span class="comment">//</span> 857 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 858 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 859 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">destroy</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 860 861 <span class="comment">// swap is called by multi_pass::swap()</span> 862 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">unique</span><span class="special">&);</span> 863 864 <span class="comment">// get_input is called whenever the next input character/token</span> 865 <span class="comment">// should be fetched. </span> 866 <span class="comment">//</span> 867 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 868 <span class="comment">//</span> 869 <span class="comment">// This method is expected to return a reference to the next </span> 870 <span class="comment">// character/token</span> 871 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 872 <span class="keyword">static</span> <span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">::</span><span class="identifier">reference</span> <span class="identifier">get_input</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 873 874 <span class="comment">// advance_input is called whenever the underlying input stream </span> 875 <span class="comment">// should be advanced so that the next call to get_input will be </span> 876 <span class="comment">// able to return the next input character/token</span> 877 <span class="comment">//</span> 878 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 879 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 880 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">advance_input</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 881 882 <span class="comment">// input_at_eof is called to test whether this instance is a </span> 883 <span class="comment">// end of input iterator.</span> 884 <span class="comment">//</span> 885 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 886 <span class="comment">//</span> 887 <span class="comment">// This method is expected to return true if the end of input is </span> 888 <span class="comment">// reached. It is often used in the implementation of the function</span> 889 <span class="comment">// storage_policy::is_eof.</span> 890 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 891 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">input_at_eof</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 892 893 <span class="comment">// input_is_valid is called to verify if the parameter t represents </span> 894 <span class="comment">// a valid input character/token</span> 895 <span class="comment">//</span> 896 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 897 <span class="comment">// t: is the character/token to test for validity</span> 898 <span class="comment">// </span> 899 <span class="comment">// This method is expected to return true if the parameter t </span> 900 <span class="comment">// represents a valid character/token.</span> 901 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 902 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">input_is_valid</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">t</span><span class="special">);</span> 903 <span class="special">};</span> 904 905 <span class="comment">// Input is the same type used as the first template parameter passed</span> 906 <span class="comment">// while instantiating the multi_pass</span> 907 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Input</span><span class="special">></span> 908 <span class="keyword">struct</span> <span class="identifier">shared</span> 909 <span class="special">{</span> 910 <span class="keyword">explicit</span> <span class="identifier">shared</span><span class="special">(</span><span class="identifier">Input</span><span class="special">)</span> <span class="special">{}</span> 911 <span class="special">};</span> 912<span class="special">};</span> 913</pre> 914<p> 915 It is possible to derive the struct <code class="computeroutput"><span class="identifier">unique</span></code> 916 from the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">default_input_policy</span></code>. This type implements 917 a minimal sufficient interface for some of the required functions, simplifying 918 the task of writing a new input policy. 919 </p> 920<p> 921 This class may implement a function <code class="computeroutput"><span class="identifier">destroy</span><span class="special">()</span></code> being called during destruction of the 922 last copy of a <code class="computeroutput"><span class="identifier">multi_pass</span></code>. 923 This function should be used to free any of the shared data items the policy 924 might have allocated during construction of its <code class="computeroutput"><span class="identifier">shared</span></code> 925 part. Because of the way <code class="computeroutput"><span class="identifier">multi_pass</span></code> 926 is implemented any allocated data members in <code class="computeroutput"><span class="identifier">shared</span></code> 927 should <span class="underline">not</span> be deep copied in a copy 928 constructor of <code class="computeroutput"><span class="identifier">shared</span></code>. 929 </p> 930<h5> 931<a name="spirit.support.multi_pass.h10"></a> 932 <span class="phrase"><a name="spirit.support.multi_pass.ownershippolicy"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.ownershippolicy">OwnershipPolicy</a> 933 </h5> 934<p> 935 The <code class="computeroutput"><span class="identifier">OwnershipPolicy</span></code> must 936 have the following interface: 937 </p> 938<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">ownership_policy</span> 939<span class="special">{</span> 940 <span class="keyword">struct</span> <span class="identifier">unique</span> 941 <span class="special">{</span> 942 <span class="comment">// destroy is called whenever the last copy of a multi_pass is</span> 943 <span class="comment">// destructed (ownership_policy::release() returned true)</span> 944 <span class="comment">//</span> 945 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 946 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 947 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">destroy</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 948 949 <span class="comment">// swap is called by multi_pass::swap()</span> 950 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">unique</span><span class="special">&);</span> 951 952 <span class="comment">// clone is called whenever a multi_pass is copied</span> 953 <span class="comment">//</span> 954 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 955 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 956 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">clone</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 957 958 <span class="comment">// release is called whenever a multi_pass is destroyed</span> 959 <span class="comment">//</span> 960 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 961 <span class="comment">//</span> 962 <span class="comment">// The method is expected to return true if the destructed </span> 963 <span class="comment">// instance is the last copy of a particular multi_pass. </span> 964 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 965 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">release</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 966 967 <span class="comment">// is_unique is called to test whether this instance is the only </span> 968 <span class="comment">// existing copy of a particular multi_pass</span> 969 <span class="comment">//</span> 970 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 971 <span class="comment">//</span> 972 <span class="comment">// The method is expected to return true if this instance is unique</span> 973 <span class="comment">// (no other copies of this multi_pass exist).</span> 974 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 975 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">is_unique</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 976 <span class="special">};</span> 977 978 <span class="keyword">struct</span> <span class="identifier">shared</span> <span class="special">{};</span> 979<span class="special">};</span> 980</pre> 981<p> 982 It is possible to derive the struct <code class="computeroutput"><span class="identifier">unique</span></code> 983 from the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">default_ownership_policy</span></code>. This type implements 984 a minimal sufficient interface for some of the required functions, simplifying 985 the task of writing a new ownership policy. 986 </p> 987<p> 988 This class may implement a function <code class="computeroutput"><span class="identifier">destroy</span><span class="special">()</span></code> being called during destruction of the 989 last copy of a <code class="computeroutput"><span class="identifier">multi_pass</span></code>. 990 This function should be used to free any of the shared data items the policy 991 might have allocated during construction of its <code class="computeroutput"><span class="identifier">shared</span></code> 992 part. Because of the way <code class="computeroutput"><span class="identifier">multi_pass</span></code> 993 is implemented any allocated data members in <code class="computeroutput"><span class="identifier">shared</span></code> 994 should <span class="underline">not</span> be deep copied in a copy 995 constructor of <code class="computeroutput"><span class="identifier">shared</span></code>. 996 </p> 997<h5> 998<a name="spirit.support.multi_pass.h11"></a> 999 <span class="phrase"><a name="spirit.support.multi_pass.checkingpolicy"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.checkingpolicy">CheckingPolicy</a> 1000 </h5> 1001<p> 1002 The <code class="computeroutput"><span class="identifier">CheckingPolicy</span></code> must have 1003 the following interface: 1004 </p> 1005<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">checking_policy</span> 1006<span class="special">{</span> 1007 <span class="keyword">struct</span> <span class="identifier">unique</span> 1008 <span class="special">{</span> 1009 <span class="comment">// swap is called by multi_pass::swap()</span> 1010 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">unique</span><span class="special">&);</span> 1011 1012 <span class="comment">// destroy is called whenever the last copy of a multi_pass is</span> 1013 <span class="comment">// destructed (ownership_policy::release() returned true)</span> 1014 <span class="comment">//</span> 1015 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1016 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1017 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">destroy</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1018 1019 <span class="comment">// docheck is called before the multi_pass is dereferenced or </span> 1020 <span class="comment">// incremented. </span> 1021 <span class="comment">//</span> 1022 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1023 <span class="comment">//</span> 1024 <span class="comment">// This method is expected to make sure the multi_pass instance is</span> 1025 <span class="comment">// still valid. If it is invalid an exception should be thrown.</span> 1026 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1027 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">docheck</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1028 1029 <span class="comment">// clear_queue is called whenever the function </span> 1030 <span class="comment">// multi_pass::clear_queue is called on this instance</span> 1031 <span class="comment">//</span> 1032 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1033 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1034 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">clear_queue</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1035 <span class="special">};</span> 1036 1037 <span class="keyword">struct</span> <span class="identifier">shared</span> <span class="special">{};</span> 1038<span class="special">};</span> 1039</pre> 1040<p> 1041 It is possible to derive the struct <code class="computeroutput"><span class="identifier">unique</span></code> 1042 from the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">default_checking_policy</span></code>. This type implements 1043 a minimal sufficient interface for some of the required functions, simplifying 1044 the task of writing a new checking policy. 1045 </p> 1046<p> 1047 This class may implement a function <code class="computeroutput"><span class="identifier">destroy</span><span class="special">()</span></code> being called during destruction of the 1048 last copy of a <code class="computeroutput"><span class="identifier">multi_pass</span></code>. 1049 This function should be used to free any of the shared data items the policy 1050 might have allocated during construction of its <code class="computeroutput"><span class="identifier">shared</span></code> 1051 part. Because of the way <code class="computeroutput"><span class="identifier">multi_pass</span></code> 1052 is implemented any allocated data members in <code class="computeroutput"><span class="identifier">shared</span></code> 1053 should <span class="underline">not</span> be deep copied in a copy 1054 constructor of <code class="computeroutput"><span class="identifier">shared</span></code>. 1055 </p> 1056<h5> 1057<a name="spirit.support.multi_pass.h12"></a> 1058 <span class="phrase"><a name="spirit.support.multi_pass.storagepolicy"></a></span><a class="link" href="multi_pass.html#spirit.support.multi_pass.storagepolicy">StoragePolicy</a> 1059 </h5> 1060<p> 1061 A <code class="computeroutput"><span class="identifier">StoragePolicy</span></code> must have 1062 the following interface: 1063 </p> 1064<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">storage_policy</span> 1065<span class="special">{</span> 1066 <span class="comment">// Value is the same type as typename MultiPass::value_type</span> 1067 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">></span> 1068 <span class="keyword">struct</span> <span class="identifier">unique</span> 1069 <span class="special">{</span> 1070 <span class="comment">// destroy is called whenever the last copy of a multi_pass is</span> 1071 <span class="comment">// destructed (ownership_policy::release() returned true)</span> 1072 <span class="comment">//</span> 1073 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1074 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1075 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">destroy</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1076 1077 <span class="comment">// swap is called by multi_pass::swap()</span> 1078 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span><span class="identifier">unique</span><span class="special">&);</span> 1079 1080 <span class="comment">// dereference is called whenever multi_pass::operator*() is invoked</span> 1081 <span class="comment">//</span> 1082 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1083 <span class="comment">//</span> 1084 <span class="comment">// This function is expected to return a reference to the current</span> 1085 <span class="comment">// character/token.</span> 1086 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1087 <span class="keyword">static</span> <span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">::</span><span class="identifier">reference</span> <span class="identifier">dereference</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1088 1089 <span class="comment">// increment is called whenever multi_pass::operator++ is invoked</span> 1090 <span class="comment">//</span> 1091 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1092 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1093 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">increment</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1094 1095 <span class="comment">//</span> 1096 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1097 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1098 <span class="keyword">static</span> <span class="keyword">void</span> <span class="identifier">clear_queue</span><span class="special">(</span><span class="identifier">MultiPass</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1099 1100 <span class="comment">// is_eof is called to test whether this instance is a end of input </span> 1101 <span class="comment">// iterator.</span> 1102 <span class="comment">//</span> 1103 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1104 <span class="comment">//</span> 1105 <span class="comment">// This method is expected to return true if the end of input is </span> 1106 <span class="comment">// reached. </span> 1107 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1108 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">is_eof</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">);</span> 1109 1110 <span class="comment">// less_than is called whenever multi_pass::operator==() is invoked</span> 1111 <span class="comment">//</span> 1112 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1113 <span class="comment">// rhs: is the multi_pass reference this instance is compared </span> 1114 <span class="comment">// to</span> 1115 <span class="comment">//</span> 1116 <span class="comment">// This function is expected to return true if the current instance</span> 1117 <span class="comment">// is equal to the right hand side multi_pass instance</span> 1118 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1119 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">equal_to</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">,</span> <span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span> 1120 1121 <span class="comment">// less_than is called whenever multi_pass::operator<() is invoked</span> 1122 <span class="comment">//</span> 1123 <span class="comment">// mp: is a reference to the whole multi_pass instance</span> 1124 <span class="comment">// rhs: is the multi_pass reference this instance is compared </span> 1125 <span class="comment">// to</span> 1126 <span class="comment">//</span> 1127 <span class="comment">// This function is expected to return true if the current instance</span> 1128 <span class="comment">// is less than the right hand side multi_pass instance</span> 1129 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">></span> 1130 <span class="keyword">static</span> <span class="keyword">bool</span> <span class="identifier">less_than</span><span class="special">(</span><span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">mp</span><span class="special">,</span> <span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span><span class="special">);</span> 1131 <span class="special">};</span> 1132 1133 <span class="comment">// Value is the same type as typename MultiPass::value_type</span> 1134 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">></span> 1135 <span class="keyword">struct</span> <span class="identifier">shared</span> <span class="special">{};</span> 1136<span class="special">};</span> 1137</pre> 1138<p> 1139 It is possible to derive the struct <code class="computeroutput"><span class="identifier">unique</span></code> 1140 from the type <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">spirit</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">default_storage_policy</span></code>. This type implements 1141 a minimal sufficient interface for some of the required functions, simplifying 1142 the task of writing a new storage policy. 1143 </p> 1144<p> 1145 This class may implement a function <code class="computeroutput"><span class="identifier">destroy</span><span class="special">()</span></code> being called during destruction of the 1146 last copy of a <code class="computeroutput"><span class="identifier">multi_pass</span></code>. 1147 This function should be used to free any of the shared data items the policy 1148 might have allocated during construction of its <code class="computeroutput"><span class="identifier">shared</span></code> 1149 part. Because of the way <code class="computeroutput"><span class="identifier">multi_pass</span></code> 1150 is implemented any allocated data members in <code class="computeroutput"><span class="identifier">shared</span></code> 1151 should <span class="underline">not</span> be deep copied in a copy 1152 constructor of <code class="computeroutput"><span class="identifier">shared</span></code>. 1153 </p> 1154<p> 1155 Generally, a <code class="computeroutput"><span class="identifier">StoragePolicy</span></code> 1156 is the trickiest policy to implement. You should study and understand the 1157 existing <code class="computeroutput"><span class="identifier">StoragePolicy</span></code> classes 1158 before you try and write your own. 1159 </p> 1160</div> 1161<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 1162<td align="left"></td> 1163<td align="right"><div class="copyright-footer">Copyright © 2001-2011 Joel de Guzman, Hartmut Kaiser<p> 1164 Distributed under the Boost Software License, Version 1.0. (See accompanying 1165 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>) 1166 </p> 1167</div></td> 1168</tr></table> 1169<hr> 1170<div class="spirit-nav"> 1171<a accesskey="p" href="../support.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../support.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="line_pos_iterator.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 1172</div> 1173</body> 1174</html> 1175