]>
Commit | Line | Data |
---|---|---|
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/transform/when.hpp"> | |
10 | <para> | |
11 | Definition of the | |
12 | <computeroutput> | |
13 | <classname alt="boost::proto::when">proto::when<></classname> | |
14 | </computeroutput> and | |
15 | <computeroutput> | |
16 | <classname alt="boost::proto::otherwise">proto::otherwise<></classname> | |
17 | </computeroutput> transforms. | |
18 | </para> | |
19 | <namespace name="boost"> | |
20 | <namespace name="proto"> | |
21 | ||
22 | <!-- struct transforms_type --> | |
23 | <struct name="transforms_type"> | |
24 | <purpose> | |
25 | The type used to define the global <code><globalname>proto::transforms</globalname></code>, | |
26 | a key for use when creating and accessing a slot in a transform environment for | |
27 | a set of external transforms. | |
28 | </purpose> | |
29 | <description> | |
30 | <para> | |
31 | The <code>proto::transforms_type</code> type, along with the <code><globalname>proto::transforms</globalname></code> | |
32 | global, are declared using the <code><macroname>BOOST_PROTO_DEFINE_ENV_VAR</macroname>()</code> macro. | |
33 | </para> | |
34 | </description> | |
35 | <method-group name="public member functions"> | |
36 | <overloaded-method name="operator="> | |
37 | <signature cv="const"> | |
38 | <template> | |
39 | <template-type-parameter name="Value"/> | |
40 | </template> | |
41 | <type><classname>env</classname><transforms_type, <replaceable>see-below</replaceable>></type> | |
42 | <parameter name="value"> | |
43 | <paramtype>Value &</paramtype> | |
44 | </parameter> | |
45 | </signature> | |
46 | <signature cv="const"> | |
47 | <template> | |
48 | <template-type-parameter name="Value"/> | |
49 | </template> | |
50 | <type><classname>env</classname><transforms_type, <replaceable>see-below</replaceable>></type> | |
51 | <parameter name="value"> | |
52 | <paramtype>Value const &</paramtype> | |
53 | </parameter> | |
54 | </signature> | |
55 | <description> | |
56 | <para> | |
57 | If <code>Value</code> is a specialization <code>boost::reference_wrapper<T></code>, | |
58 | this function returns <code><classname>env</classname><transforms_type, T &>(value.get())</code>. | |
59 | </para> | |
60 | <para> | |
61 | Else, if the type <code>Value</code> is non-copyable (i.e., a function, an array, abstract, or an ostream), | |
62 | this function returns <code><classname>env</classname><transforms_type, Value <replaceable>cv</replaceable> &>(value)</code>, | |
63 | where <code><replaceable>cv</replaceable></code> is <code>const</code> for the second overload, and empty | |
64 | for the first. | |
65 | </para> | |
66 | <para> | |
67 | Otherwise, this function returns <code><classname>env</classname><transforms_type, Value>(value)</code>. | |
68 | </para> | |
69 | </description> | |
70 | </overloaded-method> | |
71 | </method-group> | |
72 | </struct> | |
73 | ||
74 | <data-member name="transforms"> | |
75 | <description> | |
76 | <para> | |
77 | A key key for use when creating and accessing a slot in a transform environment for | |
78 | a set of external transforms. | |
79 | </para> | |
80 | </description> | |
81 | <type><classname>proto::transforms_type</classname> const</type> | |
82 | </data-member> | |
83 | ||
84 | <struct name="when"> | |
85 | <template> | |
86 | <template-type-parameter name="Grammar"/> | |
87 | <template-type-parameter name="PrimitiveTransform"> | |
88 | <default>Grammar</default> | |
89 | </template-type-parameter> | |
90 | </template> | |
91 | <purpose>A grammar element and a <conceptname>PrimitiveTransform</conceptname> that associates | |
92 | a transform with the grammar.</purpose> | |
93 | <description> | |
94 | <para> | |
95 | Use <computeroutput>proto::when<></computeroutput> to override a grammar's default | |
96 | transform with a custom transform. It is for used when composing larger transforms by | |
97 | associating smaller transforms with individual rules in your grammar, as in the following | |
98 | transform which counts the number of terminals in an expression. | |
99 | <programlisting>// Count the terminals in an expression tree. | |
100 | // Must be invoked with initial state == mpl::int_<0>(). | |
101 | struct CountLeaves : | |
102 | <classname>proto::or_</classname>< | |
103 | proto::when<<classname>proto::terminal</classname><<classname>proto::_</classname>>, mpl::next<<classname>proto::_state</classname>>()>, | |
104 | proto::otherwise<<classname>proto::fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves> > | |
105 | > | |
106 | {};</programlisting> | |
107 | </para> | |
108 | <para> | |
109 | In <computeroutput>proto::when<G, T></computeroutput>, when <computeroutput>T</computeroutput> | |
110 | is a class type it is a <conceptname>PrimitiveTransform</conceptname> and the following equivalencies hold: | |
111 | </para> | |
112 | <itemizedlist> | |
113 | <listitem> | |
114 | <para> | |
115 | <computeroutput>boost::result_of<proto::when<G,T>(E,S,V)>::type</computeroutput> is the same as | |
116 | <computeroutput>boost::result_of<T(E,S,V)>::type</computeroutput>. | |
117 | </para> | |
118 | </listitem> | |
119 | <listitem> | |
120 | <para> | |
121 | <computeroutput>proto::when<G,T>()(e,s,d)</computeroutput> is the same as | |
122 | <computeroutput>T()(e,s,d)</computeroutput>. | |
123 | </para> | |
124 | </listitem> | |
125 | </itemizedlist> | |
126 | </description> | |
127 | <inherit><type>PrimitiveTransform</type></inherit> | |
128 | <typedef name="proto_grammar"> | |
129 | <type>typename Grammar::proto_grammar</type> | |
130 | </typedef> | |
131 | </struct> | |
132 | ||
133 | <struct-specialization name="when"> | |
134 | <template> | |
135 | <template-type-parameter name="Grammar"/> | |
136 | <template-type-parameter name="Fun"/> | |
137 | </template> | |
138 | <specialization> | |
139 | <template-arg>Grammar</template-arg> | |
140 | <template-arg>Fun *</template-arg> | |
141 | </specialization> | |
142 | <inherit><type><classname>proto::when</classname>< Grammar, Fun ></type></inherit> | |
143 | <purpose>A specialization that treats function pointer <conceptname>Transform</conceptname>s as if they | |
144 | were function type <conceptname>Transform</conceptname>s.</purpose> | |
145 | <description> | |
146 | <para> | |
147 | This specialization requires that <computeroutput>Fun</computeroutput> is actually a function type. | |
148 | </para> | |
149 | <para> | |
150 | This specialization is required for nested transforms such as | |
151 | <computeroutput>proto::when<G, T0(T1(_))></computeroutput>. In C++, functions that are used | |
152 | as parameters to other functions automatically decay to funtion pointer types. In other words, the | |
153 | type <computeroutput>T0(T1(_))</computeroutput> is indistinguishable from | |
154 | <computeroutput>T0(T1(*)(_))</computeroutput>. This specialization is required to handle these | |
155 | nested function pointer type transforms properly. | |
156 | </para> | |
157 | </description> | |
158 | </struct-specialization> | |
159 | ||
160 | <struct-specialization name="when"> | |
161 | <template> | |
162 | <template-type-parameter name="Grammar"/> | |
163 | <template-type-parameter name="R"/> | |
164 | <template-type-parameter name="A" pack="1"/> | |
165 | </template> | |
166 | <specialization> | |
167 | <template-arg>Grammar</template-arg> | |
168 | <template-arg>R(A...)</template-arg> | |
169 | </specialization> | |
170 | <inherit><type><classname>proto::transform</classname>< when<Grammar, R(A...)> ></type></inherit> | |
171 | <purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a | |
172 | transform with the grammar. </purpose> | |
173 | <description> | |
174 | <para> | |
175 | Use <computeroutput>proto::when<></computeroutput> to override a grammar's default | |
176 | transform with a custom transform. It is for use when composing larger transforms by associating | |
177 | smaller transforms with individual rules in your grammar. | |
178 | </para> | |
179 | <para> | |
180 | The <computeroutput>when<G, R(A...)></computeroutput> form accepts either a | |
181 | <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its | |
182 | second parameter. <computeroutput>proto::when<></computeroutput> uses | |
183 | <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> to | |
184 | distinguish between the two, and uses | |
185 | <computeroutput><classname>proto::call<></classname></computeroutput> to evaluate | |
186 | <conceptname>CallableTransform</conceptname>s and | |
187 | <computeroutput><classname>proto::make<></classname></computeroutput> to evaluate | |
188 | <conceptname>ObjectTransform</conceptname>s. | |
189 | </para> | |
190 | </description> | |
191 | <struct name="impl"> | |
192 | <template> | |
193 | <template-type-parameter name="Expr"/> | |
194 | <template-type-parameter name="State"/> | |
195 | <template-type-parameter name="Data"/> | |
196 | </template> | |
197 | <inherit><type><classname>proto::transform_impl</classname>< Expr, State, Data ></type></inherit> | |
198 | <typedef name="call_"> | |
199 | <purpose>For exposition only</purpose> | |
200 | <type><classname>proto::call</classname><R(A...)></type> | |
201 | </typedef> | |
202 | <typedef name="make_"> | |
203 | <purpose>For exposition only</purpose> | |
204 | <type><classname>proto::make</classname><R(A...)></type> | |
205 | </typedef> | |
206 | <typedef name="which"> | |
207 | <purpose>For exposition only</purpose> | |
208 | <type>typename mpl::if_<<classname>proto::is_callable</classname><R>,call_,make_>::type</type> | |
209 | </typedef> | |
210 | <typedef name="result_type"> | |
211 | <type>typename boost::result_of<which(Expr, State, Data)>::type</type> | |
212 | </typedef> | |
213 | <method-group name="public member functions"> | |
214 | <method name="operator()" cv="const"> | |
215 | <type>result_type</type> | |
216 | <parameter name="expr"> | |
217 | <paramtype>typename impl::expr_param</paramtype> | |
218 | <description> | |
219 | <para>The current expression </para> | |
220 | </description> | |
221 | </parameter> | |
222 | <parameter name="state"> | |
223 | <paramtype>typename impl::state_param</paramtype> | |
224 | <description> | |
225 | <para>The current state </para> | |
226 | </description> | |
227 | </parameter> | |
228 | <parameter name="data"> | |
229 | <paramtype>typename impl::data_param</paramtype> | |
230 | <description> | |
231 | <para>An arbitrary data </para> | |
232 | </description> | |
233 | </parameter> | |
234 | <description> | |
235 | <para> | |
236 | Evaluate <computeroutput>R(A...)</computeroutput> as a transform either with | |
237 | <computeroutput><classname>proto::call<></classname></computeroutput> or with | |
238 | <computeroutput><classname>proto::make<></classname></computeroutput> depending | |
239 | on whether <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> | |
240 | is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>. | |
241 | </para> | |
242 | </description> | |
243 | <requires> | |
244 | <para> | |
245 | <computeroutput><classname>proto::matches</classname><Expr, Grammar>::value</computeroutput> | |
246 | is <computeroutput>true</computeroutput>. | |
247 | </para> | |
248 | </requires> | |
249 | <returns> | |
250 | <para> | |
251 | <computeroutput>which()(expr, state, data)</computeroutput> | |
252 | </para> | |
253 | </returns> | |
254 | </method> | |
255 | </method-group> | |
256 | </struct> | |
257 | <typedef name="proto_grammar"> | |
258 | <type>typename Grammar::proto_grammar</type> | |
259 | </typedef> | |
260 | </struct-specialization> | |
261 | ||
262 | <struct-specialization name="when"> | |
263 | <template> | |
264 | <template-type-parameter name="Grammar"/> | |
265 | <template-type-parameter name="R"/> | |
266 | <template-type-parameter name="A" pack="1"/> | |
267 | </template> | |
268 | <specialization> | |
269 | <template-arg>Grammar</template-arg> | |
270 | <template-arg>R(A..., ...)</template-arg> | |
271 | </specialization> | |
272 | <inherit><type><classname>proto::transform</classname>< when<Grammar, R(A..., ...)> ></type></inherit> | |
273 | <purpose>A grammar element and a <conceptname>Transform</conceptname> that associates a | |
274 | transform with the grammar. </purpose> | |
275 | <description> | |
276 | <para> | |
277 | Use <computeroutput>proto::when<></computeroutput> to override a grammar's default | |
278 | transform with a custom transform. It is for use when composing larger transforms by associating | |
279 | smaller transforms with individual rules in your grammar. | |
280 | </para> | |
281 | <para> | |
282 | The <computeroutput>when<G, R(A..., ...)></computeroutput> form accepts either a | |
283 | <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its | |
284 | second parameter. <computeroutput>proto::when<></computeroutput> uses | |
285 | <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> to | |
286 | distinguish between the two, and uses | |
287 | <computeroutput><classname>proto::call<></classname></computeroutput> to evaluate | |
288 | <conceptname>CallableTransform</conceptname>s and | |
289 | <computeroutput><classname>proto::make<></classname></computeroutput> to evaluate | |
290 | <conceptname>ObjectTransform</conceptname>s. | |
291 | </para> | |
292 | <para> | |
293 | <emphasis role="bold">Note:</emphasis> In the specialization | |
294 | <computeroutput>when<G, R(A..., ...)></computeroutput>, the first ellipsis denotes a | |
295 | C++11-style variadic template (which is emulated for C++98 compilers). The second ellipsis | |
296 | is a C-style vararg. | |
297 | </para> | |
298 | </description> | |
299 | <struct name="impl"> | |
300 | <template> | |
301 | <template-type-parameter name="Expr"/> | |
302 | <template-type-parameter name="State"/> | |
303 | <template-type-parameter name="Data"/> | |
304 | </template> | |
305 | <inherit><type><classname>proto::transform_impl</classname>< Expr, State, Data ></type></inherit> | |
306 | <typedef name="call_"> | |
307 | <purpose>For exposition only</purpose> | |
308 | <type><classname>proto::call</classname><R(A..., ...)></type> | |
309 | </typedef> | |
310 | <typedef name="make_"> | |
311 | <purpose>For exposition only</purpose> | |
312 | <type><classname>proto::make</classname><R(A..., ...)></type> | |
313 | </typedef> | |
314 | <typedef name="which"> | |
315 | <purpose>For exposition only</purpose> | |
316 | <type>typename mpl::if_<<classname>proto::is_callable</classname><R>,call_,make_>::type</type> | |
317 | </typedef> | |
318 | <typedef name="result_type"> | |
319 | <type>typename boost::result_of<which(Expr, State, Data)>::type</type> | |
320 | </typedef> | |
321 | <method-group name="public member functions"> | |
322 | <method name="operator()" cv="const"> | |
323 | <type>result_type</type> | |
324 | <parameter name="expr"> | |
325 | <paramtype>typename impl::expr_param</paramtype> | |
326 | <description> | |
327 | <para>The current expression </para> | |
328 | </description> | |
329 | </parameter> | |
330 | <parameter name="state"> | |
331 | <paramtype>typename impl::state_param</paramtype> | |
332 | <description> | |
333 | <para>The current state </para> | |
334 | </description> | |
335 | </parameter> | |
336 | <parameter name="data"> | |
337 | <paramtype>typename impl::data_param</paramtype> | |
338 | <description> | |
339 | <para>An arbitrary data </para> | |
340 | </description> | |
341 | </parameter> | |
342 | <description> | |
343 | <para> | |
344 | Evaluate <computeroutput>R(A..., ...)</computeroutput> as a transform either with | |
345 | <computeroutput><classname>proto::call<></classname></computeroutput> or with | |
346 | <computeroutput><classname>proto::make<></classname></computeroutput> depending | |
347 | on whether <computeroutput><classname>proto::is_callable</classname><R>::value</computeroutput> | |
348 | is <computeroutput>true</computeroutput> or <computeroutput>false</computeroutput>. | |
349 | </para> | |
350 | </description> | |
351 | <requires> | |
352 | <para> | |
353 | <computeroutput><classname>proto::matches</classname><Expr, Grammar>::value</computeroutput> | |
354 | is <computeroutput>true</computeroutput>. | |
355 | </para> | |
356 | </requires> | |
357 | <returns> | |
358 | <para> | |
359 | <computeroutput>which()(expr, state, data)</computeroutput> | |
360 | </para> | |
361 | </returns> | |
362 | </method> | |
363 | </method-group> | |
364 | </struct> | |
365 | <typedef name="proto_grammar"> | |
366 | <type>typename Grammar::proto_grammar</type> | |
367 | </typedef> | |
368 | </struct-specialization> | |
369 | ||
370 | <struct-specialization name="when"> | |
371 | <template> | |
372 | <template-type-parameter name="Grammar"/> | |
373 | </template> | |
374 | <specialization> | |
375 | <template-arg>Grammar</template-arg> | |
376 | <template-arg><classname>proto::external_transform</classname></template-arg> | |
377 | </specialization> | |
378 | <inherit><type> | |
379 | <classname>proto::transform</classname>< when<Grammar, <classname>proto::external_transform</classname>> ></type></inherit> | |
380 | <purpose>A grammar element that associates an externally-specified transform with the grammar. | |
381 | The transform is looked up in the Data parameter using the Grammar as a key.</purpose> | |
382 | <description> | |
383 | <para> | |
384 | Use <computeroutput>proto::when<></computeroutput> to override a grammar's default | |
385 | transform with a custom transform. It is for use when composing larger transforms by associating | |
386 | smaller transforms with individual rules in your grammar. | |
387 | </para> | |
388 | <para> | |
389 | The <computeroutput>when<G, <classname>proto::external_transform</classname>></computeroutput> | |
390 | indicates that the associated transform is not yet known. It should be looked up when the transform | |
391 | is about to be applied. It is found by looking it up in the passed-in Data parameter, which | |
392 | behaves like a compile-time map from grammar types to transform types. The map is indexed using | |
393 | <computeroutput>Grammar</computeroutput> as a key. The associated value type is used as the transform | |
394 | to apply. In this way, the same grammar can be used to define multiple evaluating strategies that | |
395 | can be added post-hoc. | |
396 | </para> | |
397 | <para> | |
398 | See <computeroutput><classname>proto::external_transforms</classname></computeroutput> for an example. | |
399 | </para> | |
400 | </description> | |
401 | <struct name="impl"> | |
402 | <template> | |
403 | <template-type-parameter name="Expr"/> | |
404 | <template-type-parameter name="State"/> | |
405 | <template-type-parameter name="Data"/> | |
406 | </template> | |
407 | <inherit><type> | |
408 | boost::remove_reference< | |
409 | typename mpl::eval_if_c< | |
410 | <classname>proto::result_of::has_env_var</classname><Data, <classname>proto::transforms_type</classname>>::value, | |
411 | <classname>proto::result_of::env_var</classname><Data, <classname>proto::transforms_type</classname>>, | |
412 | <classname>proto::result_of::env_var</classname><Data, <classname>proto::data_type</classname>> | |
413 | >::type | |
414 | >::type | |
415 | ::template when< Grammar > | |
416 | ::template impl< Expr, State, Data ></type></inherit> | |
417 | <description> | |
418 | <para> | |
419 | The implementation of the <code>impl</code> struct depends on whether the <code>Data</code> | |
420 | parameter is a transform environment that contains a value corresponding to the | |
421 | <classname>proto::transforms_type</classname> key. If so, that value is treated as a | |
422 | map from rules to transforms. Otherwise, the <code>Data</code> type itself is treated | |
423 | as such a map. | |
424 | </para> | |
425 | </description> | |
426 | </struct> | |
427 | <typedef name="proto_grammar"> | |
428 | <type>typename Grammar::proto_grammar</type> | |
429 | </typedef> | |
430 | </struct-specialization> | |
431 | ||
432 | <struct name="otherwise"> | |
433 | <template> | |
434 | <template-type-parameter name="Fun"/> | |
435 | </template> | |
436 | <inherit><type><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></type></inherit> | |
437 | <purpose> | |
438 | Syntactic sugar for <computeroutput><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></computeroutput>, | |
439 | for use in grammars to handle all the cases not yet handled. | |
440 | </purpose> | |
441 | <description> | |
442 | <para> | |
443 | Use <computeroutput>proto::otherwise<T></computeroutput> in your grammars as a synonym for | |
444 | <computeroutput><classname>proto::when</classname>< <classname>proto::_</classname>, Fun ></computeroutput> | |
445 | as in the following transform which counts the number of terminals in an expression. | |
446 | </para> | |
447 | <para> | |
448 | <programlisting>// Count the terminals in an expression tree. | |
449 | // Must be invoked with initial state == mpl::int_<0>(). | |
450 | struct CountLeaves : | |
451 | <classname>proto::or_</classname>< | |
452 | proto::when<<classname>proto::terminal</classname><<classname>proto::_</classname>>, mpl::next<<classname>proto::_state</classname>>()>, | |
453 | proto::otherwise<<classname>proto::fold</classname><<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves> > | |
454 | > | |
455 | {};</programlisting> | |
456 | </para> | |
457 | </description> | |
458 | </struct> | |
459 | ||
460 | <struct name="external_transform"> | |
461 | <purpose>A placeholder for use as the second parameter for <computeroutput><classname>proto::when</classname></computeroutput> | |
462 | to indicate that the rule's transform is specified externally.</purpose> | |
463 | <description> | |
464 | <para> | |
465 | See <computeroutput><classname>proto::external_transforms</classname></computeroutput> for an example. | |
466 | </para> | |
467 | </description> | |
468 | </struct> | |
469 | ||
470 | <struct name="external_transforms"> | |
471 | <template> | |
472 | <template-type-parameter name="When" pack="1"/> | |
473 | </template> | |
474 | <purpose>A map from grammars to transforms, used as a way to externally associate transforms.</purpose> | |
475 | <typedef name="map_type"> | |
476 | <purpose>For exposition only.</purpose> | |
477 | <type>mpl::map< typename to_mpl_pair< When >::type... ></type> | |
478 | </typedef> | |
479 | <struct name="when"> | |
480 | <template> | |
481 | <template-type-parameter name="Grammar"/> | |
482 | </template> | |
483 | <inherit><type><classname>proto::otherwise</classname>< typename mpl::at< map_type, Grammar >::type ></type></inherit> | |
484 | </struct> | |
485 | <description> | |
486 | <para> | |
487 | It is sometimes desirable to define a grammar that can be customized with different sets of transforms. | |
488 | To do that, where you would normally specify a transform within a grammar, you can instead put | |
489 | <computeroutput><classname>proto::external_transform</classname></computeroutput>; for example: | |
490 | <computeroutput>proto::when< some_grammar, proto::external_transform ></computeroutput>. Then, when | |
491 | invoking the grammar, you can pass an approriately-defined instance of <computeroutput>proto::external_transforms</computeroutput> | |
492 | as the Data parameter. When an expression matches <computeroutput>some_grammar</computeroutput>, Proto | |
493 | will look up the approprite transform in the Data parameter using <computeroutput>some_grammar</computeroutput> | |
494 | as a key. | |
495 | </para> | |
496 | <para> | |
497 | <programlisting>struct int_terminal | |
498 | : <classname>proto::terminal</classname><int> | |
499 | {}; | |
500 | ||
501 | struct char_terminal | |
502 | : <classname>proto::terminal</classname><char> | |
503 | {}; | |
504 | ||
505 | struct my_grammar | |
506 | : <classname>proto::or_</classname>< | |
507 | // The next two grammar rules are customization points. | |
508 | // The associated transforms are specified externally | |
509 | // using external_transforms below. | |
510 | <classname>proto::when</classname>< int_terminal, <classname>proto::external_transform</classname> > | |
511 | , <classname>proto::when</classname>< char_terminal, <classname>proto::external_transform</classname> > | |
512 | , <classname>proto::when</classname>< | |
513 | <classname>proto::plus</classname>< my_grammar, my_grammar > | |
514 | , <classname>proto::fold</classname>< <classname>proto::_</classname>, int(), my_grammar > | |
515 | > | |
516 | > | |
517 | {}; | |
518 | ||
519 | // Here is where the transforms are associated with the | |
520 | // grammar rules above. | |
521 | struct my_transforms | |
522 | : proto::external_transforms< | |
523 | <classname>proto::when</classname><int_terminal, print(<classname>proto::_value</classname>)> | |
524 | , <classname>proto::when</classname><char_terminal, print(<classname>proto::_value</classname>)> | |
525 | > | |
526 | {}; | |
527 | ||
528 | // ... | |
529 | ||
530 | <classname>proto::literal</classname><int> i(1); | |
531 | <classname>proto::literal</classname><char> c('a'); | |
532 | my_transforms trx; | |
533 | ||
534 | // Evaluate "i+c" using my_grammar with the specified transforms: | |
535 | my_grammar()(i + c, 0, trx); | |
536 | ||
537 | // If you would also like to pass arbitrary data along with the | |
538 | // transforms, you can use a transform environment, as so: | |
539 | my_grammar()(i + c, 0, (proto::data = 42, proto::transforms = trx));</programlisting> | |
540 | </para> | |
541 | </description> | |
542 | </struct> | |
543 | </namespace> | |
544 | </namespace> | |
545 | </header> |