• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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">&gt;&gt;</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">&gt;</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">&lt;</span><span class="identifier">iterator_type</span><span class="special">&gt;</span> <span class="identifier">r</span><span class="special">;</span>
110<span class="identifier">on_error</span><span class="special">&lt;</span><span class="identifier">retry</span><span class="special">&gt;(</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">&lt;&lt;</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">&gt;&gt;</span> <span class="identifier">block</span> <span class="special">&gt;&gt;</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">&gt;&gt;</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">&lt;&lt;</span> <span class="string">"Could not open input file: 'multi_pass.txt'"</span> <span class="special">&lt;&lt;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;</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">&lt;</span><span class="identifier">base_iterator_type</span><span class="special">&gt;</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">&lt;</span><span class="keyword">double</span><span class="special">&gt;</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">&gt;&gt;</span> <span class="special">*(</span><span class="char">','</span> <span class="special">&gt;&gt;</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">&gt;&gt;</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">&gt;&gt;</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">&lt;&lt;</span> <span class="string">"Failed parsing input file!"</span> <span class="special">&lt;&lt;</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">&lt;&lt;</span> <span class="string">"Successfully parsed input file!"</span> <span class="special">&lt;&lt;</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">&lt;</span><span class="identifier">N</span><span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;</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">&lt;</span>
646    <span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</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">&lt;</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">&gt;</span>
653<span class="special">&gt;</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">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">istream_iterator</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span>
676        <span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;</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">&lt;</span><span class="identifier">N</span><span class="special">&gt;</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 &lt;boost/spirit/home/support/look_ahead.hpp&gt;</span>
702<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;&gt;</span></code>)
715        is called <code class="computeroutput"><span class="identifier">basic_istream_iterator</span><span class="special">&lt;</span><span class="identifier">Char</span><span class="special">,</span> <span class="identifier">Traits</span><span class="special">&gt;</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">&lt;</span><span class="identifier">Char</span><span class="special">,</span> <span class="identifier">Traits</span><span class="special">&gt;</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">&lt;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="special">&gt;</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 &lt;boost/spirit/home/support/istream_iterator.hpp&gt;</span>
734<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;</span><span class="identifier">iostream</span><span class="special">&gt;</span>
757<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
758<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
759<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</span>
760<span class="preprocessor">#include</span> <span class="special">&lt;</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">&gt;</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">&lt;</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">&gt;</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">&lt;&lt;</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">&lt;&lt;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">Input</span><span class="special">&gt;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&amp;);</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">mp</span><span class="special">,</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">Input</span><span class="special">&gt;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&amp;);</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&amp;);</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">&gt;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&amp;);</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">mp</span><span class="special">,</span> <span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span><span class="special">);</span>
1120
1121        <span class="comment">// less_than is called whenever multi_pass::operator&lt;() 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">&lt;</span><span class="keyword">typename</span> <span class="identifier">MultiPass</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">mp</span><span class="special">,</span> <span class="identifier">MultiPass</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">typename</span> <span class="identifier">Value</span><span class="special">&gt;</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