Boost logo

Boost-Commit :

From: technews_at_[hidden]
Date: 2008-02-22 17:17:27


Author: turkanis
Date: 2008-02-22 17:17:26 EST (Fri, 22 Feb 2008)
New Revision: 43375
URL: http://svn.boost.org/trac/boost/changeset/43375

Log:
documented new close() semantics
Text files modified:
   branches/iostreams_dev/libs/iostreams/doc/concepts/closable.html | 40 +++++++++++++--
   branches/iostreams_dev/libs/iostreams/doc/functions/close.html | 95 +++++++++++++++++++++++++++++++++------
   2 files changed, 113 insertions(+), 22 deletions(-)

Modified: branches/iostreams_dev/libs/iostreams/doc/concepts/closable.html
==============================================================================
--- branches/iostreams_dev/libs/iostreams/doc/concepts/closable.html (original)
+++ branches/iostreams_dev/libs/iostreams/doc/concepts/closable.html 2008-02-22 17:17:26 EST (Fri, 22 Feb 2008)
@@ -32,10 +32,10 @@
 <H4>Closure Notifications</H4>
     
 <P>
- The Iostreams library sends closure notifications by invoking the function close. For a Closable Filter or Device, <CODE>close</CODE> delegates to a member function <CODE>close</CODE>; for other Devices, it does nothing. The details regarding when and how <CODE>close</CODE> is invoked are complicated. However, defining a Filter or Device which receives closure notifications is easy:
+ The Iostreams library sends closure notifications by invoking the function close. For most Closable Filter or Device, <CODE>close</CODE> delegates to a member function <CODE>close</CODE>; for non-Closable Devices, <CODE>close</CODE> calls flush. The details regarding when and how <CODE>close</CODE> is invoked are complicated. However, defining a Filter or Device which receives closure notifications is easy, as illustrated in the following sections.
 </P>
 
-<H2>Examples</H2>
+<H4>Single-Sequence Devices</H4>
 
 <P>
     If a Device controls a single sequence of characters, it can be made Closable simply by specifying a category tag which is convertible to <CODE>closable_tag</CODE> and by adding a member function <CODE>close</CODE>, like so:
@@ -44,13 +44,35 @@
 <P>
     Filters and Devices which derive from the convenience templates and typedefs have category tags convertible to <CODE>closable_tag</CODE> provided automatically.
 </P>
+
+<H4>Single-Sequence Filters</H4>
+
 <P>For Filters controlling a single sequence, the signature of <CODE>close</CODE> is:</P>
 <PRE CLASS="broken_ie"> <SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> Device&gt;
- <SPAN CLASS="keyword">void</SPAN> close(Device&amp;) { <SPAN CLASS="omitted"> ... </SPAN> }</PRE>
+ <SPAN CLASS="keyword">void</SPAN> close(Device&amp;);</PRE>
+<P>The implementation of the member function <CODE>close</CODE> may read from, write to, or seek within the given Device, depending on the mode of the device.</P>
+
+<H4>Two-Sequence Devices</H4>
+
 <P>
- For Filters and Devices controlling separate input and output sequences, the above signatures should be modified by adding a <CODE>std::ios_base::openmode</CODE> parameter at the end of the parameter list. This function will be called twice: first with argument <CODE>std::ios_base::in</CODE>, to signal the closing of the input sequence, and later with argument <CODE>std::ios_base::out</CODE>, to signal the closing of the output sequence.
-</P>
-
+ If a Device controls separate input and output sequences, the signature of <CODE>close</CODE> is:</P>
+ <PRE CLASS="broken_ie"> <SPAN CLASS="keyword">void</SPAN> close(std::ios_base::openmode);</PRE>
+<P>This function will be called twice: first with argument <CODE>std::ios_base::in</CODE>, to signal the closing of the input sequence, and later with argument <CODE>std::ios_base::out</CODE>, to signal the closing of the output sequence. </P>
+
+<H4>Two-Sequence Filters</H4>
+
+<P>
+ If a Filter controls separate input and output sequences, the signature of <CODE>close</CODE> is:</P>
+<PRE CLASS="broken_ie"> <SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> Device&gt;
+ <SPAN CLASS="keyword">void</SPAN> close(Device&amp;, std::ios_base::openmode);</PRE>
+<P>This function will be called twice: first with argument <CODE>std::ios_base::in</CODE>, to signal the closing of the input sequence, and later with argument <CODE>std::ios_base::out</CODE>, to signal the closing of the output sequence.</P>
+
+<H4>Dual-Use Filters</H4>
+
+<P>The signature of <CODE>close</CODE> for DualUserFilters is the same as that for two-sequence Filters.</P>
+<PRE CLASS="broken_ie"> <SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> Device&gt;
+ <SPAN CLASS="keyword">void</SPAN> close(Device&amp;, std::ios_base::openmode);</PRE>
+<P>This function will be called only once, depending on whether the filter is being used for input or output.</P>
 
 <H2>Refinement of</H2>
 
