<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
 "http://www.w3.org/TR/html4/strict.dtd">
<html><head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

<style type="text/css">

body {
  color: #000000;
  background-color: #FFFFFF;
}

del {
  text-decoration: line-through;
  color: #8B0040;
}
ins {
  text-decoration: underline;
  color: #005100;
}

p.example {
  margin: 2em;
}
pre.example {
  margin: 2em;
}
div.example {
  margin: 2em;
}

code.extract {
  background-color: #F5F6A2;
}
pre.extract {
  margin: 2em;
  background-color: #F5F6A2;
  border: 1px solid #E1E28E;
}

p.function {
}

p.attribute {
  text-indent: 3em;
}

blockquote.std {
  color: #000000;
  background-color: #F1F1F1;
  border: 1px solid #D1D1D1;
  padding: 0.5em;
}

blockquote.stddel {
  text-decoration: line-through;
  color: #000000;
  background-color: #FFEBFF;
  border: 1px solid #ECD7EC;
  padding: 0.5em;
}

blockquote.stdins {
  text-decoration: underline;
  color: #000000;
  background-color: #C8FFC8;
  border: 1px solid #B3EBB3;
  padding: 0.5em;
}

table {
  border: 1px solid black;
  border-spacing: 0px;
  margin-left: auto;
  margin-right: auto;
}
th {
  text-align: left;
  vertical-align: top;
  padding: 0.2em;
  border: none;
}
td {
  text-align: left;
  vertical-align: top;
  padding: 0.2em;
  border: none;
}

</style>

<title>C++ Ostream Buffers</title>
</head>
<body>
<h1>C++ Ostream Buffers</h1>

<p>
ISO/IEC JTC1 SC22 WG21 N3750 - 2013-09-01
</p>

<p>
Lawrence Crowl, Lawrence@Crowl.org
</p>

<p>
<a href="#Introduction">Introduction</a><br>
<a href="#Solution">Solution</a><br>
<a href="#Wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#string.stream.overview">27.8.1 Overview [string.stream.overview]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ostream.buffer">27.8.8 Class template <code>ostream_buffer</code> [ostream.buffer]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ostream.buffer.ctor">27.8.8.1 Constructor [ostream.buffer.ctor]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ostream.buffer.dtor">27.8.8.2 Destructor [ostream.buffer.dtor]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ostream.buffer.memfn">27.8.8.3 Member function [ostream.buffer.memfn]</a><br>
<a href="#References">References</a><br>
</p>


<h2><a name="Introduction">Introduction</a></h2>

<p>
At present,
stream output operations guarantee that they will not produce race conditions,
but do not guarantee that the effect will be sensible.
Some form of external synchronization is required.
Unfortunately, without a standard mechanism for synchronizing,
independently developed software will be unable to synchronize.
</p>

<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3535.html">
N3535 C++ Stream Mutexes</a>
proposed a standard mechanism for finding and sharing a mutex on streams.
At the Spring 2013 standards meeting,
the Concurrency Study Group requested a change
away from a full mutex definition
to a definition that also enabled buffering.
</p>

<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3678.html">
N3678 C++ Stream Guards</a>
proposed a standard mechanism for batching operations on a stream.
That batching may be implemented as mutexees, as buffering,
or some combination of both.
It was the response to the Concurrency Study Group.
A draft of that paper was reviewed in the Library Working Group,
who found too many open issues on what was reasonably exposed
to the 'buffering' part.
</p>

<p>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3665.html">
N3665 Uninterleaved Sring Output Streaming</a>
proposed making streaming of strings of length less than <code>BUFSIZ</code>
appear uninterleaved in the output.
It was a "minimal" functionality change to the existing standard
to address the problem.
The full Committee chose not to adopt that minimal solution.
</p>

<p>
The general concensus in the July 2013 meeting of the Concurrency Study Group
was that buffering should be explicit.
This paper proposes such an explicit buffering.
</p>


<h2><a name="Solution">Solution</a></h2>

<p>
We propose an <code>ostream_buffer</code>,
that provides access to a matching <code>basic_ostringstream</code>
for buffering output operations.
The <code>ostream_buffer</code>,
will atomically transfer the contents
of the <code>basic_ostringstream</code> to an <code>ostream</code>
on destruction of the <code>ostream_buffer</code>.
</p>

<p>
The transfer on destruction
simplifies the code and
ensures at least some output in the presence of an exception.
</p>

<p>
The intent is that the <code>ostream_buffer</code>
is an automatic-duration variable
with a relatively small scope
which constructs the text to appear uninterleaved.
For example,
</p>
<pre class="example">
....
<code>{
  std::ostream_buffer&lt;std::ostream&gt; bout(std::cout);
  bout.stream() &lt;&lt; "Hello, " &lt;&lt; "World!" &lt;&lt; std::endl;
}</code>
....
</pre>

