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

Click here to view the latest version of this page.
PrevUpHomeNext
Repetition Directive (repeat[])
Description

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:

Header
// forwards to <boost/spirit/home/karma/directive/repeat.hpp>
#include <boost/spirit/include/karma_repeat.hpp>

Also, see Include Structure.

Namespace

Name

boost::spirit::repeat // alias: boost::spirit::karma::repeat

boost::spirit::inf // alias: boost::spirit::karma::inf

Model of

UnaryGenerator

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'

Expression Semantics

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

Expression

Semantics

repeat[a]

Repeat the generator a zero or more times. This generator succeeds as long as its embedded generator a does not fail (except if the underlying output stream reports an error). This variant of repeat[] is semantically equivalent to the Kleene Star operator *a

repeat(num)[a]

Repeat the generator a exactly num times. This generator succeeds as long as its embedded generator a does not fail and as long as the associated attribute (container) contains at least num elements (unless the underlying output stream reports an error).

repeat(num1, num2)[a]

Repeat the generator a at least num1 times but not more than num2 times. This generator succeeds as long as its embedded generator a does not fail and as long as the associated attribute (container) contains at least num1 elements (unless the underlying output stream reports an error). If the associated attribute (container) does contain more than num2 elements, this directive limits the repeat count to num2.

repeat(num, inf)[a]

Repeat the generator a at least num1 times. No upper limit for the repeat count is set. This generator succeeds as long as its embedded generator a does not fail and as long as the associated attribute (container) contains at least num elements (unless the underlying output stream reports an error).

[Note] Note

All failing iterations of the embedded generator will consume one element from the supplied attribute. The overall repeat[a] will succeed as long as the iteration criteria (number of successful invocations of the embedded generator) is fullfilled (unless the underlying output stream reports an error).

Attributes

See Compound Attribute Notation.

Expression

Attribute

repeat[a]

a: A --> repeat[a]: vector<A>
a: Unused --> repeat[a]: Unused

repeat(num)[a]

a: A --> repeat(num)[a]: vector<A>
a: Unused --> repeat(num)[a]: Unused

repeat(num1, num2)[a]

a: A --> repeat(num1, num2)[a]: vector<A>
a: Unused --> repeat(num1, num2)[a]: Unused

repeat(num, inf)[a]

a: A --> repeat(num, inf)[a]: vector<A>
a: Unused --> repeat(num, inf)[a]: Unused

[Important] Important

The table above uses vector<A> as placeholders only.

The notation of vector<A> stands for any STL container holding elements of type A.

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] Tip

The simplest way to force a repeat[] directive to behave as if it did buffering is to wrap it into a buffering directive (see buffer):

buffer[repeat[a]]

which will not generate any output in case of a failing generator repeat[a]. The expression:

repeat[buffer[a]]

will not generate any partial output from a generator a if it fails generating in the middle of its output. The overall expression will still generate the output as produced by all succeeded invocations of the generator a.

Complexity

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.

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/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);


PrevUpHomeNext