Parser Directive for Attribute Commit/Rollback (hold[])

| Home | Libraries | People | FAQ | More

##### Parser Directive for Attribute Commit/Rollback (`hold[]`)

###### Description

The `hold[]` directive helps managing attributes, mainly for alternative parsers. It instantiates a new attribute instance for the embedded parser. The value of that attribute instance is copied to the outer attribute if the embedded parser succeeds and it is discarded otherwise. Alternative parsers normally do not rollback changes made to the outer attribute by an failed alternative. Wrapping those alternatives into a `hold[]` directive ensures that only the succeeding alternative gets to modify the attribute.

###### Header

    // forwards to <boost/spirit/home/qi/directive/hold.hpp>
    #include <boost/spirit/include/qi_hold.hpp>

Also, see Include Structure.

###### Namespace

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

###### Model of

> `UnaryParser`

Notation

`a`

  A `Parser`.

###### Expression Semantics

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

Expression | Semantics
--- | ---
`hold[a]` | Create a new attribute instance while parsing `a`, copying the result to the outer attribute only after `a` succeeds.

###### Attributes

See Compound Attribute Notation.

Expression | Attribute
--- | ---

`hold[a]`

    a: A --> hold[a]: A
    a: Unused --> hold[a]: Unused

| Note
The `hold[]` directive uses `swap()` to implement the rollback/commit semantics for the attribute. For this reason the attribute type needs to to be usable with `boost::swap` (needs to either define a proper overload for `swap(attribute_type&, attribute_type&)` or expose a member function `attribute_type::swap(attribute_type&)`.

###### Complexity

> The complexity is defined by the complexity of the subject parser, `a`

###### Example

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

Some using declarations:

    using boost::spirit::qi::hold;
    using boost::spirit::qi::int_;
    using boost::spirit::qi::attr;

The use of `hold[]` here will make sure the changes to the attribute caused by the (failing) first alternative will not be visible after the whole parsing succeeded.

    std::vector<int> v;
    test_phrase_parser_attr("123",
          hold[int_ >> ':' >> int_] | int_ >> attr(0), v);
    std::cout << v[0] << "," << v[1] << std::endl;    // will output: >123,0<