| [/============================================================================== |
| Copyright (C) 2001-2011 Hartmut Kaiser |
| Copyright (C) 2001-2011 Joel de Guzman |
| |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| ===============================================================================/] |
| |
| [import ../example/karma/customize_embedded_container.cpp] [/ this pulls in the embedded_container example] |
| [import ../example/karma/customize_counter.cpp] [/ this pulls in the counter example] |
| [import ../example/karma/customize_use_as_container.cpp] [/ this pulls in the use_as_container example] |
| |
| [def __customize_embedded_container_example__ [link spirit.advanced.customize.iterate.container_iterator.example embedded_container_example]] |
| [def __customize_counter_example__ [link spirit.advanced.customize.iterate.deref_iterator.example counter_example]] |
| [def __customize_use_as_container_example__ [link spirit.advanced.customize.iterate.next_iterator.example use_as_container]] |
| |
| [section:customize Customization of Spirit's Attribute Handling] |
| |
| [heading Why do we need Attribute Customization Points] |
| |
| [important Before you read on please be aware that the interfaces described in |
| this section are not finalized and may change in the future without |
| attempting to be backwards compatible. We document the customization |
| point interfaces anyways as we think they are important. |
| Understanding customization points helps understanding Spirit. |
| Additionally they prove to be powerful tools enabling full |
| integration of the user's data structures with /Qi's/ parsers and |
| /Karma's/ generators.] |
| |
| __spirit__ has been written with extensibility in mind. It provides many |
| different attribute customization points allowing to integrate custom data |
| types with the process of parsing in __qi__ or output generation with |
| __karma__. All attribute customization points are exposed using a similar |
| technique: full or partial template specialization. __spirit__ generally |
| implements the main template, providing a default implementation. You as the |
| user have to provide a partial or full specialization of this template for the |
| data types you want to integrate with the library. In fact, the library uses |
| these customization points itself for instance to handle the magic of the |
| __unused_type__ attribute type. |
| |
| Here is an example showing the __customize_container_value__ customization point |
| used by different parsers (such as __qi_kleene__, __qi_plus__, etc.) to find |
| the attribute type to be stored in a supplied STL container: |
| |
| [import ../../../../boost/spirit/home/support/container.hpp] |
| |
| [customization_container_value_default] |
| |
| This template is instantiated by the library at the appropriate places while |
| using the supplied container type as the template argument. The embedded `type` |
| is used as the attribute type while parsing the elements to be store in that |
| container. |
| |
| The following example shows the predefined specialization for __unused_type__: |
| |
| [customization_container_value_unused] |
| |
| which defines its embedded `type` to be __unused_type__ as well, this way |
| propagating the 'don't care' attribute status to the embedded parser. |
| |
| All attribute customization points follow the same scheme. The last template |
| parameter is always `typename Enable = void` allowing to apply SFINAE for |
| fine grained control over the template specialization process. But most of the |
| time you can safely forget about its existence. |
| |
| The following sections will describe all customization points, together with a |
| description which needs to be specialized for what purpose. |
| |
| [heading The Usage of Customization Points] |
| |
| The different customizations points are used by different parts of the library. |
| Part of the customizations points are used by both, __qi__ and __karma__, |
| whereas others are specialized to be applied for one of the sub-libraries only. |
| We will explain when a specific customization point needs to be implemented and, |
| equally important, which customization points need to be implemented at the |
| same time. Often it is not sufficient to provide a specialization for one |
| single customization point only, in this case you as the user have to provide |
| all necessary customizations for your data type you want to integrate with the |
| library. |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:is_container Determine if a Type Should be Treated as a Container (Qi and Karma)] |
| |
| [heading is_container] |
| |
| The template `is_container` is a template meta-function used as an attribute |
| customization point. It is invoked by the /Qi/ __qi_sequence__ (`>>`) and |
| /Karma/ __karma_sequence__ operators in order to determine whether a supplied |
| attribute can potentially be treated as a container. |
| |
| [heading Header] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Container, typename Enable> |
| struct is_container |
| { |
| <unspecified>; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Container`] [The type, `Container` which needs to |
| be tested whether it has to be treated |
| as a container] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `is_container` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`C`] [A type to be tested whether it needs to be treated |
| as a container.]] |
| [[`T1`, `T2`, ...] [Arbitrary types]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`is_container<C>::type`] [Result of the metafunction that evaluates to |
| `mpl::true_` if a given type, `C`, is to be |
| treated as a container, `mpl::false_` otherwise |
| Generally, any implementation of `is_container` |
| needs to behave as if if was a __mpl_boolean_constant__..]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| conditions for which the corresponding specializations will evaluate to |
| `mpl::true_` (see __mpl_boolean_constant__): |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`T`] [Returns `mpl::true_` if `T` has the following |
| embedded types defined: `value_type`, |
| `iterator`, `size_type`, and`reference`. |
| Otherwise it will return `mpl::false_`.]] |
| [[`boost::optional<T>`] [Returns `is_container<T>::type`]] |
| [[`boost::variant<T1, T2, ...>`] |
| [Returns `mpl::true_` if at least one of the |
| `is_container<TN>::type` returns `mpl::true_` |
| (where `TN` is `T1`, `T2`, ...). |
| Otherwise it will return `mpl::false_`.]] |
| [[__unused_type__] [Returns `mpl::false_`.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `is_container` needs to be implemented for a specific |
| type whenever this type is to be used as an attribute in place of a STL |
| container. It is applicable for parsers (__qi__) and generators (__karma__). |
| As a rule of thumb: it has to be implemented whenever a certain type |
| is to be passed as an attribute to a parser or a generator normally exposing a |
| STL container, `C` and if the type does not expose the interface of a STL container |
| (i.e. `is_container<C>::type` would normally return `mpl::false_`). These |
| components have an attribute propagation rule in the form: |
| |
| a: A --> Op(a): vector<A> |
| |
| where `Op(a)` stands for any meaningful operation on the component `a`. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_container_value__] [Needs to be implemented whenever `is_container` is implemented.]] |
| [[__customize_push_back_container__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| For examples of how to use the customization point `is_container` please |
| see here: __customize_embedded_container_example__, |
| __customize_use_as_container_example__, and __customize_counter_example__. |
| |
| [endsect] [/ is_container] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:is_string Determine if a Type Should be Treated as a String (Qi and Karma)] |
| |
| [heading is_string] |
| |
| The `is_string` customization point is a template meta-function. It is used by |
| /Qi/ [qi_lit_string String Literals] (`lit(str)`), /Qi/ [qi_lit_char Character Literals] |
| (`lit(c)`), /Karma/ [karma_lit_string String Literals] (`lit(str)`), /Karma/ [karma_lit_char Character Literals] |
| (`lit(c)`) and other Spirit components. It determines whether a supplied type |
| can be treated as a string. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/string_traits.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename T> |
| struct is_string |
| { |
| <unspecified>; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`T`] [The type, `T` which needs to be tested as a string] [none]] |
| ] |
| |
| [variablelist Notation |
| [[`T`] [An arbitrary type.]] |
| [[`N`] [An arbitrary integral constant.]] |
| [[`Char`] [A character type.]] |
| [[`Traits`] [A character traits type.]] |
| [[`Allocator`] [A standard allocator type.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`is_string<T>::type`] [Result of the metafunction that evalutes to mpl::true_ |
| if a given type, `T`, is to be treated as a string and |
| mpl::false_ otherwise. Generally, |
| any implementation of `is_string` needs to behave as |
| if if was a __mpl_boolean_constant__.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Type] [Semantics]] |
| [[`T`] [Returns `mpl::false_`.]] |
| [[`T const`] [Returns `is_string<T>`.]] |
| [[`char const*`] [Returns `mpl::true_`.]] |
| [[`wchar_t const*`] [Returns `mpl::true_`.]] |
| [[`char*`] [Returns `mpl::true_`.]] |
| [[`wchar_t*`] [Returns `mpl::true_`.]] |
| [[`char[N]`] [Returns `mpl::true_`.]] |
| [[`wchar_t[N]`] [Returns `mpl::true_`.]] |
| [[`char const[N]`] [Returns `mpl::true_`.]] |
| [[`wchar_t const[N]`] [Returns `mpl::true_`.]] |
| [[`char(&)[N]`] [Returns `mpl::true_`.]] |
| [[`wchar_t(&)[N]`] [Returns `mpl::true_`.]] |
| [[`char const(&)[N]`] [Returns `mpl::true_`.]] |
| [[`wchar_t const(&)[N]`] [Returns `mpl::true_`.]] |
| [[`std::basic_string<Char, Traits, Allocator>`] [Returns `mpl::true_`.]] |
| ] |
| |
| [heading When to implement] |
| |
| This customization point needs to be implemented to use user-defined string classes |
| that do not correspond to std::string syntax and semantics. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_char__] [For string types whose underlying character type |
| is not `char` or `wchar_t`, `is_char` must be |
| implemented.]] |
| [[__customize_char_type_of__] [Whenever `is_string` is implemented.]] |
| [[__customize_extract_c_string__] [Whenever `is_string` is implemented.]] |
| ] |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ is_string] |
| |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:handles_container Determine Whether a Component Handles Container Attributes (Qi and Karma)] |
| |
| [heading handles_container] |
| |
| The template `handles_container` is a template meta-function used as an attribute |
| customization point. It is invoked by the /Qi/ __qi_sequence__ (`>>`) and |
| /Karma/ __karma_sequence__ operators in order to determine whether a sequence |
| element (component) handles container attributes directly. This customization |
| point is invoked for container attributes only, and only if the sequence is |
| compatible with the supplied container attribute. |
| |
| If a component, which is part of a sequence is able to handle a container |
| attribute directly, the sequence passes the attribute to the component without |
| any additional action. In __qi__ the component uses the attribute to directly |
| store all matched attributes. In __karma__ the generator component extracts |
| the attributes needed for output generation directly from this attribute. |
| |
| If a component, which is part of a sequence is not able to handle container |
| attributes, in __qi__ the sequence passes a new instance of the container |
| attributes' `value_type` to the parser component, inserting the result into |
| the attribute on behalf of the parser component. In __karma__ the sequence |
| extracts the next container element on behalf of the generator component and |
| passing it the extracted value. |
| |
| [heading Header] |
| |
| #include <boost/spirit/home/support/handles_container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template < |
| typename Component, typename Attribute, typename Context, |
| typename Iterator, typename Enable> |
| struct handles_container |
| { |
| <unspecified>; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Component`] [The component type `Component` which needs to |
| be tested whether it handles container attributes |
| directly.] [none]] |
| [[`Attribute`] [The attribute type `Attribute` as passed to the |
| sequence operator.] [none]] |
| [[`Context`] [This is the type of the current component execution |
| context.] [`unused_type`]] |
| [[`Iterator`] [The type, `Iterator` is the type of the iterators |
| used to invoke the component.] [`unused_type`]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `is_container` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Component`] [A component type to be tested whether it directly handles |
| container attributes in the context of sequences.]] |
| [[`Attribute`] [A container attribute type as passed to the sequence.]] |
| [[`T1`, `T2`, ...] [Arbitrary types]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`handles_container<Component, Attribute>::type`] |
| [Result of the metafunction that evaluates to |
| `mpl::true_` if a given component type `Component`, |
| handles container attributes directly, |
| `mpl::false_` otherwise. Generally, |
| any implementation of `handles_container` needs to |
| behave as if if was a __mpl_boolean_constant__.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| conditions for which the corresponding specializations will evaluate to |
| `mpl::true_` (see __mpl_boolean_constant__): |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Component`, `Attribute`] [Always returns `mpl::false_` (the default).]] |
| [[`rule<Iterator, T1, T2, T3, T4>`, `Attribute`] |
| [Returns `is_container<A>`, where `A` is the |
| attribute exposed by the rule (__qi__ and |
| __karma__).]] |
| [[`grammar<Iterator, T1, T2, T3, T4>`, `Attribute`] |
| [Returns `is_container<A>`, where `A` is the |
| attribute exposed by the grammar (__qi__ and |
| __karma__).]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `handles_container` needs to be implemented for a |
| specific type whenever this type directly handles container attributes. |
| It is applicable for parsers (__qi__) and generators (__karma__). It will have |
| to be implemented under rare circumstances only. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ handles_container] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:transform Transform an Attribute to a Different Type (Qi and Karma)] |
| |
| [heading transform_attribute] |
| |
| The template `transform_attribute` is a type used as an attribute customization |
| point. It is invoked by /Qi/ `rule`, semantic action and `attr_cast`, and /Karma/ |
| `rule`, semantic action and [karma_attr_cast `attr_cast`]. It is used to |
| automatically transform the user |
| provided attribute to the attribute type expected by the right hand side |
| component (for `rule`), the semantic action, or the embedded component |
| (for `attr_cast`). |
| |
| [note The interface of this customization point has been changed with Boost |
| V1.44. We added the `Domain` template parameter to allow for more fine |
| grained specializations for __qi__ and __karma__.] |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/attributes.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Exposed, typename Transformed, typename Domain, typename Enable> |
| struct transform_attribute |
| { |
| typedef <unspecified> type; |
| |
| static type pre(Exposed& val); |
| static void post(Exposed& val, type attr); // Qi only |
| static void fail(Exposed&); // Qi only |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Exposed`] [The attribute type supplied to the component |
| which needs to be transformed.] [none]] |
| [[`Transformed`] [The attribute type expected by the component |
| to be provided as the result of the transformation.] [none]] |
| [[`Domain`] [The domain of the sub library the template is |
| instantiated in. Typically this is either `qi::domain` |
| or `karma::domain`.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `transform_attribute` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Exposed`] [The type, `Exposed` is the type of the attribute as |
| passed in by the user.]] |
| [[`Transformed`] [The type, `Transformed` is the type of the attribute |
| as passed along to the right hand side of the `rule` |
| (embedded component of `attr_cast`).]] |
| [[`Domain`] [The domain of the sub library the template is |
| instantiated in. Typically this is either `qi::domain` |
| or `karma::domain`.]] |
| [[`exposed`] [An instance of type `Exposed`.]] |
| [[`transformed`] [An instance of type `Transformed`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`transform_attribute<Exposed, Transformed, Domain>::type`] |
| [Evaluates to the type to be used as the result of the |
| transformation (to be passed to the right hand side of |
| the `rule` or to the embedded component of the |
| `attr_cast`. Most of the time this is equal to |
| `Transformed`, but in other cases this might evaluate to |
| `Transformed&` instead avoiding superfluous object |
| creation.]] |
| [[ |
| ``type transform_attribute<Exposed, Transformed, Domain>::pre(exposed)``] |
| [Do `pre`-transformation before invoking the right hand |
| side component for `rule` (or the embedded component |
| for `attr_cast`). This takes the attribute supplied as by |
| the user (of type `Exposed`) and returns the attribute |
| to be passed down the component hierarchy (of the type |
| as exposed by the metafunction `type`). This function |
| will be called in /Qi/ and for /Karma/.]] |
| [[ |
| ``void transform_attribute<Exposed, Transformed, Domain>::post(exposed, transformed)``] |
| [Do `post`-transformation after the invocation of the |
| right hand side component for `rule` (or the embedded |
| component for `attr_cast`). This takes the original |
| attribute as supplied by the user and the attribute |
| as returned from the right hand side (embedded) |
| component and is expected to propagate the result back |
| into the supplied attribute instance. This function |
| will be called in /Qi/ only.]] |
| [[ |
| ``void transform_attribute<Exposed, Transformed, Domain>::fail(exposed)``] |
| [Handling failing parse operations of the |
| right hand side component for `rule` (or the embedded |
| component for `attr_cast`). This function |
| will be called in /Qi/ only.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Template parameters] [Semantics]] |
| [[`Exposed`, `Transformed`] [`type` evaluates to `Transformed`, |
| `pre()` returns a new instance of `Transformed` |
| constructed from the argument of type `Exposed`, |
| `post()` assigns `transformed` to `exposed`.]] |
| [[`optional<Exposed>`, `Transformed`, |
| `typename disable_if<is_same<optional<Exposed>, Transformed> >::type`] |
| [`type` evaluates to `Transformed&`, |
| `pre()` returns a reference to the instance of `Transformed` |
| stored in the passed optional (the argument of type `optional<Exposed>`), |
| the optional instance is initialized, if needed. |
| `post()` does nothing, `fail()` resets the |
| optional (its parameter) instance to the non-initialized state.]] |
| [[`Exposed&`, `Transformed`] [`type` evaluates to `Transformed`, |
| `pre()` returns a new instance of `Transformed` |
| constructed from the argument of type `Exposed`, |
| `post()` assigns `transformed` to `exposed`.]] |
| [[`Attrib&`, `Attrib`] [`type` evaluates to `Attrib&`, |
| `pre()` returns it's argument, `post()` does |
| nothing.]] |
| [[`Exposed const`, `Transformed`] [(usind in /Karma/ only) `type` evaluates to |
| `Transformed`, `pre()` returns it's argument, |
| `post()` is not implemented.]] |
| [[`Attrib const&`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`, |
| `pre()` returns it's argument, `post()` is not |
| implemented.]] |
| [[`Attrib const`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`, |
| `pre()` returns it's argument, `post()` is not |
| implemented.]] |
| [[__unused_type__, `Attrib`] [`type` evaluates to __unused_type__, `pre()` |
| and `post()` do nothing.]] |
| [[`Attrib`, __unused_type__] [`type` evaluates to __unused_type__, `pre()` |
| and `post()` do nothing.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `transform_attribute` needs to be implemented for a |
| specific pair of types whenever the attribute type supplied to a `rule` or |
| `attr_cast` cannot automatically transformed to the attribute type expected by |
| the right hand side of the `rule` (embedded component of the `attr_cast`) |
| because the default implementation as shown above is not applicable. Examples |
| for this could be that the type `Transformed` is not constructible from |
| the type `Exposed`. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ transform] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [/ section:optional Handling of Optional Attributes (Qi and Karma)] |
| |
| [/ optional_attribute] |
| |
| [/ endsect] [/ optional] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:assign_to Store a Parsed Attribute Value (Qi)] |
| |
| After parsing input and generating an attribute value this value needs to |
| assigned to the attribute instance provided by the user. The customization |
| points `assign_to_attribute_from_iterators` and `assign_to_attribute_from_value` |
| are utilized to adapt this assignment to the concrete type to be assigned. |
| This section describes both. |
| |
| [section:assign_to_attribute_from_iterators Store an Attribute after a Parser Produced a Pair of Iterators (Qi)] |
| |
| [heading assign_to_attribute_from_iterators] |
| |
| The template `assign_to_attribute_from_iterators` is a type used as an attribute |
| customization point. It is invoked by the those /Qi/ parsers not producing any |
| attribute value but returning a pair of iterators pointing to the matched input |
| sequence. It is used to either store the iterator pair into the attribute |
| instance provided by the user or to convert the iterator pair into an attribute |
| as provided by the user. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/qi/detail/assign_to.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Attrib, typename Iterator, typename Enable> |
| struct assign_to_attribute_from_iterators |
| { |
| static void call(Iterator const& first, Iterator const& last, Attrib& attr); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Attrib`] [The type, `Attrib` is the type of the attribute as |
| passed in by the user.] [none]] |
| [[`Iterator`] [The type, `Iterator` is the type of the iterators |
| as produced by the parser.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `assign_to_attribute_from_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Attrib`] [A type to be used as the target to store the attribute value in.]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`Iterator`] [The iterator type used by the parser. This type usually |
| corresponds to the iterators as passed in by the user.]] |
| [[`begin`, `end`] [Iterator instances of type `Iterator` pointing to the |
| begin and the end of the matched input sequence.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``assign_to_attribute_from_iterators<Attrib, Iterator>::call(b, e, attr)``] |
| [Use the iterators `begin` and `end` to initialize |
| the attribute `attr`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Attrib`, `Iterator`] [Execute an assignment `attr = Attrib(begin, end)`.]] |
| [[__unused_type__, `T`] [Do nothing.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `assign_to_attribute_from_iterators` needs to be |
| implemented for a specific type whenever the default implementation as shown |
| above is not applicable. Examples for this could be that the type `Attrib` is |
| not constructible from the pair of iterators. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ assign_to_attribute_from_iterators] |
| |
| [section:assign_to_attribute_from_value Store an Attribute Value after a Parser Produced a Value (Qi)] |
| |
| [heading assign_to_attribute_from_value] |
| |
| The template `assign_to_attribute_from_value` is a type used as an attribute |
| customization point. It is invoked by all primitive /Qi/ parsers in order |
| to store a parsed attribute value into the attribute instance provided by the |
| user, if this attribute is not a container type (`is_container<T>::type` |
| evaluates to `mpl::false_`, where `T` is the attribute type). |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/qi/detail/assign_to.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Attrib, typename T, typename Enable> |
| struct assign_to_attribute_from_value |
| { |
| static void call(T const& val, Attrib& attr); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Attrib`] [The type, `Attrib` is the type of the attribute as |
| passed in by the user. This type is not a container |
| type (`is_container<Attrib>::type` evaluates to |
| `mpl::false_`).] [none]] |
| [[`T`] [The type, `T` is the type of the attribute instance |
| as produced by the parser.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `assign_to_attribute_from_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Attrib`] [A type to be used as the target to store the attribute |
| value in. This type is guaranteed not to be a container |
| type (`is_container<Attrib>::type` evaluates to |
| `mpl::false_`).]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`T`] [A type as produced by the parser. The parser temporarily stores |
| its parsed values using this type.]] |
| [[`t`] [An attribute instance of type `T`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``assign_to_attribute_from_value<Attrib, T>::call(t, attr)``] |
| [Copy (assign) the value `t` to the attribute `attr`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Attrib`, `T`] [Assign the argument `t` to `attr`.]] |
| [[__unused_type__, `T`] [Do nothing.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `assign_to_attribute_from_value` needs to be |
| implemented for a specific type whenever the default implementation as shown |
| above is not applicable. Examples for this could be that the type `Attrib` is |
| not copy constructible. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ assign_to_attribute_from_value] |
| |
| [section:assign_to_container_from_value Store an Attribute Value into a Container after a Parser Produced a Value (Qi)] |
| |
| [heading assign_to_container_from_value] |
| |
| The template `assign_to_container_from_value` is a type used as an attribute |
| customization point. It is invoked by all primitive /Qi/ parsers in order |
| to store a parsed attribute value into the attribute instance provided by the |
| user, if this attribute is a container type (`is_container<T>::type` evaluates |
| to `mpl::true_`, where `T` is the attribute type). |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/qi/detail/assign_to.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Attrib, typename T, typename Enable> |
| struct assign_to_container_from_value |
| { |
| static void call(T const& val, Attrib& attr); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Attrib`] [The type, `Attrib` is the type of the attribute as |
| passed in by the user. This type is a container |
| type (`is_container<Attrib>::type` evaluates to |
| `mpl::true_`).] [none]] |
| [[`T`] [The type, `T` is the type of the attribute instance |
| as produced by the parser.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `assign_to_container_from_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Attrib`] [A type to be used as the target to store the attribute |
| value in. This type is guaranteed to be a container |
| type (`is_container<Attrib>::type` evaluates to |
| `mpl::true_`).]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`T`] [A type as produced by the parser. The parser temporarily stores |
| its parsed values using this type.]] |
| [[`t`] [An attribute instance of type `T`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``assign_to_container_from_value<Attrib, T>::call(t, attr)``] |
| [Add the value `t` to the container attribute `attr`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Attrib`, `T`] [Add the argument `t` to `attr`.]] |
| [[__unused_type__, `T`] [Do nothing.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `assign_to_container_from_value` needs to be |
| implemented for a specific type whenever the default implementation as shown |
| above is not applicable. Examples for this could be that the type `Attrib` is |
| not copy constructible. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ assign_to_container_from_value] |
| |
| [endsect] [/ assign_to] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:store_value Store Parsed Attribute Values into a Container (Qi)] |
| |
| In order to customize Spirit to accept a given data type as a container for |
| elements parsed by any of the repetitive parsers (__qi_kleene__, __qi_plus__, |
| __qi_list__, and [qi_repeat Repeat]) two attribute customization points have to be |
| specialized: __customize_container_value__ and __customize_push_back_container__. |
| This section describes both. |
| |
| [section:container_value Determine the Type to be Stored in a Container (Qi)] |
| |
| [heading container_value] |
| |
| The template `container_value` is a template meta function used as an attribute |
| customization point. It is invoked by the /Qi/ repetitive parsers |
| (__qi_kleene__, __qi_plus__, __qi_list__, and [qi_repeat Repeat]) to determine the |
| type to store in a container. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Container, typename Enable> |
| struct container_value |
| { |
| typedef <unspecified> type; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Container`] [The type `Container` is the type for which the |
| type f the elements has to be deduced.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `container_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist |
| [[`C`] [A type to be tested whether it needs to be treated |
| as a container.]] |
| [[`T1`, `T2`, ...] [Arbitrary types]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`container_value<C>::type`] [Metafunction that evaluates to the type |
| to be stored in a given container type, |
| `C`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the types |
| exposed and the corresponding semantics: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`C`] [The non-const `value_type` of the given container |
| type, `C`. ]] |
| [[`boost::optional<C>`] [Returns `container_value<C>::type`]] |
| [[`boost::variant<T1, T2, ...>`] |
| [Returns `container_value<TN>::value` for the |
| first `TN` (out of `T1`, `T2`, ...) for which |
| `is_container<TN>::type` evaluates to `mpl::true_`. |
| Otherwise it will return __unused_type__.]] |
| [[__unused_type__] [Returns __unused_type__.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `is_container` needs to be implemented for a specific |
| type whenever this type is to be used as an attribute in place of a STL |
| container. It is applicable for parsers (__qi__) only. As a rule of thumb: it |
| has to be implemented whenever a certain type is to be passed as an attribute |
| to a parser normally exposing a STL container and if the type does not expose |
| the interface of a STL container (i.e. no embedded typedef for `value_type`). |
| These components have an attribute propagation rule in the form: |
| |
| a: A --> Op(a): vector<A> |
| |
| where `Op(a)` stands for any meaningful operation on the component `a`. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_push_back_container__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] |
| [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| Here is an example showing the default implementation of the |
| __customize_container_value__ customization point provided by the library: |
| |
| [customization_container_value_default] |
| |
| This template is instantiated by the library at the appropriate places while |
| using the supplied container type as the template argument. The embedded `type` |
| is used as the attribute type while parsing the elements to be store in that |
| container. |
| |
| The following example shows the predefined specialization for __unused_type__: |
| |
| [customization_container_value_unused] |
| |
| which defines its embedded `type` to be __unused_type__ as well, this way |
| propagating the 'don't care' attribute status to the embedded parser. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ container_value] |
| |
| [section:push_back Store a Parsed Attribute Value into a Container (Qi)] |
| |
| [heading push_back_container] |
| |
| The template `push_back_container` is a type used as an attribute customization |
| point. It is invoked by the /Qi/ repetitive parsers (__qi_kleene__, __qi_plus__, |
| __qi_list__, and [qi_repeat Repeat]) to store a parsed attribute value into a |
| container. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Container, typename Attrib, typename Enable> |
| struct push_back_container |
| { |
| static bool call(Container& c, Attrib const& val); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Container`] [The type, `Container` needs to |
| be tested whether it has to be treated |
| as a container] [none]] |
| [[`Attrib`] [The type, `Attrib` is the one returned from the |
| customization point __customize_container_value__ |
| and represents the attribute value to be stored in |
| the container of type `Container`.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `push_back_container` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`C`] [A type to be used as a container to store attribute values in.]] |
| [[`c`] [A container instance of type `C`.] |
| [[`Attrib`] [A type to be used as a container to store attribute values in.]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`T1`, `T2`, ...] [Arbitrary types]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``push_back_container<C, Attrib>::call(c, attr)``] |
| [Static function that is invoked whenever an |
| attribute value, `attr` needs to be stored |
| into the container instance `c`. This function |
| should return `true` on success and `false` |
| otherwise. Returning `false` causes the |
| corresponding parser to fail.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the types |
| exposed and the corresponding semantics: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`C`, `Attrib`] [Store the provided attribute instance `attr` into |
| the given container `c` using the function call |
| `c.insert(c.end(), attr)`.]] |
| [[`boost::optional<C>`, `Attrib`] |
| [If the provided instance of `boost::optional<>` is not |
| initialized, invoke the appropriate initialization |
| and afterwards apply the customization point |
| `push_back_container<C, Attrib>`, treating the |
| instance held by the optional (of type `C`) as |
| the container to store the attribute in.]] |
| [[`boost::variant<T1, T2, ...>`, `Attrib`] |
| [If the instance of the variant currently holds a |
| value with a type, `TN`, for which `is_container<TN>::type` |
| evaluates to `mpl::true_`, this customization |
| point specialization will apply |
| `push_back_container<TN, Attrib>`, treating the |
| instance held by the variant (of type `TN`) as |
| the container to store the attribute in. Otherwise |
| it will raise an assertion.]] |
| [[__unused_type__] [Do nothing.]] |
| ] |
| |
| [heading When to Implement] |
| |
| The customization point `push_back_container` needs to be implemented for a |
| specific type whenever this type is to be used as an attribute in place of a STL |
| container. It is applicable for parsers (__qi__) only. As a rule of thumb: it |
| has to be implemented whenever a certain type is to be passed as an attribute |
| to a parser normally exposing a STL container and if the type does not expose |
| the interface of a STL container (i.e. no function being equivalent to |
| `c.insert(c.end(), attr)`. These components have an attribute propagation rule |
| in the form: |
| |
| a: A --> Op(a): vector<A> |
| |
| where `Op(a)` stands for any meaningful operation on the component `a`. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_container_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] |
| [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| Here is an example showing the default implementation of the |
| __customize_container_value__ customization point provided by the library: |
| |
| [customization_push_back_default] |
| |
| This template is instantiated by the library at the appropriate places while |
| using the supplied container and element types as the template arguments. The |
| member function `call()` will be called whenever an element has to be added to |
| the supplied container |
| |
| The following example shows the predefined specialization for __unused_type__: |
| |
| [customization_push_back_unused] |
| |
| which defines an empty member function `call()`. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ push_back] |
| |
| [endsect] [/ store_value] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:clear_value Re-Initialize an Attribute Value before Parsing (Qi)] |
| |
| [heading clear_value] |
| |
| The template `clear_value` is a type used as an attribute customization point. |
| It is invoked by the /Qi/ repetitive parsers (__qi_kleene__, __qi_plus__, |
| __qi_list__, and [qi_repeat Repeat]) in order to re-initialize the attribute |
| instance passed to the embedded parser after it has been stored in the provided |
| container. This re-initialized attribute instance is reused during the next |
| iteration of the repetitive parser. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/attributes.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Attrib, typename Enable> |
| struct clear_value |
| { |
| static void call(Attrib& val); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Attrib`] [The type, `Attrib` of the attribute to be |
| re-initialized.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `clear_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Attrib`] [A type to be used as a container to store attribute values in.]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`T1`, `T2`, ...] [Arbitrary types]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``clear_value<Attrib>::call(Attrib& attr)``] [Re-initialize the instance referred to by |
| `attr` in the most efficient way.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the types |
| exposed and the corresponding semantics: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Attrib`] [Re-initialize using assignment of default |
| constructed value.]] |
| [[Any type `T` for which `is_container<>::type` is `mpl::true_`] |
| [Call the member function `attr.clear()` for the |
| passed attribute instance.]] |
| [[`boost::optional<Attrib>`] [Clear the `optional` instance and leave it |
| uninitialized.]] |
| [[`boost::variant<T1, T2, ...>`][Invoke the `clear_value` customization |
| point for the currently held value.]] |
| [[`fusion::tuple<T1, T2, ...>`][Invoke the `clear_value` customization |
| point for all elements of the tuple.]] |
| [[__unused_type__] [Do nothing.]] |
| ] |
| |
| [heading When to Implement] |
| |
| The customization point `clear_value` needs to be implemented for a |
| specific type whenever this type is to be used as an attribute to be stored |
| into a STL container and if the type cannot be re-initialized using one of the |
| specializations listed above. Examples for this might be types not being default |
| constructible or container types not exposing a member function `clear()`. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ clear_value] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:extract_from Extract an Attribute Value to Generate Output (Karma)] |
| |
| [heading extract_from] |
| |
| Before generating output for a value this value needs to extracted from the |
| attribute instance provided by the user. The customization point |
| `extract_from_attribute` is utilized to adapt this extraction for any data type possibly |
| used to store the values to output. |
| |
| [note The interface of this customization point has been changed with Boost |
| V1.44. We added the `Exposed` template parameter to allow for more fine |
| grained specializations of the required __karma__ attribute |
| transformations.] |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/karma/detail/extract_from.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Exposed, typename Attrib, typename Enable> |
| struct extract_from_attribute |
| { |
| typedef <unspecified> type; |
| |
| template <typename Context> |
| static type call(Attrib const& attr, Context& context); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Exposed`] [The type, `Exposed` of the attribute natively |
| exposed by the component the `extract_from_attribute` is |
| invoked from.] [none]] |
| [[`Attrib`] [The type, `Attrib` of the attribute to be used to |
| generate output from.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `clear_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| [[`Context`] [This is the type of the current generator execution |
| context.]] |
| ] |
| |
| [variablelist Notation |
| [[`Exposed`] [A type exposed as the native attribute of a component.]] |
| [[`Attrib`] [A type to be used to generate output from.]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`ctx`] [An instance of type `Context`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``extract_from_attribute<Exposed, Attrib>::call(attr, ctx)``] |
| [Extract the value to generate |
| output from `attr` and return it to the caller.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the types |
| exposed and the corresponding semantics: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Attrib`] [The exposed typedef `type` is defined to |
| `Attrib const&`. The function `call()` returns |
| the argument by reference without change.]] |
| [[`boost::optional<Attrib>`] [The exposed typedef `type` is defined to |
| `Attrib const&`. The function `call()` returns |
| the value held by the `optional<>` argument |
| by reference without change.]] |
| [[`boost::reference_wrapper<Attrib>`] |
| [The exposed typedef `type` is defined to |
| `Attrib const&`. The function `call()` returns |
| the value held by the `reference_wrapper<>` |
| argument by reference without change.]] |
| [[__unused_type__] [The exposed typedef `type` is defined to |
| __unused_type__. The function `call()` returns |
| an instance of __unused_type__.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `extract_from_attribute` needs to be implemented for a |
| specific type whenever the default implementation as shown above is not |
| applicable. Examples for this could be that the type to be extracted is |
| different from `Attrib` and is not copy constructible. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ extract_from] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:extract_from_container Extract From a Container Attribute Value to Generate Output (Karma)] |
| |
| [heading extract_from_container] |
| |
| Before generating output for a value this value needs to extracted from the |
| attribute instance provided by the user. The customization point |
| `extract_from_container` is utilized to adapt this extraction for any data type possibly |
| used to store the values to output. |
| |
| [note The interface of this customization point has been changed with Boost |
| V1.44. We added the `Exposed` template parameter to allow for more fine |
| grained specializations of the required __karma__ attribute |
| transformations.] |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/karma/detail/extract_from.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Exposed, typename Attrib, typename Enable> |
| struct extract_from_container |
| { |
| typedef <unspecified> type; |
| |
| template <typename Context> |
| static type call(Attrib const& attr, Context& context); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Exposed`] [The type, `Exposed` of the attribute natively |
| exposed by the component the `extract_from_container` is |
| invoked from.] [none]] |
| [[`Attrib`] [The type, `Attrib` is the container attribute to be used to |
| generate output from.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `clear_value` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| [[`Context`] [This is the type of the current generator execution |
| context.]] |
| ] |
| |
| [heading Notation] |
| |
| [variablelist Notation |
| [[`Exposed`] [A type exposed as the native attribute of a component.]] |
| [[`Attrib`] [A container type to be used to generate output from.]] |
| [[`attr`] [An attribute instance of type `Attrib`.]] |
| [[`ctx`] [An instance of type `Context`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[ |
| ``extract_from_container<Exposed, Attrib>::call(attr, ctx)``] |
| [Extract the value to generate |
| output from the contaner given by `attr` and return |
| it to the caller.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the types |
| exposed and the corresponding semantics: |
| |
| [table |
| [[Template Parameters] [Value]] |
| [[`Attrib`] [The exposed typedef `type` is defined to |
| `Attrib const&`. The function `call()` returns |
| the argument by reference without change.]] |
| [[__unused_type__] [The exposed typedef `type` is defined to |
| __unused_type__. The function `call()` returns |
| an instance of __unused_type__.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `extract_from_container` needs to be implemented for a |
| specific container type whenever the default implementation as shown above is not |
| applicable. Examples for this could be that the type to be extracted is |
| different from `Attrib` and is not copy constructible. |
| |
| [heading Example] |
| |
| TBD |
| |
| [endsect] [/ extract_from] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:iterate Extract Attribute Values to Generate Output from a Container (Karma)] |
| |
| [section:container_iterator Determine the Type of the Iterator of a Container] |
| |
| [heading container_iterator] |
| |
| The template `container_iterator` is a template meta-function used as an attribute |
| customization point. It is invoked by the /Karma/ repetitive generators (such |
| as __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, and |
| [karma_repeat Repeat]) in order to determine the type of the iterator to use to |
| iterate over the items to be exposed as the elements of a container. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Container, typename Enable> |
| struct container_iterator |
| { |
| typedef <unspecified> type; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Container`] [The type, `Container` for which the |
| iterator type has to be returned] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `container_iterator` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`C`] [A container type the iterator type needs to be evaluated for.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`container_iterator<C>::type`] [Result of the metafunction that evaluates |
| the type to be used as the iterator for |
| accessing all elements of a container, `C`.]] |
| ] |
| |
| The returned type conceptually needs to be equivalent to a standard forward |
| iterator. But it does not have to expose the standardized interface. If this |
| customization point is implemented for a certain container type, all related |
| customization points need to be implemented as well (see |
| [link spirit.advanced.customize.iterate.container_iterator.related_attribute_customization_points Related Attribute Customization Points] |
| below). This encapsulates the specific iterator interface required for a |
| given type. The minimal requirements for a type to be exposed as an iterator in |
| this context are: |
| |
| * it needs to be comparable for equality (see __customize_compare_iterators__), |
| * it needs to be incrementable (see __customize_next_iterator__), |
| * it needs to be dereferencible (see __customize_deref_iterator__). |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| types returned by the embedded typedef `type`: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`C`] [Returns `C::iterator`.]] |
| [[`C const`] [Returns `C::const_iterator`.]] |
| [[__unused_type__] [Returns __unused_type__` const*`.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `container_iterator` needs to be implemented for a specific |
| type whenever this type is to be used as an attribute in place of a STL |
| container. It is applicable for generators (__karma__) only. As a rule of thumb: |
| it has to be implemented whenever a certain type is to be passed as an attribute |
| to a generator normally exposing a STL container, `C` and if the type does not expose |
| the interface of a STL container (i.e. `is_container<C>::type` would normally |
| return `mpl::false_`). |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| Here are the header files needed to make the example code below compile: |
| |
| [customize_karma_embedded_container_includes] |
| |
| The example (for the full source code please see here: |
| [@../../example/karma/customize_embedded_container.cpp customize_embedded_container.cpp]) |
| uses the data structure |
| |
| [customize_karma_embedded_container_data] |
| |
| as a direct container attribute to the __karma_list__ generator. In order to |
| make this data structure compatible we need to specialize a couple of attribute |
| customization points: __customize_is_container__, __customize_container_iterator__, |
| __customize_begin_container__, and __customize_end_container__. As you can see |
| the specializations simply expose the embedded `std::vector<int>` as the |
| container to use. We don't need to specialize the customization points related |
| to iterators (__customize_deref_iterator__, __customize_next_iterator__, |
| and __customize_compare_iterators__) as we expose a standard iterator and the |
| default implementation of these customizations handles standard iterators out |
| of the box. |
| |
| [customize_karma_embedded_container_traits] |
| |
| The last code snippet shows an example using an instance of the data structure |
| `client::embedded_container` to generate output from a __karma_list__ |
| generator: |
| |
| [customize_karma_embedded_container] |
| |
| As you can see, the specializations for the customization points as defined |
| above enable the seamless integration of the custom data structure without |
| having to modify the output format or the generator itself. |
| |
| For other examples of how to use the customization point `container_iterator` |
| please see here: __customize_use_as_container_example__ and |
| __customize_counter_example__. |
| |
| [endsect] [/ container_iterator] |
| |
| |
| [section:begin_container Get the Iterator pointing to the Begin of a Container Attribute] |
| |
| [heading begin_container] |
| |
| The template `begin_container` is a type used as an attribute customization point. |
| It is invoked by the /Karma/ repetitive generators (such as __karma_list__, |
| [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat]) |
| in order to get an iterator pointing to the first element of the container |
| holding the attributes to generate output from. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Container, typename Enable> |
| struct begin_container |
| { |
| static typename container_iterator<Container>::type |
| call(Container& c); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Container`] [The type, `Container` for which the iterator pointing |
| to the first element has to be returned] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `begin_container` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`C`] [A container type the begin iterator needs to be returned for.]] |
| [[`c`] [An instance of a container, `C`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`begin_container<C>::call(c)`] [Return the iterator usable to dereference |
| the first element of the given container, |
| `c`. The type of the returned iterator is |
| expected to be the same as the type returned |
| by the customization point |
| __customize_container_iterator__.]] |
| ] |
| |
| The returned instance conceptually needs to be equivalent to a standard forward |
| iterator. But it does not have to expose the standardized interface. If this |
| customization point is implemented for a certain container type, all related |
| customization points need to be implemented as well (see |
| [link spirit.advanced.customize.iterate.begin_container.related_attribute_customization_points Related Attribute Customization Points] |
| below). This encapsulates the specific iterator interface required for a |
| given type. The minimal requirements for a type to be exposed as an iterator in |
| this context are: |
| |
| * it needs to be comparable for equality (see __customize_compare_iterators__), |
| * it needs to be incrementable (see __customize_next_iterator__), |
| * it needs to be dereferencible (see __customize_deref_iterator__). |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| types returned by the embedded typedef `type`: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`C`] [Returns `c.begin()`.]] |
| [[`C const`] [Returns `c.begin()`.]] |
| [[__unused_type__] [Returns `&unused`.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `begin_container` needs to be implemented for a specific |
| type whenever this type is to be used as an attribute in place of a STL |
| container. It is applicable for generators (__karma__) only. As a rule of thumb: |
| it has to be implemented whenever a certain type is to be passed as an attribute |
| to a generator normally exposing a STL container, `C` and if the type does not expose |
| the interface of a STL container (i.e. `is_container<C>::type` would normally |
| return `mpl::false_`). |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| For examples of how to use the customization point `begin_container` please |
| see here: __customize_embedded_container_example__, |
| __customize_use_as_container_example__, and __customize_counter_example__. |
| |
| [endsect] [/ begin_container] |
| |
| |
| [section:end_container Get the Iterator pointing to the End of a Container Attribute] |
| |
| [heading end_container] |
| |
| The template `end_container` is a type used as an attribute customization point. |
| It is invoked by the /Karma/ repetitive generators (such as __karma_list__, |
| [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat]) |
| in order to get an iterator pointing to the end of the container |
| holding the attributes to generate output from. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Container, typename Enable> |
| struct end_container |
| { |
| static typename container_iterator<Container>::type |
| call(Container& c); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Container`] [The type, `Container` for which the iterator pointing |
| to the first element has to be returned] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `end_container` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`C`] [A container type the end iterator needs to be returned for.]] |
| [[`c`] [An instance of a container, `C`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`end_container<C>::call(c)`] [Return the iterator usable to compare a |
| different iterator with in order to detect |
| whether the other iterator reached the end |
| of the given container, `c`. The type of |
| the returned iterator is expected to be the |
| same as the type returned by the |
| customization point __customize_container_iterator__.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| types returned by the embedded typedef `type`: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`C`] [Returns `c.end()`.]] |
| [[`C const`] [Returns `c.end()`.]] |
| [[__unused_type__] [Returns `&unused`.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `end_container` needs to be implemented for a specific |
| type whenever this type is to be used as an attribute in place of a STL |
| container. It is applicable for generators (__karma__) only. As a rule of thumb: |
| it has to be implemented whenever a certain type is to be passed as an attribute |
| to a generator normally exposing a STL container, `C` and if the type does not expose |
| the interface of a STL container (i.e. `is_container<C>::type` would normally |
| return `mpl::false_`). |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| For examples of how to use the customization point `end_container` please |
| see here: __customize_embedded_container_example__, |
| __customize_use_as_container_example__, and __customize_counter_example__. |
| |
| [endsect] [/ end_container] |
| |
| |
| [section:next_iterator Increment the Iterator pointing into a Container Attribute] |
| |
| [heading next_iterator] |
| |
| The template `next_iterator` is a type used as an attribute customization point. |
| It is invoked by the /Karma/ repetitive generators (such as __karma_list__, |
| [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat]) |
| in order to get an iterator pointing to the next element of a container |
| holding the attributes to generate output from. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Iterator, typename Enable> |
| struct next_iterator |
| { |
| static void call(Iterator& it); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Iterator`] [The type, `Iterator` of the iterator to increment. |
| This is the same as the type returned by the |
| customization point __customize_container_iterator__.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `next_iterator` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Iterator`] [An iterator type.]] |
| [[`it`] [An instance of an iterator of type `Iterator`.]] |
| [[`C`] [A container type whose iterator type is `Iterator`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`next_iterator<Iterator>::call(it)`] [Increment the iterator pointing so that |
| it is pointing to the next element.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| types returned by the embedded typedef `type`: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Iterator`] [Executes `++it`.]] |
| [[__unused_type__` const*`][Does nothing.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `next_iterator` needs to be implemented for a specific |
| iterator type whenever the container this iterator belongs to is to be used as |
| an attribute in place of a STL container. It is applicable for generators |
| (__karma__) only. As a rule of thumb: it has to be implemented whenever a certain |
| iterator type belongs to a container which is to be passed as an attribute |
| to a generator normally exposing a STL container, `C` and if the container type |
| does not expose the interface of a STL container (i.e. `is_container<C>::type` |
| would normally return `mpl::false_`). |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| Here are the header files needed to make the example code below compile: |
| |
| [customize_karma_use_as_container_includes] |
| |
| The example (for the full source code please see here: |
| [@../../example/karma/customize_use_as_container.cpp customize_use_as_container.cpp]) |
| uses the data structure |
| |
| [customize_karma_use_as_container_data] |
| |
| as a direct attribute to the __karma_list__ generator. This type does not |
| expose any of the interfaces of an STL container. It does not even expose the |
| usual semantics of a container. The purpose of this artificial example is to |
| demonstrate how the customization points can be used to expose independent data |
| elements as a single container. The example shows how to enable its use as an |
| attribute to /Karma's/ repetitive generators. |
| |
| In order to make this data structure compatible we need to specialize a couple |
| of attribute customization points: __customize_is_container__, |
| __customize_container_iterator__, __customize_begin_container__, and |
| __customize_end_container__. In addition, we specialize all of the |
| iterator related customization points as well: __customize_deref_iterator__, |
| __customize_next_iterator__, and __customize_compare_iterators__. |
| |
| [customize_karma_use_as_container_traits] |
| [customize_karma_use_as_container_iterator_traits] |
| |
| The last code snippet shows an example using an instance of the data structure |
| `client::use_as_container` to generate output from a __karma_list__ generator: |
| |
| [customize_karma_use_as_container] |
| |
| As you can see, the specializations for the customization points as defined |
| above enable the seamless integration of the custom data structure without |
| having to modify the output format or the generator itself. |
| |
| [endsect] [/ next_iterator] |
| |
| |
| [section:deref_iterator Dereference the Iterator pointing into a Container Attribute] |
| |
| [heading deref_iterator] |
| |
| The template `deref_iterator` is a type used as an attribute customization point. |
| It is invoked by the /Karma/ repetitive generators (such as __karma_list__, |
| [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat]) |
| in order to dereference an iterator pointing to an element of a container |
| holding the attributes to generate output from. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Iterator, typename Enable> |
| struct deref_iterator |
| { |
| typedef <unspecified> type; |
| static type call(Iterator& it); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Iterator`] [The type, `Iterator` of the iterator to dereference. |
| This is the same as the type returned by the |
| customization point __customize_container_iterator__.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `deref_iterator` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Iterator`] [An iterator type.]] |
| [[`it`] [An instance of an iterator of type `Iterator`.]] |
| [[`C`] [A container type whose iterator type is `Iterator`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`deref_iterator<Iterator>::type`] [Metafunction result evaluating to the |
| type returned by dereferencing the iterator.]] |
| [[`deref_iterator<Iterator>::call(it)`] [Return the element in the container |
| referred to by the iterator. The type of the |
| returned value is the same as returned by the |
| metafunction result `type`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| types returned by the embedded typedef `type`: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Iterator`] [The metafunction result `type` evaluates to |
| `boost::detail::iterator_traits<Iterator>::reference` and the |
| function `call()` returns `*it`.]] |
| [[__unused_type__` const*`][The metafunction result `type` evaluates to |
| __unused_type__ and the function `call()` returns `unused`.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `deref_iterator` needs to be implemented for a specific |
| iterator type whenever the container this iterator belongs to is to be used as |
| an attribute in place of a STL container. It is applicable for generators |
| (__karma__) only. As a rule of thumb: it has to be implemented whenever a certain |
| iterator type belongs to a container which is to be passed as an attribute |
| to a generator normally exposing a STL container, `C` and if the container type |
| does not expose the interface of a STL container (i.e. `is_container<C>::type` |
| would normally return `mpl::false_`). |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| Here are the header files needed to make the example code below compile: |
| |
| [customize_karma_counter_includes] |
| |
| The example (for the full source code please see here: |
| [@../../example/karma/customize_counter.cpp customize_counter.cpp]) |
| uses the data structure |
| |
| [customize_karma_counter_data] |
| |
| as a direct attribute to the __karma_list__ generator. This type does not |
| expose any of the interfaces of an STL container. It does not even expose the |
| usual semantics of a container. The presented customization points build a |
| counter instance which is incremented each time it is accessed. The examples |
| shows how to enable its use as an attribute to /Karma's/ repetitive generators. |
| |
| In order to make this data structure compatible we need to specialize a couple |
| of attribute customization points: __customize_is_container__, |
| __customize_container_iterator__, __customize_begin_container__, and |
| __customize_end_container__. In addition, we specialize one of the |
| iterator related customization points as well: __customize_deref_iterator__. |
| |
| [customize_karma_counter_traits] |
| [customize_karma_counter_iterator_traits] |
| |
| The last code snippet shows an example using an instance of the data structure |
| `client::counter` to generate output from a __karma_list__ generator: |
| |
| [customize_karma_counter] |
| |
| As you can see, the specializations for the customization points as defined |
| above enable the seamless integration of the custom data structure without |
| having to modify the output format or the generator itself. |
| |
| For other examples of how to use the customization point `deref_iterator` |
| please see here: __customize_use_as_container_example__. |
| |
| [endsect] [/ deref_iterator] |
| |
| |
| [section:compare_iterators Compare two Iterator pointing into a Container Attribute for Equality] |
| |
| [heading compare_iterators] |
| |
| The template `compare_iterators` is a type used as an attribute customization |
| point. It is invoked by the /Karma/ repetitive generators (such as __karma_list__, |
| [karma_kleene Kleene (unary `*`)], __karma_plus__, and [karma_repeat Repeat]) |
| in order to compare the current iterator (returned either from |
| __customize_begin_container__ or from __customize_next_iterator__) with the end |
| iterator (returned from __customize_end_container__) in order to find the end |
| of the element sequence to generate output for. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/container.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename Iterator, typename Enable> |
| struct compare_iterators |
| { |
| static bool call(Iterator const& it1, Iterator const& it2); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`Iterator`] [The type, `Iterator` of the iterator to dereference. |
| This is the same as the type returned by the |
| customization point __customize_container_iterator__.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `compare_iterators` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`Iterator`] [An iterator type.]] |
| [[`it1`, `it2`] [Instances of an iterator of type `Iterator`.]] |
| [[`C`] [A container type whose iterator type is `Iterator`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`compare_iterators<Iterator>::call(it1, it2)`] |
| [Returns whether the iterators `it1` |
| `it2` are to be treated as being |
| equal.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the |
| types returned by the embedded typedef `type`: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[`Iterator`] [The function `call()` returns it1 == it2.]] |
| [[__unused_type__` const*`][The function `call()` always returns false.]] |
| ] |
| |
| [heading When to implement] |
| |
| The customization point `compare_iterators` needs to be implemented for a specific |
| iterator type whenever the container this iterator belongs to is to be used as |
| an attribute in place of a STL container. It is applicable for generators |
| (__karma__) only. As a rule of thumb: it has to be implemented whenever a certain |
| iterator type belongs to a container which is to be passed as an attribute |
| to a generator normally exposing a STL container, `C` and if the container type |
| does not expose the interface of a STL container (i.e. `is_container<C>::type` |
| would normally return `mpl::false_`). |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points might need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_container__] [Needs to be implemented whenever a type is to be used as a container attribute in /Karma/.]] |
| [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] |
| ] |
| |
| [heading Example] |
| |
| For an example of how to use the customization point `compare_iterators` |
| please see here: __customize_use_as_container_example__. |
| |
| [endsect] [/ compare_iterators] |
| |
| [endsect] [/ iterate] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:string_traits Extract a C-Style String to Generate Output from a String Type (Karma)] |
| |
| [section:is_char Determine if a Type is a Character] |
| |
| [heading is_char] |
| |
| `is_char` is a metafunction that detects if a given type is a character. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/string_traits.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename T> |
| struct is_char |
| { |
| <unspecified>; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`T`] [The type to detect.] [none]] |
| ] |
| |
| [variablelist Notation |
| [[`T`] [An arbitrary type]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`is_char<T>::type`] [`mpl::true_` if T should be treated as a character |
| type, and `mpl::false_` otherwise. Generally, |
| any implementation of `is_char` needs to behave as |
| if if was a __mpl_boolean_constant__.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Type] [Semantics]] |
| [[`T`] [`mpl::false_`]] |
| [[`T const`] [`is_char<T>`]] |
| [[`char`] [`mpl::true_`]] |
| [[`wchar_t`] [`mpl::true_`]] |
| ] |
| |
| [heading When to implement] |
| |
| This customization point needs to be implemented for any strings that use a |
| type other than `char` or `wchar_t to store character data. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_string__] [Whenever `is_char` is implemented.]] |
| [[__customize_char_type_of__] [Whenever `is_char` is implemented.]] |
| ] |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ is_char] |
| |
| [section:char_type_of Determine the Character Type of a String] |
| |
| [heading char_type_of] |
| |
| This customization point is an MPL metafunction which returns the character |
| type of a given string type. `char_type_of` handles user-defined types such as |
| std::string, as well as C-style strings. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/string_traits.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename T> |
| struct char_type_of |
| { |
| typedef <unspecified> type; |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`T`] [A string type.] [none]] |
| ] |
| |
| [variablelist Notation |
| [[`T`] [An arbitrary type.]] |
| [[`N`] [An arbitrary integral constant.]] |
| [[`Char`] [A character type.]] |
| [[`Traits`] [A character traits type.]] |
| [[`Allocator`] [A standard allocator type.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`char_type_of<T>::type`] [The character type of the string type `T`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Type] [Semantics]] |
| [[`T const`] [Returns `char_type_of<T>`.]] |
| [[`char`] [Returns `char`.]] |
| [[`wchar_t`] [Returns `wchar_t`.]] |
| [[`char const*`] [Returns `char const`.]] |
| [[`wchar_t const*`] [Returns `wchar_t const`.]] |
| [[`char*`] [Returns `char`.]] |
| [[`wchar_t*`] [Returns `wchar_t`.]] |
| [[`char[N]`] [Returns `char`.]] |
| [[`wchar_t[N]`] [Returns `wchar_t`.]] |
| [[`char const[N]`] [Returns `char const`.]] |
| [[`wchar_t const[N]`] [Returns `wchar_t const`.]] |
| [[`char(&)[N]`] [Returns `char`.]] |
| [[`wchar_t(&)[N]`] [Returns `wchar_t`.]] |
| [[`char const(&)[N]`] [Returns `char const`.]] |
| [[`wchar_t const(&)[N]`] [Returns `wchar_t const`.]] |
| [[`std::basic_string<Char, Traits, Allocator>`] [Returns `Char`.]] |
| ] |
| |
| [heading When to implement] |
| |
| This customization point needs to be implemented whenever __customize_is_string__ |
| is implemented. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_char__] [For string types whose underlying character type |
| is not `char` or `wchar_t`, `is_char` must be |
| implemented.]] |
| [[__customize_is_string__] [Whenever `char_type_of` is implemented.]] |
| [[__customize_extract_c_string__] [Whenever `char_type_of` is implemented.]] |
| ] |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ char_type_of] |
| |
| [section:extract_c_string Get a C-style String from a String Type] |
| |
| [heading extract_c_string] |
| |
| `extract_c_string` returns a pointer to an array of elements of a const character |
| type. It is invoked through a static method `call`. This customization point is |
| responsible for handling it's own garbage collecting; the lifetime of the returned |
| C-string must be no shorter than the lifetime of the string instance passed to |
| the `call` method. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/string_traits.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename String> |
| struct extract_c_string |
| { |
| typedef <unspecified> char_type; |
| |
| static char_type const* call (String const&); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`String`] [A string type.] [none]] |
| ] |
| |
| [variablelist Notation |
| [[`T`] [An arbitrary type.]] |
| [[`Char`] [A character type.]] |
| [[`Traits`] [A character traits type.]] |
| [[`Allocator`] [A standard allocator type.]] |
| [[`str`] [A string instance.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`extract_c_string<T>::char_type`] [The return type of `call`.]] |
| [[`extract_c_string<T>::call(str)`] [Extract a c-string of type `char_type` |
| from `str`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| [table |
| [[Type] [Semantics]] |
| [[`T`] [`call` takes a parameter of type `T const*`, and returns it without |
| modification. An overload of `call` takes a parameter of type `T*` |
| and casts it to `T const*`, returning the result. `char_type` is |
| `char_type_of<T>::type`.]] |
| [[`T const`] [`call` takes a parameter `str` of type `T const` and returns |
| `extract_c_string<T>::call(str)`. `char_type` is |
| `char_type_of<T>::type`.]] |
| [[`T&`] [`call` takes a parameter `str` of type `T&` and returns |
| `extract_c_string<T>::call(str)`. `char_type` is |
| `char_type_of<T>::type`.]] |
| [[`T const&`] [`call` takes a parameter `str` of type `T const&` and returns |
| `extract_c_string<T>::call(str)`. `char_type` is |
| `char_type_of<T>::type`.]] |
| [[`std::basic_string<Char, Traits, Allocator>`] |
| [`call` takes a parameter `str` and returns `str.c_str()`. `char_type` is |
| `Char`.]] |
| ] |
| |
| [heading When to implement] |
| |
| This customization point needs to be implemented whenever __customize_is_string__ |
| is implemented. |
| |
| [heading Related Attribute Customization Points] |
| |
| If this customization point is implemented, the following other customization |
| points need to be implemented as well. |
| |
| [table |
| [[Name] [When to implement]] |
| [[__customize_is_char__] [For string types whose underlying character type |
| is not `char` or `wchar_t`, `is_char` must be |
| implemented.]] |
| [[__customize_is_string__] [Whenever `extract_c_string` is implemented.]] |
| [[__customize_char_type_of__] [Whenever `extract_c_string` is implemented.]] |
| ] |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ string] |
| |
| [endsect] [/ string_traits] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:attribute_as Atomically Extract an Attribute Value from a Container (Karma)] |
| |
| [heading attribute_as] |
| |
| `attribute_as` atomically extracts an instance of a type from another type. |
| This customization point is used by the __karma_as__ directive. |
| |
| [heading Module Headers] |
| |
| #include <boost/spirit/home/support/attributes_fwd.hpp> |
| |
| Also, see __include_structure__. |
| |
| [note This header file does not need to be included directly by any user |
| program as it is normally included by other Spirit header files relying |
| on its content.] |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename T, typename Attribute, typename Enable = void> |
| struct attribute_as; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`T`] [The type of the attribute natively |
| exposed by the component the `attribute_as` is |
| invoked from.] [none]] |
| [[`Attribute`] [The type of the attribute to be used to |
| generate output from.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `attribute_as` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`attr`] [An instance of type `Attrib`.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`attribute_as<T, Attribute>::type`] [The result type of the extraction.]] |
| [[`attribute_as<T, Attribute>::call(attr)`] [Extract and return an instance |
| of `type`.]] |
| [[`attribute_as<T, Attribute>::valid_as(attr)`] [Determine, at runtime, if the extraction of |
| an instance of `type` from `attr` |
| would cause an error.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. The following table lists those types together with the types |
| exposed and the corresponding semantics: |
| |
| [table |
| [[Template Parameters] [Semantics]] |
| [[__unused_type__] [The exposed typedef `type` is defined to |
| __unused_type__. The function `call()` returns |
| an instance of __unused_type__.]] |
| ] |
| |
| [heading When to implement] |
| |
| This customization point may need to be implemented when using the __karma_as__ |
| directive. |
| |
| [/ TODO: examples ] |
| |
| [endsect] [/ attribute_as] |
| |
| [/////////////////////////////////////////////////////////////////////////////] |
| [section:auto Create Components from Attributes (Qi and Karma)] |
| |
| [def __auto_parser_requirements__ [link spirit.qi.reference.auto.additional_requirements Additional Attribute Requirements for Parsers]] |
| [def __auto_generator_requirements__ [link spirit.karma.reference.auto.additional_requirements Additional Attribute Requirements for Generators]] |
| [def __auto_parser_example__ [link spirit.qi.reference.auto.example Example for Using the `qi::auto_` Parser]] |
| [def __auto_generator_example__ [link spirit.karma.reference.auto.example Example for Using the `karma::auto_` Generator]] |
| |
| __spirit__ supports the creation of a default parser or a default generator from |
| a given attribute type. It implements a minimal set of predefined mappings from |
| different attribute types to parsers and generators (for a description of the |
| predefined mappings see __auto_parser_requirements__ and |
| __auto_generator_requirements__). |
| The customization points described in this section (__customize_create_parser__ |
| and __customize_create_generator__) can be specialized to define additional |
| mappings for custom data types. |
| |
| [section:create_parser Define a Custom Attribute Mapping for a Parser] |
| |
| [heading create_parser] |
| |
| The template `create_parser` is a type used as an customization point. It is |
| invoked by the /Qi/ __create_parser__ API function in order to create |
| a custom mapping of the given data type to a parser expression. This |
| parser expression will be returned from __create_parser__ whenever the |
| given data type is encountered. |
| |
| [heading Module Headers] |
| |
| // forwards to <boost/spirit/home/qi/auto.hpp> |
| #include <boost/spirit/include/qi_auto.hpp> |
| |
| Also, see __include_structure__. |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename T, typename Enable> |
| struct create_parser |
| { |
| typedef <unspecified> type; |
| static type const& call(); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`T`] [The type, `T` for which a custom mapping to a |
| parser should be established.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `create_generator` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`T`] [An arbitrary type.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`create_parser<T>::type`] [Defines the type of the parser |
| expression returned from `call`.]] |
| [[`create_parser<T>::call()`] [Returns a parser expression (usually |
| this is a proto::expression) to be used |
| as the default parser for the given |
| type, `T`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. All predefined mappings are listed here: __auto_parser_requirements__. |
| |
| [note It is possible to overload the predefined mappings for the listed types |
| by providing your own specialization of the `create_parser` customization |
| point for the type to modify.] |
| |
| [heading When to implement] |
| |
| The customization point `create_parser` needs to be implemented for a specific |
| type whenever this type should be usable with the API function __create_parser__ |
| (which includes using the `qi::auto_` parser and the special API functions |
| based on the automatic creation of the matching parser type). |
| |
| [heading Example] |
| |
| For an example of how to use the customization point `create_parser` |
| please see here: __auto_parser_example__. |
| |
| [endsect] |
| |
| [section:create_generator Define a Custom Attribute Mapping for a Generator] |
| |
| [heading create_generator] |
| |
| The template `create_generator` is a type used as an customization point. It is |
| invoked by the /Karma/ __create_generator__ API function in order to create |
| a custom mapping of the given data type to a generator expression. This |
| generator expression will be returned from __create_generator__ whenever the |
| given data type is encountered. |
| |
| [heading Module Headers] |
| |
| // forwards to <boost/spirit/home/karma/auto.hpp> |
| #include <boost/spirit/include/karma_auto.hpp> |
| |
| Also, see __include_structure__. |
| |
| [heading Namespace] |
| |
| [table |
| [[Name]] |
| [[`boost::spirit::traits`]] |
| ] |
| |
| [heading Synopsis] |
| |
| template <typename T, typename Enable> |
| struct create_generator |
| { |
| typedef <unspecified> type; |
| static type const& call(); |
| }; |
| |
| [heading Template parameters] |
| |
| [table |
| [[Parameter] [Description] [Default]] |
| [[`T`] [The type, `T` for which a custom mapping to a |
| generator should be established.] [none]] |
| [[`Enable`] [Helper template parameter usable to selectively |
| enable or disable certain specializations |
| of `create_generator` utilizing SFINAE (i.e. |
| `boost::enable_if` or `boost::disable_if`).] [`void`]] |
| ] |
| |
| [variablelist Notation |
| [[`T`] [An arbitrary type.]] |
| ] |
| |
| [heading Expression Semantics] |
| |
| [table |
| [[Expression] [Semantics]] |
| [[`create_generator<T>::type`] [Defines the type of the generator |
| expression returned from `call`.]] |
| [[`create_generator<T>::call()`] [Returns a generator expression (usually |
| this is a proto::expression) to be used |
| as the default generator for the given |
| type, `T`.]] |
| ] |
| |
| [heading Predefined Specializations] |
| |
| __spirit__ predefines specializations of this customization point for |
| several types. All predefined mappings are listed here: __auto_generator_requirements__. |
| |
| [note It is possible to overload the predefined mappings for the listed types |
| by providing your own specialization of the `create_generator` customization |
| point for the type to modify.] |
| |
| [heading When to implement] |
| |
| The customization point `create_generator` needs to be implemented for a specific |
| type whenever this type should be usable with the API function __create_generator__ |
| (which includes using the `karma::auto_` generator and the special API functions |
| based on the automatic creation of the matching generator type). |
| |
| [heading Example] |
| |
| For an example of how to use the customization point `create_generator` |
| please see here: __auto_generator_example__. |
| |
| [endsect] |
| |
| [endsect] |
| |
| [endsect] [/ customize] |
| |