@@ -112,7 +134,11 @@
 
 <H2>Models</H2>
 
-<P>Many of the Filters and Devices provided by the Iostreams library are Closable, but this is an implementation detail.</P>
+<UL>
+ <LI>Generic Streams and Stream Buffers.
+ <LI>Filtering Streams and Stream Buffers.
+ <LI>Standard file streams and stream buffers.</A>
+</UL>
 
 <!-- Begin Footer -->
 

Modified: branches/iostreams_dev/libs/iostreams/doc/functions/close.html
==============================================================================
--- branches/iostreams_dev/libs/iostreams/doc/functions/close.html (original)
+++ branches/iostreams_dev/libs/iostreams/doc/functions/close.html 2008-02-22 17:17:26 EST (Fri, 22 Feb 2008)
@@ -25,8 +25,19 @@
 <A NAME="description"></A>
 <H2>Description</H2>
 
-<P>
- The two overloads of the function template <CODE>close</CODE> are invoked automatically by the Iostreams library to indicate to Filters and Devices that a sequence of data is about to end. This gives Filters and Devices an opportunity to free resources or to reset their states in preparation for a new character sequence. Filters and Devices which perform output can use the opportunity to write additional data to the end of a stream.
+<P>The Iostreams library provides three overloads of the function template <CODE>close</CODE>.</P>
+
+<P>The first overload of <CODE>close</CODE> takes a single Device argument. It allows a user to close a Device without worrying whether the Device controls a single sequence or two sequences:</P>
+
+<PRE CLASS="broken_ie"><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
+
+<SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> <A CLASS="documented" HREF="#template_params">T</A>&gt;
+<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#close_device">close</A>(T& t);
+
+} } <SPAN CLASS="comment">// End namespace boost::io</SPAN></PRE>
+
+
+<P>The other two overloads of <CODE>close</CODE> should rarely be called by library users; they are invoked automatically by the library to indicate to Filters and Devices that a sequence of data is about to end. This gives Filters and Devices an opportunity to free resources or to reset their states in preparation for a new character sequence. Filters and Devices which perform output can use the opportunity to write additional data to the end of a stream.
 </P>
 
 <P>The details regarding when and how <CODE>close</CODE> is invoked are a bit messy:</P>
@@ -68,8 +79,14 @@
     boost::iostreams::close(f<SUB>n-1</SUB>, buf<SUB>n</SUB>,<SPAN STYLE="visibility:hidden"><SUB>n-</SUB></SPAN> ios_base::out);
     boost::iostreams::close(d,<SPAN STYLE="visibility:hidden"><SUB>n-1</SUB>, buf<SUB>n-1</SUB></SPAN> ios_base::out);</PRE>
 </P>
-<P>The effect is that with input streams, the elements of a chain are closed in reverse order; with output streams, they are closed in forward order; and with streams controlling separate input and output sequences, each element receives two closure notifications, the first with argument <CODE>ios_base::in</CODE> and the second with argument <CODE>ios_base::out</CODE>. (<I>See</I> the semantics of <CODE>close</CODE> for Filter and Device types, below.)
-</P>
+<P>This implies</P>
+<UL>
+<LI>For filter chains consisting of read-only components, the elements of the chain are closed in reverse order</LI>
+<LI>For filter chains consisting of write-only components, the elements of the chain are closed in forward order</LI>
+<LI>Filters and Devices controlling separate input and output sequences receive two closure notifications, the first with argument <CODE>ios_base::in</CODE> and the second with argument <CODE>ios_base::out</CODE>.
+</UL>
+
+<P>(<I>See</I> the semantics of <CODE>close</CODE> for Filter and Device types, below.)</P>
 
 <A NAME="headers"></A>
 <H2>Headers</H2>
