1 [/==============================================================================
2 Copyright (C) 2001-2011 Hartmut Kaiser
3 Copyright (C) 2001-2011 Joel de Guzman
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 ===============================================================================/]
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]
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]]
17 [section:customize Customization of Spirit's Attribute Handling]
19 [heading Why do we need Attribute Customization Points]
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.]
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.
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:
45 [import ../../../../boost/spirit/home/support/container.hpp]
47 [customization_container_value_default]
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
54 The following example shows the predefined specialization for __unused_type__:
56 [customization_container_value_unused]
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.
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.
66 The following sections will describe all customization points, together with a
67 description which needs to be specialized for what purpose.
69 [heading The Usage of Customization Points]
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
81 [/////////////////////////////////////////////////////////////////////////////]
82 [section:is_container Determine if a Type Should be Treated as a Container (Qi and Karma)]
84 [heading is_container]
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.
93 #include <boost/spirit/home/support/container.hpp>
95 Also, see __include_structure__.
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
105 [[`boost::spirit::traits`]]
110 template <typename Container, typename Enable>
116 [heading Template parameters]
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`]]
129 [variablelist Notation
130 [[`C`] [A type to be tested whether it needs to be treated
132 [[`T1`, `T2`, ...] [Arbitrary types]]
135 [heading Expression Semantics]
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__..]]
146 [heading Predefined Specializations]
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__):
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_`.]]
168 [heading When to implement]
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:
179 a: A --> Op(a): vector<A>
181 where `Op(a)` stands for any meaningful operation on the component `a`.
183 [heading Related Attribute Customization Points]
185 If this customization point is implemented, the following other customization
186 points might need to be implemented as well.
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].]]
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__.
207 [endsect] [/ is_container]
209 [/////////////////////////////////////////////////////////////////////////////]
210 [section:is_string Determine if a Type Should be Treated as a String (Qi and Karma)]
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.
220 [heading Module Headers]
222 #include <boost/spirit/home/support/string_traits.hpp>
224 Also, see __include_structure__.
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
234 [[`boost::spirit::traits`]]
239 template <typename T>
245 [heading Template parameters]
248 [[Parameter] [Description] [Default]]
249 [[`T`] [The type, `T` which needs to be tested as a string] [none]]
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.]]
260 [heading Expression Semantics]
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__.]]
271 [heading Predefined Specializations]
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_`.]]
292 [heading When to implement]
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.
297 [heading Related Attribute Customization Points]
299 If this customization point is implemented, the following other customization
300 points need to be implemented as well.
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
307 [[__customize_char_type_of__] [Whenever `is_string` is implemented.]]
308 [[__customize_extract_c_string__] [Whenever `is_string` is implemented.]]
313 [endsect] [/ is_string]
316 [/////////////////////////////////////////////////////////////////////////////]
317 [section:handles_container Determine Whether a Component Handles Container Attributes (Qi and Karma)]
319 [heading handles_container]
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.
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.
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.
343 #include <boost/spirit/home/support/handles_container.hpp>
345 Also, see __include_structure__.
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
355 [[`boost::spirit::traits`]]
361 typename Component, typename Attribute, typename Context,
362 typename Iterator, typename Enable>
363 struct handles_container
368 [heading Template parameters]
371 [[Parameter] [Description] [Default]]
372 [[`Component`] [The component type `Component` which needs to
373 be tested whether it handles container attributes
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`]]
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]]
394 [heading Expression Semantics]
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__.]]
407 [heading Predefined Specializations]
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__):
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
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
427 [heading When to implement]
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.
436 [endsect] [/ handles_container]
438 [/////////////////////////////////////////////////////////////////////////////]
439 [section:transform Transform an Attribute to a Different Type (Qi and Karma)]
441 [heading transform_attribute]
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
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__.]
455 [heading Module Headers]
457 #include <boost/spirit/home/support/attributes.hpp>
459 Also, see __include_structure__.
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
469 [[`boost::spirit::traits`]]
474 template <typename Exposed, typename Transformed, typename Domain, typename Enable>
475 struct transform_attribute
477 typedef <unspecified> type;
479 static type pre(Exposed& val);
480 static void post(Exposed& val, type attr); // Qi only
481 static void fail(Exposed&); // Qi only
484 [heading Template parameters]
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`]]
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`.]]
514 [heading Expression Semantics]
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
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/.]]
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.]]
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.]]
553 [heading Predefined Specializations]
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
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
582 [[`Attrib const`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`,
583 `pre()` returns it's argument, `post()` is not
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.]]
591 [heading When to implement]
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
603 [endsect] [/ transform]
605 [/////////////////////////////////////////////////////////////////////////////]
606 [/ section:optional Handling of Optional Attributes (Qi and Karma)]
608 [/ optional_attribute]
610 [/ endsect] [/ optional]
612 [/////////////////////////////////////////////////////////////////////////////]
613 [section:assign_to Store a Parsed Attribute Value (Qi)]
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.
621 [section:assign_to_attribute_from_iterators Store an Attribute after a Parser Produced a Pair of Iterators (Qi)]
623 [heading assign_to_attribute_from_iterators]
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.
632 [heading Module Headers]
634 #include <boost/spirit/home/qi/detail/assign_to.hpp>
636 Also, see __include_structure__.
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
646 [[`boost::spirit::traits`]]
651 template <typename Attrib, typename Iterator, typename Enable>
652 struct assign_to_attribute_from_iterators
654 static void call(Iterator const& first, Iterator const& last, Attrib& attr);
657 [heading Template parameters]
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`]]
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.]]
680 [heading Expression Semantics]
683 [[Expression] [Semantics]]
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`.]]
690 [heading Predefined Specializations]
693 [[Template Parameters] [Semantics]]
694 [[`Attrib`, `Iterator`] [Execute an assignment `attr = Attrib(begin, end)`.]]
695 [[__unused_type__, `T`] [Do nothing.]]
698 [heading When to implement]
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.
707 [endsect] [/ assign_to_attribute_from_iterators]
709 [section:assign_to_attribute_from_value Store an Attribute Value after a Parser Produced a Value (Qi)]
711 [heading assign_to_attribute_from_value]
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).
719 [heading Module Headers]
721 #include <boost/spirit/home/qi/detail/assign_to.hpp>
723 Also, see __include_structure__.
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
733 [[`boost::spirit::traits`]]
738 template <typename Attrib, typename T, typename Enable>
739 struct assign_to_attribute_from_value
741 static void call(T const& val, Attrib& attr);
744 [heading Template parameters]
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`]]
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
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`.]]
771 [heading Expression Semantics]
774 [[Expression] [Semantics]]
776 ``assign_to_attribute_from_value<Attrib, T>::call(t, attr)``]
777 [Copy (assign) the value `t` to the attribute `attr`.]]
780 [heading Predefined Specializations]
783 [[Template Parameters] [Semantics]]
784 [[`Attrib`, `T`] [Assign the argument `t` to `attr`.]]
785 [[__unused_type__, `T`] [Do nothing.]]
788 [heading When to implement]
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.
797 [endsect] [/ assign_to_attribute_from_value]
799 [section:assign_to_container_from_value Store an Attribute Value into a Container after a Parser Produced a Value (Qi)]
801 [heading assign_to_container_from_value]
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).
809 [heading Module Headers]
811 #include <boost/spirit/home/qi/detail/assign_to.hpp>
813 Also, see __include_structure__.
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
823 [[`boost::spirit::traits`]]
828 template <typename Attrib, typename T, typename Enable>
829 struct assign_to_container_from_value
831 static void call(T const& val, Attrib& attr);
834 [heading Template parameters]
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`]]
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
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`.]]
861 [heading Expression Semantics]
864 [[Expression] [Semantics]]
866 ``assign_to_container_from_value<Attrib, T>::call(t, attr)``]
867 [Add the value `t` to the container attribute `attr`.]]
870 [heading Predefined Specializations]
873 [[Template Parameters] [Semantics]]
874 [[`Attrib`, `T`] [Add the argument `t` to `attr`.]]
875 [[__unused_type__, `T`] [Do nothing.]]
878 [heading When to implement]
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.
887 [endsect] [/ assign_to_container_from_value]
889 [endsect] [/ assign_to]
891 [/////////////////////////////////////////////////////////////////////////////]
892 [section:store_value Store Parsed Attribute Values into a Container (Qi)]
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.
900 [section:container_value Determine the Type to be Stored in a Container (Qi)]
902 [heading container_value]
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.
909 [heading Module Headers]
911 #include <boost/spirit/home/support/container.hpp>
913 Also, see __include_structure__.
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
923 [[`boost::spirit::traits`]]
928 template <typename Container, typename Enable>
929 struct container_value
931 typedef <unspecified> type;
934 [heading Template parameters]
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`]]
947 [[`C`] [A type to be tested whether it needs to be treated
949 [[`T1`, `T2`, ...] [Arbitrary types]]
952 [heading Expression Semantics]
955 [[Expression] [Semantics]]
956 [[`container_value<C>::type`] [Metafunction that evaluates to the type
957 to be stored in a given container type,
961 [heading Predefined Specializations]
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:
968 [[Template Parameters] [Semantics]]
969 [[`C`] [The non-const `value_type` of the given container
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__.]]
980 [heading When to implement]
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:
990 a: A --> Op(a): vector<A>
992 where `Op(a)` stands for any meaningful operation on the component `a`.
994 [heading Related Attribute Customization Points]
996 If this customization point is implemented, the following other customization
997 points might need to be implemented as well.
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].]]
1007 Here is an example showing the default implementation of the
1008 __customize_container_value__ customization point provided by the library:
1010 [customization_container_value_default]
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
1017 The following example shows the predefined specialization for __unused_type__:
1019 [customization_container_value_unused]
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.
1026 [endsect] [/ container_value]
1028 [section:push_back Store a Parsed Attribute Value into a Container (Qi)]
1030 [heading push_back_container]
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
1037 [heading Module Headers]
1039 #include <boost/spirit/home/support/container.hpp>
1041 Also, see __include_structure__.
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
1051 [[`boost::spirit::traits`]]
1056 template <typename Container, typename Attrib, typename Enable>
1057 struct push_back_container
1059 static bool call(Container& c, Attrib const& val);
1062 [heading Template parameters]
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`]]
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]]
1087 [heading Expression Semantics]
1090 [[Expression] [Semantics]]
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.]]
1101 [heading Predefined Specializations]
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:
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.]]
1131 [heading When to Implement]
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
1142 a: A --> Op(a): vector<A>
1144 where `Op(a)` stands for any meaningful operation on the component `a`.
1146 [heading Related Attribute Customization Points]
1148 If this customization point is implemented, the following other customization
1149 points might need to be implemented as well.
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].]]
1159 Here is an example showing the default implementation of the
1160 __customize_container_value__ customization point provided by the library:
1162 [customization_push_back_default]
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
1169 The following example shows the predefined specialization for __unused_type__:
1171 [customization_push_back_unused]
1173 which defines an empty member function `call()`.
1177 [endsect] [/ push_back]
1179 [endsect] [/ store_value]
1181 [/////////////////////////////////////////////////////////////////////////////]
1182 [section:clear_value Re-Initialize an Attribute Value before Parsing (Qi)]
1184 [heading clear_value]
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.
1193 [heading Module Headers]
1195 #include <boost/spirit/home/support/attributes.hpp>
1197 Also, see __include_structure__.
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
1207 [[`boost::spirit::traits`]]
1212 template <typename Attrib, typename Enable>
1215 static void call(Attrib& val);
1218 [heading Template parameters]
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`]]
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]]
1236 [heading Expression Semantics]
1239 [[Expression] [Semantics]]
1241 ``clear_value<Attrib>::call(Attrib& attr)``] [Re-initialize the instance referred to by
1242 `attr` in the most efficient way.]]
1245 [heading Predefined Specializations]
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:
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
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.]]
1267 [heading When to Implement]
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()`.
1277 [endsect] [/ clear_value]
1279 [/////////////////////////////////////////////////////////////////////////////]
1280 [section:extract_from Extract an Attribute Value to Generate Output (Karma)]
1282 [heading extract_from]
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.
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
1294 [heading Module Headers]
1296 #include <boost/spirit/home/karma/detail/extract_from.hpp>
1298 Also, see __include_structure__.
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
1308 [[`boost::spirit::traits`]]
1313 template <typename Exposed, typename Attrib, typename Enable>
1314 struct extract_from_attribute
1316 typedef <unspecified> type;
1318 template <typename Context>
1319 static type call(Attrib const& attr, Context& context);
1322 [heading Template parameters]
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
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`.]]
1346 [heading Expression Semantics]
1349 [[Expression] [Semantics]]
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.]]
1356 [heading Predefined Specializations]
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:
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__.]]
1381 [heading When to implement]
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.
1390 [endsect] [/ extract_from]
1392 [/////////////////////////////////////////////////////////////////////////////]
1393 [section:extract_from_container Extract From a Container Attribute Value to Generate Output (Karma)]
1395 [heading extract_from_container]
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.
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
1407 [heading Module Headers]
1409 #include <boost/spirit/home/karma/detail/extract_from.hpp>
1411 Also, see __include_structure__.
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
1421 [[`boost::spirit::traits`]]
1426 template <typename Exposed, typename Attrib, typename Enable>
1427 struct extract_from_container
1429 typedef <unspecified> type;
1431 template <typename Context>
1432 static type call(Attrib const& attr, Context& context);
1435 [heading Template parameters]
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
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`.]]
1461 [heading Expression Semantics]
1464 [[Expression] [Semantics]]
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
1472 [heading Predefined Specializations]
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:
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__.]]
1488 [heading When to implement]
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.
1499 [endsect] [/ extract_from]
1501 [/////////////////////////////////////////////////////////////////////////////]
1502 [section:iterate Extract Attribute Values to Generate Output from a Container (Karma)]
1504 [section:container_iterator Determine the Type of the Iterator of a Container]
1506 [heading container_iterator]
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.
1514 [heading Module Headers]
1516 #include <boost/spirit/home/support/container.hpp>
1518 Also, see __include_structure__.
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
1528 [[`boost::spirit::traits`]]
1533 template <typename Container, typename Enable>
1534 struct container_iterator
1536 typedef <unspecified> type;
1539 [heading Template parameters]
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`]]
1551 [variablelist Notation
1552 [[`C`] [A container type the iterator type needs to be evaluated for.]]
1555 [heading Expression Semantics]
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`.]]
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
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__).
1577 [heading Predefined Specializations]
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`:
1584 [[Template Parameters] [Semantics]]
1585 [[`C`] [Returns `C::iterator`.]]
1586 [[`C const`] [Returns `C::const_iterator`.]]
1587 [[__unused_type__] [Returns __unused_type__` const*`.]]
1590 [heading When to implement]
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_`).
1600 [heading Related Attribute Customization Points]
1602 If this customization point is implemented, the following other customization
1603 points might need to be implemented as well.
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].]]
1618 Here are the header files needed to make the example code below compile:
1620 [customize_karma_embedded_container_includes]
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
1626 [customize_karma_embedded_container_data]
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
1639 [customize_karma_embedded_container_traits]
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__
1645 [customize_karma_embedded_container]
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.
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__.
1655 [endsect] [/ container_iterator]
1658 [section:begin_container Get the Iterator pointing to the Begin of a Container Attribute]
1660 [heading begin_container]
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.
1668 [heading Module Headers]
1670 #include <boost/spirit/home/support/container.hpp>
1672 Also, see __include_structure__.
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
1682 [[`boost::spirit::traits`]]
1687 template <typename Container, typename Enable>
1688 struct begin_container
1690 static typename container_iterator<Container>::type
1694 [heading Template parameters]
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`]]
1706 [variablelist Notation
1707 [[`C`] [A container type the begin iterator needs to be returned for.]]
1708 [[`c`] [An instance of a container, `C`.]]
1711 [heading Expression Semantics]
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__.]]
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
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__).
1736 [heading Predefined Specializations]
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`:
1743 [[Template Parameters] [Semantics]]
1744 [[`C`] [Returns `c.begin()`.]]
1745 [[`C const`] [Returns `c.begin()`.]]
1746 [[__unused_type__] [Returns `&unused`.]]
1749 [heading When to implement]
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_`).
1759 [heading Related Attribute Customization Points]
1761 If this customization point is implemented, the following other customization
1762 points might need to be implemented as well.
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].]]
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__.
1781 [endsect] [/ begin_container]
1784 [section:end_container Get the Iterator pointing to the End of a Container Attribute]
1786 [heading end_container]
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.
1794 [heading Module Headers]
1796 #include <boost/spirit/home/support/container.hpp>
1798 Also, see __include_structure__.
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
1808 [[`boost::spirit::traits`]]
1813 template <typename Container, typename Enable>
1814 struct end_container
1816 static typename container_iterator<Container>::type
1820 [heading Template parameters]
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`]]
1832 [variablelist Notation
1833 [[`C`] [A container type the end iterator needs to be returned for.]]
1834 [[`c`] [An instance of a container, `C`.]]
1837 [heading Expression Semantics]
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__.]]
1850 [heading Predefined Specializations]
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`:
1857 [[Template Parameters] [Semantics]]
1858 [[`C`] [Returns `c.end()`.]]
1859 [[`C const`] [Returns `c.end()`.]]
1860 [[__unused_type__] [Returns `&unused`.]]
1863 [heading When to implement]
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_`).
1873 [heading Related Attribute Customization Points]
1875 If this customization point is implemented, the following other customization
1876 points might need to be implemented as well.
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].]]
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__.
1895 [endsect] [/ end_container]
1898 [section:next_iterator Increment the Iterator pointing into a Container Attribute]
1900 [heading next_iterator]
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.
1908 [heading Module Headers]
1910 #include <boost/spirit/home/support/container.hpp>
1912 Also, see __include_structure__.
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
1922 [[`boost::spirit::traits`]]
1927 template <typename Iterator, typename Enable>
1928 struct next_iterator
1930 static void call(Iterator& it);
1933 [heading Template parameters]
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`]]
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`.]]
1952 [heading Expression Semantics]
1955 [[Expression] [Semantics]]
1956 [[`next_iterator<Iterator>::call(it)`] [Increment the iterator pointing so that
1957 it is pointing to the next element.]]
1960 [heading Predefined Specializations]
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`:
1967 [[Template Parameters] [Semantics]]
1968 [[`Iterator`] [Executes `++it`.]]
1969 [[__unused_type__` const*`][Does nothing.]]
1972 [heading When to implement]
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_`).
1983 [heading Related Attribute Customization Points]
1985 If this customization point is implemented, the following other customization
1986 points might need to be implemented as well.
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].]]
2001 Here are the header files needed to make the example code below compile:
2003 [customize_karma_use_as_container_includes]
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
2009 [customize_karma_use_as_container_data]
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.
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__.
2025 [customize_karma_use_as_container_traits]
2026 [customize_karma_use_as_container_iterator_traits]
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:
2031 [customize_karma_use_as_container]
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.
2037 [endsect] [/ next_iterator]
2040 [section:deref_iterator Dereference the Iterator pointing into a Container Attribute]
2042 [heading deref_iterator]
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.
2050 [heading Module Headers]
2052 #include <boost/spirit/home/support/container.hpp>
2054 Also, see __include_structure__.
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
2064 [[`boost::spirit::traits`]]
2069 template <typename Iterator, typename Enable>
2070 struct deref_iterator
2072 typedef <unspecified> type;
2073 static type call(Iterator& it);
2076 [heading Template parameters]
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`]]
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`.]]
2095 [heading Expression Semantics]
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`.]]
2107 [heading Predefined Specializations]
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`:
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`.]]
2122 [heading When to implement]
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_`).
2133 [heading Related Attribute Customization Points]
2135 If this customization point is implemented, the following other customization
2136 points might need to be implemented as well.
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].]]
2151 Here are the header files needed to make the example code below compile:
2153 [customize_karma_counter_includes]
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
2159 [customize_karma_counter_data]
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.
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__.
2173 [customize_karma_counter_traits]
2174 [customize_karma_counter_iterator_traits]
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:
2179 [customize_karma_counter]
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.
2185 For other examples of how to use the customization point `deref_iterator`
2186 please see here: __customize_use_as_container_example__.
2188 [endsect] [/ deref_iterator]
2191 [section:compare_iterators Compare two Iterator pointing into a Container Attribute for Equality]
2193 [heading compare_iterators]
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.
2203 [heading Module Headers]
2205 #include <boost/spirit/home/support/container.hpp>
2207 Also, see __include_structure__.
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
2217 [[`boost::spirit::traits`]]
2222 template <typename Iterator, typename Enable>
2223 struct compare_iterators
2225 static bool call(Iterator const& it1, Iterator const& it2);
2228 [heading Template parameters]
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`]]
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`.]]
2247 [heading Expression Semantics]
2250 [[Expression] [Semantics]]
2251 [[`compare_iterators<Iterator>::call(it1, it2)`]
2252 [Returns whether the iterators `it1`
2253 `it2` are to be treated as being
2257 [heading Predefined Specializations]
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`:
2264 [[Template Parameters] [Semantics]]
2265 [[`Iterator`] [The function `call()` returns it1 == it2.]]
2266 [[__unused_type__` const*`][The function `call()` always returns false.]]
2269 [heading When to implement]
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_`).
2280 [heading Related Attribute Customization Points]
2282 If this customization point is implemented, the following other customization
2283 points might need to be implemented as well.
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].]]
2298 For an example of how to use the customization point `compare_iterators`
2299 please see here: __customize_use_as_container_example__.
2301 [endsect] [/ compare_iterators]
2303 [endsect] [/ iterate]
2305 [/////////////////////////////////////////////////////////////////////////////]
2306 [section:string_traits Extract a C-Style String to Generate Output from a String Type (Karma)]
2308 [section:is_char Determine if a Type is a Character]
2312 `is_char` is a metafunction that detects if a given type is a character.
2314 [heading Module Headers]
2316 #include <boost/spirit/home/support/string_traits.hpp>
2318 Also, see __include_structure__.
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
2328 [[`boost::spirit::traits`]]
2333 template <typename T>
2339 [heading Template parameters]
2342 [[Parameter] [Description] [Default]]
2343 [[`T`] [The type to detect.] [none]]
2346 [variablelist Notation
2347 [[`T`] [An arbitrary type]]
2350 [heading Expression Semantics]
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__.]]
2360 [heading Predefined Specializations]
2363 [[Type] [Semantics]]
2364 [[`T`] [`mpl::false_`]]
2365 [[`T const`] [`is_char<T>`]]
2366 [[`char`] [`mpl::true_`]]
2367 [[`wchar_t`] [`mpl::true_`]]
2370 [heading When to implement]
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.
2375 [heading Related Attribute Customization Points]
2377 If this customization point is implemented, the following other customization
2378 points need to be implemented as well.
2381 [[Name] [When to implement]]
2382 [[__customize_is_string__] [Whenever `is_char` is implemented.]]
2383 [[__customize_char_type_of__] [Whenever `is_char` is implemented.]]
2388 [endsect] [/ is_char]
2390 [section:char_type_of Determine the Character Type of a String]
2392 [heading char_type_of]
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.
2398 [heading Module Headers]
2400 #include <boost/spirit/home/support/string_traits.hpp>
2402 Also, see __include_structure__.
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
2412 [[`boost::spirit::traits`]]
2417 template <typename T>
2420 typedef <unspecified> type;
2423 [heading Template parameters]
2426 [[Parameter] [Description] [Default]]
2427 [[`T`] [A string type.] [none]]
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.]]
2438 [heading Expression Semantics]
2441 [[Expression] [Semantics]]
2442 [[`char_type_of<T>::type`] [The character type of the string type `T`.]]
2445 [heading Predefined Specializations]
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`.]]
2467 [heading When to implement]
2469 This customization point needs to be implemented whenever __customize_is_string__
2472 [heading Related Attribute Customization Points]
2474 If this customization point is implemented, the following other customization
2475 points need to be implemented as well.
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
2482 [[__customize_is_string__] [Whenever `char_type_of` is implemented.]]
2483 [[__customize_extract_c_string__] [Whenever `char_type_of` is implemented.]]
2488 [endsect] [/ char_type_of]
2490 [section:extract_c_string Get a C-style String from a String Type]
2492 [heading extract_c_string]
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
2500 [heading Module Headers]
2502 #include <boost/spirit/home/support/string_traits.hpp>
2504 Also, see __include_structure__.
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
2514 [[`boost::spirit::traits`]]
2519 template <typename String>
2520 struct extract_c_string
2522 typedef <unspecified> char_type;
2524 static char_type const* call (String const&);
2527 [heading Template parameters]
2530 [[Parameter] [Description] [Default]]
2531 [[`String`] [A string type.] [none]]
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.]]
2542 [heading Expression Semantics]
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`
2551 [heading Predefined Specializations]
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
2573 [heading When to implement]
2575 This customization point needs to be implemented whenever __customize_is_string__
2578 [heading Related Attribute Customization Points]
2580 If this customization point is implemented, the following other customization
2581 points need to be implemented as well.
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
2588 [[__customize_is_string__] [Whenever `extract_c_string` is implemented.]]
2589 [[__customize_char_type_of__] [Whenever `extract_c_string` is implemented.]]
2594 [endsect] [/ string]
2596 [endsect] [/ string_traits]
2598 [/////////////////////////////////////////////////////////////////////////////]
2599 [section:attribute_as Atomically Extract an Attribute Value from a Container (Karma)]
2601 [heading attribute_as]
2603 `attribute_as` atomically extracts an instance of a type from another type.
2604 This customization point is used by the __karma_as__ directive.
2606 [heading Module Headers]
2608 #include <boost/spirit/home/support/attributes_fwd.hpp>
2610 Also, see __include_structure__.
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
2620 [[`boost::spirit::traits`]]
2625 template <typename T, typename Attribute, typename Enable = void>
2626 struct attribute_as;
2628 [heading Template parameters]
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`]]
2643 [variablelist Notation
2644 [[`attr`] [An instance of type `Attrib`.]]
2647 [heading Expression Semantics]
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
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.]]
2659 [heading Predefined Specializations]
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:
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__.]]
2672 [heading When to implement]
2674 This customization point may need to be implemented when using the __karma_as__
2679 [endsect] [/ attribute_as]
2681 [/////////////////////////////////////////////////////////////////////////////]
2682 [section:auto Create Components from Attributes (Qi and Karma)]
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]]
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.
2698 [section:create_parser Define a Custom Attribute Mapping for a Parser]
2700 [heading create_parser]
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.
2708 [heading Module Headers]
2710 // forwards to <boost/spirit/home/qi/auto.hpp>
2711 #include <boost/spirit/include/qi_auto.hpp>
2713 Also, see __include_structure__.
2719 [[`boost::spirit::traits`]]
2724 template <typename T, typename Enable>
2725 struct create_parser
2727 typedef <unspecified> type;
2728 static type const& call();
2731 [heading Template parameters]
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`]]
2743 [variablelist Notation
2744 [[`T`] [An arbitrary type.]]
2747 [heading Expression Semantics]
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
2759 [heading Predefined Specializations]
2761 __spirit__ predefines specializations of this customization point for
2762 several types. All predefined mappings are listed here: __auto_parser_requirements__.
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.]
2768 [heading When to implement]
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).
2777 For an example of how to use the customization point `create_parser`
2778 please see here: __auto_parser_example__.
2782 [section:create_generator Define a Custom Attribute Mapping for a Generator]
2784 [heading create_generator]
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.
2792 [heading Module Headers]
2794 // forwards to <boost/spirit/home/karma/auto.hpp>
2795 #include <boost/spirit/include/karma_auto.hpp>
2797 Also, see __include_structure__.
2803 [[`boost::spirit::traits`]]
2808 template <typename T, typename Enable>
2809 struct create_generator
2811 typedef <unspecified> type;
2812 static type const& call();
2815 [heading Template parameters]
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`]]
2827 [variablelist Notation
2828 [[`T`] [An arbitrary type.]]
2831 [heading Expression Semantics]
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
2843 [heading Predefined Specializations]
2845 __spirit__ predefines specializations of this customization point for
2846 several types. All predefined mappings are listed here: __auto_generator_requirements__.
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.]
2852 [heading When to implement]
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).
2861 For an example of how to use the customization point `create_generator`
2862 please see here: __auto_generator_example__.
2868 [endsect] [/ customize]