]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/proto/doc/reference/transform/when.xml
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / proto / doc / reference / transform / when.xml
CommitLineData
7c673cae
FG
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&lt;&gt;</classname>
14 </computeroutput> and
15 <computeroutput>
16 <classname alt="boost::proto::otherwise">proto::otherwise&lt;&gt;</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>&lt;transforms_type, <replaceable>see-below</replaceable>&gt;</type>
42 <parameter name="value">
43 <paramtype>Value &amp;</paramtype>
44 </parameter>
45 </signature>
46 <signature cv="const">
47 <template>
48 <template-type-parameter name="Value"/>
49 </template>
50 <type><classname>env</classname>&lt;transforms_type, <replaceable>see-below</replaceable>&gt;</type>
51 <parameter name="value">
52 <paramtype>Value const &amp;</paramtype>
53 </parameter>
54 </signature>
55 <description>
56 <para>
57 If <code>Value</code> is a specialization <code>boost::reference_wrapper&lt;T&gt;</code>,
58 this function returns <code><classname>env</classname>&lt;transforms_type, T &amp;&gt;(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>&lt;transforms_type, Value <replaceable>cv</replaceable> &amp;&gt;(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>&lt;transforms_type, Value&gt;(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&lt;&gt;</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_&lt;0&gt;().
101struct CountLeaves :
102 <classname>proto::or_</classname>&lt;
103 proto::when&lt;<classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt;, mpl::next&lt;<classname>proto::_state</classname>&gt;()&gt;,
104 proto::otherwise&lt;<classname>proto::fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves&gt; &gt;
105 &gt;
106{};</programlisting>
107 </para>
108 <para>
109 In <computeroutput>proto::when&lt;G, T&gt;</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&lt;proto::when&lt;G,T&gt;(E,S,V)&gt;::type</computeroutput> is the same as
116 <computeroutput>boost::result_of&lt;T(E,S,V)&gt;::type</computeroutput>.
117 </para>
118 </listitem>
119 <listitem>
120 <para>
121 <computeroutput>proto::when&lt;G,T&gt;()(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>&lt; Grammar, Fun &gt;</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&lt;G, T0(T1(_))&gt;</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>&lt; when&lt;Grammar, R(A...)&gt; &gt;</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&lt;&gt;</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&lt;G, R(A...)&gt;</computeroutput> form accepts either a
181 <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its
182 second parameter. <computeroutput>proto::when&lt;&gt;</computeroutput> uses
183 <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput> to
184 distinguish between the two, and uses
185 <computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> to evaluate
186 <conceptname>CallableTransform</conceptname>s and
187 <computeroutput><classname>proto::make&lt;&gt;</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>&lt; Expr, State, Data &gt;</type></inherit>
198 <typedef name="call_">
199 <purpose>For exposition only</purpose>
200 <type><classname>proto::call</classname>&lt;R(A...)&gt;</type>
201 </typedef>
202 <typedef name="make_">
203 <purpose>For exposition only</purpose>
204 <type><classname>proto::make</classname>&lt;R(A...)&gt;</type>
205 </typedef>
206 <typedef name="which">
207 <purpose>For exposition only</purpose>
208 <type>typename mpl::if_&lt;<classname>proto::is_callable</classname>&lt;R&gt;,call_,make_&gt;::type</type>
209 </typedef>
210 <typedef name="result_type">
211 <type>typename boost::result_of&lt;which(Expr, State, Data)&gt;::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&lt;&gt;</classname></computeroutput> or with
238 <computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> depending
239 on whether <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::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>&lt;Expr, Grammar&gt;::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>&lt; when&lt;Grammar, R(A..., ...)&gt; &gt;</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&lt;&gt;</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&lt;G, R(A..., ...)&gt;</computeroutput> form accepts either a
283 <conceptname>CallableTransform</conceptname> or an <conceptname>ObjectTransform</conceptname> as its
284 second parameter. <computeroutput>proto::when&lt;&gt;</computeroutput> uses
285 <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::value</computeroutput> to
286 distinguish between the two, and uses
287 <computeroutput><classname>proto::call&lt;&gt;</classname></computeroutput> to evaluate
288 <conceptname>CallableTransform</conceptname>s and
289 <computeroutput><classname>proto::make&lt;&gt;</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&lt;G, R(A..., ...)&gt;</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>&lt; Expr, State, Data &gt;</type></inherit>
306 <typedef name="call_">
307 <purpose>For exposition only</purpose>
308 <type><classname>proto::call</classname>&lt;R(A..., ...)&gt;</type>
309 </typedef>
310 <typedef name="make_">
311 <purpose>For exposition only</purpose>
312 <type><classname>proto::make</classname>&lt;R(A..., ...)&gt;</type>
313 </typedef>
314 <typedef name="which">
315 <purpose>For exposition only</purpose>
316 <type>typename mpl::if_&lt;<classname>proto::is_callable</classname>&lt;R&gt;,call_,make_&gt;::type</type>
317 </typedef>
318 <typedef name="result_type">
319 <type>typename boost::result_of&lt;which(Expr, State, Data)&gt;::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&lt;&gt;</classname></computeroutput> or with
346 <computeroutput><classname>proto::make&lt;&gt;</classname></computeroutput> depending
347 on whether <computeroutput><classname>proto::is_callable</classname>&lt;R&gt;::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>&lt;Expr, Grammar&gt;::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>&lt; when&lt;Grammar, <classname>proto::external_transform</classname>&gt; &gt;</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&lt;&gt;</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&lt;G, <classname>proto::external_transform</classname>&gt;</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&lt;
409 typename mpl::eval_if_c&lt;
410 <classname>proto::result_of::has_env_var</classname>&lt;Data, <classname>proto::transforms_type</classname>&gt;::value,
411 <classname>proto::result_of::env_var</classname>&lt;Data, <classname>proto::transforms_type</classname>&gt;,
412 <classname>proto::result_of::env_var</classname>&lt;Data, <classname>proto::data_type</classname>&gt;
413 &gt;::type
414 &gt;::type
415 ::template when&lt; Grammar &gt;
416 ::template impl&lt; Expr, State, Data &gt;</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>&lt; <classname>proto::_</classname>, Fun &gt;</type></inherit>
437 <purpose>
438 Syntactic sugar for <computeroutput><classname>proto::when</classname>&lt; <classname>proto::_</classname>, Fun &gt;</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&lt;T&gt;</computeroutput> in your grammars as a synonym for
444 <computeroutput><classname>proto::when</classname>&lt; <classname>proto::_</classname>, Fun &gt;</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_&lt;0&gt;().
450struct CountLeaves :
451 <classname>proto::or_</classname>&lt;
452 proto::when&lt;<classname>proto::terminal</classname>&lt;<classname>proto::_</classname>&gt;, mpl::next&lt;<classname>proto::_state</classname>&gt;()&gt;,
453 proto::otherwise&lt;<classname>proto::fold</classname>&lt;<classname>proto::_</classname>, <classname>proto::_state</classname>, CountLeaves&gt; &gt;
454 &gt;
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&lt; typename to_mpl_pair&lt; When &gt;::type... &gt;</type>
478 </typedef>
479 <struct name="when">
480 <template>
481 <template-type-parameter name="Grammar"/>
482 </template>
483 <inherit><type><classname>proto::otherwise</classname>&lt; typename mpl::at&lt; map_type, Grammar &gt;::type &gt;</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&lt; some_grammar, proto::external_transform &gt;</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>&lt;int&gt;
499{};
500
501struct char_terminal
502 : <classname>proto::terminal</classname>&lt;char&gt;
503{};
504
505struct my_grammar
506 : <classname>proto::or_</classname>&lt;
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>&lt; int_terminal, <classname>proto::external_transform</classname> &gt;
511 , <classname>proto::when</classname>&lt; char_terminal, <classname>proto::external_transform</classname> &gt;
512 , <classname>proto::when</classname>&lt;
513 <classname>proto::plus</classname>&lt; my_grammar, my_grammar &gt;
514 , <classname>proto::fold</classname>&lt; <classname>proto::_</classname>, int(), my_grammar &gt;
515 &gt;
516 &gt;
517{};
518
519// Here is where the transforms are associated with the
520// grammar rules above.
521struct my_transforms
522 : proto::external_transforms&lt;
523 <classname>proto::when</classname>&lt;int_terminal, print(<classname>proto::_value</classname>)&gt;
524 , <classname>proto::when</classname>&lt;char_terminal, print(<classname>proto::_value</classname>)&gt;
525 &gt;
526{};
527
528// ...
529
530<classname>proto::literal</classname>&lt;int&gt; i(1);
531<classname>proto::literal</classname>&lt;char&gt; c('a');
532my_transforms trx;
533
534// Evaluate "i+c" using my_grammar with the specified transforms:
535my_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:
539my_grammar()(i + c, 0, (proto::data = 42, proto::transforms = trx));</programlisting>
540 </para>
541 </description>
542 </struct>
543 </namespace>
544 </namespace>
545</header>