<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- saved from url=(0130)http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19 -->
<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++ Synchronized Buffered Ostream</title>
</head>
<body>
<h1>C++ Synchronized Buffered Ostream</h1>

<p>
ISO/IEC JTC1 SC22 WG21 P0053R1 - 2015-10-24
</p>

<p>
Lawrence Crowl, Lawrence@Crowl.org<br>
Peter Sommerlad, Peter.Sommerlad@hsr.ch<br>
Nicolai Josuttis
</p>

<p>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#Introduction">Introduction</a><br>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#Solution">Solution</a><br>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#Design">Design</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#Feature">Feature Test</a><br>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#Wording">Wording</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#contents">17.6.1 Library contents [contents]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#input.output.general">27.1 General [input.output.general]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#iostream.forward">27.3 Forward declarations [iostream.forward]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#syncstream">27.10 Synchronized output stream [syncstream]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#syncstream.overview">27.10.1 Overview [syncstream.overview]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#syncstream.osyncstream">27.10.2 Class template <code>basic_osyncstream</code> [syncstream.osyncstream]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#synstream.osyncstream.ctor">27.10.2.1 Constructor [syncstream.osyncstream.ctor]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#synstream.osyncstream.dtor">27.10.2.2 Destructor [synstream.osyncstream.dtor]</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#syncstream.osyncstream.mfun">27.10.2.3 Member Functions [syncstream.osyncstream.mfun]</a><br>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#implementation">Implementation</a><br>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#Revisions">Revisions</a><br>
<a href="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#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>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3750.html">N3750
C++ Ostream Buffers</a> proposed an explicit buffering,
at the direction of the general consensus
in the July 2013 meeting of the Concurrency Study Group.
In November 2014 a further updated version
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4187.html">N4187</a>
was discussed in Library Evolution in Urbana
and it was consensus to work with a library expert
to get the naming and wording better suited to LWG expectations.
Nico Josuttis volunteered to help the original authors.
More information on the discussion is available at
<a href="http://wiki.edg.com/twiki/bin/view/Wg21urbana-champaign/N4187">LEWG
wiki</a>
and the corresponding
<a href="https://issues.isocpp.org/show_bug.cgi?id=20">LEWG
bug tracker entry (20)</a>.
This paper address issues raised with
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4187.html">N4187</a>.
This paper has a change of title to reflect a change in class name,
but contains the same fundamental approach.
</p>


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

<p>
We propose a <code>basic_osyncstream</code>,
that buffers output operations for a wrapped stream.
The <code>basic_osyncstream</code>
will atomically transfer the contents
of an internal stream buffer
to an <code>ostream</code>
on destruction of the <code>basic_osyncstream</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>basic_osyncstream</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>{
  osyncstream bout(cout);
  bout &lt;&lt; "Hello, " &lt;&lt; "World!" &lt;&lt; endl;
}</code></pre>


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

<p>
We follow typical stream conventions
of <code>basic_</code> prefixes and typedefs.
</p>

<p>
The constructor for <code>osyncstream</code>
takes a non-const reference
to a <code>basic_ostream</code>.
This non-const reference indicates that
the destruction of the buffer
may write to the stream associated with the argument.
</p>

<p>
The wording below
permits implementation of <code>basic_osyncstream</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="http://wiki.edg.com/pub/Wg21oulu/LibraryWorkingGroup/D0053R1_osynstream.html?twiki_redirect_cache=eb7567ff4025519722118612e3e31e19#PSL">[PSL]</a>
</p>

<h3><a name="Feature">Feature Test</a></h3>

<p>
No header called <code>&lt;syncstream&gt;</code> exists;
testing for this header's existence is thus sufficient
for testing existence of the feature.
</p>

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

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

<h3><a name="contents">17.6.1 Library contents [contents]</a></h3>
<p>Add a new entry to table 14:

</p><blockquote class="stdins">
<table>
<tbody><tr>
<td>&lt;syncstream&gt;</td>
</tr>
</tbody></table>
</blockquote>


<h3><a name="input.output.general">27.1 General [input.output.general]</a></h3>

<p>
Add a new row to table 120.
</p>

