Parser Directives Forcing Atomic Assignment (as<T>, as_string[], as_wstring[])

| Home | Libraries | People | FAQ | More

##### Parser Directives Forcing Atomic Assignment (`as<T>, as_string[], as_wstring[]`)

###### Description

The `as<T>` class forces the atomic assignment of it's subject's synthesized attribute. Usually, repetitive parsers (such as Kleene, etc) or sequences exposing a `vector<A>` will assign elements to the container supplied as their synthesized attribute by calling `traits::push_back_container` repeatedly. In some cases, this may be undesirable. The `as<T>` class creates a directive that will pass a temporary object of type `T` to it's subject. If the subject parser passes, the temporary object will be assigned to the directive's supplied attribute with a single call to `traits::assign_to`. If the subject parser fails, the directive's attribute is not mutated.

| Note
`T` is required to be a container type. If `traits::is_container` does not return true for `T`, a compile-time error will occur.

| Note
The `as<T>` implicitly causes commit/rollback semantics similar in nature to the `hold` directive.

| Caution
The `traits::assign_to` customization point may end up using `traits::push_back_container` to assign the temporary object to the supplied attribute by default, depending on the types involved. Use the interface described in Customization of Attribute Handling to manipulate the semantics of this assignment operation.

###### Header

    // forwards to <boost/spirit/home/qi/directive/as.hpp>
    #include <boost/spirit/include/qi_as.hpp>

Also, see Include Structure.

###### Namespace

Name
`boost::spirit::as // alias: boost::spirit::qi::as`
`boost::spirit::as_string // alias: boost::spirit::qi::as_string`
`boost::spirit::as_wstring // alias: boost::spirit::qi::as_wstring`

###### Synopsis

    template <typename T>
    struct as;

###### Template parameters

Parameter | Description | Default
--- | --- | ---
`T` | A container type. [none

###### Model of

> `UnaryParser`

Notation

`a`

  A `Parser`.

`t`

  A container of type `T`.

`attr`

  The attribute supplied to the directive.

###### Expression Semantics

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

Expression | Semantics
--- | ---
`as<T>()[a]` | Create a temporary object of `t` of type `T`, and invoke the subject parser `a`, supplying `t` as an attribute. If the subject parser passes, assign `t` to `attr`.
`as_string[a]` | Equivalent to `as<std::string>()[a]`
`as_wstring[a]` | Equivalent to `as<std::wstring>()[a]`

###### Attributes

See Compound Attribute Notation.

Expression | Attribute
--- | ---
`as<T>()[a]` | `a: A --> as<T>()[a]: T`

###### Complexity

> The complexity is defined by the complexity of the subject parser, `a`, and the complexity of the assignment of the container `t` to the supplied attribute `attr`.

###### Example

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

Some using declarations:

    using boost::spirit::utree;
    using boost::spirit::utree_type;
    using boost::spirit::utf8_symbol_type;
    using boost::spirit::qi::as;
    using boost::spirit::qi::as_string;
    using boost::spirit::qi::char_;

Simple usage of `as<T>`, `as_string` and `as_wstring`:

To properly handle string concatenation with `utree`, we make use of `as_string[]`. We also use `as<T>` to explicitly create a `utree` symbol node.

    utree ut;

    typedef as<utf8_symbol_type> as_symbol_type;
    as_symbol_type const as_symbol = as_symbol_type();

    test_parser_attr("foo", as_string[*char_], ut);
    std::cout << ut << std::endl; // will output >"foo"<
    BOOST_ASSERT(ut.which() == utree_type::string_type);
    ut.clear();

    test_parser_attr("foo", as<std::string>()[*char_], ut);
    std::cout << ut << std::endl; // will output >"foo"<
    BOOST_ASSERT(ut.which() == utree_type::string_type);
    ut.clear();

    test_parser_attr("foo", as_symbol[*char_], ut);
    std::cout << ut << std::endl; // will output >foo<
    BOOST_ASSERT(ut.which() == utree_type::symbol_type);
    ut.clear();

    test_parser_attr("foo", as<utf8_symbol_type>()[*char_], ut);
    std::cout << ut << std::endl; // will output >foo<
    BOOST_ASSERT(ut.which() == utree_type::symbol_type);