@@ -88,6 +105,9 @@
 <PRE CLASS="broken_ie"><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
               
 <SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> <A CLASS="documented" HREF="#template_params">T</A>&gt;
+<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#close_convenience">close</A>(T& t);
+
+<SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> <A CLASS="documented" HREF="#template_params">T</A>&gt;
 <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#close_device">close</A>(T& t, std::ios_base::openmode which);
 
 <SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> <A CLASS="documented" HREF="#template_params">T</A>, <SPAN CLASS="keyword">typename</SPAN> <A CLASS="documented" HREF="#template_params">Device</A>&gt;
@@ -95,8 +115,30 @@
 
 } } <SPAN CLASS="comment">// End namespace boost::io</SPAN></PRE>
 
+
+<A NAME="close_convenience"></A>
+<H3>Function Template <CODE>close</CODE> &#8212; Convenience Function</H3>
+
+<A NAME="template_params"></A>
+<H4>Template Parameters</H4>
+
+<TABLE STYLE="margin-left:2em" BORDER=0 CELLPADDING=2>
+<TR>
+ <TR>
+ <TD VALIGN="top"><I>T</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>A model of one of the Device concepts.
+ </TR>
+</TABLE>
+
+<H4>Semantics</H4>
+
+<PRE CLASS="broken_ie"><SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> T&gt;
+<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#close_device">close</A>(T& t);</PRE>
+
+<P>This overload of <CODE>close</CODE> calls <CODE>close(t, std::ios_base::in)</CODE> followed by <CODE>close(t, std::ios_base::out)</CODE>. It ensures that <CODE>t</CODE> is closed properly, regardless of the mode or <CODE>t</CODE>.
+
 <A NAME="close_device"></A>
-<H3>Function Template <CODE>close</CODE> &#8212; Device Types</H3>
+<H3>Function Template <CODE>close</CODE> &#8212; Closure Notification for Devices</H3>
 
 <A NAME="template_params"></A>
 <H4>Template Parameters</H4>
@@ -114,13 +156,27 @@
 <PRE CLASS="broken_ie"><SPAN CLASS="keyword">template</SPAN>&lt;<SPAN CLASS="keyword">typename</SPAN> T&gt;
 <SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#close_device">close</A>(T& t, std::ios_base::openmode which);</PRE>
 
-<P>The semantics of <CODE>close</CODE> for a Device type <CODE>T</CODE> depends on its category as follows:</P>
+<P>If <CODE>t</CODE> is a filtering stream or stream buffer, <CODE>close</CODE> calls <CODE>pop</CODE>:</P>
+
+<TABLE STYLE="margin-left:2em" BORDER=1 CELLPADDING=4>
+ <TR><TH><CODE>category&lt;T&gt;::type</CODE></TH><TH>semantics</TH></TR>
+ <TR>
+ <TD VALIGN="top">convertible to input but not to output</TD>
+ <TD>calls <CODE>t.pop()</CODE> if <CODE>which == ios_base::in</CODE></TD>
+ </TR>
+ <TR>
+ <TD VALIGN="top">otherwise</TD>
+ <TD>calls <CODE>t.pop()</CODE> if <CODE>which == ios_base::out</CODE></TD>
+ </TR>
+</TABLE>
+
+<P>The semantics of <CODE>close</CODE> for a device <CODE>T</CODE> other than a filtering stream or stream buffer depends on its category as follows:</P>
 
 <TABLE STYLE="margin-left:2em" BORDER=1 CELLPADDING=4>
     <TR><TH><CODE>category&lt;T&gt;::type</CODE></TH><TH>semantics</TH></TR>
     <TR>
         <TD VALIGN="top">not convertible to closable_tag</TD>
- <TD>no-op</TD>
+ <TD>calls flush</TD>
     </TR>
     <TR>
         <TD VALIGN="top">convertible to closable_tag and to bidirectional</A></TD>
@@ -128,25 +184,31 @@
     </TR>
     <TR>
         <TD VALIGN="top">convertible to closable_tag and to input but not to output</TD>
- <TD>calls <CODE>t.close()</CODE> if <CODE>(which & ios_base::in) != 0</CODE></TD>
+ <TD>calls <CODE>t.close()</CODE> if <CODE>which == ios_base::in</CODE></TD>
     </TR>
     <TR>
         <TD VALIGN="top">convertible to closable_tag and to output but not to bidirectional</TD>