<blockquote class="stdins">
<table>
<tbody><tr>
<td>27.10</td>
<td>Synchronized output streams</td>
<td>&lt;syncstream&gt;</td>
</tr>
</tbody></table>
</blockquote>

<h3><a name="iostream.forward">27.3 Forward declarations [iostream.forward]</a></h3>

<p>
Add the following forward declarations to the synopsis of &lt;iosfwd&gt;
in the <code>namespace std</code>.
</p>

<blockquote class="stdins">
<pre><code>template &lt;class charT,
          class traits = char_traits&lt;charT&gt;,
          class Allocator = allocator&lt;charT&gt; &gt;
  class basic_osyncstream;
typedef basic_osyncstream&lt;char&gt; osyncstream;
typedef basic_osyncstream&lt;wchar_t&gt; wosyncstream;
</code></pre>
</blockquote>


<h3><a name="syncstream">27.10 Synchronized output stream [syncstream]</a></h3>

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


<h3><a name="syncstream.overview">27.10.1 Overview [syncstream.overview]</a></h3>

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

<blockquote class="stdins">
<p>
The header <code>&lt;syncstream&gt;</code>
provides a mechanism to synchronize execution agents writing to the same stream.
It defines a class template <code>basic_osyncstream</code>
to buffer output and
atomically transfer the buffered content into an <code>ostream</code>.
The transfer occurs when <code>emit()</code> is called
and when the <code>basic_osyncstream</code> object is destroyed.
</p>
</blockquote>

<p>
Add a synopsis for header <code>&lt;syncstream&gt;</code>.
</p>

<blockquote class="stdins">
<pre><code>template &lt;class charT,
          class traits,
          class Allocator&gt;
  class basic_osyncstream;
</code></pre>
</blockquote>


<h3><a name="syncstream.osyncstream">27.10.2 Class template <code>basic_osyncstream</code> [syncstream.osyncstream]</a></h3>

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

<blockquote class="stdins">
<pre><code>template &lt;class charT,
          class traits,
          class Allocator&gt;
class basic_osyncstream
  : public basic_ostream&lt;charT,traits&gt;
{
public:
  typedef charT                          char_type;
  typedef typename traits_type::int_type int_type;
  typedef typename traits_type::pos_type pos_type;
  typedef typename traits_type::off_type off_type;
  typedef traits                         traits_type;
  typedef Allocator                      allocator_type;

  explicit basic_osyncstream(basic_ostream&lt;charT,traits&gt; &amp;os);
  basic_osyncstream(basic_osyncstream&amp;&amp;) = delete;
  ~basic_osyncstream();
  void emit();
  basic_ostream&lt;charT,traits&gt;&amp; get() const;
  basic_osyncstream&amp; operator=(basic_osyncstream&amp;&amp;) = delete;
};
</code></pre>

<p>
The class template <code>basic_osyncstream</code>
supports buffering into an internal buffer
and then
atomically transfering the contents of the buffer
to a <code>basic_ostream</code>.
</p>

<p>
[<i>Example:</i>
Use a named variable within a block statement for streaming
acrosss multiple statments.
</p>
<pre class="example"><code>{
  osyncstream bout(cout);
  bout &lt;&lt; "Hello, ";
  bout &lt;&lt; "World!";
  bout &lt;&lt; endl;
}</code></pre>
<p>
<i>end example</i>]
</p>

<p>
[<i>Example:</i>
Use a temporary object for streaming within a single statement.
</p>
<pre class="example"><code>osyncstream(cout) &lt;&lt; "Hello, " &lt;&lt; "World!" &lt;&lt; endl;</code></pre>
<p>
<i>end example</i>]
</p>

</blockquote>


<h3><a name="synstream.osyncstream.ctor">27.10.2.1 Constructor [syncstream.osyncstream.ctor]</a></h3>

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

<blockquote class="stdins">

<dl>

<dt><code>explicit basic_osyncstream(basic_ostream&lt;charT,traits&gt;&amp; os);</code></dt>
<dd>

<p><i>Effects:</i>
Stores the reference <code>os</code>,
which will be the final destination of characters.
</p>

<p>
[<i>Note:</i>
May construct a mutex. 
<i>end note</i>]
</p>

