• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3  Copyright 2012 Eric Niebler
4
5  Distributed under the Boost
6  Software License, Version 1.0. (See accompanying
7  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8  -->
9<header name="boost/proto/matches.hpp">
10  <para>
11    Contains definition of the
12    <computeroutput>
13      <classname alt="boost::proto::matches">proto::matches&lt;&gt;</classname>
14    </computeroutput>
15    metafunction for determining if a given expression matches a given pattern.
16  </para>
17  <namespace name="boost">
18    <namespace name="proto">
19      <struct name="_">
20        <inherit><type><classname>proto::transform</classname>&lt;_&gt;</type></inherit>
21        <purpose>A wildcard grammar element that matches any expression, and a transform that returns
22          the current expression unchanged.</purpose>
23        <description>
24          <para>
25            The wildcard type, <computeroutput>proto::_</computeroutput>, is a grammar element such
26            that <computeroutput><classname>proto::matches</classname>&lt;E, proto::_&gt;::value</computeroutput>
27            is <computeroutput>true</computeroutput> for any expression type <computeroutput>E</computeroutput>.
28          </para>
29          <para>
30            The wildcard can also be used as a stand-in for a template argument when matching terminals.
31            For instance, the following is a grammar that will match any
32            <computeroutput>std::complex&lt;&gt;</computeroutput> terminal:<programlisting>BOOST_MPL_ASSERT((
33  <classname>proto::matches</classname>&lt;
34    <classname>proto::terminal</classname>&lt;std::complex&lt;double&gt; &gt;::type,
35    <emphasis role="bold"><classname>proto::terminal</classname>&lt;std::complex&lt; proto::_ &gt; &gt;</emphasis>
36  &gt;
37));</programlisting>
38          </para>
39          <para>
40            When used as a transform, <computeroutput>proto::_</computeroutput> returns the current expression
41            unchanged. For instance, in the following, <computeroutput>proto::_</computeroutput> is used with
42            the <computeroutput><classname alt="proto::fold">proto::fold&lt;&gt;</classname></computeroutput>
43            transform to fold the children of a node:<programlisting>struct CountChildren :
44  <classname>proto::or_</classname>&lt;
45    // Terminals have no children
46    <classname>proto::when</classname>&lt;<classname>proto::terminal</classname>&lt;proto::_&gt;, mpl::int_&lt;0&gt;()&gt;,
47    // Use proto::fold&lt;&gt; to count the children of non-terminals
48    <classname>proto::otherwise</classname>&lt;
49      <classname>proto::fold</classname>&lt;
50        proto::_, // &lt;-- fold the current expression
51        mpl::int_&lt;0&gt;(),
52        mpl::plus&lt;<classname>proto::_state</classname>, mpl::int_&lt;1&gt; &gt;()
53      &gt;
54    &gt;
55  &gt;
56{};</programlisting>
57          </para>
58        </description>
59        <struct name="impl">
60          <template>
61            <template-type-parameter name="Expr"/>
62            <template-type-parameter name="State"/>
63            <template-type-parameter name="Data"/>
64          </template>
65          <inherit><type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type></inherit>
66          <typedef name="result_type">
67            <type>Expr</type>
68          </typedef>
69          <method-group name="public member functions">
70            <method name="operator()" cv="const">
71              <type>Expr</type>
72              <parameter name="expr">
73                <paramtype>typename impl::expr_param</paramtype>
74                <description>
75                  <para>An expression </para>
76                </description>
77              </parameter>
78              <parameter name="">
79                <paramtype>typename impl::state_param</paramtype>
80              </parameter>
81              <parameter name="">
82                <paramtype>typename impl::data_param</paramtype>
83              </parameter>
84              <returns>
85                <para>
86                  <computeroutput>expr</computeroutput>
87                </para>
88              </returns>
89            </method>
90          </method-group>
91        </struct>
92        <typedef name="proto_grammar">
93          <type>_</type>
94        </typedef>
95      </struct>
96
97      <!-- proto::not_ -->
98      <struct name="not_">
99        <template>
100          <template-type-parameter name="Grammar"/>
101        </template>
102        <inherit><type><classname>proto::transform</classname>&lt;not_&lt;Grammar&gt; &gt;</type></inherit>
103        <purpose>Inverts the set of expressions matched by a grammar. When used as a transform,
104          <computeroutput>proto::not_&lt;&gt;</computeroutput> returns the current expression unchanged.
105        </purpose>
106        <description>
107          <para>
108            If an expression type <computeroutput>E</computeroutput> does not match a grammar
109            <computeroutput>G</computeroutput>, then <computeroutput>E</computeroutput> <emphasis>does</emphasis>
110            match <computeroutput>proto::not_&lt;G&gt;</computeroutput>. For example,
111            <computeroutput><classname>proto::not_</classname>&lt;<classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt; &gt;</computeroutput>
112            will match any non-terminal.
113          </para>
114        </description>
115        <struct name="impl">
116          <template>
117            <template-type-parameter name="Expr"/>
118            <template-type-parameter name="State"/>
119            <template-type-parameter name="Data"/>
120          </template>
121          <inherit><type><classname>proto::transform_impl</classname>&lt;Expr, State, Data&gt;</type></inherit>
122          <typedef name="result_type">
123            <type>Expr</type>
124          </typedef>
125          <method-group name="public member functions">
126            <method name="operator()" cv="const">
127              <type>Expr</type>
128              <parameter name="expr">
129                <paramtype>typename impl::expr_param</paramtype>
130                <description>
131                  <para>An expression </para>
132                </description>
133              </parameter>
134              <parameter name="">
135                <paramtype>typename impl::state_param</paramtype>
136              </parameter>
137              <parameter name="">
138                <paramtype>typename impl::data_param</paramtype>
139              </parameter>
140              <requires>
141                <para>
142                  <computeroutput><classname>proto::matches</classname>&lt;Expr, proto::not_&gt;::value</computeroutput>
143                  is <computeroutput>true</computeroutput>.
144                </para>
145              </requires>
146              <returns>
147                <para>
148                  <computeroutput>expr</computeroutput>
149                </para>
150              </returns>
151            </method>
152          </method-group>
153        </struct>
154        <typedef name="proto_grammar">
155          <type>not_</type>
156        </typedef>
157      </struct>
158
159      <!-- proto::if_ -->
160      <struct name="if_">
161        <template>
162          <template-type-parameter name="If"/>
163          <template-type-parameter name="Then">
164            <default><type><classname>proto::_</classname></type></default>
165          </template-type-parameter>
166          <template-type-parameter name="Else">
167            <default><type><classname>proto::not_</classname>&lt;<classname>proto::_</classname>&gt;</type></default>
168          </template-type-parameter>
169        </template>
170        <inherit><classname>proto::transform</classname>&lt;if_&lt;If, Then, Else&gt; &gt;</inherit>
171        <purpose>Used to select one grammar or another based on the result of a compile-time Boolean.
172          When used as a transform, <computeroutput>proto::if_&lt;&gt;</computeroutput> selects between two
173          transforms based on a compile-time Boolean.</purpose>
174        <description>
175          <para>
176            When <computeroutput>proto::if_&lt;If, Then, Else&gt;</computeroutput> is used as a grammar,
177            <computeroutput>If</computeroutput> must be a Proto transform and
178            <computeroutput>Then</computeroutput> and <computeroutput>Else</computeroutput> must be grammars.
179            An expression type <computeroutput>E</computeroutput> matches
180            <computeroutput>proto::if_&lt;If, Then, Else&gt;</computeroutput> if
181            <computeroutput>boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, If&gt;(E)&gt;::type::value</computeroutput>
182            is <computeroutput>true</computeroutput> and
183            <computeroutput>E</computeroutput> matches <computeroutput>Then</computeroutput>; or, if
184            <computeroutput>boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, If&gt;(E)&gt;::type::value</computeroutput>
185            is <computeroutput>false</computeroutput> and <computeroutput>E</computeroutput> matches <computeroutput>Else</computeroutput>.
186          </para>
187          <para>
188            The template parameter <computeroutput>Then</computeroutput> defaults to <computeroutput><classname>proto::_</classname></computeroutput>
189            and <computeroutput>Else</computeroutput> defaults to
190            <computeroutput><classname>proto::not_</classname>&lt;<classname>proto::_</classname>&gt;</computeroutput>,
191            so an expression type <computeroutput>E</computeroutput> will match
192            <computeroutput>proto::if_&lt;If&gt;</computeroutput> if and only if
193            <computeroutput>boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, If&gt;(E)&gt;::type::value</computeroutput>
194            is <computeroutput>true</computeroutput>.
195          </para>
196          <para>
197            <programlisting>// A grammar that only matches integral terminals,
198// using is_integral&lt;&gt; from Boost.Type_traits.
199struct IsIntegral :
200  <classname>proto::and_</classname>&lt;
201    <classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt;,
202    <classname>proto::if_</classname>&lt; boost::is_integral&lt;<classname>proto::_value</classname>&gt;()&gt;
203  &gt;
204{};</programlisting>
205          </para>
206          <para>
207            When <computeroutput>proto::if_&lt;If, Then, Else&gt;</computeroutput> is used as a transform,
208            <computeroutput>If</computeroutput>, <computeroutput>Then</computeroutput> and
209            <computeroutput>Else</computeroutput> must be Proto transforms. When applying the transform to
210            an expression <computeroutput>E</computeroutput>, state <computeroutput>S</computeroutput> and
211            data <computeroutput>V</computeroutput>, if
212            <computeroutput>boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, If&gt;(E,S,V)&gt;::type::value</computeroutput>
213            is <computeroutput>true</computeroutput> then the <computeroutput>Then</computeroutput> transform
214            is applied; otherwise the <computeroutput>Else</computeroutput> transform is applied.
215            <programlisting>// Match a terminal. If the terminal is integral, return
216// mpl::true_; otherwise, return mpl::false_.
217struct IsIntegral2 :
218  <classname>proto::when</classname>&lt;
219    <classname>proto::terminal</classname>&lt;_&gt;,
220    proto::if_&lt;
221      boost::is_integral&lt;<classname>proto::_value</classname>&gt;(),
222      mpl::true_(),
223      mpl::false_()
224    &gt;
225  &gt;
226{};</programlisting>
227          </para>
228        </description>
229        <struct name="impl">
230          <template>
231            <template-type-parameter name="Expr"/>
232            <template-type-parameter name="State"/>
233            <template-type-parameter name="Data"/>
234          </template>
235          <inherit><type><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</type></inherit>
236          <typedef name="result_type">
237            <type>typename mpl::if_&lt;
238      typename boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, If&gt;(Expr, State, Data)&gt;::type,
239      typename boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, Then&gt;(Expr, State, Data)&gt;::type,
240      typename boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>, Else&gt;(Expr, State, Data)&gt;::type
241    &gt;::type</type>
242          </typedef>
243          <method-group name="public member functions">
244            <method name="operator()" cv="const">
245              <type>result_type</type>
246              <parameter name="expr">
247                <paramtype>typename impl::expr_param</paramtype>
248                <description>
249                  <para>An expression </para>
250                </description>
251              </parameter>
252              <parameter name="state">
253                <paramtype>typename impl::state_param</paramtype>
254                <description>
255                  <para>The current state </para>
256                </description>
257              </parameter>
258              <parameter name="data">
259                <paramtype>typename impl::data_param</paramtype>
260                <description>
261                  <para>A data of arbitrary type </para>
262                </description>
263              </parameter>
264              <returns>
265                <para>
266                  <computeroutput><classname>proto::when</classname>&lt;<classname>proto::_</classname>, <replaceable>Then-or-Else</replaceable>&gt;()(expr, state, data)</computeroutput>
267                </para>
268              </returns>
269            </method>
270          </method-group>
271        </struct>
272        <typedef name="proto_grammar">
273          <type>if_</type>
274        </typedef>
275      </struct>
276
277      <!-- proto::or_ -->
278      <struct name="or_">
279        <template>
280          <template-type-parameter name="G" pack="1"/>
281        </template>
282        <inherit><type><classname>proto::transform</classname>&lt;or_&lt;G...&gt; &gt;</type></inherit>
283        <purpose>For matching one of a set of alternate grammars. Alternates are tried in order to avoid ambiguity.
284          When used as a transform, <computeroutput>proto::or_&lt;&gt;</computeroutput> applies the transform
285          associated with the first grammar that matches the expression.</purpose>
286        <description>
287          <para>
288            An expression type <computeroutput>E</computeroutput> matches
289            <computeroutput>proto::or_&lt;G<subscript>0</subscript>,G<subscript>1</subscript>,...G<subscript>n</subscript>&gt;</computeroutput>
290            if <computeroutput>E</computeroutput> matches any <computeroutput>G<subscript>x</subscript></computeroutput> for
291            <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>.
292          </para>
293          <para>
294            When applying
295            <computeroutput>proto::or_&lt;G<subscript>0</subscript>,G<subscript>1</subscript>,...G<subscript>n</subscript>&gt;</computeroutput>
296            as a transform with an expression <computeroutput>e</computeroutput> of type <computeroutput>E</computeroutput>,
297            state <computeroutput>s</computeroutput> and data <computeroutput>d</computeroutput>, it is equivalent to
298            <computeroutput>G<subscript>x</subscript>()(e, s, d)</computeroutput>, where
299            <computeroutput>x</computeroutput> is the lowest number such that
300            <computeroutput><classname>proto::matches</classname>&lt;E, G<subscript>x</subscript>&gt;::value</computeroutput>
301            is <computeroutput>true</computeroutput>.
302          </para>
303          <para>
304            The maximun number of template arguments <computeroutput>proto::or_&lt;&gt;</computeroutput> accepts
305            is controlled by the <computeroutput><macroname>BOOST_PROTO_MAX_LOGICAL_ARITY</macroname></computeroutput>
306            macro.
307          </para>
308        </description>
309        <struct name="impl">
310          <template>
311            <template-type-parameter name="Expr"/>
312            <template-type-parameter name="State"/>
313            <template-type-parameter name="Data"/>
314          </template>
315          <inherit><type><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</type></inherit>
316          <typedef name="result_type">
317            <type><replaceable>unspecified</replaceable></type>
318          </typedef>
319          <method-group name="public member functions">
320            <method name="operator()" cv="const">
321              <type>result_type</type>
322              <parameter name="expr">
323                <paramtype>typename impl::expr_param</paramtype>
324                <description>
325                  <para>An expression </para>
326                </description>
327              </parameter>
328              <parameter name="state">
329                <paramtype>typename impl::state_param</paramtype>
330                <description>
331                  <para>The current state </para>
332                </description>
333              </parameter>
334              <parameter name="data">
335                <paramtype>typename impl::data_param</paramtype>
336                <description>
337                  <para>A data of arbitrary type </para>
338                </description>
339              </parameter>
340              <returns>
341                <para>
342                  <computeroutput>
343                    G<subscript>x</subscript>()(expr, state, data)
344                  </computeroutput>, where
345                  <computeroutput>x</computeroutput> is the lowest number such that
346                  <computeroutput>
347                    <classname>proto::matches</classname>&lt;Expr, G<subscript>x</subscript>&gt;::value
348                  </computeroutput>
349                  is <computeroutput>true</computeroutput>.
350                </para>
351              </returns>
352            </method>
353          </method-group>
354        </struct>
355        <typedef name="proto_grammar">
356          <type>or_</type>
357        </typedef>
358      </struct>
359
360      <!-- proto::and_ -->
361      <struct name="and_">
362        <template>
363          <template-type-parameter name="G" pack="1"/>
364        </template>
365        <inherit><type><classname>proto::transform</classname>&lt;and_&lt;G...&gt; &gt;</type></inherit>
366        <purpose>For matching all of a set of grammars. When used as a transform,
367          <computeroutput>proto::and_&lt;&gt;</computeroutput> applies the transform associated
368          with each grammar in the set and returns the result of the last.</purpose>
369        <description>
370          <para>
371            An expression type <computeroutput>E</computeroutput> matches
372            <computeroutput>proto::and_&lt;G<subscript>0</subscript>,G<subscript>1</subscript>,...G<subscript>n</subscript>&gt;</computeroutput>
373            if <computeroutput>E</computeroutput> matches all <computeroutput>G<subscript>x</subscript></computeroutput>
374            for <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>.
375          </para>
376          <para>
377            When applying
378            <computeroutput>proto::and_&lt;G<subscript>0</subscript>,G<subscript>1</subscript>,...G<subscript>n</subscript>&gt;</computeroutput>
379            as a transform with an expression <computeroutput>e</computeroutput>, state
380            <computeroutput>s</computeroutput> and data <computeroutput>d</computeroutput>, it is equivalent
381            to <computeroutput>(G<subscript>0</subscript>()(e, s, d),G<subscript>1</subscript>()(e, s, d),...G<subscript>n</subscript>()(e, s, d))</computeroutput>.
382          </para>
383          <para>
384            The maximun number of template arguments <computeroutput>proto::and_&lt;&gt;</computeroutput> accepts
385            is controlled by the <computeroutput><macroname>BOOST_PROTO_MAX_LOGICAL_ARITY</macroname></computeroutput>
386            macro.
387          </para>
388        </description>
389        <struct name="impl">
390          <template>
391            <template-type-parameter name="Expr"/>
392            <template-type-parameter name="State"/>
393            <template-type-parameter name="Data"/>
394          </template>
395          <inherit><type><classname>proto::transform_impl</classname>&lt; Expr, State, Data &gt;</type></inherit>
396          <typedef name="result_type">
397            <type>typename boost::result_of&lt;G<subscript>n</subscript>(Expr, State, Data)&gt;::type</type>
398          </typedef>
399          <method-group name="public member functions">
400            <method name="operator()" cv="const">
401              <type>result_type</type>
402              <parameter name="expr">
403                <paramtype>typename impl::expr_param</paramtype>
404                <description>
405                  <para>An expression </para>
406                </description>
407              </parameter>
408              <parameter name="state">
409                <paramtype>typename impl::state_param</paramtype>
410                <description>
411                  <para>The current state </para>
412                </description>
413              </parameter>
414              <parameter name="data">
415                <paramtype>typename impl::data_param</paramtype>
416                <description>
417                  <para>A data of arbitrary type </para>
418                </description>
419              </parameter>
420              <returns>
421                <para>
422                  <computeroutput>(G<subscript>0</subscript>()(expr, state, data),G<subscript>1</subscript>()(expr, state, data),...G<subscript>n</subscript>()(expr, state, data))</computeroutput>
423                </para>
424              </returns>
425            </method>
426          </method-group>
427        </struct>
428        <typedef name="proto_grammar">
429          <type>and_</type>
430        </typedef>
431      </struct>
432
433      <!-- proto::switch_ -->
434      <struct name="switch_">
435        <template>
436          <template-type-parameter name="Cases"/>
437          <template-type-parameter name="Transform"/>
438        </template>
439        <inherit><classname>proto::transform</classname>&lt;switch_&lt;Cases, Transform&gt; &gt;</inherit>
440        <purpose>For matching one of a set of alternate grammars, which are looked up based on
441          the result type of the transform passed in second template parameter.
442          If no transform is passed, the default one is <computeroutput><classname>proto::tag_of</classname>&lt;<classname>proto::_</classname>&gt;()</computeroutput>
443          so the default matching is based on the expression's tag type. When used as a transform,
444          <computeroutput>proto::switch_&lt;&gt;</computeroutput> applies the transform associated
445          with the sub-grammar that matches the expression.</purpose>
446        <description>
447        <para>
448          An expression type <computeroutput>E</computeroutput> matches
449            <computeroutput>proto::switch_&lt;C,T&gt;</computeroutput> if
450          <computeroutput>E</computeroutput> matches
451            <computeroutput>C::case_&lt;boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>,T&gt;(E)&gt;::type&gt;</computeroutput>.
452          </para>
453        <para>
454          When applying <computeroutput>proto::switch_&lt;C,T&gt;</computeroutput> as a
455            transform with an expression <computeroutput>e</computeroutput> of type
456            <computeroutput>E</computeroutput>, state <computeroutput>s</computeroutput> of
457            type <computeroutput>S</computeroutput> and data <computeroutput>d</computeroutput>
458            of type <computeroutput>D</computeroutput>, it is equivalent to
459            <computeroutput>C::case_&lt;boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>,T&gt;(E,S,D)&gt;::type&gt;()(e, s, d)</computeroutput>.
460          </para>
461        </description>
462        <struct name="impl">
463          <template>
464            <template-type-parameter name="Expr"/>
465            <template-type-parameter name="State"/>
466            <template-type-parameter name="Data"/>
467          </template>
468          <inherit><type>
469    Cases::template case_&lt;
470      typename <classname>when</classname>&lt;_, Transform&gt;::template impl&lt;Expr, State, Data&gt;::result_type
471    &gt;::template impl&lt;Expr, State, Data&gt;</type>
472          </inherit>
473        </struct>
474        <typedef name="proto_grammar">
475          <type>switch_</type>
476        </typedef>
477      </struct>
478
479      <!-- proto::exact -->
480      <struct name="exact">
481        <template>
482          <template-type-parameter name="T"/>
483        </template>
484        <purpose>For forcing exact matches of terminal types.</purpose>
485        <description>
486          <para>By default, matching terminals ignores references and cv-qualifiers. For instance,
487            a terminal expression of type
488            <computeroutput><classname>proto::terminal</classname>&lt;int const &amp;&gt;::type</computeroutput>
489            will match the grammar <computeroutput><classname>proto::terminal</classname>&lt;int&gt;</computeroutput>.
490            If that is not desired, you can force an exact match with
491            <computeroutput><classname>proto::terminal</classname>&lt;proto::exact&lt;int&gt; &gt;</computeroutput>.
492            This will only match integer terminals where the terminal is held by value.</para>
493        </description>
494      </struct>
495
496      <!-- proto::convertible_to -->
497      <struct name="convertible_to">
498        <template>
499          <template-type-parameter name="T"/>
500        </template>
501        <purpose>For matching terminals that are convertible to a type.</purpose>
502        <description>
503          <para>
504            Use <computeroutput>proto::convertible_to&lt;&gt;</computeroutput> to match a terminal that is
505            convertible to some type. For example, the grammar
506            <computeroutput><classname>proto::terminal</classname>&lt;proto::convertible_to&lt;int&gt; &gt;</computeroutput>
507            will match any terminal whose argument is convertible to an integer.
508          </para>
509        </description>
510      </struct>
511
512      <!-- proto::vararg -->
513      <struct name="vararg">
514        <template>
515          <template-type-parameter name="Grammar"/>
516        </template>
517        <purpose>For matching a Grammar to a variable number of sub-expressions.</purpose>
518        <description>
519          <para>
520            An expression type <computeroutput><classname>proto::basic_expr</classname>&lt;AT,
521            <classname alt="proto::listN">proto::list<replaceable>N</replaceable></classname>&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>,U<subscript>0</subscript>,...U<subscript>m</subscript>&gt; &gt;</computeroutput>
522            matches a grammar <computeroutput><classname>proto::basic_expr</classname>&lt;BT,
523            <classname alt="proto::listN">proto::list<replaceable>M</replaceable></classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>,proto::vararg&lt;V&gt; &gt; &gt;</computeroutput>
524            if <computeroutput>BT</computeroutput> is <computeroutput><classname>proto::_</classname></computeroutput>
525            or <computeroutput>AT</computeroutput>, and if
526            <computeroutput>A<subscript>x</subscript></computeroutput> matches
527            <computeroutput>B<subscript>x</subscript></computeroutput>
528            for each <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>
529            and if <computeroutput>U<subscript>x</subscript></computeroutput> matches
530            <computeroutput>V</computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,m]</computeroutput>.
531          </para>
532          <para>For example:</para>
533          <para>
534            <programlisting>// Match any function call expression, regardless
535// of the number of function arguments:
536struct Function :
537  <classname>proto::function</classname>&lt; proto::vararg&lt;proto::_&gt; &gt;
538{};</programlisting>
539          </para>
540          <para>
541            When used as a transform, <computeroutput>proto::vararg&lt;G&gt;</computeroutput>
542            applies <computeroutput>G</computeroutput>'s transform.
543          </para>
544        </description>
545      </struct>
546
547      <!-- proto::matches -->
548      <struct name="matches">
549        <template>
550          <template-type-parameter name="Expr"/>
551          <template-type-parameter name="Grammar"/>
552        </template>
553        <purpose>A Boolean metafunction that evaluates whether a given expression type matches a grammar.</purpose>
554        <description>
555          <para>
556            <computeroutput>proto::matches&lt;Expr, Grammar&gt;</computeroutput> inherits from
557            <computeroutput>mpl::true_</computeroutput> if
558            <computeroutput>Expr::proto_grammar</computeroutput> matches
559            <computeroutput>Grammar::proto_grammar</computeroutput>, and from
560            <computeroutput>mpl::false_</computeroutput> otherwise.
561          </para>
562          <para>
563            Non-terminal expressions are matched against a grammar according to the following rules:
564            <itemizedlist>
565              <listitem>
566                <para>
567                  The wildcard pattern, <computeroutput>
568                    <classname>proto::_</classname>
569                  </computeroutput>, matches any expression.
570                </para>
571              </listitem>
572              <listitem>
573                <para>
574                  An expression
575                  <computeroutput>
576                    <classname>proto::basic_expr</classname>&lt;AT,
577                    <classname alt="proto::listN">
578                      proto::list<replaceable>N</replaceable>
579                    </classname>&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>&gt;
580                    &gt;
581                  </computeroutput>
582                  matches a grammar
583                  <computeroutput>
584                    <classname>proto::basic_expr</classname>&lt;BT,
585                    <classname alt="proto::listN">
586                      proto::list<replaceable>N</replaceable>
587                    </classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>&gt;
588                    &gt;
589                  </computeroutput> if
590                  <computeroutput>BT</computeroutput> is <computeroutput>
591                    <classname>proto::_</classname>
592                  </computeroutput> or
593                  <computeroutput>AT</computeroutput>, and if <computeroutput>
594                    A<subscript>x</subscript>
595                  </computeroutput> matches
596                  <computeroutput>
597                    B<subscript>x</subscript>
598                  </computeroutput> for each <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>.
599                </para>
600              </listitem>
601              <listitem>
602                <para>
603                  An expression
604                  <computeroutput>
605                    <classname>proto::basic_expr</classname>&lt;AT,
606                    <classname alt="proto::listN">
607                      proto::list<replaceable>N</replaceable>
608                    </classname>&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>,U<subscript>0</subscript>,...U<subscript>m</subscript>&gt;
609                    &gt;
610                  </computeroutput> matches a grammar
611                  <computeroutput>
612                    <classname>proto::basic_expr</classname>&lt;BT,
613                    <classname alt="proto::listN">
614                      proto::list<replaceable>M</replaceable>
615                    </classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>,<classname>proto::vararg</classname>&lt;V&gt;
616                    &gt; &gt;
617                  </computeroutput> if
618                  <computeroutput>BT</computeroutput> is <computeroutput>
619                    <classname>proto::_</classname>
620                  </computeroutput> or
621                  <computeroutput>AT</computeroutput>, and if
622                  <computeroutput>
623                    A<subscript>x</subscript>
624                  </computeroutput> matches
625                  <computeroutput>
626                    B<subscript>x</subscript>
627                  </computeroutput> for each
628                  <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput> and if
629                  <computeroutput>
630                    U<subscript>x</subscript>
631                  </computeroutput> matches
632                  <computeroutput>V</computeroutput> for each <computeroutput>x</computeroutput> in
633                  <computeroutput>[0,m]</computeroutput>.
634                </para>
635              </listitem>
636              <listitem>
637                <para>
638                  An expression <computeroutput>E</computeroutput> matches
639                  <computeroutput>
640                    <classname>proto::or_</classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>&gt;
641                  </computeroutput> if
642                  <computeroutput>E</computeroutput> matches some
643                  <computeroutput>
644                    B<subscript>x</subscript>
645                  </computeroutput> for
646                  <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>.
647                </para>
648              </listitem>
649              <listitem>
650                <para>
651                  An expression <computeroutput>E</computeroutput> matches
652                  <computeroutput>
653                    <classname>proto::and_</classname>&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>&gt;
654                  </computeroutput> if
655                  <computeroutput>E</computeroutput> matches all
656                  <computeroutput>
657                    B<subscript>x</subscript>
658                  </computeroutput> for
659                  <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>.
660                </para>
661              </listitem>
662              <listitem>
663                <para>
664                  An expression <computeroutput>E</computeroutput> matches
665                  <computeroutput>
666                    <classname>proto::if_</classname>&lt;T,U,V&gt;
667                  </computeroutput> if:
668                  <itemizedlist>
669                    <listitem>
670                      <computeroutput>
671                        boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>,T&gt;(E)&gt;::type::value
672                      </computeroutput>
673                      is <computeroutput>true</computeroutput> and
674                      <computeroutput>E</computeroutput> matches
675                      <computeroutput>U</computeroutput>, <emphasis>or</emphasis>
676                    </listitem>
677                    <listitem>
678                      <computeroutput>
679                        boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>,T&gt;(E)&gt;::type::value
680                      </computeroutput>
681                      is <computeroutput>false</computeroutput> and <computeroutput>E</computeroutput> matches
682                      <computeroutput>V</computeroutput>.
683                    </listitem>
684                  </itemizedlist>
685                  Note: <computeroutput>U</computeroutput> defaults to <computeroutput>
686                    <classname>proto::_</classname>
687                  </computeroutput>
688                  and <computeroutput>V</computeroutput> defaults to
689                  <computeroutput>
690                    <classname>proto::not_</classname>&lt;<classname>proto::_</classname>&gt;
691                  </computeroutput>.
692                </para>
693              </listitem>
694              <listitem>
695                <para>
696                  An expression <computeroutput>E</computeroutput> matches
697                  <computeroutput>
698                    <classname>proto::not_</classname>&lt;T&gt;
699                  </computeroutput> if
700                  <computeroutput>E</computeroutput> does <emphasis>not</emphasis> match <computeroutput>T</computeroutput>.
701                </para>
702              </listitem>
703              <listitem>
704                <para>
705                  An expression <computeroutput>E</computeroutput> matches
706                  <computeroutput>
707                    <classname>proto::switch_</classname>&lt;C, T&gt;
708                  </computeroutput> if
709                  <computeroutput>E</computeroutput> matches <computeroutput>C::case_&lt;boost::result_of&lt;<classname>proto::when</classname>&lt;<classname>proto::_</classname>,T&gt;(E)&gt;::type&gt;</computeroutput>.
710                  Note: <computeroutput>T</computeroutput> defaults to <computeroutput><classname>proto::tag_of</classname>&lt;<classname>proto::_</classname>&gt;()</computeroutput>
711                </para>
712              </listitem>
713            </itemizedlist>
714          </para>
715          <para>
716            A terminal expression can trivially match the grammar <classname>proto::_</classname>. In addition,
717            a terminal expression
718            <computeroutput>
719              <classname>proto::basic_expr</classname>&lt;AT,
720              <classname>proto::term</classname>&lt;A&gt; &gt;
721            </computeroutput> matches a grammar
722            <computeroutput>
723              <classname>proto::basic_expr</classname>&lt;BT, <classname>proto::term</classname>&lt;B&gt; &gt;
724            </computeroutput>
725            if <computeroutput>BT</computeroutput> is <computeroutput><classname>proto::_</classname></computeroutput>
726            or <computeroutput>AT</computeroutput> and one of the following is true:
727            <itemizedlist>
728              <listitem>
729                <para>
730                  <computeroutput>B</computeroutput> is the wildcard pattern,
731                  <computeroutput>
732                    <classname>proto::_</classname>
733                  </computeroutput>
734                </para>
735              </listitem>
736              <listitem>
737                <para>
738                  <computeroutput>A</computeroutput> is <computeroutput>B</computeroutput>
739                </para>
740              </listitem>
741              <listitem>
742                <para>
743                  <computeroutput>A</computeroutput> is <computeroutput>B &amp;</computeroutput>
744                </para>
745              </listitem>
746              <listitem>
747                <para>
748                  <computeroutput>A</computeroutput> is <computeroutput>B const &amp;</computeroutput>
749                </para>
750              </listitem>
751              <listitem>
752                <para>
753                  <computeroutput>B</computeroutput> is <computeroutput>
754                    <classname>proto::exact</classname>&lt;A&gt;
755                  </computeroutput>
756                </para>
757              </listitem>
758              <listitem>
759                <para>
760                  <computeroutput>B</computeroutput> is
761                  <computeroutput>
762                    <classname>proto::convertible_to</classname>&lt;X&gt;
763                  </computeroutput>
764                  and <computeroutput>boost::is_convertible&lt;A,X&gt;::value</computeroutput> is
765                  <computeroutput>true</computeroutput>.
766                </para>
767              </listitem>
768              <listitem>
769                <para>
770                  <computeroutput>A</computeroutput> is <computeroutput>X[M]</computeroutput> or
771                  <computeroutput>X(&amp;)[M]</computeroutput> and
772                  <computeroutput>B</computeroutput> is <computeroutput>
773                    X[<globalname>proto::N</globalname>]
774                  </computeroutput>.
775                </para>
776              </listitem>
777              <listitem>
778                <para>
779                  <computeroutput>A</computeroutput> is <computeroutput>X(&amp;)[M]</computeroutput>
780                  and <computeroutput>B</computeroutput> is <computeroutput>
781                    X(&amp;)[<globalname>proto::N</globalname>]
782                  </computeroutput>.
783                </para>
784              </listitem>
785              <listitem>
786                <para>
787                  <computeroutput>A</computeroutput> is <computeroutput>X[M]</computeroutput> or
788                  <computeroutput>X(&amp;)[M]</computeroutput> and <computeroutput>B</computeroutput> is
789                  <computeroutput>X*</computeroutput>.
790                </para>
791              </listitem>
792              <listitem>
793                <para>
794                  <computeroutput>B</computeroutput> <replaceable>lambda-matches</replaceable>
795                  <computeroutput>A</computeroutput> (see below).
796                </para>
797              </listitem>
798            </itemizedlist>
799          </para>
800          <para>
801            A type <computeroutput>B</computeroutput> <replaceable>lambda-matches</replaceable>
802            <computeroutput>A</computeroutput> if one of the following is true:
803            <itemizedlist>
804              <listitem>
805                <para>
806                  <computeroutput>B</computeroutput> is <computeroutput>A</computeroutput>
807                </para>
808              </listitem>
809              <listitem>
810                <para>
811                  <computeroutput>B</computeroutput> is the wildcard pattern, <computeroutput>
812                    <classname>proto::_</classname>
813                  </computeroutput>
814                </para>
815              </listitem>
816              <listitem>
817                <para>
818                  <computeroutput>B</computeroutput> is <computeroutput>
819                    T&lt;B<subscript>0</subscript>,...B<subscript>n</subscript>&gt;
820                  </computeroutput> and <computeroutput>A</computeroutput> is <computeroutput>
821                    T&lt;A<subscript>0</subscript>,...A<subscript>n</subscript>&gt;
822                  </computeroutput> and for each <computeroutput>x</computeroutput> in <computeroutput>[0,n]</computeroutput>,
823                  <computeroutput>A<subscript>x</subscript></computeroutput> and
824                  <computeroutput>B<subscript>x</subscript></computeroutput> are types such that
825                  <computeroutput>A<subscript>x</subscript></computeroutput> <replaceable>lambda-matches</replaceable>
826                  <computeroutput>B<subscript>x</subscript></computeroutput>
827                </para>
828              </listitem>
829            </itemizedlist>
830          </para>
831        </description>
832        <inherit>
833          <type>mpl::bool_&lt;<replaceable>true-or-false</replaceable>&gt;</type></inherit>
834      </struct>
835    </namespace>
836  </namespace>
837</header>
838