]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/spirit/doc/advanced/customization_points.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / spirit / doc / advanced / customization_points.qbk
1 [/==============================================================================
2 Copyright (C) 2001-2011 Hartmut Kaiser
3 Copyright (C) 2001-2011 Joel de Guzman
4
5 Distributed under the Boost Software License, Version 1.0. (See accompanying
6 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 ===============================================================================/]
8
9 [import ../example/karma/customize_embedded_container.cpp] [/ this pulls in the embedded_container example]
10 [import ../example/karma/customize_counter.cpp] [/ this pulls in the counter example]
11 [import ../example/karma/customize_use_as_container.cpp] [/ this pulls in the use_as_container example]
12
13 [def __customize_embedded_container_example__ [link spirit.advanced.customize.iterate.container_iterator.example embedded_container_example]]
14 [def __customize_counter_example__ [link spirit.advanced.customize.iterate.deref_iterator.example counter_example]]
15 [def __customize_use_as_container_example__ [link spirit.advanced.customize.iterate.next_iterator.example use_as_container]]
16
17 [section:customize Customization of Spirit's Attribute Handling]
18
19 [heading Why do we need Attribute Customization Points]
20
21 [important Before you read on please be aware that the interfaces described in
22 this section are not finalized and may change in the future without
23 attempting to be backwards compatible. We document the customization
24 point interfaces anyways as we think they are important.
25 Understanding customization points helps understanding Spirit.
26 Additionally they prove to be powerful tools enabling full
27 integration of the user's data structures with /Qi's/ parsers and
28 /Karma's/ generators.]
29
30 __spirit__ has been written with extensibility in mind. It provides many
31 different attribute customization points allowing to integrate custom data
32 types with the process of parsing in __qi__ or output generation with
33 __karma__. All attribute customization points are exposed using a similar
34 technique: full or partial template specialization. __spirit__ generally
35 implements the main template, providing a default implementation. You as the
36 user have to provide a partial or full specialization of this template for the
37 data types you want to integrate with the library. In fact, the library uses
38 these customization points itself for instance to handle the magic of the
39 __unused_type__ attribute type.
40
41 Here is an example showing the __customize_container_value__ customization point
42 used by different parsers (such as __qi_kleene__, __qi_plus__, etc.) to find
43 the attribute type to be stored in a supplied STL container:
44
45 [import ../../../../boost/spirit/home/support/container.hpp]
46
47 [customization_container_value_default]
48
49 This template is instantiated by the library at the appropriate places while
50 using the supplied container type as the template argument. The embedded `type`
51 is used as the attribute type while parsing the elements to be store in that
52 container.
53
54 The following example shows the predefined specialization for __unused_type__:
55
56 [customization_container_value_unused]
57
58 which defines its embedded `type` to be __unused_type__ as well, this way
59 propagating the 'don't care' attribute status to the embedded parser.
60
61 All attribute customization points follow the same scheme. The last template
62 parameter is always `typename Enable = void` allowing to apply SFINAE for
63 fine grained control over the template specialization process. But most of the
64 time you can safely forget about its existence.
65
66 The following sections will describe all customization points, together with a
67 description which needs to be specialized for what purpose.
68
69 [heading The Usage of Customization Points]
70
71 The different customizations points are used by different parts of the library.
72 Part of the customizations points are used by both, __qi__ and __karma__,
73 whereas others are specialized to be applied for one of the sub-libraries only.
74 We will explain when a specific customization point needs to be implemented and,
75 equally important, which customization points need to be implemented at the
76 same time. Often it is not sufficient to provide a specialization for one
77 single customization point only, in this case you as the user have to provide
78 all necessary customizations for your data type you want to integrate with the
79 library.
80
81 [/////////////////////////////////////////////////////////////////////////////]
82 [section:is_container Determine if a Type Should be Treated as a Container (Qi and Karma)]
83
84 [heading is_container]
85
86 The template `is_container` is a template meta-function used as an attribute
87 customization point. It is invoked by the /Qi/ __qi_sequence__ (`>>`) and
88 /Karma/ __karma_sequence__ operators in order to determine whether a supplied
89 attribute can potentially be treated as a container.
90
91 [heading Header]
92
93 #include <boost/spirit/home/support/container.hpp>
94
95 Also, see __include_structure__.
96
97 [note This header file does not need to be included directly by any user
98 program as it is normally included by other Spirit header files relying
99 on its content.]
100
101 [heading Namespace]
102
103 [table
104 [[Name]]
105 [[`boost::spirit::traits`]]
106 ]
107
108 [heading Synopsis]
109
110 template <typename Container, typename Enable>
111 struct is_container
112 {
113 <unspecified>;
114 };
115
116 [heading Template parameters]
117
118 [table
119 [[Parameter] [Description] [Default]]
120 [[`Container`] [The type, `Container` which needs to
121 be tested whether it has to be treated
122 as a container] [none]]
123 [[`Enable`] [Helper template parameter usable to selectively
124 enable or disable certain specializations
125 of `is_container` utilizing SFINAE (i.e.
126 `boost::enable_if` or `boost::disable_if`).] [`void`]]
127 ]
128
129 [variablelist Notation
130 [[`C`] [A type to be tested whether it needs to be treated
131 as a container.]]
132 [[`T1`, `T2`, ...] [Arbitrary types]]
133 ]
134
135 [heading Expression Semantics]
136
137 [table
138 [[Expression] [Semantics]]
139 [[`is_container<C>::type`] [Result of the metafunction that evaluates to
140 `mpl::true_` if a given type, `C`, is to be
141 treated as a container, `mpl::false_` otherwise
142 Generally, any implementation of `is_container`
143 needs to behave as if if was a __mpl_boolean_constant__..]]
144 ]
145
146 [heading Predefined Specializations]
147
148 __spirit__ predefines specializations of this customization point for
149 several types. The following table lists those types together with the
150 conditions for which the corresponding specializations will evaluate to
151 `mpl::true_` (see __mpl_boolean_constant__):
152
153 [table
154 [[Template Parameters] [Semantics]]
155 [[`T`] [Returns `mpl::true_` if `T` has the following
156 embedded types defined: `value_type`,
157 `iterator`, `size_type`, and`reference`.
158 Otherwise it will return `mpl::false_`.]]
159 [[`boost::optional<T>`] [Returns `is_container<T>::type`]]
160 [[`boost::variant<T1, T2, ...>`]
161 [Returns `mpl::true_` if at least one of the
162 `is_container<TN>::type` returns `mpl::true_`
163 (where `TN` is `T1`, `T2`, ...).
164 Otherwise it will return `mpl::false_`.]]
165 [[__unused_type__] [Returns `mpl::false_`.]]
166 ]
167
168 [heading When to implement]
169
170 The customization point `is_container` needs to be implemented for a specific
171 type whenever this type is to be used as an attribute in place of a STL
172 container. It is applicable for parsers (__qi__) and generators (__karma__).
173 As a rule of thumb: it has to be implemented whenever a certain type
174 is to be passed as an attribute to a parser or a generator normally exposing a
175 STL container, `C` and if the type does not expose the interface of a STL container
176 (i.e. `is_container<C>::type` would normally return `mpl::false_`). These
177 components have an attribute propagation rule in the form:
178
179 a: A --> Op(a): vector<A>
180
181 where `Op(a)` stands for any meaningful operation on the component `a`.
182
183 [heading Related Attribute Customization Points]
184
185 If this customization point is implemented, the following other customization
186 points might need to be implemented as well.
187
188 [table
189 [[Name] [When to implement]]
190 [[__customize_container_value__] [Needs to be implemented whenever `is_container` is implemented.]]
191 [[__customize_push_back_container__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
192 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
193 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
194 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
195 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
196 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
197 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
198 [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
199 ]
200
201 [heading Example]
202
203 For examples of how to use the customization point `is_container` please
204 see here: __customize_embedded_container_example__,
205 __customize_use_as_container_example__, and __customize_counter_example__.
206
207 [endsect] [/ is_container]
208
209 [/////////////////////////////////////////////////////////////////////////////]
210 [section:is_string Determine if a Type Should be Treated as a String (Qi and Karma)]
211
212 [heading is_string]
213
214 The `is_string` customization point is a template meta-function. It is used by
215 /Qi/ [qi_lit_string String Literals] (`lit(str)`), /Qi/ [qi_lit_char Character Literals]
216 (`lit(c)`), /Karma/ [karma_lit_string String Literals] (`lit(str)`), /Karma/ [karma_lit_char Character Literals]
217 (`lit(c)`) and other Spirit components. It determines whether a supplied type
218 can be treated as a string.
219
220 [heading Module Headers]
221
222 #include <boost/spirit/home/support/string_traits.hpp>
223
224 Also, see __include_structure__.
225
226 [note This header file does not need to be included directly by any user
227 program as it is normally included by other Spirit header files relying
228 on its content.]
229
230 [heading Namespace]
231
232 [table
233 [[Name]]
234 [[`boost::spirit::traits`]]
235 ]
236
237 [heading Synopsis]
238
239 template <typename T>
240 struct is_string
241 {
242 <unspecified>;
243 };
244
245 [heading Template parameters]
246
247 [table
248 [[Parameter] [Description] [Default]]
249 [[`T`] [The type, `T` which needs to be tested as a string] [none]]
250 ]
251
252 [variablelist Notation
253 [[`T`] [An arbitrary type.]]
254 [[`N`] [An arbitrary integral constant.]]
255 [[`Char`] [A character type.]]
256 [[`Traits`] [A character traits type.]]
257 [[`Allocator`] [A standard allocator type.]]
258 ]
259
260 [heading Expression Semantics]
261
262 [table
263 [[Expression] [Semantics]]
264 [[`is_string<T>::type`] [Result of the metafunction that evalutes to mpl::true_
265 if a given type, `T`, is to be treated as a string and
266 mpl::false_ otherwise. Generally,
267 any implementation of `is_string` needs to behave as
268 if if was a __mpl_boolean_constant__.]]
269 ]
270
271 [heading Predefined Specializations]
272
273 [table
274 [[Type] [Semantics]]
275 [[`T`] [Returns `mpl::false_`.]]
276 [[`T const`] [Returns `is_string<T>`.]]
277 [[`char const*`] [Returns `mpl::true_`.]]
278 [[`wchar_t const*`] [Returns `mpl::true_`.]]
279 [[`char*`] [Returns `mpl::true_`.]]
280 [[`wchar_t*`] [Returns `mpl::true_`.]]
281 [[`char[N]`] [Returns `mpl::true_`.]]
282 [[`wchar_t[N]`] [Returns `mpl::true_`.]]
283 [[`char const[N]`] [Returns `mpl::true_`.]]
284 [[`wchar_t const[N]`] [Returns `mpl::true_`.]]
285 [[`char(&)[N]`] [Returns `mpl::true_`.]]
286 [[`wchar_t(&)[N]`] [Returns `mpl::true_`.]]
287 [[`char const(&)[N]`] [Returns `mpl::true_`.]]
288 [[`wchar_t const(&)[N]`] [Returns `mpl::true_`.]]
289 [[`std::basic_string<Char, Traits, Allocator>`] [Returns `mpl::true_`.]]
290 ]
291
292 [heading When to implement]
293
294 This customization point needs to be implemented to use user-defined string classes
295 that do not correspond to std::string syntax and semantics.
296
297 [heading Related Attribute Customization Points]
298
299 If this customization point is implemented, the following other customization
300 points need to be implemented as well.
301
302 [table
303 [[Name] [When to implement]]
304 [[__customize_is_char__] [For string types whose underlying character type
305 is not `char` or `wchar_t`, `is_char` must be
306 implemented.]]
307 [[__customize_char_type_of__] [Whenever `is_string` is implemented.]]
308 [[__customize_extract_c_string__] [Whenever `is_string` is implemented.]]
309 ]
310
311 [/ TODO: examples ]
312
313 [endsect] [/ is_string]
314
315
316 [/////////////////////////////////////////////////////////////////////////////]
317 [section:handles_container Determine Whether a Component Handles Container Attributes (Qi and Karma)]
318
319 [heading handles_container]
320
321 The template `handles_container` is a template meta-function used as an attribute
322 customization point. It is invoked by the /Qi/ __qi_sequence__ (`>>`) and
323 /Karma/ __karma_sequence__ operators in order to determine whether a sequence
324 element (component) handles container attributes directly. This customization
325 point is invoked for container attributes only, and only if the sequence is
326 compatible with the supplied container attribute.
327
328 If a component, which is part of a sequence is able to handle a container
329 attribute directly, the sequence passes the attribute to the component without
330 any additional action. In __qi__ the component uses the attribute to directly
331 store all matched attributes. In __karma__ the generator component extracts
332 the attributes needed for output generation directly from this attribute.
333
334 If a component, which is part of a sequence is not able to handle container
335 attributes, in __qi__ the sequence passes a new instance of the container
336 attributes' `value_type` to the parser component, inserting the result into
337 the attribute on behalf of the parser component. In __karma__ the sequence
338 extracts the next container element on behalf of the generator component and
339 passing it the extracted value.
340
341 [heading Header]
342
343 #include <boost/spirit/home/support/handles_container.hpp>
344
345 Also, see __include_structure__.
346
347 [note This header file does not need to be included directly by any user
348 program as it is normally included by other Spirit header files relying
349 on its content.]
350
351 [heading Namespace]
352
353 [table
354 [[Name]]
355 [[`boost::spirit::traits`]]
356 ]
357
358 [heading Synopsis]
359
360 template <
361 typename Component, typename Attribute, typename Context,
362 typename Iterator, typename Enable>
363 struct handles_container
364 {
365 <unspecified>;
366 };
367
368 [heading Template parameters]
369
370 [table
371 [[Parameter] [Description] [Default]]
372 [[`Component`] [The component type `Component` which needs to
373 be tested whether it handles container attributes
374 directly.] [none]]
375 [[`Attribute`] [The attribute type `Attribute` as passed to the
376 sequence operator.] [none]]
377 [[`Context`] [This is the type of the current component execution
378 context.] [`unused_type`]]
379 [[`Iterator`] [The type, `Iterator` is the type of the iterators
380 used to invoke the component.] [`unused_type`]]
381 [[`Enable`] [Helper template parameter usable to selectively
382 enable or disable certain specializations
383 of `is_container` utilizing SFINAE (i.e.
384 `boost::enable_if` or `boost::disable_if`).] [`void`]]
385 ]
386
387 [variablelist Notation
388 [[`Component`] [A component type to be tested whether it directly handles
389 container attributes in the context of sequences.]]
390 [[`Attribute`] [A container attribute type as passed to the sequence.]]
391 [[`T1`, `T2`, ...] [Arbitrary types]]
392 ]
393
394 [heading Expression Semantics]
395
396 [table
397 [[Expression] [Semantics]]
398 [[`handles_container<Component, Attribute>::type`]
399 [Result of the metafunction that evaluates to
400 `mpl::true_` if a given component type `Component`,
401 handles container attributes directly,
402 `mpl::false_` otherwise. Generally,
403 any implementation of `handles_container` needs to
404 behave as if if was a __mpl_boolean_constant__.]]
405 ]
406
407 [heading Predefined Specializations]
408
409 __spirit__ predefines specializations of this customization point for
410 several types. The following table lists those types together with the
411 conditions for which the corresponding specializations will evaluate to
412 `mpl::true_` (see __mpl_boolean_constant__):
413
414 [table
415 [[Template Parameters] [Semantics]]
416 [[`Component`, `Attribute`] [Always returns `mpl::false_` (the default).]]
417 [[`rule<Iterator, T1, T2, T3, T4>`, `Attribute`]
418 [Returns `is_container<A>`, where `A` is the
419 attribute exposed by the rule (__qi__ and
420 __karma__).]]
421 [[`grammar<Iterator, T1, T2, T3, T4>`, `Attribute`]
422 [Returns `is_container<A>`, where `A` is the
423 attribute exposed by the grammar (__qi__ and
424 __karma__).]]
425 ]
426
427 [heading When to implement]
428
429 The customization point `handles_container` needs to be implemented for a
430 specific type whenever this type directly handles container attributes.
431 It is applicable for parsers (__qi__) and generators (__karma__). It will have
432 to be implemented under rare circumstances only.
433
434 [/ TODO: examples ]
435
436 [endsect] [/ handles_container]
437
438 [/////////////////////////////////////////////////////////////////////////////]
439 [section:transform Transform an Attribute to a Different Type (Qi and Karma)]
440
441 [heading transform_attribute]
442
443 The template `transform_attribute` is a type used as an attribute customization
444 point. It is invoked by /Qi/ `rule`, semantic action and `attr_cast`, and /Karma/
445 `rule`, semantic action and [karma_attr_cast `attr_cast`]. It is used to
446 automatically transform the user
447 provided attribute to the attribute type expected by the right hand side
448 component (for `rule`), the semantic action, or the embedded component
449 (for `attr_cast`).
450
451 [note The interface of this customization point has been changed with Boost
452 V1.44. We added the `Domain` template parameter to allow for more fine
453 grained specializations for __qi__ and __karma__.]
454
455 [heading Module Headers]
456
457 #include <boost/spirit/home/support/attributes.hpp>
458
459 Also, see __include_structure__.
460
461 [note This header file does not need to be included directly by any user
462 program as it is normally included by other Spirit header files relying
463 on its content.]
464
465 [heading Namespace]
466
467 [table
468 [[Name]]
469 [[`boost::spirit::traits`]]
470 ]
471
472 [heading Synopsis]
473
474 template <typename Exposed, typename Transformed, typename Domain, typename Enable>
475 struct transform_attribute
476 {
477 typedef <unspecified> type;
478
479 static type pre(Exposed& val);
480 static void post(Exposed& val, type attr); // Qi only
481 static void fail(Exposed&); // Qi only
482 };
483
484 [heading Template parameters]
485
486 [table
487 [[Parameter] [Description] [Default]]
488 [[`Exposed`] [The attribute type supplied to the component
489 which needs to be transformed.] [none]]
490 [[`Transformed`] [The attribute type expected by the component
491 to be provided as the result of the transformation.] [none]]
492 [[`Domain`] [The domain of the sub library the template is
493 instantiated in. Typically this is either `qi::domain`
494 or `karma::domain`.] [none]]
495 [[`Enable`] [Helper template parameter usable to selectively
496 enable or disable certain specializations
497 of `transform_attribute` utilizing SFINAE (i.e.
498 `boost::enable_if` or `boost::disable_if`).] [`void`]]
499 ]
500
501 [variablelist Notation
502 [[`Exposed`] [The type, `Exposed` is the type of the attribute as
503 passed in by the user.]]
504 [[`Transformed`] [The type, `Transformed` is the type of the attribute
505 as passed along to the right hand side of the `rule`
506 (embedded component of `attr_cast`).]]
507 [[`Domain`] [The domain of the sub library the template is
508 instantiated in. Typically this is either `qi::domain`
509 or `karma::domain`.]]
510 [[`exposed`] [An instance of type `Exposed`.]]
511 [[`transformed`] [An instance of type `Transformed`.]]
512 ]
513
514 [heading Expression Semantics]
515
516 [table
517 [[Expression] [Semantics]]
518 [[`transform_attribute<Exposed, Transformed, Domain>::type`]
519 [Evaluates to the type to be used as the result of the
520 transformation (to be passed to the right hand side of
521 the `rule` or to the embedded component of the
522 `attr_cast`. Most of the time this is equal to
523 `Transformed`, but in other cases this might evaluate to
524 `Transformed&` instead avoiding superfluous object
525 creation.]]
526 [[
527 ``type transform_attribute<Exposed, Transformed, Domain>::pre(exposed)``]
528 [Do `pre`-transformation before invoking the right hand
529 side component for `rule` (or the embedded component
530 for `attr_cast`). This takes the attribute supplied as by
531 the user (of type `Exposed`) and returns the attribute
532 to be passed down the component hierarchy (of the type
533 as exposed by the metafunction `type`). This function
534 will be called in /Qi/ and for /Karma/.]]
535 [[
536 ``void transform_attribute<Exposed, Transformed, Domain>::post(exposed, transformed)``]
537 [Do `post`-transformation after the invocation of the
538 right hand side component for `rule` (or the embedded
539 component for `attr_cast`). This takes the original
540 attribute as supplied by the user and the attribute
541 as returned from the right hand side (embedded)
542 component and is expected to propagate the result back
543 into the supplied attribute instance. This function
544 will be called in /Qi/ only.]]
545 [[
546 ``void transform_attribute<Exposed, Transformed, Domain>::fail(exposed)``]
547 [Handling failing parse operations of the
548 right hand side component for `rule` (or the embedded
549 component for `attr_cast`). This function
550 will be called in /Qi/ only.]]
551 ]
552
553 [heading Predefined Specializations]
554
555 [table
556 [[Template parameters] [Semantics]]
557 [[`Exposed`, `Transformed`] [`type` evaluates to `Transformed`,
558 `pre()` returns a new instance of `Transformed`
559 constructed from the argument of type `Exposed`,
560 `post()` assigns `transformed` to `exposed`.]]
561 [[`optional<Exposed>`, `Transformed`,
562 `typename disable_if<is_same<optional<Exposed>, Transformed> >::type`]
563 [`type` evaluates to `Transformed&`,
564 `pre()` returns a reference to the instance of `Transformed`
565 stored in the passed optional (the argument of type `optional<Exposed>`),
566 the optional instance is initialized, if needed.
567 `post()` does nothing, `fail()` resets the
568 optional (its parameter) instance to the non-initialized state.]]
569 [[`Exposed&`, `Transformed`] [`type` evaluates to `Transformed`,
570 `pre()` returns a new instance of `Transformed`
571 constructed from the argument of type `Exposed`,
572 `post()` assigns `transformed` to `exposed`.]]
573 [[`Attrib&`, `Attrib`] [`type` evaluates to `Attrib&`,
574 `pre()` returns it's argument, `post()` does
575 nothing.]]
576 [[`Exposed const`, `Transformed`] [(usind in /Karma/ only) `type` evaluates to
577 `Transformed`, `pre()` returns it's argument,
578 `post()` is not implemented.]]
579 [[`Attrib const&`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`,
580 `pre()` returns it's argument, `post()` is not
581 implemented.]]
582 [[`Attrib const`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`,
583 `pre()` returns it's argument, `post()` is not
584 implemented.]]
585 [[__unused_type__, `Attrib`] [`type` evaluates to __unused_type__, `pre()`
586 and `post()` do nothing.]]
587 [[`Attrib`, __unused_type__] [`type` evaluates to __unused_type__, `pre()`
588 and `post()` do nothing.]]
589 ]
590
591 [heading When to implement]
592
593 The customization point `transform_attribute` needs to be implemented for a
594 specific pair of types whenever the attribute type supplied to a `rule` or
595 `attr_cast` cannot automatically transformed to the attribute type expected by
596 the right hand side of the `rule` (embedded component of the `attr_cast`)
597 because the default implementation as shown above is not applicable. Examples
598 for this could be that the type `Transformed` is not constructible from
599 the type `Exposed`.
600
601 [/ TODO: examples ]
602
603 [endsect] [/ transform]
604
605 [/////////////////////////////////////////////////////////////////////////////]
606 [/ section:optional Handling of Optional Attributes (Qi and Karma)]
607
608 [/ optional_attribute]
609
610 [/ endsect] [/ optional]
611
612 [/////////////////////////////////////////////////////////////////////////////]
613 [section:assign_to Store a Parsed Attribute Value (Qi)]
614
615 After parsing input and generating an attribute value this value needs to
616 assigned to the attribute instance provided by the user. The customization
617 points `assign_to_attribute_from_iterators` and `assign_to_attribute_from_value`
618 are utilized to adapt this assignment to the concrete type to be assigned.
619 This section describes both.
620
621 [section:assign_to_attribute_from_iterators Store an Attribute after a Parser Produced a Pair of Iterators (Qi)]
622
623 [heading assign_to_attribute_from_iterators]
624
625 The template `assign_to_attribute_from_iterators` is a type used as an attribute
626 customization point. It is invoked by the those /Qi/ parsers not producing any
627 attribute value but returning a pair of iterators pointing to the matched input
628 sequence. It is used to either store the iterator pair into the attribute
629 instance provided by the user or to convert the iterator pair into an attribute
630 as provided by the user.
631
632 [heading Module Headers]
633
634 #include <boost/spirit/home/qi/detail/assign_to.hpp>
635
636 Also, see __include_structure__.
637
638 [note This header file does not need to be included directly by any user
639 program as it is normally included by other Spirit header files relying
640 on its content.]
641
642 [heading Namespace]
643
644 [table
645 [[Name]]
646 [[`boost::spirit::traits`]]
647 ]
648
649 [heading Synopsis]
650
651 template <typename Attrib, typename Iterator, typename Enable>
652 struct assign_to_attribute_from_iterators
653 {
654 static void call(Iterator const& first, Iterator const& last, Attrib& attr);
655 };
656
657 [heading Template parameters]
658
659 [table
660 [[Parameter] [Description] [Default]]
661 [[`Attrib`] [The type, `Attrib` is the type of the attribute as
662 passed in by the user.] [none]]
663 [[`Iterator`] [The type, `Iterator` is the type of the iterators
664 as produced by the parser.] [none]]
665 [[`Enable`] [Helper template parameter usable to selectively
666 enable or disable certain specializations
667 of `assign_to_attribute_from_value` utilizing SFINAE (i.e.
668 `boost::enable_if` or `boost::disable_if`).] [`void`]]
669 ]
670
671 [variablelist Notation
672 [[`Attrib`] [A type to be used as the target to store the attribute value in.]]
673 [[`attr`] [An attribute instance of type `Attrib`.]]
674 [[`Iterator`] [The iterator type used by the parser. This type usually
675 corresponds to the iterators as passed in by the user.]]
676 [[`begin`, `end`] [Iterator instances of type `Iterator` pointing to the
677 begin and the end of the matched input sequence.]]
678 ]
679
680 [heading Expression Semantics]
681
682 [table
683 [[Expression] [Semantics]]
684 [[
685 ``assign_to_attribute_from_iterators<Attrib, Iterator>::call(b, e, attr)``]
686 [Use the iterators `begin` and `end` to initialize
687 the attribute `attr`.]]
688 ]
689
690 [heading Predefined Specializations]
691
692 [table
693 [[Template Parameters] [Semantics]]
694 [[`Attrib`, `Iterator`] [Execute an assignment `attr = Attrib(begin, end)`.]]
695 [[__unused_type__, `T`] [Do nothing.]]
696 ]
697
698 [heading When to implement]
699
700 The customization point `assign_to_attribute_from_iterators` needs to be
701 implemented for a specific type whenever the default implementation as shown
702 above is not applicable. Examples for this could be that the type `Attrib` is
703 not constructible from the pair of iterators.
704
705 [/ TODO: examples ]
706
707 [endsect] [/ assign_to_attribute_from_iterators]
708
709 [section:assign_to_attribute_from_value Store an Attribute Value after a Parser Produced a Value (Qi)]
710
711 [heading assign_to_attribute_from_value]
712
713 The template `assign_to_attribute_from_value` is a type used as an attribute
714 customization point. It is invoked by all primitive /Qi/ parsers in order
715 to store a parsed attribute value into the attribute instance provided by the
716 user, if this attribute is not a container type (`is_container<T>::type`
717 evaluates to `mpl::false_`, where `T` is the attribute type).
718
719 [heading Module Headers]
720
721 #include <boost/spirit/home/qi/detail/assign_to.hpp>
722
723 Also, see __include_structure__.
724
725 [note This header file does not need to be included directly by any user
726 program as it is normally included by other Spirit header files relying
727 on its content.]
728
729 [heading Namespace]
730
731 [table
732 [[Name]]
733 [[`boost::spirit::traits`]]
734 ]
735
736 [heading Synopsis]
737
738 template <typename Attrib, typename T, typename Enable>
739 struct assign_to_attribute_from_value
740 {
741 static void call(T const& val, Attrib& attr);
742 };
743
744 [heading Template parameters]
745
746 [table
747 [[Parameter] [Description] [Default]]
748 [[`Attrib`] [The type, `Attrib` is the type of the attribute as
749 passed in by the user. This type is not a container
750 type (`is_container<Attrib>::type` evaluates to
751 `mpl::false_`).] [none]]
752 [[`T`] [The type, `T` is the type of the attribute instance
753 as produced by the parser.] [none]]
754 [[`Enable`] [Helper template parameter usable to selectively
755 enable or disable certain specializations
756 of `assign_to_attribute_from_value` utilizing SFINAE (i.e.
757 `boost::enable_if` or `boost::disable_if`).] [`void`]]
758 ]
759
760 [variablelist Notation
761 [[`Attrib`] [A type to be used as the target to store the attribute
762 value in. This type is guaranteed not to be a container
763 type (`is_container<Attrib>::type` evaluates to
764 `mpl::false_`).]]
765 [[`attr`] [An attribute instance of type `Attrib`.]]
766 [[`T`] [A type as produced by the parser. The parser temporarily stores
767 its parsed values using this type.]]
768 [[`t`] [An attribute instance of type `T`.]]
769 ]
770
771 [heading Expression Semantics]
772
773 [table
774 [[Expression] [Semantics]]
775 [[
776 ``assign_to_attribute_from_value<Attrib, T>::call(t, attr)``]
777 [Copy (assign) the value `t` to the attribute `attr`.]]
778 ]
779
780 [heading Predefined Specializations]
781
782 [table
783 [[Template Parameters] [Semantics]]
784 [[`Attrib`, `T`] [Assign the argument `t` to `attr`.]]
785 [[__unused_type__, `T`] [Do nothing.]]
786 ]
787
788 [heading When to implement]
789
790 The customization point `assign_to_attribute_from_value` needs to be
791 implemented for a specific type whenever the default implementation as shown
792 above is not applicable. Examples for this could be that the type `Attrib` is
793 not copy constructible.
794
795 [/ TODO: examples ]
796
797 [endsect] [/ assign_to_attribute_from_value]
798
799 [section:assign_to_container_from_value Store an Attribute Value into a Container after a Parser Produced a Value (Qi)]
800
801 [heading assign_to_container_from_value]
802
803 The template `assign_to_container_from_value` is a type used as an attribute
804 customization point. It is invoked by all primitive /Qi/ parsers in order
805 to store a parsed attribute value into the attribute instance provided by the
806 user, if this attribute is a container type (`is_container<T>::type` evaluates
807 to `mpl::true_`, where `T` is the attribute type).
808
809 [heading Module Headers]
810
811 #include <boost/spirit/home/qi/detail/assign_to.hpp>
812
813 Also, see __include_structure__.
814
815 [note This header file does not need to be included directly by any user
816 program as it is normally included by other Spirit header files relying
817 on its content.]
818
819 [heading Namespace]
820
821 [table
822 [[Name]]
823 [[`boost::spirit::traits`]]
824 ]
825
826 [heading Synopsis]
827
828 template <typename Attrib, typename T, typename Enable>
829 struct assign_to_container_from_value
830 {
831 static void call(T const& val, Attrib& attr);
832 };
833
834 [heading Template parameters]
835
836 [table
837 [[Parameter] [Description] [Default]]
838 [[`Attrib`] [The type, `Attrib` is the type of the attribute as
839 passed in by the user. This type is a container
840 type (`is_container<Attrib>::type` evaluates to
841 `mpl::true_`).] [none]]
842 [[`T`] [The type, `T` is the type of the attribute instance
843 as produced by the parser.] [none]]
844 [[`Enable`] [Helper template parameter usable to selectively
845 enable or disable certain specializations
846 of `assign_to_container_from_value` utilizing SFINAE (i.e.
847 `boost::enable_if` or `boost::disable_if`).] [`void`]]
848 ]
849
850 [variablelist Notation
851 [[`Attrib`] [A type to be used as the target to store the attribute
852 value in. This type is guaranteed to be a container
853 type (`is_container<Attrib>::type` evaluates to
854 `mpl::true_`).]]
855 [[`attr`] [An attribute instance of type `Attrib`.]]
856 [[`T`] [A type as produced by the parser. The parser temporarily stores
857 its parsed values using this type.]]
858 [[`t`] [An attribute instance of type `T`.]]
859 ]
860
861 [heading Expression Semantics]
862
863 [table
864 [[Expression] [Semantics]]
865 [[
866 ``assign_to_container_from_value<Attrib, T>::call(t, attr)``]
867 [Add the value `t` to the container attribute `attr`.]]
868 ]
869
870 [heading Predefined Specializations]
871
872 [table
873 [[Template Parameters] [Semantics]]
874 [[`Attrib`, `T`] [Add the argument `t` to `attr`.]]
875 [[__unused_type__, `T`] [Do nothing.]]
876 ]
877
878 [heading When to implement]
879
880 The customization point `assign_to_container_from_value` needs to be
881 implemented for a specific type whenever the default implementation as shown
882 above is not applicable. Examples for this could be that the type `Attrib` is
883 not copy constructible.
884
885 [/ TODO: examples ]
886
887 [endsect] [/ assign_to_container_from_value]
888
889 [endsect] [/ assign_to]
890
891 [/////////////////////////////////////////////////////////////////////////////]
892 [section:store_value Store Parsed Attribute Values into a Container (Qi)]
893
894 In order to customize Spirit to accept a given data type as a container for
895 elements parsed by any of the repetitive parsers (__qi_kleene__, __qi_plus__,
896 __qi_list__, and [qi_repeat Repeat]) two attribute customization points have to be
897 specialized: __customize_container_value__ and __customize_push_back_container__.
898 This section describes both.
899
900 [section:container_value Determine the Type to be Stored in a Container (Qi)]
901
902 [heading container_value]
903
904 The template `container_value` is a template meta function used as an attribute
905 customization point. It is invoked by the /Qi/ repetitive parsers
906 (__qi_kleene__, __qi_plus__, __qi_list__, and [qi_repeat Repeat]) to determine the
907 type to store in a container.
908
909 [heading Module Headers]
910
911 #include <boost/spirit/home/support/container.hpp>
912
913 Also, see __include_structure__.
914
915 [note This header file does not need to be included directly by any user
916 program as it is normally included by other Spirit header files relying
917 on its content.]
918
919 [heading Namespace]
920
921 [table
922 [[Name]]
923 [[`boost::spirit::traits`]]
924 ]
925
926 [heading Synopsis]
927
928 template <typename Container, typename Enable>
929 struct container_value
930 {
931 typedef <unspecified> type;
932 };
933
934 [heading Template parameters]
935
936 [table
937 [[Parameter] [Description] [Default]]
938 [[`Container`] [The type `Container` is the type for which the
939 type f the elements has to be deduced.] [none]]
940 [[`Enable`] [Helper template parameter usable to selectively
941 enable or disable certain specializations
942 of `container_value` utilizing SFINAE (i.e.
943 `boost::enable_if` or `boost::disable_if`).] [`void`]]
944 ]
945
946 [variablelist
947 [[`C`] [A type to be tested whether it needs to be treated
948 as a container.]]
949 [[`T1`, `T2`, ...] [Arbitrary types]]
950 ]
951
952 [heading Expression Semantics]
953
954 [table
955 [[Expression] [Semantics]]
956 [[`container_value<C>::type`] [Metafunction that evaluates to the type
957 to be stored in a given container type,
958 `C`.]]
959 ]
960
961 [heading Predefined Specializations]
962
963 __spirit__ predefines specializations of this customization point for
964 several types. The following table lists those types together with the types
965 exposed and the corresponding semantics:
966
967 [table
968 [[Template Parameters] [Semantics]]
969 [[`C`] [The non-const `value_type` of the given container
970 type, `C`. ]]
971 [[`boost::optional<C>`] [Returns `container_value<C>::type`]]
972 [[`boost::variant<T1, T2, ...>`]
973 [Returns `container_value<TN>::value` for the
974 first `TN` (out of `T1`, `T2`, ...) for which
975 `is_container<TN>::type` evaluates to `mpl::true_`.
976 Otherwise it will return __unused_type__.]]
977 [[__unused_type__] [Returns __unused_type__.]]
978 ]
979
980 [heading When to implement]
981
982 The customization point `is_container` needs to be implemented for a specific
983 type whenever this type is to be used as an attribute in place of a STL
984 container. It is applicable for parsers (__qi__) only. As a rule of thumb: it
985 has to be implemented whenever a certain type is to be passed as an attribute
986 to a parser normally exposing a STL container and if the type does not expose
987 the interface of a STL container (i.e. no embedded typedef for `value_type`).
988 These components have an attribute propagation rule in the form:
989
990 a: A --> Op(a): vector<A>
991
992 where `Op(a)` stands for any meaningful operation on the component `a`.
993
994 [heading Related Attribute Customization Points]
995
996 If this customization point is implemented, the following other customization
997 points might need to be implemented as well.
998
999 [table
1000 [[Name] [When to implement]]
1001 [[__customize_push_back_container__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
1002 [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
1003 ]
1004
1005 [heading Example]
1006
1007 Here is an example showing the default implementation of the
1008 __customize_container_value__ customization point provided by the library:
1009
1010 [customization_container_value_default]
1011
1012 This template is instantiated by the library at the appropriate places while
1013 using the supplied container type as the template argument. The embedded `type`
1014 is used as the attribute type while parsing the elements to be store in that
1015 container.
1016
1017 The following example shows the predefined specialization for __unused_type__:
1018
1019 [customization_container_value_unused]
1020
1021 which defines its embedded `type` to be __unused_type__ as well, this way
1022 propagating the 'don't care' attribute status to the embedded parser.
1023
1024 [/ TODO: examples ]
1025
1026 [endsect] [/ container_value]
1027
1028 [section:push_back Store a Parsed Attribute Value into a Container (Qi)]
1029
1030 [heading push_back_container]
1031
1032 The template `push_back_container` is a type used as an attribute customization
1033 point. It is invoked by the /Qi/ repetitive parsers (__qi_kleene__, __qi_plus__,
1034 __qi_list__, and [qi_repeat Repeat]) to store a parsed attribute value into a
1035 container.
1036
1037 [heading Module Headers]
1038
1039 #include <boost/spirit/home/support/container.hpp>
1040
1041 Also, see __include_structure__.
1042
1043 [note This header file does not need to be included directly by any user
1044 program as it is normally included by other Spirit header files relying
1045 on its content.]
1046
1047 [heading Namespace]
1048
1049 [table
1050 [[Name]]
1051 [[`boost::spirit::traits`]]
1052 ]
1053
1054 [heading Synopsis]
1055
1056 template <typename Container, typename Attrib, typename Enable>
1057 struct push_back_container
1058 {
1059 static bool call(Container& c, Attrib const& val);
1060 };
1061
1062 [heading Template parameters]
1063
1064 [table
1065 [[Parameter] [Description] [Default]]
1066 [[`Container`] [The type, `Container` needs to
1067 be tested whether it has to be treated
1068 as a container] [none]]
1069 [[`Attrib`] [The type, `Attrib` is the one returned from the
1070 customization point __customize_container_value__
1071 and represents the attribute value to be stored in
1072 the container of type `Container`.] [none]]
1073 [[`Enable`] [Helper template parameter usable to selectively
1074 enable or disable certain specializations
1075 of `push_back_container` utilizing SFINAE (i.e.
1076 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1077 ]
1078
1079 [variablelist Notation
1080 [[`C`] [A type to be used as a container to store attribute values in.]]
1081 [[`c`] [A container instance of type `C`.]
1082 [[`Attrib`] [A type to be used as a container to store attribute values in.]]
1083 [[`attr`] [An attribute instance of type `Attrib`.]]
1084 [[`T1`, `T2`, ...] [Arbitrary types]]
1085 ]
1086
1087 [heading Expression Semantics]
1088
1089 [table
1090 [[Expression] [Semantics]]
1091 [[
1092 ``push_back_container<C, Attrib>::call(c, attr)``]
1093 [Static function that is invoked whenever an
1094 attribute value, `attr` needs to be stored
1095 into the container instance `c`. This function
1096 should return `true` on success and `false`
1097 otherwise. Returning `false` causes the
1098 corresponding parser to fail.]]
1099 ]
1100
1101 [heading Predefined Specializations]
1102
1103 __spirit__ predefines specializations of this customization point for
1104 several types. The following table lists those types together with the types
1105 exposed and the corresponding semantics:
1106
1107 [table
1108 [[Template Parameters] [Semantics]]
1109 [[`C`, `Attrib`] [Store the provided attribute instance `attr` into
1110 the given container `c` using the function call
1111 `c.insert(c.end(), attr)`.]]
1112 [[`boost::optional<C>`, `Attrib`]
1113 [If the provided instance of `boost::optional<>` is not
1114 initialized, invoke the appropriate initialization
1115 and afterwards apply the customization point
1116 `push_back_container<C, Attrib>`, treating the
1117 instance held by the optional (of type `C`) as
1118 the container to store the attribute in.]]
1119 [[`boost::variant<T1, T2, ...>`, `Attrib`]
1120 [If the instance of the variant currently holds a
1121 value with a type, `TN`, for which `is_container<TN>::type`
1122 evaluates to `mpl::true_`, this customization
1123 point specialization will apply
1124 `push_back_container<TN, Attrib>`, treating the
1125 instance held by the variant (of type `TN`) as
1126 the container to store the attribute in. Otherwise
1127 it will raise an assertion.]]
1128 [[__unused_type__] [Do nothing.]]
1129 ]
1130
1131 [heading When to Implement]
1132
1133 The customization point `push_back_container` needs to be implemented for a
1134 specific type whenever this type is to be used as an attribute in place of a STL
1135 container. It is applicable for parsers (__qi__) only. As a rule of thumb: it
1136 has to be implemented whenever a certain type is to be passed as an attribute
1137 to a parser normally exposing a STL container and if the type does not expose
1138 the interface of a STL container (i.e. no function being equivalent to
1139 `c.insert(c.end(), attr)`. These components have an attribute propagation rule
1140 in the form:
1141
1142 a: A --> Op(a): vector<A>
1143
1144 where `Op(a)` stands for any meaningful operation on the component `a`.
1145
1146 [heading Related Attribute Customization Points]
1147
1148 If this customization point is implemented, the following other customization
1149 points might need to be implemented as well.
1150
1151 [table
1152 [[Name] [When to implement]]
1153 [[__customize_container_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
1154 [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
1155 ]
1156
1157 [heading Example]
1158
1159 Here is an example showing the default implementation of the
1160 __customize_container_value__ customization point provided by the library:
1161
1162 [customization_push_back_default]
1163
1164 This template is instantiated by the library at the appropriate places while
1165 using the supplied container and element types as the template arguments. The
1166 member function `call()` will be called whenever an element has to be added to
1167 the supplied container
1168
1169 The following example shows the predefined specialization for __unused_type__:
1170
1171 [customization_push_back_unused]
1172
1173 which defines an empty member function `call()`.
1174
1175 [/ TODO: examples ]
1176
1177 [endsect] [/ push_back]
1178
1179 [endsect] [/ store_value]
1180
1181 [/////////////////////////////////////////////////////////////////////////////]
1182 [section:clear_value Re-Initialize an Attribute Value before Parsing (Qi)]
1183
1184 [heading clear_value]
1185
1186 The template `clear_value` is a type used as an attribute customization point.
1187 It is invoked by the /Qi/ repetitive parsers (__qi_kleene__, __qi_plus__,
1188 __qi_list__, and [qi_repeat Repeat]) in order to re-initialize the attribute
1189 instance passed to the embedded parser after it has been stored in the provided
1190 container. This re-initialized attribute instance is reused during the next
1191 iteration of the repetitive parser.
1192
1193 [heading Module Headers]
1194
1195 #include <boost/spirit/home/support/attributes.hpp>
1196
1197 Also, see __include_structure__.
1198
1199 [note This header file does not need to be included directly by any user
1200 program as it is normally included by other Spirit header files relying
1201 on its content.]
1202
1203 [heading Namespace]
1204
1205 [table
1206 [[Name]]
1207 [[`boost::spirit::traits`]]
1208 ]
1209
1210 [heading Synopsis]
1211
1212 template <typename Attrib, typename Enable>
1213 struct clear_value
1214 {
1215 static void call(Attrib& val);
1216 };
1217
1218 [heading Template parameters]
1219
1220 [table
1221 [[Parameter] [Description] [Default]]
1222 [[`Attrib`] [The type, `Attrib` of the attribute to be
1223 re-initialized.] [none]]
1224 [[`Enable`] [Helper template parameter usable to selectively
1225 enable or disable certain specializations
1226 of `clear_value` utilizing SFINAE (i.e.
1227 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1228 ]
1229
1230 [variablelist Notation
1231 [[`Attrib`] [A type to be used as a container to store attribute values in.]]
1232 [[`attr`] [An attribute instance of type `Attrib`.]]
1233 [[`T1`, `T2`, ...] [Arbitrary types]]
1234 ]
1235
1236 [heading Expression Semantics]
1237
1238 [table
1239 [[Expression] [Semantics]]
1240 [[
1241 ``clear_value<Attrib>::call(Attrib& attr)``] [Re-initialize the instance referred to by
1242 `attr` in the most efficient way.]]
1243 ]
1244
1245 [heading Predefined Specializations]
1246
1247 __spirit__ predefines specializations of this customization point for
1248 several types. The following table lists those types together with the types
1249 exposed and the corresponding semantics:
1250
1251 [table
1252 [[Template Parameters] [Semantics]]
1253 [[`Attrib`] [Re-initialize using assignment of default
1254 constructed value.]]
1255 [[Any type `T` for which `is_container<>::type` is `mpl::true_`]
1256 [Call the member function `attr.clear()` for the
1257 passed attribute instance.]]
1258 [[`boost::optional<Attrib>`] [Clear the `optional` instance and leave it
1259 uninitialized.]]
1260 [[`boost::variant<T1, T2, ...>`][Invoke the `clear_value` customization
1261 point for the currently held value.]]
1262 [[`fusion::tuple<T1, T2, ...>`][Invoke the `clear_value` customization
1263 point for all elements of the tuple.]]
1264 [[__unused_type__] [Do nothing.]]
1265 ]
1266
1267 [heading When to Implement]
1268
1269 The customization point `clear_value` needs to be implemented for a
1270 specific type whenever this type is to be used as an attribute to be stored
1271 into a STL container and if the type cannot be re-initialized using one of the
1272 specializations listed above. Examples for this might be types not being default
1273 constructible or container types not exposing a member function `clear()`.
1274
1275 [/ TODO: examples ]
1276
1277 [endsect] [/ clear_value]
1278
1279 [/////////////////////////////////////////////////////////////////////////////]
1280 [section:extract_from Extract an Attribute Value to Generate Output (Karma)]
1281
1282 [heading extract_from]
1283
1284 Before generating output for a value this value needs to extracted from the
1285 attribute instance provided by the user. The customization point
1286 `extract_from_attribute` is utilized to adapt this extraction for any data type possibly
1287 used to store the values to output.
1288
1289 [note The interface of this customization point has been changed with Boost
1290 V1.44. We added the `Exposed` template parameter to allow for more fine
1291 grained specializations of the required __karma__ attribute
1292 transformations.]
1293
1294 [heading Module Headers]
1295
1296 #include <boost/spirit/home/karma/detail/extract_from.hpp>
1297
1298 Also, see __include_structure__.
1299
1300 [note This header file does not need to be included directly by any user
1301 program as it is normally included by other Spirit header files relying
1302 on its content.]
1303
1304 [heading Namespace]
1305
1306 [table
1307 [[Name]]
1308 [[`boost::spirit::traits`]]
1309 ]
1310
1311 [heading Synopsis]
1312
1313 template <typename Exposed, typename Attrib, typename Enable>
1314 struct extract_from_attribute
1315 {
1316 typedef <unspecified> type;
1317
1318 template <typename Context>
1319 static type call(Attrib const& attr, Context& context);
1320 };
1321
1322 [heading Template parameters]
1323
1324 [table
1325 [[Parameter] [Description] [Default]]
1326 [[`Exposed`] [The type, `Exposed` of the attribute natively
1327 exposed by the component the `extract_from_attribute` is
1328 invoked from.] [none]]
1329 [[`Attrib`] [The type, `Attrib` of the attribute to be used to
1330 generate output from.] [none]]
1331 [[`Enable`] [Helper template parameter usable to selectively
1332 enable or disable certain specializations
1333 of `clear_value` utilizing SFINAE (i.e.
1334 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1335 [[`Context`] [This is the type of the current generator execution
1336 context.]]
1337 ]
1338
1339 [variablelist Notation
1340 [[`Exposed`] [A type exposed as the native attribute of a component.]]
1341 [[`Attrib`] [A type to be used to generate output from.]]
1342 [[`attr`] [An attribute instance of type `Attrib`.]]
1343 [[`ctx`] [An instance of type `Context`.]]
1344 ]
1345
1346 [heading Expression Semantics]
1347
1348 [table
1349 [[Expression] [Semantics]]
1350 [[
1351 ``extract_from_attribute<Exposed, Attrib>::call(attr, ctx)``]
1352 [Extract the value to generate
1353 output from `attr` and return it to the caller.]]
1354 ]
1355
1356 [heading Predefined Specializations]
1357
1358 __spirit__ predefines specializations of this customization point for
1359 several types. The following table lists those types together with the types
1360 exposed and the corresponding semantics:
1361
1362 [table
1363 [[Template Parameters] [Semantics]]
1364 [[`Attrib`] [The exposed typedef `type` is defined to
1365 `Attrib const&`. The function `call()` returns
1366 the argument by reference without change.]]
1367 [[`boost::optional<Attrib>`] [The exposed typedef `type` is defined to
1368 `Attrib const&`. The function `call()` returns
1369 the value held by the `optional<>` argument
1370 by reference without change.]]
1371 [[`boost::reference_wrapper<Attrib>`]
1372 [The exposed typedef `type` is defined to
1373 `Attrib const&`. The function `call()` returns
1374 the value held by the `reference_wrapper<>`
1375 argument by reference without change.]]
1376 [[__unused_type__] [The exposed typedef `type` is defined to
1377 __unused_type__. The function `call()` returns
1378 an instance of __unused_type__.]]
1379 ]
1380
1381 [heading When to implement]
1382
1383 The customization point `extract_from_attribute` needs to be implemented for a
1384 specific type whenever the default implementation as shown above is not
1385 applicable. Examples for this could be that the type to be extracted is
1386 different from `Attrib` and is not copy constructible.
1387
1388 [/ TODO: examples ]
1389
1390 [endsect] [/ extract_from]
1391
1392 [/////////////////////////////////////////////////////////////////////////////]
1393 [section:extract_from_container Extract From a Container Attribute Value to Generate Output (Karma)]
1394
1395 [heading extract_from_container]
1396
1397 Before generating output for a value this value needs to extracted from the
1398 attribute instance provided by the user. The customization point
1399 `extract_from_container` is utilized to adapt this extraction for any data type possibly
1400 used to store the values to output.
1401
1402 [note The interface of this customization point has been changed with Boost
1403 V1.44. We added the `Exposed` template parameter to allow for more fine
1404 grained specializations of the required __karma__ attribute
1405 transformations.]
1406
1407 [heading Module Headers]
1408
1409 #include <boost/spirit/home/karma/detail/extract_from.hpp>
1410
1411 Also, see __include_structure__.
1412
1413 [note This header file does not need to be included directly by any user
1414 program as it is normally included by other Spirit header files relying
1415 on its content.]
1416
1417 [heading Namespace]
1418
1419 [table
1420 [[Name]]
1421 [[`boost::spirit::traits`]]
1422 ]
1423
1424 [heading Synopsis]
1425
1426 template <typename Exposed, typename Attrib, typename Enable>
1427 struct extract_from_container
1428 {
1429 typedef <unspecified> type;
1430
1431 template <typename Context>
1432 static type call(Attrib const& attr, Context& context);
1433 };
1434
1435 [heading Template parameters]
1436
1437 [table
1438 [[Parameter] [Description] [Default]]
1439 [[`Exposed`] [The type, `Exposed` of the attribute natively
1440 exposed by the component the `extract_from_container` is
1441 invoked from.] [none]]
1442 [[`Attrib`] [The type, `Attrib` is the container attribute to be used to
1443 generate output from.] [none]]
1444 [[`Enable`] [Helper template parameter usable to selectively
1445 enable or disable certain specializations
1446 of `clear_value` utilizing SFINAE (i.e.
1447 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1448 [[`Context`] [This is the type of the current generator execution
1449 context.]]
1450 ]
1451
1452 [heading Notation]
1453
1454 [variablelist Notation
1455 [[`Exposed`] [A type exposed as the native attribute of a component.]]
1456 [[`Attrib`] [A container type to be used to generate output from.]]
1457 [[`attr`] [An attribute instance of type `Attrib`.]]
1458 [[`ctx`] [An instance of type `Context`.]]
1459 ]
1460
1461 [heading Expression Semantics]
1462
1463 [table
1464 [[Expression] [Semantics]]
1465 [[
1466 ``extract_from_container<Exposed, Attrib>::call(attr, ctx)``]
1467 [Extract the value to generate
1468 output from the contaner given by `attr` and return
1469 it to the caller.]]
1470 ]
1471
1472 [heading Predefined Specializations]
1473
1474 __spirit__ predefines specializations of this customization point for
1475 several types. The following table lists those types together with the types
1476 exposed and the corresponding semantics:
1477
1478 [table
1479 [[Template Parameters] [Value]]
1480 [[`Attrib`] [The exposed typedef `type` is defined to
1481 `Attrib const&`. The function `call()` returns
1482 the argument by reference without change.]]
1483 [[__unused_type__] [The exposed typedef `type` is defined to
1484 __unused_type__. The function `call()` returns
1485 an instance of __unused_type__.]]
1486 ]
1487
1488 [heading When to implement]
1489
1490 The customization point `extract_from_container` needs to be implemented for a
1491 specific container type whenever the default implementation as shown above is not
1492 applicable. Examples for this could be that the type to be extracted is
1493 different from `Attrib` and is not copy constructible.
1494
1495 [heading Example]
1496
1497 TBD
1498
1499 [endsect] [/ extract_from]
1500
1501 [/////////////////////////////////////////////////////////////////////////////]
1502 [section:iterate Extract Attribute Values to Generate Output from a Container (Karma)]
1503
1504 [section:container_iterator Determine the Type of the Iterator of a Container]
1505
1506 [heading container_iterator]
1507
1508 The template `container_iterator` is a template meta-function used as an attribute
1509 customization point. It is invoked by the /Karma/ repetitive generators (such
1510 as __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, and
1511 [karma_repeat Repeat]) in order to determine the type of the iterator to use to
1512 iterate over the items to be exposed as the elements of a container.
1513
1514 [heading Module Headers]
1515
1516 #include <boost/spirit/home/support/container.hpp>
1517
1518 Also, see __include_structure__.
1519
1520 [note This header file does not need to be included directly by any user
1521 program as it is normally included by other Spirit header files relying
1522 on its content.]
1523
1524 [heading Namespace]
1525
1526 [table
1527 [[Name]]
1528 [[`boost::spirit::traits`]]
1529 ]
1530
1531 [heading Synopsis]
1532
1533 template <typename Container, typename Enable>
1534 struct container_iterator
1535 {
1536 typedef <unspecified> type;
1537 };
1538
1539 [heading Template parameters]
1540
1541 [table
1542 [[Parameter] [Description] [Default]]
1543 [[`Container`] [The type, `Container` for which the
1544 iterator type has to be returned] [none]]
1545 [[`Enable`] [Helper template parameter usable to selectively
1546 enable or disable certain specializations
1547 of `container_iterator` utilizing SFINAE (i.e.
1548 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1549 ]
1550
1551 [variablelist Notation
1552 [[`C`] [A container type the iterator type needs to be evaluated for.]]
1553 ]
1554
1555 [heading Expression Semantics]
1556
1557 [table
1558 [[Expression] [Semantics]]
1559 [[`container_iterator<C>::type`] [Result of the metafunction that evaluates
1560 the type to be used as the iterator for
1561 accessing all elements of a container, `C`.]]
1562 ]
1563
1564 The returned type conceptually needs to be equivalent to a standard forward
1565 iterator. But it does not have to expose the standardized interface. If this
1566 customization point is implemented for a certain container type, all related
1567 customization points need to be implemented as well (see
1568 [link spirit.advanced.customize.iterate.container_iterator.related_attribute_customization_points Related Attribute Customization Points]
1569 below). This encapsulates the specific iterator interface required for a
1570 given type. The minimal requirements for a type to be exposed as an iterator in
1571 this context are:
1572
1573 * it needs to be comparable for equality (see __customize_compare_iterators__),
1574 * it needs to be incrementable (see __customize_next_iterator__),
1575 * it needs to be dereferencible (see __customize_deref_iterator__).
1576
1577 [heading Predefined Specializations]
1578
1579 __spirit__ predefines specializations of this customization point for
1580 several types. The following table lists those types together with the
1581 types returned by the embedded typedef `type`:
1582
1583 [table
1584 [[Template Parameters] [Semantics]]
1585 [[`C`] [Returns `C::iterator`.]]
1586 [[`C const`] [Returns `C::const_iterator`.]]
1587 [[__unused_type__] [Returns __unused_type__` const*`.]]
1588 ]
1589
1590 [heading When to implement]
1591
1592 The customization point `container_iterator` needs to be implemented for a specific
1593 type whenever this type is to be used as an attribute in place of a STL
1594 container. It is applicable for generators (__karma__) only. As a rule of thumb:
1595 it has to be implemented whenever a certain type is to be passed as an attribute
1596 to a generator normally exposing a STL container, `C` and if the type does not expose
1597 the interface of a STL container (i.e. `is_container<C>::type` would normally
1598 return `mpl::false_`).
1599
1600 [heading Related Attribute Customization Points]
1601
1602 If this customization point is implemented, the following other customization
1603 points might need to be implemented as well.
1604
1605 [table
1606 [[Name] [When to implement]]
1607 [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]]
1608 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1609 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1610 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1611 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1612 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1613 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1614 ]
1615
1616 [heading Example]
1617
1618 Here are the header files needed to make the example code below compile:
1619
1620 [customize_karma_embedded_container_includes]
1621
1622 The example (for the full source code please see here:
1623 [@../../example/karma/customize_embedded_container.cpp customize_embedded_container.cpp])
1624 uses the data structure
1625
1626 [customize_karma_embedded_container_data]
1627
1628 as a direct container attribute to the __karma_list__ generator. In order to
1629 make this data structure compatible we need to specialize a couple of attribute
1630 customization points: __customize_is_container__, __customize_container_iterator__,
1631 __customize_begin_container__, and __customize_end_container__. As you can see
1632 the specializations simply expose the embedded `std::vector<int>` as the
1633 container to use. We don't need to specialize the customization points related
1634 to iterators (__customize_deref_iterator__, __customize_next_iterator__,
1635 and __customize_compare_iterators__) as we expose a standard iterator and the
1636 default implementation of these customizations handles standard iterators out
1637 of the box.
1638
1639 [customize_karma_embedded_container_traits]
1640
1641 The last code snippet shows an example using an instance of the data structure
1642 `client::embedded_container` to generate output from a __karma_list__
1643 generator:
1644
1645 [customize_karma_embedded_container]
1646
1647 As you can see, the specializations for the customization points as defined
1648 above enable the seamless integration of the custom data structure without
1649 having to modify the output format or the generator itself.
1650
1651 For other examples of how to use the customization point `container_iterator`
1652 please see here: __customize_use_as_container_example__ and
1653 __customize_counter_example__.
1654
1655 [endsect] [/ container_iterator]
1656
1657
1658 [section:begin_container Get the Iterator pointing to the Begin of a Container Attribute]
1659
1660 [heading begin_container]
1661
1662 The template `begin_container` is a type used as an attribute customization point.
1663 It is invoked by the /Karma/ repetitive generators (such as __karma_list__,
1664 [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat])
1665 in order to get an iterator pointing to the first element of the container
1666 holding the attributes to generate output from.
1667
1668 [heading Module Headers]
1669
1670 #include <boost/spirit/home/support/container.hpp>
1671
1672 Also, see __include_structure__.
1673
1674 [note This header file does not need to be included directly by any user
1675 program as it is normally included by other Spirit header files relying
1676 on its content.]
1677
1678 [heading Namespace]
1679
1680 [table
1681 [[Name]]
1682 [[`boost::spirit::traits`]]
1683 ]
1684
1685 [heading Synopsis]
1686
1687 template <typename Container, typename Enable>
1688 struct begin_container
1689 {
1690 static typename container_iterator<Container>::type
1691 call(Container& c);
1692 };
1693
1694 [heading Template parameters]
1695
1696 [table
1697 [[Parameter] [Description] [Default]]
1698 [[`Container`] [The type, `Container` for which the iterator pointing
1699 to the first element has to be returned] [none]]
1700 [[`Enable`] [Helper template parameter usable to selectively
1701 enable or disable certain specializations
1702 of `begin_container` utilizing SFINAE (i.e.
1703 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1704 ]
1705
1706 [variablelist Notation
1707 [[`C`] [A container type the begin iterator needs to be returned for.]]
1708 [[`c`] [An instance of a container, `C`.]]
1709 ]
1710
1711 [heading Expression Semantics]
1712
1713 [table
1714 [[Expression] [Semantics]]
1715 [[`begin_container<C>::call(c)`] [Return the iterator usable to dereference
1716 the first element of the given container,
1717 `c`. The type of the returned iterator is
1718 expected to be the same as the type returned
1719 by the customization point
1720 __customize_container_iterator__.]]
1721 ]
1722
1723 The returned instance conceptually needs to be equivalent to a standard forward
1724 iterator. But it does not have to expose the standardized interface. If this
1725 customization point is implemented for a certain container type, all related
1726 customization points need to be implemented as well (see
1727 [link spirit.advanced.customize.iterate.begin_container.related_attribute_customization_points Related Attribute Customization Points]
1728 below). This encapsulates the specific iterator interface required for a
1729 given type. The minimal requirements for a type to be exposed as an iterator in
1730 this context are:
1731
1732 * it needs to be comparable for equality (see __customize_compare_iterators__),
1733 * it needs to be incrementable (see __customize_next_iterator__),
1734 * it needs to be dereferencible (see __customize_deref_iterator__).
1735
1736 [heading Predefined Specializations]
1737
1738 __spirit__ predefines specializations of this customization point for
1739 several types. The following table lists those types together with the
1740 types returned by the embedded typedef `type`:
1741
1742 [table
1743 [[Template Parameters] [Semantics]]
1744 [[`C`] [Returns `c.begin()`.]]
1745 [[`C const`] [Returns `c.begin()`.]]
1746 [[__unused_type__] [Returns `&unused`.]]
1747 ]
1748
1749 [heading When to implement]
1750
1751 The customization point `begin_container` needs to be implemented for a specific
1752 type whenever this type is to be used as an attribute in place of a STL
1753 container. It is applicable for generators (__karma__) only. As a rule of thumb:
1754 it has to be implemented whenever a certain type is to be passed as an attribute
1755 to a generator normally exposing a STL container, `C` and if the type does not expose
1756 the interface of a STL container (i.e. `is_container<C>::type` would normally
1757 return `mpl::false_`).
1758
1759 [heading Related Attribute Customization Points]
1760
1761 If this customization point is implemented, the following other customization
1762 points might need to be implemented as well.
1763
1764 [table
1765 [[Name] [When to implement]]
1766 [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]]
1767 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1768 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1769 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1770 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1771 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1772 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1773 ]
1774
1775 [heading Example]
1776
1777 For examples of how to use the customization point `begin_container` please
1778 see here: __customize_embedded_container_example__,
1779 __customize_use_as_container_example__, and __customize_counter_example__.
1780
1781 [endsect] [/ begin_container]
1782
1783
1784 [section:end_container Get the Iterator pointing to the End of a Container Attribute]
1785
1786 [heading end_container]
1787
1788 The template `end_container` is a type used as an attribute customization point.
1789 It is invoked by the /Karma/ repetitive generators (such as __karma_list__,
1790 [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat])
1791 in order to get an iterator pointing to the end of the container
1792 holding the attributes to generate output from.
1793
1794 [heading Module Headers]
1795
1796 #include <boost/spirit/home/support/container.hpp>
1797
1798 Also, see __include_structure__.
1799
1800 [note This header file does not need to be included directly by any user
1801 program as it is normally included by other Spirit header files relying
1802 on its content.]
1803
1804 [heading Namespace]
1805
1806 [table
1807 [[Name]]
1808 [[`boost::spirit::traits`]]
1809 ]
1810
1811 [heading Synopsis]
1812
1813 template <typename Container, typename Enable>
1814 struct end_container
1815 {
1816 static typename container_iterator<Container>::type
1817 call(Container& c);
1818 };
1819
1820 [heading Template parameters]
1821
1822 [table
1823 [[Parameter] [Description] [Default]]
1824 [[`Container`] [The type, `Container` for which the iterator pointing
1825 to the first element has to be returned] [none]]
1826 [[`Enable`] [Helper template parameter usable to selectively
1827 enable or disable certain specializations
1828 of `end_container` utilizing SFINAE (i.e.
1829 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1830 ]
1831
1832 [variablelist Notation
1833 [[`C`] [A container type the end iterator needs to be returned for.]]
1834 [[`c`] [An instance of a container, `C`.]]
1835 ]
1836
1837 [heading Expression Semantics]
1838
1839 [table
1840 [[Expression] [Semantics]]
1841 [[`end_container<C>::call(c)`] [Return the iterator usable to compare a
1842 different iterator with in order to detect
1843 whether the other iterator reached the end
1844 of the given container, `c`. The type of
1845 the returned iterator is expected to be the
1846 same as the type returned by the
1847 customization point __customize_container_iterator__.]]
1848 ]
1849
1850 [heading Predefined Specializations]
1851
1852 __spirit__ predefines specializations of this customization point for
1853 several types. The following table lists those types together with the
1854 types returned by the embedded typedef `type`:
1855
1856 [table
1857 [[Template Parameters] [Semantics]]
1858 [[`C`] [Returns `c.end()`.]]
1859 [[`C const`] [Returns `c.end()`.]]
1860 [[__unused_type__] [Returns `&unused`.]]
1861 ]
1862
1863 [heading When to implement]
1864
1865 The customization point `end_container` needs to be implemented for a specific
1866 type whenever this type is to be used as an attribute in place of a STL
1867 container. It is applicable for generators (__karma__) only. As a rule of thumb:
1868 it has to be implemented whenever a certain type is to be passed as an attribute
1869 to a generator normally exposing a STL container, `C` and if the type does not expose
1870 the interface of a STL container (i.e. `is_container<C>::type` would normally
1871 return `mpl::false_`).
1872
1873 [heading Related Attribute Customization Points]
1874
1875 If this customization point is implemented, the following other customization
1876 points might need to be implemented as well.
1877
1878 [table
1879 [[Name] [When to implement]]
1880 [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]]
1881 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1882 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1883 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1884 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1885 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1886 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1887 ]
1888
1889 [heading Example]
1890
1891 For examples of how to use the customization point `end_container` please
1892 see here: __customize_embedded_container_example__,
1893 __customize_use_as_container_example__, and __customize_counter_example__.
1894
1895 [endsect] [/ end_container]
1896
1897
1898 [section:next_iterator Increment the Iterator pointing into a Container Attribute]
1899
1900 [heading next_iterator]
1901
1902 The template `next_iterator` is a type used as an attribute customization point.
1903 It is invoked by the /Karma/ repetitive generators (such as __karma_list__,
1904 [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat])
1905 in order to get an iterator pointing to the next element of a container
1906 holding the attributes to generate output from.
1907
1908 [heading Module Headers]
1909
1910 #include <boost/spirit/home/support/container.hpp>
1911
1912 Also, see __include_structure__.
1913
1914 [note This header file does not need to be included directly by any user
1915 program as it is normally included by other Spirit header files relying
1916 on its content.]
1917
1918 [heading Namespace]
1919
1920 [table
1921 [[Name]]
1922 [[`boost::spirit::traits`]]
1923 ]
1924
1925 [heading Synopsis]
1926
1927 template <typename Iterator, typename Enable>
1928 struct next_iterator
1929 {
1930 static void call(Iterator& it);
1931 };
1932
1933 [heading Template parameters]
1934
1935 [table
1936 [[Parameter] [Description] [Default]]
1937 [[`Iterator`] [The type, `Iterator` of the iterator to increment.
1938 This is the same as the type returned by the
1939 customization point __customize_container_iterator__.] [none]]
1940 [[`Enable`] [Helper template parameter usable to selectively
1941 enable or disable certain specializations
1942 of `next_iterator` utilizing SFINAE (i.e.
1943 `boost::enable_if` or `boost::disable_if`).] [`void`]]
1944 ]
1945
1946 [variablelist Notation
1947 [[`Iterator`] [An iterator type.]]
1948 [[`it`] [An instance of an iterator of type `Iterator`.]]
1949 [[`C`] [A container type whose iterator type is `Iterator`.]]
1950 ]
1951
1952 [heading Expression Semantics]
1953
1954 [table
1955 [[Expression] [Semantics]]
1956 [[`next_iterator<Iterator>::call(it)`] [Increment the iterator pointing so that
1957 it is pointing to the next element.]]
1958 ]
1959
1960 [heading Predefined Specializations]
1961
1962 __spirit__ predefines specializations of this customization point for
1963 several types. The following table lists those types together with the
1964 types returned by the embedded typedef `type`:
1965
1966 [table
1967 [[Template Parameters] [Semantics]]
1968 [[`Iterator`] [Executes `++it`.]]
1969 [[__unused_type__` const*`][Does nothing.]]
1970 ]
1971
1972 [heading When to implement]
1973
1974 The customization point `next_iterator` needs to be implemented for a specific
1975 iterator type whenever the container this iterator belongs to is to be used as
1976 an attribute in place of a STL container. It is applicable for generators
1977 (__karma__) only. As a rule of thumb: it has to be implemented whenever a certain
1978 iterator type belongs to a container which is to be passed as an attribute
1979 to a generator normally exposing a STL container, `C` and if the container type
1980 does not expose the interface of a STL container (i.e. `is_container<C>::type`
1981 would normally return `mpl::false_`).
1982
1983 [heading Related Attribute Customization Points]
1984
1985 If this customization point is implemented, the following other customization
1986 points might need to be implemented as well.
1987
1988 [table
1989 [[Name] [When to implement]]
1990 [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]]
1991 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1992 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1993 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1994 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1995 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1996 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
1997 ]
1998
1999 [heading Example]
2000
2001 Here are the header files needed to make the example code below compile:
2002
2003 [customize_karma_use_as_container_includes]
2004
2005 The example (for the full source code please see here:
2006 [@../../example/karma/customize_use_as_container.cpp customize_use_as_container.cpp])
2007 uses the data structure
2008
2009 [customize_karma_use_as_container_data]
2010
2011 as a direct attribute to the __karma_list__ generator. This type does not
2012 expose any of the interfaces of an STL container. It does not even expose the
2013 usual semantics of a container. The purpose of this artificial example is to
2014 demonstrate how the customization points can be used to expose independent data
2015 elements as a single container. The example shows how to enable its use as an
2016 attribute to /Karma's/ repetitive generators.
2017
2018 In order to make this data structure compatible we need to specialize a couple
2019 of attribute customization points: __customize_is_container__,
2020 __customize_container_iterator__, __customize_begin_container__, and
2021 __customize_end_container__. In addition, we specialize all of the
2022 iterator related customization points as well: __customize_deref_iterator__,
2023 __customize_next_iterator__, and __customize_compare_iterators__.
2024
2025 [customize_karma_use_as_container_traits]
2026 [customize_karma_use_as_container_iterator_traits]
2027
2028 The last code snippet shows an example using an instance of the data structure
2029 `client::use_as_container` to generate output from a __karma_list__ generator:
2030
2031 [customize_karma_use_as_container]
2032
2033 As you can see, the specializations for the customization points as defined
2034 above enable the seamless integration of the custom data structure without
2035 having to modify the output format or the generator itself.
2036
2037 [endsect] [/ next_iterator]
2038
2039
2040 [section:deref_iterator Dereference the Iterator pointing into a Container Attribute]
2041
2042 [heading deref_iterator]
2043
2044 The template `deref_iterator` is a type used as an attribute customization point.
2045 It is invoked by the /Karma/ repetitive generators (such as __karma_list__,
2046 [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat])
2047 in order to dereference an iterator pointing to an element of a container
2048 holding the attributes to generate output from.
2049
2050 [heading Module Headers]
2051
2052 #include <boost/spirit/home/support/container.hpp>
2053
2054 Also, see __include_structure__.
2055
2056 [note This header file does not need to be included directly by any user
2057 program as it is normally included by other Spirit header files relying
2058 on its content.]
2059
2060 [heading Namespace]
2061
2062 [table
2063 [[Name]]
2064 [[`boost::spirit::traits`]]
2065 ]
2066
2067 [heading Synopsis]
2068
2069 template <typename Iterator, typename Enable>
2070 struct deref_iterator
2071 {
2072 typedef <unspecified> type;
2073 static type call(Iterator& it);
2074 };
2075
2076 [heading Template parameters]
2077
2078 [table
2079 [[Parameter] [Description] [Default]]
2080 [[`Iterator`] [The type, `Iterator` of the iterator to dereference.
2081 This is the same as the type returned by the
2082 customization point __customize_container_iterator__.] [none]]
2083 [[`Enable`] [Helper template parameter usable to selectively
2084 enable or disable certain specializations
2085 of `deref_iterator` utilizing SFINAE (i.e.
2086 `boost::enable_if` or `boost::disable_if`).] [`void`]]
2087 ]
2088
2089 [variablelist Notation
2090 [[`Iterator`] [An iterator type.]]
2091 [[`it`] [An instance of an iterator of type `Iterator`.]]
2092 [[`C`] [A container type whose iterator type is `Iterator`.]]
2093 ]
2094
2095 [heading Expression Semantics]
2096
2097 [table
2098 [[Expression] [Semantics]]
2099 [[`deref_iterator<Iterator>::type`] [Metafunction result evaluating to the
2100 type returned by dereferencing the iterator.]]
2101 [[`deref_iterator<Iterator>::call(it)`] [Return the element in the container
2102 referred to by the iterator. The type of the
2103 returned value is the same as returned by the
2104 metafunction result `type`.]]
2105 ]
2106
2107 [heading Predefined Specializations]
2108
2109 __spirit__ predefines specializations of this customization point for
2110 several types. The following table lists those types together with the
2111 types returned by the embedded typedef `type`:
2112
2113 [table
2114 [[Template Parameters] [Semantics]]
2115 [[`Iterator`] [The metafunction result `type` evaluates to
2116 `boost::detail::iterator_traits<Iterator>::reference` and the
2117 function `call()` returns `*it`.]]
2118 [[__unused_type__` const*`][The metafunction result `type` evaluates to
2119 __unused_type__ and the function `call()` returns `unused`.]]
2120 ]
2121
2122 [heading When to implement]
2123
2124 The customization point `deref_iterator` needs to be implemented for a specific
2125 iterator type whenever the container this iterator belongs to is to be used as
2126 an attribute in place of a STL container. It is applicable for generators
2127 (__karma__) only. As a rule of thumb: it has to be implemented whenever a certain
2128 iterator type belongs to a container which is to be passed as an attribute
2129 to a generator normally exposing a STL container, `C` and if the container type
2130 does not expose the interface of a STL container (i.e. `is_container<C>::type`
2131 would normally return `mpl::false_`).
2132
2133 [heading Related Attribute Customization Points]
2134
2135 If this customization point is implemented, the following other customization
2136 points might need to be implemented as well.
2137
2138 [table
2139 [[Name] [When to implement]]
2140 [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]]
2141 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2142 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2143 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2144 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2145 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2146 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2147 ]
2148
2149 [heading Example]
2150
2151 Here are the header files needed to make the example code below compile:
2152
2153 [customize_karma_counter_includes]
2154
2155 The example (for the full source code please see here:
2156 [@../../example/karma/customize_counter.cpp customize_counter.cpp])
2157 uses the data structure
2158
2159 [customize_karma_counter_data]
2160
2161 as a direct attribute to the __karma_list__ generator. This type does not
2162 expose any of the interfaces of an STL container. It does not even expose the
2163 usual semantics of a container. The presented customization points build a
2164 counter instance which is incremented each time it is accessed. The examples
2165 shows how to enable its use as an attribute to /Karma's/ repetitive generators.
2166
2167 In order to make this data structure compatible we need to specialize a couple
2168 of attribute customization points: __customize_is_container__,
2169 __customize_container_iterator__, __customize_begin_container__, and
2170 __customize_end_container__. In addition, we specialize one of the
2171 iterator related customization points as well: __customize_deref_iterator__.
2172
2173 [customize_karma_counter_traits]
2174 [customize_karma_counter_iterator_traits]
2175
2176 The last code snippet shows an example using an instance of the data structure
2177 `client::counter` to generate output from a __karma_list__ generator:
2178
2179 [customize_karma_counter]
2180
2181 As you can see, the specializations for the customization points as defined
2182 above enable the seamless integration of the custom data structure without
2183 having to modify the output format or the generator itself.
2184
2185 For other examples of how to use the customization point `deref_iterator`
2186 please see here: __customize_use_as_container_example__.
2187
2188 [endsect] [/ deref_iterator]
2189
2190
2191 [section:compare_iterators Compare two Iterator pointing into a Container Attribute for Equality]
2192
2193 [heading compare_iterators]
2194
2195 The template `compare_iterators` is a type used as an attribute customization
2196 point. It is invoked by the /Karma/ repetitive generators (such as __karma_list__,
2197 [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat])
2198 in order to compare the current iterator (returned either from
2199 __customize_begin_container__ or from __customize_next_iterator__) with the end
2200 iterator (returned from __customize_end_container__) in order to find the end
2201 of the element sequence to generate output for.
2202
2203 [heading Module Headers]
2204
2205 #include <boost/spirit/home/support/container.hpp>
2206
2207 Also, see __include_structure__.
2208
2209 [note This header file does not need to be included directly by any user
2210 program as it is normally included by other Spirit header files relying
2211 on its content.]
2212
2213 [heading Namespace]
2214
2215 [table
2216 [[Name]]
2217 [[`boost::spirit::traits`]]
2218 ]
2219
2220 [heading Synopsis]
2221
2222 template <typename Iterator, typename Enable>
2223 struct compare_iterators
2224 {
2225 static bool call(Iterator const& it1, Iterator const& it2);
2226 };
2227
2228 [heading Template parameters]
2229
2230 [table
2231 [[Parameter] [Description] [Default]]
2232 [[`Iterator`] [The type, `Iterator` of the iterator to dereference.
2233 This is the same as the type returned by the
2234 customization point __customize_container_iterator__.] [none]]
2235 [[`Enable`] [Helper template parameter usable to selectively
2236 enable or disable certain specializations
2237 of `compare_iterators` utilizing SFINAE (i.e.
2238 `boost::enable_if` or `boost::disable_if`).] [`void`]]
2239 ]
2240
2241 [variablelist Notation
2242 [[`Iterator`] [An iterator type.]]
2243 [[`it1`, `it2`] [Instances of an iterator of type `Iterator`.]]
2244 [[`C`] [A container type whose iterator type is `Iterator`.]]
2245 ]
2246
2247 [heading Expression Semantics]
2248
2249 [table
2250 [[Expression] [Semantics]]
2251 [[`compare_iterators<Iterator>::call(it1, it2)`]
2252 [Returns whether the iterators `it1`
2253 `it2` are to be treated as being
2254 equal.]]
2255 ]
2256
2257 [heading Predefined Specializations]
2258
2259 __spirit__ predefines specializations of this customization point for
2260 several types. The following table lists those types together with the
2261 types returned by the embedded typedef `type`:
2262
2263 [table
2264 [[Template Parameters] [Semantics]]
2265 [[`Iterator`] [The function `call()` returns it1 == it2.]]
2266 [[__unused_type__` const*`][The function `call()` always returns false.]]
2267 ]
2268
2269 [heading When to implement]
2270
2271 The customization point `compare_iterators` needs to be implemented for a specific
2272 iterator type whenever the container this iterator belongs to is to be used as
2273 an attribute in place of a STL container. It is applicable for generators
2274 (__karma__) only. As a rule of thumb: it has to be implemented whenever a certain
2275 iterator type belongs to a container which is to be passed as an attribute
2276 to a generator normally exposing a STL container, `C` and if the container type
2277 does not expose the interface of a STL container (i.e. `is_container<C>::type`
2278 would normally return `mpl::false_`).
2279
2280 [heading Related Attribute Customization Points]
2281
2282 If this customization point is implemented, the following other customization
2283 points might need to be implemented as well.
2284
2285 [table
2286 [[Name] [When to implement]]
2287 [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]]
2288 [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2289 [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2290 [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2291 [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2292 [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2293 [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
2294 ]
2295
2296 [heading Example]
2297
2298 For an example of how to use the customization point `compare_iterators`
2299 please see here: __customize_use_as_container_example__.
2300
2301 [endsect] [/ compare_iterators]
2302
2303 [endsect] [/ iterate]
2304
2305 [/////////////////////////////////////////////////////////////////////////////]
2306 [section:string_traits Extract a C-Style String to Generate Output from a String Type (Karma)]
2307
2308 [section:is_char Determine if a Type is a Character]
2309
2310 [heading is_char]
2311
2312 `is_char` is a metafunction that detects if a given type is a character.
2313
2314 [heading Module Headers]
2315
2316 #include <boost/spirit/home/support/string_traits.hpp>
2317
2318 Also, see __include_structure__.
2319
2320 [note This header file does not need to be included directly by any user
2321 program as it is normally included by other Spirit header files relying
2322 on its content.]
2323
2324 [heading Namespace]
2325
2326 [table
2327 [[Name]]
2328 [[`boost::spirit::traits`]]
2329 ]
2330
2331 [heading Synopsis]
2332
2333 template <typename T>
2334 struct is_char
2335 {
2336 <unspecified>;
2337 };
2338
2339 [heading Template parameters]
2340
2341 [table
2342 [[Parameter] [Description] [Default]]
2343 [[`T`] [The type to detect.] [none]]
2344 ]
2345
2346 [variablelist Notation
2347 [[`T`] [An arbitrary type]]
2348 ]
2349
2350 [heading Expression Semantics]
2351
2352 [table
2353 [[Expression] [Semantics]]
2354 [[`is_char<T>::type`] [`mpl::true_` if T should be treated as a character
2355 type, and `mpl::false_` otherwise. Generally,
2356 any implementation of `is_char` needs to behave as
2357 if if was a __mpl_boolean_constant__.]]
2358 ]
2359
2360 [heading Predefined Specializations]
2361
2362 [table
2363 [[Type] [Semantics]]
2364 [[`T`] [`mpl::false_`]]
2365 [[`T const`] [`is_char<T>`]]
2366 [[`char`] [`mpl::true_`]]
2367 [[`wchar_t`] [`mpl::true_`]]
2368 ]
2369
2370 [heading When to implement]
2371
2372 This customization point needs to be implemented for any strings that use a
2373 type other than `char` or `wchar_t to store character data.
2374
2375 [heading Related Attribute Customization Points]
2376
2377 If this customization point is implemented, the following other customization
2378 points need to be implemented as well.
2379
2380 [table
2381 [[Name] [When to implement]]
2382 [[__customize_is_string__] [Whenever `is_char` is implemented.]]
2383 [[__customize_char_type_of__] [Whenever `is_char` is implemented.]]
2384 ]
2385
2386 [/ TODO: examples ]
2387
2388 [endsect] [/ is_char]
2389
2390 [section:char_type_of Determine the Character Type of a String]
2391
2392 [heading char_type_of]
2393
2394 This customization point is an MPL metafunction which returns the character
2395 type of a given string type. `char_type_of` handles user-defined types such as
2396 std::string, as well as C-style strings.
2397
2398 [heading Module Headers]
2399
2400 #include <boost/spirit/home/support/string_traits.hpp>
2401
2402 Also, see __include_structure__.
2403
2404 [note This header file does not need to be included directly by any user
2405 program as it is normally included by other Spirit header files relying
2406 on its content.]
2407
2408 [heading Namespace]
2409
2410 [table
2411 [[Name]]
2412 [[`boost::spirit::traits`]]
2413 ]
2414
2415 [heading Synopsis]
2416
2417 template <typename T>
2418 struct char_type_of
2419 {
2420 typedef <unspecified> type;
2421 };
2422
2423 [heading Template parameters]
2424
2425 [table
2426 [[Parameter] [Description] [Default]]
2427 [[`T`] [A string type.] [none]]
2428 ]
2429
2430 [variablelist Notation
2431 [[`T`] [An arbitrary type.]]
2432 [[`N`] [An arbitrary integral constant.]]
2433 [[`Char`] [A character type.]]
2434 [[`Traits`] [A character traits type.]]
2435 [[`Allocator`] [A standard allocator type.]]
2436 ]
2437
2438 [heading Expression Semantics]
2439
2440 [table
2441 [[Expression] [Semantics]]
2442 [[`char_type_of<T>::type`] [The character type of the string type `T`.]]
2443 ]
2444
2445 [heading Predefined Specializations]
2446
2447 [table
2448 [[Type] [Semantics]]
2449 [[`T const`] [Returns `char_type_of<T>`.]]
2450 [[`char`] [Returns `char`.]]
2451 [[`wchar_t`] [Returns `wchar_t`.]]
2452 [[`char const*`] [Returns `char const`.]]
2453 [[`wchar_t const*`] [Returns `wchar_t const`.]]
2454 [[`char*`] [Returns `char`.]]
2455 [[`wchar_t*`] [Returns `wchar_t`.]]
2456 [[`char[N]`] [Returns `char`.]]
2457 [[`wchar_t[N]`] [Returns `wchar_t`.]]
2458 [[`char const[N]`] [Returns `char const`.]]
2459 [[`wchar_t const[N]`] [Returns `wchar_t const`.]]
2460 [[`char(&)[N]`] [Returns `char`.]]
2461 [[`wchar_t(&)[N]`] [Returns `wchar_t`.]]
2462 [[`char const(&)[N]`] [Returns `char const`.]]
2463 [[`wchar_t const(&)[N]`] [Returns `wchar_t const`.]]
2464 [[`std::basic_string<Char, Traits, Allocator>`] [Returns `Char`.]]
2465 ]
2466
2467 [heading When to implement]
2468
2469 This customization point needs to be implemented whenever __customize_is_string__
2470 is implemented.
2471
2472 [heading Related Attribute Customization Points]
2473
2474 If this customization point is implemented, the following other customization
2475 points need to be implemented as well.
2476
2477 [table
2478 [[Name] [When to implement]]
2479 [[__customize_is_char__] [For string types whose underlying character type
2480 is not `char` or `wchar_t`, `is_char` must be
2481 implemented.]]
2482 [[__customize_is_string__] [Whenever `char_type_of` is implemented.]]
2483 [[__customize_extract_c_string__] [Whenever `char_type_of` is implemented.]]
2484 ]
2485
2486 [/ TODO: examples ]
2487
2488 [endsect] [/ char_type_of]
2489
2490 [section:extract_c_string Get a C-style String from a String Type]
2491
2492 [heading extract_c_string]
2493
2494 `extract_c_string` returns a pointer to an array of elements of a const character
2495 type. It is invoked through a static method `call`. This customization point is
2496 responsible for handling it's own garbage collecting; the lifetime of the returned
2497 C-string must be no shorter than the lifetime of the string instance passed to
2498 the `call` method.
2499
2500 [heading Module Headers]
2501
2502 #include <boost/spirit/home/support/string_traits.hpp>
2503
2504 Also, see __include_structure__.
2505
2506 [note This header file does not need to be included directly by any user
2507 program as it is normally included by other Spirit header files relying
2508 on its content.]
2509
2510 [heading Namespace]
2511
2512 [table
2513 [[Name]]
2514 [[`boost::spirit::traits`]]
2515 ]
2516
2517 [heading Synopsis]
2518
2519 template <typename String>
2520 struct extract_c_string
2521 {
2522 typedef <unspecified> char_type;
2523
2524 static char_type const* call (String const&);
2525 };
2526
2527 [heading Template parameters]
2528
2529 [table
2530 [[Parameter] [Description] [Default]]
2531 [[`String`] [A string type.] [none]]
2532 ]
2533
2534 [variablelist Notation
2535 [[`T`] [An arbitrary type.]]
2536 [[`Char`] [A character type.]]
2537 [[`Traits`] [A character traits type.]]
2538 [[`Allocator`] [A standard allocator type.]]
2539 [[`str`] [A string instance.]]
2540 ]
2541
2542 [heading Expression Semantics]
2543
2544 [table
2545 [[Expression] [Semantics]]
2546 [[`extract_c_string<T>::char_type`] [The return type of `call`.]]
2547 [[`extract_c_string<T>::call(str)`] [Extract a c-string of type `char_type`
2548 from `str`.]]
2549 ]
2550
2551 [heading Predefined Specializations]
2552
2553 [table
2554 [[Type] [Semantics]]
2555 [[`T`] [`call` takes a parameter of type `T const*`, and returns it without
2556 modification. An overload of `call` takes a parameter of type `T*`
2557 and casts it to `T const*`, returning the result. `char_type` is
2558 `char_type_of<T>::type`.]]
2559 [[`T const`] [`call` takes a parameter `str` of type `T const` and returns
2560 `extract_c_string<T>::call(str)`. `char_type` is
2561 `char_type_of<T>::type`.]]
2562 [[`T&`] [`call` takes a parameter `str` of type `T&` and returns
2563 `extract_c_string<T>::call(str)`. `char_type` is
2564 `char_type_of<T>::type`.]]
2565 [[`T const&`] [`call` takes a parameter `str` of type `T const&` and returns
2566 `extract_c_string<T>::call(str)`. `char_type` is
2567 `char_type_of<T>::type`.]]
2568 [[`std::basic_string<Char, Traits, Allocator>`]
2569 [`call` takes a parameter `str` and returns `str.c_str()`. `char_type` is
2570 `Char`.]]
2571 ]
2572
2573 [heading When to implement]
2574
2575 This customization point needs to be implemented whenever __customize_is_string__
2576 is implemented.
2577
2578 [heading Related Attribute Customization Points]
2579
2580 If this customization point is implemented, the following other customization
2581 points need to be implemented as well.
2582
2583 [table
2584 [[Name] [When to implement]]
2585 [[__customize_is_char__] [For string types whose underlying character type
2586 is not `char` or `wchar_t`, `is_char` must be
2587 implemented.]]
2588 [[__customize_is_string__] [Whenever `extract_c_string` is implemented.]]
2589 [[__customize_char_type_of__] [Whenever `extract_c_string` is implemented.]]
2590 ]
2591
2592 [/ TODO: examples ]
2593
2594 [endsect] [/ string]
2595
2596 [endsect] [/ string_traits]
2597
2598 [/////////////////////////////////////////////////////////////////////////////]
2599 [section:attribute_as Atomically Extract an Attribute Value from a Container (Karma)]
2600
2601 [heading attribute_as]
2602
2603 `attribute_as` atomically extracts an instance of a type from another type.
2604 This customization point is used by the __karma_as__ directive.
2605
2606 [heading Module Headers]
2607
2608 #include <boost/spirit/home/support/attributes_fwd.hpp>
2609
2610 Also, see __include_structure__.
2611
2612 [note This header file does not need to be included directly by any user
2613 program as it is normally included by other Spirit header files relying
2614 on its content.]
2615
2616 [heading Namespace]
2617
2618 [table
2619 [[Name]]
2620 [[`boost::spirit::traits`]]
2621 ]
2622
2623 [heading Synopsis]
2624
2625 template <typename T, typename Attribute, typename Enable = void>
2626 struct attribute_as;
2627
2628 [heading Template parameters]
2629
2630 [table
2631 [[Parameter] [Description] [Default]]
2632 [[`T`] [The type of the attribute natively
2633 exposed by the component the `attribute_as` is
2634 invoked from.] [none]]
2635 [[`Attribute`] [The type of the attribute to be used to
2636 generate output from.] [none]]
2637 [[`Enable`] [Helper template parameter usable to selectively
2638 enable or disable certain specializations
2639 of `attribute_as` utilizing SFINAE (i.e.
2640 `boost::enable_if` or `boost::disable_if`).] [`void`]]
2641 ]
2642
2643 [variablelist Notation
2644 [[`attr`] [An instance of type `Attrib`.]]
2645 ]
2646
2647 [heading Expression Semantics]
2648
2649 [table
2650 [[Expression] [Semantics]]
2651 [[`attribute_as<T, Attribute>::type`] [The result type of the extraction.]]
2652 [[`attribute_as<T, Attribute>::call(attr)`] [Extract and return an instance
2653 of `type`.]]
2654 [[`attribute_as<T, Attribute>::valid_as(attr)`] [Determine, at runtime, if the extraction of
2655 an instance of `type` from `attr`
2656 would cause an error.]]
2657 ]
2658
2659 [heading Predefined Specializations]
2660
2661 __spirit__ predefines specializations of this customization point for
2662 several types. The following table lists those types together with the types
2663 exposed and the corresponding semantics:
2664
2665 [table
2666 [[Template Parameters] [Semantics]]
2667 [[__unused_type__] [The exposed typedef `type` is defined to
2668 __unused_type__. The function `call()` returns
2669 an instance of __unused_type__.]]
2670 ]
2671
2672 [heading When to implement]
2673
2674 This customization point may need to be implemented when using the __karma_as__
2675 directive.
2676
2677 [/ TODO: examples ]
2678
2679 [endsect] [/ attribute_as]
2680
2681 [/////////////////////////////////////////////////////////////////////////////]
2682 [section:auto Create Components from Attributes (Qi and Karma)]
2683
2684 [def __auto_parser_requirements__ [link spirit.qi.reference.auto.additional_requirements Additional Attribute Requirements for Parsers]]
2685 [def __auto_generator_requirements__ [link spirit.karma.reference.auto.additional_requirements Additional Attribute Requirements for Generators]]
2686 [def __auto_parser_example__ [link spirit.qi.reference.auto.example Example for Using the `qi::auto_` Parser]]
2687 [def __auto_generator_example__ [link spirit.karma.reference.auto.example Example for Using the `karma::auto_` Generator]]
2688
2689 __spirit__ supports the creation of a default parser or a default generator from
2690 a given attribute type. It implements a minimal set of predefined mappings from
2691 different attribute types to parsers and generators (for a description of the
2692 predefined mappings see __auto_parser_requirements__ and
2693 __auto_generator_requirements__).
2694 The customization points described in this section (__customize_create_parser__
2695 and __customize_create_generator__) can be specialized to define additional
2696 mappings for custom data types.
2697
2698 [section:create_parser Define a Custom Attribute Mapping for a Parser]
2699
2700 [heading create_parser]
2701
2702 The template `create_parser` is a type used as an customization point. It is
2703 invoked by the /Qi/ __create_parser__ API function in order to create
2704 a custom mapping of the given data type to a parser expression. This
2705 parser expression will be returned from __create_parser__ whenever the
2706 given data type is encountered.
2707
2708 [heading Module Headers]
2709
2710 // forwards to <boost/spirit/home/qi/auto.hpp>
2711 #include <boost/spirit/include/qi_auto.hpp>
2712
2713 Also, see __include_structure__.
2714
2715 [heading Namespace]
2716
2717 [table
2718 [[Name]]
2719 [[`boost::spirit::traits`]]
2720 ]
2721
2722 [heading Synopsis]
2723
2724 template <typename T, typename Enable>
2725 struct create_parser
2726 {
2727 typedef <unspecified> type;
2728 static type const& call();
2729 };
2730
2731 [heading Template parameters]
2732
2733 [table
2734 [[Parameter] [Description] [Default]]
2735 [[`T`] [The type, `T` for which a custom mapping to a
2736 parser should be established.] [none]]
2737 [[`Enable`] [Helper template parameter usable to selectively
2738 enable or disable certain specializations
2739 of `create_generator` utilizing SFINAE (i.e.
2740 `boost::enable_if` or `boost::disable_if`).] [`void`]]
2741 ]
2742
2743 [variablelist Notation
2744 [[`T`] [An arbitrary type.]]
2745 ]
2746
2747 [heading Expression Semantics]
2748
2749 [table
2750 [[Expression] [Semantics]]
2751 [[`create_parser<T>::type`] [Defines the type of the parser
2752 expression returned from `call`.]]
2753 [[`create_parser<T>::call()`] [Returns a parser expression (usually
2754 this is a proto::expression) to be used
2755 as the default parser for the given
2756 type, `T`.]]
2757 ]
2758
2759 [heading Predefined Specializations]
2760
2761 __spirit__ predefines specializations of this customization point for
2762 several types. All predefined mappings are listed here: __auto_parser_requirements__.
2763
2764 [note It is possible to overload the predefined mappings for the listed types
2765 by providing your own specialization of the `create_parser` customization
2766 point for the type to modify.]
2767
2768 [heading When to implement]
2769
2770 The customization point `create_parser` needs to be implemented for a specific
2771 type whenever this type should be usable with the API function __create_parser__
2772 (which includes using the `qi::auto_` parser and the special API functions
2773 based on the automatic creation of the matching parser type).
2774
2775 [heading Example]
2776
2777 For an example of how to use the customization point `create_parser`
2778 please see here: __auto_parser_example__.
2779
2780 [endsect]
2781
2782 [section:create_generator Define a Custom Attribute Mapping for a Generator]
2783
2784 [heading create_generator]
2785
2786 The template `create_generator` is a type used as an customization point. It is
2787 invoked by the /Karma/ __create_generator__ API function in order to create
2788 a custom mapping of the given data type to a generator expression. This
2789 generator expression will be returned from __create_generator__ whenever the
2790 given data type is encountered.
2791
2792 [heading Module Headers]
2793
2794 // forwards to <boost/spirit/home/karma/auto.hpp>
2795 #include <boost/spirit/include/karma_auto.hpp>
2796
2797 Also, see __include_structure__.
2798
2799 [heading Namespace]
2800
2801 [table
2802 [[Name]]
2803 [[`boost::spirit::traits`]]
2804 ]
2805
2806 [heading Synopsis]
2807
2808 template <typename T, typename Enable>
2809 struct create_generator
2810 {
2811 typedef <unspecified> type;
2812 static type const& call();
2813 };
2814
2815 [heading Template parameters]
2816
2817 [table
2818 [[Parameter] [Description] [Default]]
2819 [[`T`] [The type, `T` for which a custom mapping to a
2820 generator should be established.] [none]]
2821 [[`Enable`] [Helper template parameter usable to selectively
2822 enable or disable certain specializations
2823 of `create_generator` utilizing SFINAE (i.e.
2824 `boost::enable_if` or `boost::disable_if`).] [`void`]]
2825 ]
2826
2827 [variablelist Notation
2828 [[`T`] [An arbitrary type.]]
2829 ]
2830
2831 [heading Expression Semantics]
2832
2833 [table
2834 [[Expression] [Semantics]]
2835 [[`create_generator<T>::type`] [Defines the type of the generator
2836 expression returned from `call`.]]
2837 [[`create_generator<T>::call()`] [Returns a generator expression (usually
2838 this is a proto::expression) to be used
2839 as the default generator for the given
2840 type, `T`.]]
2841 ]
2842
2843 [heading Predefined Specializations]
2844
2845 __spirit__ predefines specializations of this customization point for
2846 several types. All predefined mappings are listed here: __auto_generator_requirements__.
2847
2848 [note It is possible to overload the predefined mappings for the listed types
2849 by providing your own specialization of the `create_generator` customization
2850 point for the type to modify.]
2851
2852 [heading When to implement]
2853
2854 The customization point `create_generator` needs to be implemented for a specific
2855 type whenever this type should be usable with the API function __create_generator__
2856 (which includes using the `karma::auto_` generator and the special API functions
2857 based on the automatic creation of the matching generator type).
2858
2859 [heading Example]
2860
2861 For an example of how to use the customization point `create_generator`
2862 please see here: __auto_generator_example__.
2863
2864 [endsect]
2865
2866 [endsect]
2867
2868 [endsect] [/ customize]
2869