<p>
Constructs a <code>streambuf</code>.
Any flush on the <code>streambuf</code>
will not act immediately on <code>os</code>,
but will be deferred until immediately after
the transfer of characters to <code>os</code>.
</p>

</dd>

</dl>

</blockquote>


<h3><a name="synstream.osyncstream.dtor">27.10.2.2 Destructor [synstream.osyncstream.dtor]</a></h3>

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

<blockquote class="stdins">

<dl>

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

<p><i>Effects:</i>
As if <code>emit()</code>.
</p>
<p>
[<i>Note:</i> 
May destroy a lock. 
<i>end note</i>]
</p>

<p>
[<i>Example:</i>
To protect against exceptions from within the destructor,
use <code>emit()</code> to catch them.
</p>
<pre class="example"><code>{
  osyncstream bout(cout);
  bout &lt;&lt; "Hello, " &lt;&lt; "World!" &lt;&lt; endl;
  try {
    bout.emit();
  } catch ( ... ) {
    // stuff
  }
}</code>
</pre>
<p>
<i>end example</i>]
</p>

</dd>
</dl>

</blockquote>


<h3><a name="syncstream.osyncstream.mfun">27.10.2.3 Member Functions [syncstream.osyncstream.mfun]</a></h3>

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

<blockquote class="stdins">

<dl>

<dt><code>void emit();</code></dt>
<dd>

<p><i>Effects:</i>
Transfers the contents of the internal <code>streambuf</code>
to the stream specified in the constructor,
so that they appear in the output stream as a contiguous sequence of characters,
with respect to all other uses of <code>basic_osyncstream</code>
on that stream.
If and only if a flush was requested on the <code>streambuf</code>,
the stream specified in the constructor will be flushed.
</p>

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

</dd>

<dt><code>basic_ostream&lt;charT,traits&gt;&amp; get() const;</code></dt>
<dd>

<p><i>Returns:</i>
The reference to the wrapped <code>basic_ostream</code>.
</p>

<p>[<i>Example:</i>
Obtaining the wrapped <code>basic_osyncstream</code> with <code>get()</code> allows wrapping it 
again with a <code>basic_osyncstream</code>.
For example,
</p>
<pre class="example"><code>{
  osyncstream bout1(cout);
  bout1 &lt;&lt; "Hello, ";
  {
    osyncstream bout2(bout1.get());
    bout2 &lt;&lt; "Goodbye, " &lt;&lt; "Planet!" &lt;&lt; endl;
  }
  bout1 &lt;&lt; "World!" &lt;&lt; endl;
}</code></pre>
<p>
produces the <em>uninterleaved</em> output
</p>
<pre class="example"><code>Goodbye, Planet!
Hello, World!
</code></pre>
<p>
<i>end example.</i>]
</p>


</dd>


</dl>

</blockquote>

<h2><a name="implementation">Implementation</a></h2>

<p>
The streambuf class used by basic_osyncstream could be something along the lines of the 
following.
</p>

<blockquote>

<pre><code>template &lt;class charT, class traits, class Allocator&gt;
class noteflush_streambuf
  : public std::basic_stringbuf&lt;charT,traits,Allocator&gt;
{
  protected:
    virtual int sync();
};
</code></pre>
<p>
The class template <code>noteflush_streambuf</code>
behaves like a <code>basic_stringbuf</code>
except that flushes of the stream using it,
which incur in calling the <code>sync()</code> member function,
are noted instead of being a no-op.
</p>

<dl>
<dt><code>int sync() noexcept;</code></dt>
<dd>

<p><i>Effects:</i>
Notes the request of a flush within the object.
</p>
<p>[<i>Note</i>:
Any call to <code>sync()</code> ensures that
a subsequent call to <code>emit()</code>
in the owning <code>basic_osyncstream</code>
will flush the stream being synchronized.
<i>end note</i>]
</p>

<p><i>Returns:</i>
<code>0</code>.
</p>

</dd>

</dl>

</blockquote>


