...one of the most highly
regarded and expertly designed C++ library projects in the
world. — Herb Sutter and Andrei
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.
// forwards to <boost/spirit/home/karma/operator/alternative.hpp> #include <boost/spirit/include/karma_alternative.hpp>
Also, see Include Structure.
Semantics of an expression is defined only where it differs from, or
is not defined in
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.
See Compound Attribute Notation.
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
The table above uses
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.
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.
The test harness for the example(s) below is presented in the Basics Examples section.
#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,
is chosen for output formatting because the supplied attribute type is
not compatible (i.e. not convertible) to the attribute type of the
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
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");