...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
The repetition directive allows to repeat an arbitrary generator expression
while optionally specifying the lower and upper repetition counts. It
provides a more powerful and flexible mechanism for repeating a generator.
There are grammars that are impractical and cumbersome, if not impossible,
for the basic EBNF iteration syntax ( unary
'*'
and the unary
'+'
) to specify. Examples:
// forwards to <boost/spirit/home/karma/directive/repeat.hpp> #include <boost/spirit/include/karma_repeat.hpp>
Also, see Include Structure.
Name |
---|
|
|
Notation
a
A generator object
num,
num1,
num2
Numeric literals, any unsigned integer value, or a Lazy Argument that evaluates to an unsigned integer value
inf
Placeholder expression standing for 'no upper repeat limit'
Semantics of an expression is defined only where it differs from, or
is not defined in UnaryGenerator
.
Expression |
Semantics |
---|---|
|
Repeat the generator |
|
Repeat the generator |
|
Repeat the generator |
|
Repeat the generator |
Note | |
---|---|
All failing iterations of the embedded generator will consume one element
from the supplied attribute. The overall |
See Compound Attribute Notation.
Expression |
Attribute |
---|---|
|
a: A --> repeat[a]: vector<A> a: Unused --> repeat[a]: Unused
|
|
a: A --> repeat(num)[a]: vector<A> a: Unused --> repeat(num)[a]: Unused
|
|
a: A --> repeat(num1, num2)[a]: vector<A> a: Unused --> repeat(num1, num2)[a]: Unused
|
|
a: A --> repeat(num, inf)[a]: vector<A> a: Unused --> repeat(num, inf)[a]: Unused
|
Important | |
---|---|
The table above uses
The notation of |
It is important to note, that the repeat[]
directive does not perform any buffering
of the output generated by its embedded elements. That means that any
failing element generator might have already generated some output, which
is not rolled back.
Tip | |
---|---|
The simplest way to force a
buffer[repeat[a]]
which will not generate any output in case of
a failing generator
repeat[buffer[a]]
will not generate any partial output from a generator |
The overall complexity of the repetition generator is defined by the complexity of its embedded generator. The complexity of the repeat itself is O(N), where N is the number of repetitions to execute.
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::repeat;
Basic usage of repeat
generator directive:
std::vector<double> v; v.push_back(1.0); v.push_back(2.0); v.push_back(3.0); test_generator_attr("[1.0][2.0][3.0]", repeat['[' << double_ << ']'], v); test_generator_attr("[1.0][2.0]", repeat(2)['[' << double_ << ']'], v); // fails because of insufficient number of items test_generator_attr("", repeat(4)['[' << double_ << ']'], v);