<h2><a name="Revisions">Revisions</a></h2>
<p>
This paper revises
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0053r0.html">
P0053R0 C++ Synchronized Buffered Ostream</a>
</p>
<ul>
<li>
<p>
List the new header in corresponding table.
</p>
</li>
<li>
<p>
Provide type aliases in &lt;iosfwd&gt;.
</p>
</li>

<li>
<p>
Removed copy constructor in favor of providing get().
</p>
</li>
<li>
<p>
Notify that move construction and assignment is deleted.
</p>
</li>
<li>
<p>
Moved class noteflush_streambuf into an implementation note.
</p>
</li>
<li>
<p>
Add a design subsection that states that
a header test is a sufficient feature test.
</p>
</li>
</ul>


<p>
This paper revises
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4187.html">
N4187 C++ Ostream Buffers</a>
</p>

<ul>

<li><p>
Updated introduction with recent history.
</p></li>

<li><p>
Rename <code>ostream_buffer</code> to <code>osyncstream</code>
to reflect its appearance is more like a stream than like a buffer.
</p></li>

<li><p>
Add an example of using <code>osyncstream</code> as a temporary object.
</p></li>

<li><p>
Add an example of a <code>osyncstream</code>
constructed with another <code>osyncstream</code>.
</p></li>

<li><p>
Clarify the behavior of nested <code>osyncstream</code> executions.
</p></li>

<li><p>
Clarify the behavior of exceptions
occuring with the <code>osyncstream</code> destructor.
</p></li>

<li><p>
Clarify the deferral of flush from the 
<code>osyncstream</code>'s <code>streambuf</code>
to the final <code>basic_ostream</code>.
</p></li>

<li><p>
Limit the number of references to <code>noteflush_stringbuf</code>
in anticipation of the committee removing it from the specification.
</p></li>

<li><p>
Rename <code>noteflush_stringbuf</code>
to <code>noteflush_streambuf</code> to hide possible implementation details.
</p></li>

<li><p>
Change the base class of <code>noteflush_streambuf</code>
from <code>basic_stringbuf</code> to <code>basic_streambuf</code>.
</p></li>

</ul>

<p>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4187.html">
N4187</a>
revised
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4069.html">
N4069 C++ Ostream Buffers</a>
</p>

<ul>
<li><p>
Added note to sync as suggested by BSI via email.
</p></li>
</ul>

<p>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4069.html">
N4069</a>
revised
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3978.html">
N3978 C++ Ostream Buffers</a>
</p>

<ul>

<li><p>
Added a Design section.
</p></li>

<li><p>
Clarify the reference capturing behavior
of the <code>ostream_buffer</code> constructors.
</p></li>

<li><p>
Added noexcept and const as appropriate to members.
</p></li>

<li><p>
Added note on throwing wrapped streams.
</p></li>

<li><p>
Change the
<code>noteflush_stringbuf</code>
public member variable
<code>needsflush</code>
to a public member query function <code>flushed</code>.
</p></li>

<li><p>
Removed the public member function <code>noteflush_stringbuf::clear</code>.
</p></li>

<li><p>
Minor synopsis formatting changes.
</p></li>

<li><p>
Incorporated feedback from SG1 and Dietmar Khl in specific in Rapperswil.
</p></li>
</ul>

<p>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3978.html">
N3978</a> revised
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3892.html">
N3892 C++ Ostream Buffers</a>
</p>

<ul>

<li><p>
Flush the ostream if and only if the <code>ostream_buffer</code> was flushed.
</p></li>

<li><p>
Add the <code>clear_for_reuse</code> function.
</p></li>

<li><p>
Change the design from inheriting from <code>basic_ostream</code>
to using a <code>noteflush_stringbuf</code>,
which is a slightly modified <code>basic_stringbuf</code>.
The modification is to note the flush rather than act upon it.
</p></li>

</ul>

<p>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3892.html">
N3892</a> revised
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3750.html">
N3750 C++ Ostream Buffers</a>
</p>

<ul>

<li><p>
Change name to <code>basic_ostream_buffer</code>
and add the usual typedefs.
</p></li>

<li><p>
Change interface to inherit from <code>basic_ostringstream</code>
rather than provide access to a member of that type.
</p></li>

<li><p>
Add a Revisions section.
</p></li>

</ul>


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