Generator Directives Consuming Attributes (omit[] and skip[])

| Home | Libraries | People | FAQ | More

##### Generator Directives Consuming Attributes (`omit[]` and `skip[]`)

###### Description

The directives `omit[]` and `skip[]` consumes the attribute type of the embedded generator without generating any output. The `omit[]` directive will still execute the embedded generator while discarding the generated output afterwards. The `skip[]` directive will not execute the embedded generator, but will use it only to extract the exposed attribute type.

###### Header

    // forwards to <boost/spirit/home/karma/directive/omit.hpp>
    #include <boost/spirit/include/karma_omit.hpp>

Also, see Include Structure.

Name
`boost::spirit::omit // alias: boost::spirit::karma::omit`
`boost::spirit::skip // alias: boost::spirit::karma::skip`

###### Model of

> `UnaryGenerator`

Notation

`a`

  A generator object

`A`

  Attribute type of generator `a`

###### Expression Semantics

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

Expression | Semantics
--- | ---
`omit[a]` | The `omit` directive consumes the attribute type of the embedded generator `A` without generating any output. It succeeds always. The embedded generator is executed and any generated output is discarded.
`skip[a]` | The `skip` directive consumes the attribute type of the embedded generator `A` without generating any output. It succeeds always. The embedded generator is not executed.

###### Attributes

See Compound Attribute Notation.

Expression | Attribute
--- | ---

`omit[a]`

    a: A --> omit[a]: A
    a: Unused --> omit[a]: Unused

`skip[a]`

    a: A --> skip[a]: A
    a: Unused --> skip[a]: Unused

###### Complexity

> The overall complexity of the `omit[]` directive depends on the complexity of the embedded generator. The overall complexity of the `skip[]` generator directive is O(1) as it does not generate any output.

###### 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::omit;

Basic usage of a `omit` generator directive. It shows how it consumes the first element of the provided attribute without generating anything, leaving the second element of the attribute to the non-wrapped `double_` generator.

    std::pair<double, double> p (1.0, 2.0);
    test_generator_attr("2.0", omit[double_] << double_, p);

Generally, this directive is helpful in situations, where the attribute type contains more information (elements) than need to be used to generate the required output. Normally in such situations we would resolve to use semantic actions to explicitly pass the correct parts of the overall attribute to the generators. The `omit` directive helps achieving the same without having to use semantic actions.

Consider the attribute type:

    typedef fusion::vector<int, double, std::string> attribute_type;

where we need to generate output only from the first and last element:

    typedef std::back_insert:iterator<std::string> iterator_type;

    karma::rule<iterator_type, attribute_type()> r;
    r = int_[_1 = phoenix::at_c<0>(_val)] << string[_1 = phoenix::at_c<2>(_val)];

    std::string str;
    iterator_type sink(str);
    generate(sink, r, attribute_type(1, 2.0, "example"));  // will generate: '1example'

This is error prone and not really readable. The same can be achieved by using the `omit` directive:

    r = int_ << omit[double_] << string;

which is at the same time more readable and more efficient as we don't have to use semantic actions.

The semantics of using the `skip[]` directive are identical to the `omit[]` directive, except that it does not actually execute the embedded generator. For this reason it is usually preferable to utilize the `skip[]` directive instead of the `omit[]` directive. On the other hand, the `omit[]` directive is very useful whenever the embedded generator produces side effects (has semantic actions which need to be executed).