Determine if a Type Should be Treated as a Container (Qi and Karma)

| Home | Libraries | People | FAQ | More

#### Determine if a Type Should be Treated as a Container (Qi and Karma)

###### is_container

The template `is_container` is a template meta-function used as an attribute customization point. It is invoked by the Qi Sequence (`>>`) and Karma Sequence (`<<`) operators in order to determine whether a supplied attribute can potentially be treated as a container.

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

###### Namespace

Name
`boost::spirit::traits`

###### Synopsis

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

###### Template parameters

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`

###### Notation

`C`

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

`T1`, `T2`, ...

  Arbitrary types

###### Expression Semantics

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

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

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

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

###### 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` | Needs to be implemented whenever `is_container` is implemented.
`push_back_container` | Qi: List, Kleene, Plus, Repeat.
`container_iterator` | Karma: List (`%`), Kleene (unary `*`), Plus (unary `+`), Repeat.
`begin_container` | Karma: List (`%`), Kleene (unary `*`), Plus (unary `+`), Repeat.
`end_container` | Karma: List (`%`), Kleene (unary `*`), Plus (unary `+`), Repeat.
`deref_iterator` | Karma: List (`%`), Kleene (unary `*`), Plus (unary `+`), Repeat.
`next_iterator` | Karma: List (`%`), Kleene (unary `*`), Plus (unary `+`), Repeat.
`compare_iterators` | Karma: List (`%`), Kleene (unary `*`), Plus (unary `+`), Repeat.

###### Example

For examples of how to use the customization point `is_container` please see here: embedded_container_example, use_as_container, and counter_example.