Alternative Generator (a | b)

| Home | Libraries | People | FAQ | More

##### Alternative Generator (`a | b`)

###### Description

Generator alternatives are used to combine different, more primitive generators into alternatives. All generators in an alternative are invoked from left to right until one of them succeeds.

###### Header

    // forwards to <boost/spirit/home/karma/operator/alternative.hpp>
    #include <boost/spirit/include/karma_alternative.hpp>

Also, see Include Structure.

###### Model of

> `NaryGenerator`

###### Expression Semantics

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

Expression | Semantics
--- | ---
`a | b` | The generators `a` and `b` are executed sequentially from left to right until one of them succeeds. A failed generator forces the alternative generator to try the next one. The alternative fails as a whole only if all elements of the alternative fail. Each element of the alternative gets passed the whole attribute of the alternative.

Alternatives intercept and buffer the output of the currently executed element. This allows to avoid partial outputs from failing elements as the buffered content will be forwarded to the actual output only after an element succeeded.

###### Attributes

See Compound Attribute Notation.

Expression | Attribute
--- | ---

`a | b` (alternative)

    a: A, b: B --> (a | b): variant<A, B>
    a: A, b: Unused --> (a | b): A
    a: Unused, b: B --> (a | b): B
    a: Unused, b: Unused --> (a | b): Unused
    a: A, b: A --> (a | b): A

| Important
The table above uses `variant<A, B>` as a placeholder only. The notation `variant<A, B>` stands for the type `boost::variant<A, B>`.

The attribute handling of Alternatives is special as their behavior is not completely defined at compile time. First of all the selected alternative element depends on the actual type of the attribute supplied to the alternative generator (i.e. what is stored in the variant). The attribute type supplied at runtime narrows the set of considered alternatives to those being compatible attribute wise. The remaining alternatives are tried sequentially until the first of them succeeds. See below for an example of this behavior.

###### Complexity

> The overall complexity of the alternative generator is defined by the sum of the complexities of its elements. The complexity of the alternative itself is O(N), where N is the number of elements in the alternative.

###### Example

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

Some includes:

    #include <boost/spirit/include/karma.hpp>
    #include <boost/spirit/include/support_utree.hpp>
    #include <boost/spirit/include/phoenix_core.hpp>
    #include <boost/spirit/include/phoenix_operator.hpp>
    #include <boost/fusion/include/std_pair.hpp>
    #include <iostream>
    #include <string>

Some using declarations:

    using boost::spirit::karma::double_;
    using boost::spirit::karma::ascii::string;

Basic usage of an alternative. While being only the second alternative, the `double_` generator is chosen for output formatting because the supplied attribute type is not compatible (i.e. not convertible) to the attribute type of the `string` alternative.

    boost::variant<std::string, double> v1(1.0);
    test_generator_attr("1.0", string | double_, v1);
    test_generator_attr("2.0", string | double_, 2.0);

The same formatting rules may be used to output a string. This time we supply the string `"example"`, resulting in the first alternative to be chosen for the generated output.

    boost::variant<std::string, double> v2("example");
    test_generator_attr("example", string | double_, v2);
    test_generator_attr("example", string | double_, "example");