<p>
The wording below
permits implementation of <code>ostream_buffer</code>
with either a <code>stream_mutex</code>
from
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3535.html">
N3535</a>
or with implementations suitable for
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3665.html">
N3665</a>,
e.g. with Posix file locks
<a href="#PSL">[PSL]</a>
</p>


<h2><a name="Wording">Wording</a></h2>

<p>
This wording is relative to N3691.
</p>

<h3><a name="string.stream.overview">27.8.1 Overview [string.stream.overview]</a></h3>

<p>
Edit within paragraph 1 as follows.
</p>

<blockquote class="std">
<p>
The header <code>&lt;sstream&gt;</code>
defines four class templates and eight types
that associate stream buffers with objects
of class basic_string, as described in 21.3.
<ins>
It also defines a class template
to buffer a <code>basic_ostringstream</code>
into an <code>ostream</code>.
</ins>
</blockquote>

<p>
Edit within the synopsis as follows.
</p>

<blockquote class="std">
<pre>
  template &lt;class charT, class traits = char_traits&lt;charT&gt;,
        class Allocator = allocator&lt;charT&gt; &gt;
    class basic_stringstream;
  typedef basic_stringstream&lt;char&gt; stringstream;
  typedef basic_stringstream&lt;wchar_t&gt; wstringstream;

<ins>  template &lt;class Stream&gt;
    class ostream_buffer;</ins>
}
</pre>
</blockquote>

<h3><a name="ostream.buffer">27.8.8 Class template <code>ostream_buffer</code> [ostream.buffer]</a></h3>

<p>
Add a new section.
</p>

<blockquote class="stdins">
<pre><code>template &lt;class Stream&gt;
  class ostream_buffer;</code>
</pre>

<p>
The class template <code>ostream_buffer&lt;Stream&gt;</code>
supports buffering into a <code>basic_ostringstream</code>
and then
automatically transfering the contents of the <code>basic_ostringstream</code>
to an <code>ostream</code>.
</p>

<p>
[<i>Example:</i>
</p>
<pre class="example">
....
<code>{
  std::ostream_buffer&lt;std::ostream&gt; bout(std::cout);
  bout.stream() &lt;&lt; "Hello, " &lt;&lt; "World!" &lt;&lt; std::endl;
}</code>
....
</pre>
<p>
&mdash;<i>end example</i>]
</p>
</blockquote>


<h3><a name="ostream.buffer.ctor">27.8.8.1 Constructor [ostream.buffer.ctor]</a></h3>

<p>
Add a new section.
</p>

<blockquote class="stdins">

<dl>

<dt><code>ostream_buffer(Stream&amp; stream);</code></dt>
<dd>

<p><i>Effects:</i>
Constructs an internal <code>basic_ostringstream</code>.
</p>

</dd>
</dl>

</blockquote>

<h3><a name="ostream.buffer.dtor">27.8.8.2 Destructor [ostream.buffer.dtor]</a></h3>

<p>
Add a new section.
</p>

<blockquote class="stdins">

<dl>

<dt><code>~ostream_buffer();</code></dt>
<dd>

<p><i>Effects:</i>
Transfers the contents of the internal <code>basic_ostringstream</code>
to the <code>Stream</code> specified in the constructor
as an indivisible uninterleaved sequence of characters,
with respect to all other uses of <code>ostream_buffer</code>
on that <code>Stream</code>.
</p>

<p><i>Synchronization:</i>
May or may not acquire a mutex
while transfering characters.
</p>

</dd>
</dl>
</blockquote>

<h3><a name="ostream.buffer.memfn">27.8.8.3 Member function [ostream.buffer.memfn]</a></h3>

<p>
Add a new section.
</p>

<blockquote class="stdins">

<dl>

<dt><code>std::basic_ostringstream&lt;typename Stream::char_type,
typename Stream::traits_type&gt;&amp; stream();</code>
</dt>
<dd>

<p><i>Returns:</i>
A reference to the internal <code>basic_ostring</code>.
</p>

</dl>

</blockquote>


<h2><a name="References">References</a></h2>

<dl>

<dt><a name="PSL">[PSL]</a></dt>
<dd>
<cite>The Open Group Base Specifications Issue 6,
IEEE Std 1003.1, 2004 Edition</cite>,
functions, flockfile,
<a href="http://pubs.opengroup.org/onlinepubs/009695399/functions/flockfile.html">
http://pubs.opengroup.org/onlinepubs/009695399/functions/flockfile.html</a>
</dd>

</dl>


</body></html>
