| Home | Libraries | People | FAQ | More

##### Store a Parsed Attribute Value into a Container (Qi)

###### 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 (Kleene, Plus, List, and Repeat) to store a parsed attribute value into 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 Attrib, typename Enable>
    struct push_back_container
    {
        static bool call(Container& c, Attrib const& val);
    };

###### Template parameters

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

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

  A attribute instance of type `Attrib`.

`T1`, `T2`, ...

  Arbitrary types

###### Expression Semantics

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.

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

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

###### 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
--- | ---
`container_value` | 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 T, typename Enable/* = void*/>
    struct push_back_container
    {
        static bool call(Container& c, T const& val)
        {
            c.insert(c.end(), val);
            return true;
        }
    };

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

    template <typename Container>
    bool push_back(Container&, unused_type)
    {
        return true;
    }

which defines an empty member function `call()`.

More examples: TBD