blob: 2afb97776e287626cc1dbc973ee08e2469b8c637 [file] [log] [blame]
[/==============================================================================
Copyright (C) 2001-2010 Hartmut Kaiser
Copyright (C) 2001-2010 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
{
typedef <unspecified> type;
};
[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`]]
]
[heading Notation]
[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]]
[[`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
(See __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] [Value]]
[[`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: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`]]
]
[heading Notation]
[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`.
[heading Example]
TBD
[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`]]
]
[heading Notation]
[variablelist Notation
[[`Attrib`] [A type to be used as the target to store the attribute value in.]]
[[`attr`] [A 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.
[heading Example]
TBD
[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 the all primitive /Qi/ parsers in order
to store a parsed attribute value into the attribute instance 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 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.] [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`]]
]
[heading Notation]
[variablelist Notation
[[`Attrib`] [A type to be used as the target to store the attribute value in.]]
[[`attr`] [A attribute instance of type `Attrib`.]]
[[`T`] [A type as produced by the parser. The parser temporarily stores
its parsed values using this type.]]
[[`t`] [A 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.
[heading Example]
TBD
[endsect] [/ assign_to_attribute_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`]]
]
[heading Notation]
[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] [Value]]
[[`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.
More examples: TBD.
[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`]]
]
[heading Notation]
[variablelist
[[`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`] [A 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] [Value]]
[[`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()`.
More examples: TBD
[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`]]
]
[heading Notation]
[variablelist Notation
[[`Attrib`] [A type to be used as a container to store attribute values in.]]
[[`attr`] [A 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] [Value]]
[[`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()`.
[heading Example]
TBD
[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` 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` 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.]]
]
[heading Notation]
[variablelist Notation
[[`Exposed`] [A type exposed as the native attribute of a component.]]
[[`Attrib`] [A type to be used to generate output from.]]
[[`attr`] [A attribute instance of type `Attrib`.]]
]
[heading Expression Semantics]
[table
[[Expression] [Semantics]]
[[
``extract_from_attribute<Exposed, Attrib>::call(attr, ctx)``]
[Extract the value to generate
output from 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.]]
[[`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.
[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 (Karma)]
[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`]]
]
[heading Notation]
[variablelist
[[`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] [Value]]
[[`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`]]
]
[heading Notation]
[variablelist
[[`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] [Value]]
[[`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`]]
]
[heading Notation]
[variablelist
[[`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] [Value]]
[[`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`]]
]
[heading Notation]
[variablelist
[[`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] [Value]]
[[`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`]]
]
[heading Notation]
[variablelist
[[`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] [Value]]
[[`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`]]
]
[heading Notation]
[variablelist
[[`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] [Value]]
[[`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:auto Create Components from Attributes]
[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`]]
]
[heading Notation]
[variablelist
[[`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`]]
]
[heading Notation]
[variablelist
[[`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]