Stream Generators (stream, wstream, etc.)

| Home | Libraries | People | FAQ | More

##### Stream Generators (`stream`, `wstream`, etc.)

###### Description

The `stream_generator` is a primitive which allows to use pre-existing standard streaming operators for output generation integrated with Spirit.Karma. It provides a wrapper generator dispatching the value to output to the stream operator of the corresponding type. Any value `a` to be formatted using the `stream_generator` will result in invoking the standard streaming operator for its type `A`, for instance:

    std::ostream& operator<< (std::ostream&, A const&);

###### Header

    // forwards to <boost/spirit/home/karma/stream.hpp>
    #include <boost/spirit/include/karma_stream.hpp>

Also, see Include Structure.

###### Namespace

Name
`boost::spirit::stream // alias: boost::spirit::karma::stream`
`boost::spirit::wstream // alias: boost::spirit::karma::wstream`

###### Synopsis

    template <typename Char>
    struct stream_generator;

###### Template parameters

Parameter | Description | Default
--- | --- | ---
`Char` | The character type to use to generate the output. This type will be used while assigning the generated characters to the underlying output iterator. | `char`

###### Model of

> `PrimitiveGenerator`

Notation

`s`

  A variable instance of any type with a defined matching streaming `operator<<()` or a Lazy Argument that evaluates to any type with a defined matching streaming `operator<<()`.

###### Expression Semantics

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

Expression | Description
--- | ---
`stream` | Call the streaming `operator<<()` for the type of the mandatory attribute. The output emitted by this operator will be the result of the `stream` generator. This generator never fails (unless the underlying output stream reports an error). The character type of the I/O ostream is assumed to be `char`.
`stream(s)` | Call the streaming `operator<<()` for the type of the immediate value `s`. The output emitted by this operator will be the result of the `stream` generator. This generator never fails (unless the underlying output stream reports an error). The character type of the I/O ostream is assumed to be `char`.
`wstream` | Call the streaming `operator<<()` for the type of the mandatory attribute. The output emitted by this operator will be the result of the `stream` generator. This generator never fails (unless the underlying output stream reports an error). The character type of the I/O ostream is assumed to be `wchar_t`.
`wstream(s)` | Call the streaming `operator<<()` for the type of the immediate value `s`. The output emitted by this operator will be the result of the `stream` generator. This generator never fails (unless the underlying output stream reports an error). The character type of the I/O ostream is assumed to be `wchar_t`.

All generators listed in the table above are predefined specializations of the `stream_generator<Char>` basic stream generator type described below. It is possible to directly use this type to create stream generators using an arbitrary underlying character type.

Expression | Semantics
--- | ---
    stream_generator<
        Char
    >()
| Call the streaming `operator<<()` for the type of the mandatory attribute. The output emitted by this operator will be the result of the `stream` generator. This generator never fails (unless the underlying output stream reports an error). The character type of the I/O ostream is assumed to be `Char`
    stream_generator<
        Char
    >()(s)
| Call the streaming `operator<<()` for the type of the immediate value `s`. The output emitted by this operator will be the result of the `stream` generator. This generator never fails (unless the underlying output stream reports an error). The character type of the I/O ostream is assumed to be `Char`.

###### Additional Requirements

All of the stream generators listed above require the type of the value to generate output for (either the immediate value or the associated attribute) to implement a streaming operator conforming to the usual I/O streams conventions (where `attribute_type` is the type of the value to generate output for):

    template <typename Ostream>
    Ostream& operator<< (Ostream& os, attribute_type const& attr)
    {
        // type specific output generation
        return os;
    }

This operator will be called by the stream generators to gather the output for the attribute of type `attribute_type`. All data streamed into the given `Ostream` will end up being generated by the corresponding stream generator instance.

| Note
If the `stream` generator is invoked inside a `format` (or `format_delimited`) stream manipulator the `Ostream` passed to the `operator<<()` will have registered (imbued) the same standard locale instance as the stream the `format` (or `format_delimited`) manipulator has been used with. This ensures all facets registered (imbued) with the original I/O stream object are used during output generation.

###### Attributes

Expression | Attribute
--- | ---
`stream` | `hold_any`, attribute is mandatory (otherwise compilation will fail)
`stream(s)` | `unused`
`wstream` | `whold_any`, attribute is mandatory (otherwise compilation will fail)
`wstream(s)` | `unused`
`stream_generator<Char>()` | `basic_hold_any<Char>`, attribute is mandatory (otherwise compilation will fail)
`stream_generator<Char>()(s)` | `unused`

| Important
The attribute type `hold_any` exposed by some of the stream generators is semantically and syntactically equivalent to the type implemented by Boost.Any. It has been added to Spirit as it has better a performance and a smaller footprint if compared to Boost.Any.

| Note
In addition to their usual attribute of type `Attrib` all listed generators accept an instance of a `boost::optional<Attrib>` as well. If the `boost::optional<>` is initialized (holds a value) the generators behave as if their attribute was an instance of `Attrib` and emit the value stored in the `boost::optional<>`. Otherwise the generators will fail.

###### Complexity

> O(N), where N is the number of characters emitted by the stream generator

###### 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/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::stream;

And a class definition used in the examples:

    // a simple complex number representation z = a + bi
    struct complex
    {
        complex (double a, double b)
          : a(a), b(b)
        {}

        double a;
        double b;
    };

    // define streaming operator for the type complex
    std::ostream&
    operator<< (std::ostream& os, complex const& z)
    {
        os << "{" << z.a << "," << z.b << "}";
        return os;
    }

Basic usage of `stream` generators:

    test_generator_attr("abc", stream, "abc");
    test_generator("abc", stream("abc"));
    test_generator_attr("{1.2,2.4}", stream, complex(1.2, 2.4));
    test_generator("{1.2,2.4}", stream(complex(1.2, 2.4)));