Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext
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] 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] 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/phoenix/core.hpp>
#include <boost/phoenix/operator.hpp>
#include <boost/fusion/include/std_pair.hpp>
#include <boost/proto/deep_copy.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");


PrevUpHomeNext