- <TD>calls <CODE>t.close()</CODE> if <CODE>(which & ios_base::out) != 0</CODE></TD>
+ <TD>calls <CODE>t.close()</CODE> if <CODE>which == ios_base::out</CODE></TD>
     </TR>
 </TABLE>
 
 <P>In short:
 <UL>
- <LI CLASS="square">If <CODE>T</CODE> is not Closable, <CODE>close</CODE> does nothing.
+ <LI CLASS="square">If <CODE>T</CODE> is not Closable, <CODE>close</CODE> calls flush.
     <LI CLASS="square">If <CODE>T</CODE> is Closable and controls two separate sequences, <CODE>close</CODE> delegates to a member function <CODE>close</CODE> taking a single <CODE>openmode</CODE> parameter.
     <LI CLASS="square">Otherwise, <CODE>close</CODE> delegates to a member function <CODE>close</CODE> taking no parameters, but only if its <CODE>openmode</CODE> parameter is consistent with the mode of <CODE>T</CODE>.
 </UL>
 
 <P>The last condition prevents a Device controlling a single sequence from being closed twice in succession.</P>
 
+<P><B>NOTE:</B> Starting with Boost 1.35, the invocation of this function with an <CODE>openmode</CODE> other than <CODE>std::ios_base::in</CODE> or
+ <CODE>std::ios_base::out</CODE> is <B>deprecated</B>. To close both sequences at once, use
+<PRE>close(t)</PRE>
+instead of
+<PRE>close(t, std::ios_base::in | std::ios_base::out)</PRE></P>
+
 <A NAME="close_filter"></A>
-<H3>Function Template <CODE>close</CODE> &#8212; Filter Types</H3>
+<H3>Function Template <CODE>close</CODE> &#8212; Closure Notification for Filters</H3>
 
 <A NAME="template_params"></A>
 <H4>Template Parameters</H4>
@@ -174,7 +236,7 @@
     <TR><TH><CODE>category&lt;T&gt;::type</CODE></TH><TH>semantics</TH></TR>
     <TR>
         <TD VALIGN="top">not convertible to closable_tag</TD>
- <TD>no-op</TD>
+ <TD>calls flush</TD>
     </TR>
     <TR>
         <TD VALIGN="top">convertible to closable_tag and to bidirectional</A></TD>
@@ -182,23 +244,26 @@
     </TR>
     <TR>
         <TD VALIGN="top">convertible to closable_tag and to input but not to output</TD>
- <TD>calls <CODE>t.close(next)</CODE> if <CODE>(which & ios_base::in) != 0</CODE></TD>
+ <TD>calls <CODE>t.close(next)</CODE> if <CODE>which == ios_base::in</CODE></TD>
     </TR>
     <TR>
         <TD VALIGN="top">convertible to closable_tag and to output but not to bidirectional</TD>
- <TD>calls <CODE>t.close(next)</CODE> if <CODE>(which & ios_base::out) != 0</CODE></TD>
+ <TD>calls <CODE>t.close(next)</CODE> if <CODE>which == ios_base::out</CODE></TD>
     </TR>
 </TABLE>
 
 <P>In short:
 <UL>
- <LI CLASS="square">If <CODE>T</CODE> is not Closable, <CODE>close</CODE> does nothing.
+ <LI CLASS="square">If <CODE>T</CODE> is not Closable, <CODE>close</CODE> calls flush.
     <LI CLASS="square">If <CODE>T</CODE> is Closable and controls two separate sequences, <CODE>close</CODE> delegates to a member function <CODE>close</CODE> taking <CODE>openmode</CODE> and stream buffer parameters.
     <LI CLASS="square">Otherwise, <CODE>close</CODE> delegates to a member function <CODE>close</CODE> taking a single stream buffer parameter, but only if its <CODE>openmode</CODE> parameter is consistent with the mode of <CODE>T</CODE>.
 </UL>
 
 <P>The last condition prevents a Filter controlling a single sequence from being closed twice in succession.</P>
 
+<P><B>NOTE:</B> Starting with Boost 1.35, the invocation of this function with an <CODE>openmode</CODE> other than <CODE>std::ios_base::in</CODE> or
+ <CODE>std::ios_base::out</CODE> is <B>deprecated</B>.</P>
+
 <!-- End Footnotes -->
 
 <HR>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk