mirror of
https://github.com/boostorg/iostreams.git
synced 2026-02-22 15:32:20 +00:00
221 lines
13 KiB
HTML
Executable File
221 lines
13 KiB
HTML
Executable File
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<TITLE>Function Template close</TITLE>
|
|
<LINK REL='stylesheet' HREF='../../../../boost.css'>
|
|
<LINK REL='stylesheet' HREF='../theme/iostreams.css'>
|
|
<STYLE> H3 CODE { font-size: 120% } </STYLE>
|
|
</HEAD>
|
|
<BODY>
|
|
|
|
<!-- Begin Banner -->
|
|
|
|
<H1 CLASS='title'>Function Template <CODE>close</CODE></H1>
|
|
<HR CLASS='banner'>
|
|
|
|
<!-- End Banner -->
|
|
|
|
<DL class='page-index'>
|
|
<DT><A href='#description'>Description</A></DT>
|
|
<DT><A href='#when'>When is <CODE>close</CODE> invoked?</DT>
|
|
<DT><A href='#headers'>Headers</A></DT>
|
|
<DT><A href='#reference'>Reference</A></DT>
|
|
</DL>
|
|
|
|
<A NAME='description'>
|
|
<H2>Description</H2>
|
|
|
|
<P>
|
|
The two overloads of the function template <CODE>close</CODE> are invoked automatically by the Iostreams Library to indicate to <A HREF="../concepts.html#filter_concepts">Filters</A> and <A HREF="../concepts.html#device_concepts">Devices</A> that a sequence of data is about to end. This gives Filters and Devices an opportunity to free Devices or reset their states in preparation for a fresh stream of data. Filters and Devices which perform output can use the opportunity to write additional data to the end of a stream.
|
|
</P>
|
|
|
|
<P>
|
|
<CODE>close</CODE> is designed to be overloaded or specialized for <A HREF="../concepts.html#filter_concepts">filter</A> and <A HREF="../concepts.html#device_concepts">Device</A> types external to the Iostreams Library. The default implementation, however, should be suitable for most purposes.</P>
|
|
</P>
|
|
|
|
<P>The details regarding when and how <CODE>close</CODE> is invoked are a bit messy:</P>
|
|
|
|
<A NAME='when'>
|
|
<H2>When is <CODE>close</CODE> invoked?</H2>
|
|
|
|
<H4><CODE>streambuf_facade</CODE> and <CODE>stream_facade</CODE></H4>
|
|
|
|
<P>When an instance of <CODE>streambuf_facade</CODE> or <CODE>stream_facade</CODE> based on a Device <CODE>d</CODE> is closed using member function <CODE>close</CODE>, the following sequence of functions calls is made:<P>
|
|
<PRE CLASS='broken_ie'> boost::iostreams::close(d, std::ios_base::in);
|
|
boost::iostreams::close(d, std::ios_base::out);</PRE>
|
|
<P>The effect, if <CODE>D</CODE> is <A HREF="../concepts/closable.html">Closable</A> and controls a single sequence, is as follows:</P>
|
|
<PRE CLASS='broken_ie'> d.close();</PRE>
|
|
<P>If <CODE>D</CODE> is <A HREF="../concepts/closable.html">Closable</A> and controls separate input and output sequences, the effect is as follows:</P>
|
|
<PRE CLASS='broken_ie'> d.close(std::ios_base::in);
|
|
d.close(std::ios_base::out);</PRE>
|
|
|
|
<P>(<I>See</I> the semantics of <CODE>close</CODE> for <A HREF='#close_device'>Device types</A>, below.)
|
|
|
|
<H4><CODE>filtering_streambuf</CODE> and <CODE>filtering_stream</CODE></H4>
|
|
|
|
<P>
|
|
A <A HREF="../classes/filtering_streambuf.html"><CODE>filtering_streambuf</CODE></A> or <A HREF="../classes/filtering_stream.html"><CODE>filtering_stream</CODE></A> is considered to be <I>closed</I> if its lifetime ends while its chain is complete or if its terminal Device is removed using <CODE>pop</CODE> or <CODE>reset</CODE>. When this occurs, the following sequence of calls is made, assuming that the underlying sequence of Filters and Devices is <CODE>f<SUB>1</SUB></CODE>, <CODE>f<SUB>1</SUB></CODE>, ..., <CODE>f<SUB>n-1</SUB></CODE>, <CODE>d</CODE> and the corresponding sequence of stream buffers is <CODE>buf<SUB>1</SUB></CODE>, <CODE>buf<SUB>2</SUB></CODE>, ..., <CODE>buf<SUB>n-1</SUB></CODE>, <CODE>buf<SUB>n</SUB></CODE>:
|
|
|
|
<PRE CLASS='broken_ie'> <SPAN CLASS="keyword">using</SPAN> <SPAN CLASS="keyword">namespace</SPAN> std;
|
|
|
|
<SPAN CLASS='comment'>// Close each input sequence, in reverse order:</SPAN>
|
|
boost::iostreams::close(d,<SPAN STYLE='visibility:hidden'><SUB>n-1</SUB>, buf<SUB>n-1</SUB></SPAN> ios_base::in);
|
|
boost::iostreams::close(f<SUB>n-1</SUB>, buf<SUB>n</SUB>,<SPAN STYLE='visibility:hidden'><SUB>-1</SUB></SPAN> ios_base::in);
|
|
boost::iostreams::close(f<SUB>n-2</SUB>, buf<SUB>n-1</SUB>, ios_base::in);
|
|
<SPAN CLASS='omitted'>...</SPAN>
|
|
boost::iostreams::close(f<SUB>1</SUB>,<SPAN STYLE='visibility:hidden'><SUB>n-</SUB></SPAN> buf<SUB>2</SUB>,<SPAN STYLE='visibility:hidden'><SUB>n-</SUB></SPAN> ios_base::in);
|
|
|
|
<SPAN CLASS='comment'>// Close each output sequence, in order:</SPAN>
|
|
boost::iostreams::close(f<SUB>1</SUB>,<SPAN STYLE='visibility:hidden'><SUB>n-</SUB></SPAN> buf<SUB>2</SUB>,<SPAN STYLE='visibility:hidden'><SUB>n-</SUB></SPAN> ios_base::out);
|
|
boost::iostreams::close(f<SUB>2</SUB>,<SPAN STYLE='visibility:hidden'><SUB>n-</SUB></SPAN> buf<SUB>3</SUB>,<SPAN STYLE='visibility:hidden'><SUB>n-</SUB></SPAN> ios_base::out);
|
|
<SPAN CLASS='omitted'>...</SPAN>
|
|
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>(It may be helpful to refer to <A CLASS='caption_ref' HREF='../filtering_streams.html#figure_3'>Figures 3-6</A>.) 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 <A HREF='#close_filter'>Filter</A> and <A HREF='#close_device'>Device</A> types, below.)
|
|
</P>
|
|
|
|
<A NAME='headers'>
|
|
<H2>Headers</H2>
|
|
|
|
<DL>
|
|
<DT><A CLASS='header' HREF='../../../../boost/iostreams/operations.hpp'><CODE><boost/iostreams/operations.hpp></CODE></A></DT>
|
|
</DL>
|
|
|
|
<A NAME='reference'>
|
|
<H2>Reference</H2>
|
|
|
|
<A NAME='synopsis'>
|
|
<H3>Synopsis</H3>
|
|
|
|
<PRE CLASS='broken_ie'><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
|
|
|
|
<SPAN CLASS="keyword">template</SPAN><<SPAN CLASS="keyword">typename</SPAN> <A CLASS="documented" HREF="#template_params">T</A>>
|
|
<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><<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>>
|
|
<SPAN CLASS="keyword">void</SPAN> <A CLASS="documented" HREF="#close_filter">close</A>(T& t, Device& next, std::ios_base::openmode which);
|
|
|
|
} } <SPAN CLASS='comment'>// End namespace boost::io</SPAN></PRE>
|
|
|
|
<A NAME='close_device'></A>
|
|
<H3>Function Template <CODE>close</CODE> — Device Types</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 <A HREF='../concepts.html#device_concepts'>Device</A> concepts.
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<H4>Semantics</H4>
|
|
|
|
<PRE CLASS='broken_ie'><SPAN CLASS="keyword">template</SPAN><<SPAN CLASS="keyword">typename</SPAN> T>
|
|
<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 <A HREF="../traits.html#category">category</A> as follows:</P>
|
|
|
|
<TABLE STYLE='margin-left:2em' BORDER=1 CELLPADDING=4>
|
|
<TR><TH><CODE>category<T>::type</CODE></TH><TH>semantics</TH></TR>
|
|
<TR>
|
|
<TD VALIGN='top'>not convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A></TD>
|
|
<TD>no-op</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'>convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A> and to <A HREF="../modes.html#bidirectional"><CODE>bidirectional</CODE></A></A></TD>
|
|
<TD>calls <CODE>t.close(which)</CODE></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'>convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A> and to <A HREF="../modes.html#input"><CODE>input</CODE></A> but not to <A HREF="../modes.html#output"><CODE>output</CODE></A></TD>
|
|
<TD>calls <CODE>t.close()</CODE> if <CODE>(which & ios_base::in) != 0</CODE></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'>convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A> and to <A HREF="../modes.html#input"><CODE>output</CODE></A> but not to <A HREF="../modes.html#bidirectional"><CODE>bidirectional</CODE></A></TD>
|
|
<TD>calls <CODE>t.close()</CODE> if <CODE>(which & ios_base::out) != 0</CODE></TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<P>In short:
|
|
<UL>
|
|
<LI CLASS='square'>If <CODE>T</CODE> is not <A HREF="../concepts/closable.html">Closable</A>, <CODE>close</CODE> does nothing.
|
|
<LI CLASS='square'>If <CODE>T</CODE> is <A HREF="../concepts/closable.html">Closable</A> 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>
|
|
|
|
<A NAME='close_filter'></A>
|
|
<H3>Function Template <CODE>close</CODE> — Filter Types</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 <A HREF='../concepts.html#filter_concepts'>Filter</A> concepts</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'><I>Device</I></TD><TD WIDTH='2em' VALIGN='top'>-</TD>
|
|
<TD>A model of one of <A HREF='../concepts/device.html'>Device</A> whose <A HREF='../modes.html'>i/o mode</A> refines that of <CODE>T</CODE>.</TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<H4>Semantics</H4>
|
|
|
|
<PRE CLASS='broken_ie'><SPAN CLASS="keyword">template</SPAN><<SPAN CLASS="keyword">typename</SPAN> T, <SPAN CLASS="keyword">typename</SPAN> Device>
|
|
<SPAN CLASS="keyword">void</SPAN> close(T& t, Device& next, std::ios_base::openmode which);</PRE>
|
|
|
|
<P>The semantics of <CODE>close</CODE> for a Filter type <CODE>T</CODE> depends on its <A HREF="../traits.html#category">category</A> as follows:</P>
|
|
|
|
<TABLE STYLE='margin-left:2em' BORDER=1 CELLPADDING=4>
|
|
<TR><TH><CODE>category<T>::type</CODE></TH><TH>semantics</TH></TR>
|
|
<TR>
|
|
<TD VALIGN='top'>not convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A></TD>
|
|
<TD>no-op</TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'>convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A> and to <A HREF="../modes.html#bidirectional"><CODE>bidirectional</CODE></A></A></TD>
|
|
<TD>calls <CODE>t.close(next, which)</CODE></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'>convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A> and to <A HREF="../modes.html#input"><CODE>input</CODE></A> but not to <A HREF="../modes.html#output"><CODE>output</CODE></A></TD>
|
|
<TD>calls <CODE>t.close(next)</CODE> if <CODE>(which & ios_base::in) != 0</CODE></TD>
|
|
</TR>
|
|
<TR>
|
|
<TD VALIGN='top'>convertible to <A HREF="../traits.html#category_tags"><CODE>closable_tag</CODE></A> and to <A HREF="../modes.html#input"><CODE>output</CODE></A> but not to <A HREF="../modes.html#bidirectional"><CODE>bidirectional</CODE></A></TD>
|
|
<TD>calls <CODE>t.close(next)</CODE> if <CODE>(which & ios_base::out) != 0</CODE></TD>
|
|
</TR>
|
|
</TABLE>
|
|
|
|
<P>In short:
|
|
<UL>
|
|
<LI CLASS='square'>If <CODE>T</CODE> is not <A HREF="../concepts/closable.html">Closable</A>, <CODE>close</CODE> does nothing.
|
|
<LI CLASS='square'>If <CODE>T</CODE> is <A HREF="../concepts/closable.html">Closable</A> 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 i/o mode of <CODE>T</CODE>.
|
|
</UL>
|
|
|
|
<P>The last condition prevents a Filter controlling a single sequence from being closed twice in succession.</P>
|
|
|
|
<!-- Begin Footer -->
|
|
|
|
<HR>
|
|
<P CLASS='copyright'>Revised
|
|
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
|
|
20 May, 2004
|
|
<!--webbot bot="Timestamp" endspan i-checksum="38504" -->
|
|
</P>
|
|
|
|
<P CLASS='copyright'>© Copyright Jonathan Turkanis, 2004</P>
|
|
<P CLASS='copyright'>
|
|
Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at <A HREF='http://www.boost.org/LICENSE_1_0.txt'>http://www.boost.org/LICENSE_1_0.txt</A>)
|
|
</P>
|
|
|
|
<!-- End Footer -->
|
|
|
|
</BODY> |