STL Sequence Adapters

Overview
Headers
Examples
Acknowledgments

Overview

The Iostreams library provides the following mechanisms for streams and stream buffers to access standard library sequences:

  1. The overloaded function template adapt returns a Device when passed a single OutputIterator or two ForwardIterators. (See Example I and Example II, below.)
  2. Filtering stream and stream buffer constructors, as well as their member functions push, are overloaded to accept iterator pairs wherever a Filter or Device is permitted.[1] (See Example I and Example II, below.)
  3. The standard library template back_insert_iterator is recognized as a full-fledged model of Sink.
  4. The class template back_insert_device, and the associated object generator boost::iostreams::back_inserter, provide efficient insertion at the end of a sequence.[2] (See Example III, below.)

In addition, the Iostreams library will provide a generic component container_device for accessing an arbitrary STL sequence in a manner similar to std::stringstream. This differs from a Device based on an iterator range, since the underlying sequence expands automatically as characters are written past its end. The component will be flexible enough to store either a reference to or a copy of a provided sequence.[3]

Headers

<boost/iostreams/adapt.hpp>
<boost/iostreams/device/back_inserter.hpp>

Examples

I. Reading from an STL Sequence

One can read existing data from a sequence as follows:

    std::string s = "A shade of sadness, a blush of shame,"
                    "Over the face of the leader came";
    filtering_istream in(adapt(s.begin(), s.end()));

Or equivalently, since filtering stream constuctors are overloaded to accept iterator pairs:

    filtering_istream in(s.begin(), s.end());

II. Overwriting an STL Sequence

One can overwrite the contents of a sequence as follows:

    std::string s = "We till shadowed days are done,"
                    "We must weep and sing";
    filtering_ostream  out(adapt(s.begin(), s.end())); 

Or equivalently, since filtering stream constuctors are overloaded to accept iterator pairs:

    filtering_ostream  out(s.begin(), s.end()); 

III. Appending to an STL Sequence

A stream which appends characters to a sequence, say std::vector, can be defined as follows:

    typedef back_insert_device< vector<char> > vector_sink;
    typedef stream<vector_sink>           appending_ostream;

    vector<char>       v;
    appending_ostream  out(boost::iostreams::back_inserter(v));

Or one can leave the type of Device implicit:

    vector<char>       v;
    filtering_ostream  out(boost::iostreams::back_inserter(v));

Acknowledgments

The sequence adapters were inspired by the work of Maxim Egorushkin ([Egorushkin]).


[1]Item 2 is syntactic sugar, since iterator ranges may be added to filtering streams and stream buffers using the function adapt from item 1. Item 1 is more general, since the return value of adapt may be passed to a function such as copy instead of added to a filtering stream or stream buffer. Items 1 and 2 together could be replaced by allowing instances of iterator_range from the new library Boost.Range to be treated as full-fledged Devices — more precisely, as smart adapters which have their mode supplied at the context of use.

[2]It is probably unnecessary to support both item 3 and item 4, so one will likely be dropped.

[3]This component has been implemented, but not fully tested. (See <boost/iostreams/device/container_device.hpp>.)