Determine the Type to be Stored in a Container (Qi)

| Home | Libraries | People | FAQ | More

##### Determine the Type to be Stored in a Container (Qi)

###### 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 (Kleene, Plus, List, and Repeat) to determine the type to store in a container.

###### 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.

###### Namespace

Name
`boost::spirit::traits`

###### Synopsis

    template <typename Container, typename Enable>
    struct container_value
    {
        typedef <unspecified> type;
    };

###### Template parameters

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`

###### Notation

`C`

  A type to be tested whether it needs to be treated as a container.

`T1`, `T2`, ...

  Arbitrary types

###### Expression Semantics

Expression | Semantics
--- | ---
`container_value<C>::type` | Metafunction that evaluates to the type to be stored in a given container type, `C`.

###### 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:

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`.

###### 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 (Spirit.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`.

###### Related Attribute Customization Points

If this customization point is implemented, the following other customization points might need to be implemented as well.

Name | When to implement
--- | ---
`push_back_container` | Qi: List, Kleene, Plus, Repeat.
`clear_value` | Qi: List, Kleene, Plus, Repeat.

###### Example

Here is an example showing the default implementation of the `container_value` customization point provided by the library:

    template <typename Container, typename Enable/* = void*/>
    struct container_value
      : detail::remove_value_const<typename Container::value_type>
    {};

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`:

    template <>
    struct container_value<unused_type>
    {
        typedef unused_type type;
    };

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.