| Home | Libraries | People | FAQ | More

##### Attribute Transformation Pseudo Parser (`attr_cast`)

###### Description

The `attr_cast<Exposed, Transformed>()` component invokes the embedded parser while supplying an attribute of type `Transformed`. The supplied attribute gets created from the original attribute (of type `Exposed`) passed to this component using the customization point `traits::transform_attribute`.

###### Header

    // forwards to <boost/spirit/home/qi/auxiliary/attr_cast.hpp>
    #include <boost/spirit/include/qi_attr_cast.hpp>

Also, see Include Structure.

###### Namespace

Name
`boost::spirit::attr_cast // alias: boost::spirit::qi::attr_cast`

###### Synopsis

    template <Exposed, Transformed>
    <unspecified> attr_cast(<unspecified>);

###### Template parameters

Parameter | Description | Default
--- | --- | ---
`Exposed` | The type of the attribute supplied to the `attr_cast`. | `unused_type`
`Transformed` | The type of the attribute expected by the embedded parser `p`. | `unused_type`

The `attr_cast` is a function template. It is possible to invoke it using the following schemes:

    attr_cast(p)
    attr_cast<Exposed>(p)
    attr_cast<Exposed, Transformed>(p)

depending on which of the attribute types can be deduced properly if not explicitly specified.

###### Model of

> `UnaryParser`

Notation

`p`

  A parser object.

###### Expression Semantics

Semantics of an expression is defined only where it differs from, or is not defined in `UnaryParser`.

Expression | Semantics
--- | ---
`attr_cast(p)` | Create a component invoking the parser `p` while passing an attribute of the type as normally expected by `p`. The type of the supplied attribute will be transformed to the type `p` exposes as its attribute type (by using the attribute customization point `traits::transform_attribute`).
`attr_cast<Exposed>(p)` | Create a component invoking the parser `p` while passing an attribute of the type as normally expected by `p`. The supplied attribute is expected to be of the type `Exposed`, it will be transformed to the type `p` exposes as its attribute type (using the attribute customization point `traits::transform_attribute`).
`attr_cast<Exposed, Transformed>(p)` | Create a component invoking the parser `p` while passing an attribute of type `Transformed`. The supplied attribute is expected to be of the type `Exposed`, it will be transformed to the type `Transformed` (using the attribute customization point `traits::transform_attribute`).

###### Attributes

Expression | Attribute
--- | ---
`attr_cast(p)` | `p: A --> attr_cast(p): A`
`attr_cast<Exposed>(p)` | `p: A --> attr_cast<Exposed>(p): Exposed`
`attr_cast<Exposed, Transformed>(p)` | `p: A --> attr_cast<Exposed, Transformed>(p): Exposed`

###### Complexity

> The complexity of this component is fully defined by the complexity of the embedded parser `p`.

###### Example

| Note
The test harness for the example(s) below is presented in the Basics Examples section.

Some using declarations:

    using boost::spirit::qi::int_;

The example references data structure `int_data` which needs a specialization of the customization point `traits::transform_attribute`:

    // this is just a test structure we want to use in place of an int
    struct int_data
    {
        int i;
    };

    // we provide a custom attribute transformation to allow its use as an int
    namespace boost { namespace spirit { namespace traits
    {
        // in this case we just expose the embedded 'int' as the attribute instance
        // to use, allowing to leave the function 'post()' empty
        template <>
        struct transform_attribute<int_data, int, qi::domain>
        {
            typedef int& type;
            static int& pre(int_data& d) { return d.i; }
            static void post(int_data& val, int const& attr) {}
            static void fail(int_data&) {}
        };
    }}}

Now we use the `attr_cast` pseudo parser to invoke the attribute transformation:

    int_data d = { 0 };
    test_parser_attr("1", boost::spirit::qi::attr_cast(int_), d);
    std::cout << d.i << std::endl;