1 <!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN">
4 <TITLE>Tutorial
</TITLE>
5 <LINK REL=
"stylesheet" HREF=
"../../../../boost.css">
6 <LINK REL=
"stylesheet" HREF=
"../theme/iostreams.css">
12 <H1 CLASS=
"title">Tutorial
</H1>
20 <A HREF='multichar_filters.html'
><IMG BORDER=
0 WIDTH=
19 HEIGHT=
19 SRC='../../../../doc/src/images/prev.png'
></A>
21 <A HREF='tutorial.html'
><IMG BORDER=
0 WIDTH=
19 HEIGHT=
19 SRC='../../../../doc/src/images/up.png'
></A>
22 <A HREF='finite_state_filters.html'
><IMG BORDER=
0 WIDTH=
19 HEIGHT=
19 SRC='../../../../doc/src/images/next.png'
></A>
27 <A NAME=
"dual_use"></A>
28 <H2>2.2.9. Dual-Use Filters
</H2>
32 It can be confusing to maintain two separate filters
— one for input and the other for output
— to implement the same filtering algorithm. One way to avoid this is to use the
<A HREF=
"writing_filters.html#filter_helpers">filter helpers
</A> mentioned above. The filter helpers produce filters which can be used for either input or output, but not both simultaneously. Such filters are called
<A HREF=
"../concepts/dual_use_filter.html">Dual-Use Filters
</A>.
36 A
<A HREF=
"../concepts/dual_use_filter.html">Dual-Use Filter
</A> can be produced by merging the implementations of an
<A HREF=
"../concepts/input_filter.html">InputFilter
</A> and an
<A HREF=
"../concepts/output_filter.html">OutputFilter
</A>, and giving the resulting class a
<A HREF=
"../guide/traits.html#category">category
</A> convertible to
<A HREF=
"../guide/traits.html#category_tags"><CODE>dual_use_filter_tag
</CODE></A>. For example, you can implement a
<A HREF=
"shell_comments_filters.html">shell comments Filter
</A> as a Dual-Use Filter as follows:
39 <PRE CLASS=
"broken_ie"><SPAN CLASS='preprocessor'
>#include
</SPAN> <A CLASS=
"header" HREF=
"../../../../boost/iostreams/char_traits.hpp"><SPAN CLASS=
"literal"><boost/iostreams/char_traits.hpp
></SPAN></A> <SPAN CLASS=
"comment">// EOF, WOULD_BLOCK
</SPAN>
40 <SPAN CLASS='preprocessor'
>#include
</SPAN> <A CLASS=
"header" HREF=
"../../../../boost/iostreams/concepts.hpp"><SPAN CLASS=
"literal"><boost/iostreams/concepts.hpp
></SPAN></A> <SPAN CLASS=
"comment">// input_filter
</SPAN>
41 <SPAN CLASS='preprocessor'
>#include
</SPAN> <A CLASS=
"header" HREF=
"../../../../boost/iostreams/operations.hpp"><SPAN CLASS=
"literal"><boost/iostreams/operations.hpp
></SPAN></A> <SPAN CLASS=
"comment">// get
</SPAN>
43 <SPAN CLASS='keyword'
>namespace
</SPAN> boost {
<SPAN CLASS='keyword'
>namespace
</SPAN> iostreams {
<SPAN CLASS='keyword'
>namespace
</SPAN> example {
45 <SPAN CLASS=
"keyword">class
</SPAN> shell_comments_input_filter :
<SPAN CLASS=
"keyword"><SPAN CLASS=
"keyword"><SPAN CLASS=
"keyword">public
</SPAN></SPAN></SPAN> dual_use_filter {
46 <SPAN CLASS=
"keyword">public
</SPAN>:
47 <SPAN CLASS=
"keyword">explicit
</SPAN> shell_comments_input_filter(
<SPAN CLASS=
"keyword">char
</SPAN> comment_char =
<SPAN CLASS=
"literal">'#'
</SPAN>)
48 : comment_char_(comment_char), skip_(
<SPAN CLASS=
"keyword">false
</SPAN>)
51 <SPAN CLASS=
"keyword">template
</SPAN><<SPAN CLASS=
"keyword">typename
</SPAN> Source
>
52 <SPAN CLASS=
"keyword"><SPAN CLASS=
"keyword">int
</SPAN></SPAN> get(Source
& src)
54 <SPAN CLASS='comment'
>/* same as shell_comments_input_filter::get() */
</SPAN>
57 <SPAN CLASS=
"keyword">template
</SPAN><<SPAN CLASS=
"keyword">typename
</SPAN> Sink
>
58 <SPAN CLASS=
"keyword"><SPAN CLASS=
"keyword">bool
</SPAN></SPAN> put(Sink
& dest,
<SPAN CLASS=
"keyword"><SPAN CLASS=
"keyword">int
</SPAN></SPAN> c)
60 <SPAN CLASS='comment'
>/* same as shell_comments_output_filter::put() */
</SPAN>
63 <SPAN CLASS=
"keyword">template
</SPAN><<SPAN CLASS=
"keyword">typename
</SPAN> Device
>
64 <SPAN CLASS=
"keyword">void
</SPAN> close(Device
&, std::ios_base::openmode)
66 skip_ =
<SPAN CLASS=
"keyword">false
</SPAN>;
68 <SPAN CLASS=
"keyword">private
</SPAN>:
69 <SPAN CLASS=
"keyword">char
</SPAN> comment_char_;
70 <SPAN CLASS=
"keyword"><SPAN CLASS=
"keyword">bool
</SPAN></SPAN> skip_;
73 } } }
<SPAN CLASS=
"comment">// End namespace boost::iostreams:example
</SPAN></PRE>
76 When a
<A HREF=
"../guide/filtering_streams.html">filtering stream or stream buffer
</A> containing a
<A HREF=
"../concepts/closable.html">Closable
</A> <A HREF=
"../concepts/dual_use_filter.html">Dual-Use Filter
</A> is closed, the Filter's member function
<CODE>close
</CODE> is called with one of the values
<CODE>std::ios_base::in
</CODE> or
<CODE>std::ios_base::out
</CODE> as the second function argument, indicating whether the Filter was used for input or output.
82 <A HREF='multichar_filters.html'
><IMG BORDER=
0 WIDTH=
19 HEIGHT=
19 SRC='../../../../doc/src/images/prev.png'
></A>
83 <A HREF='tutorial.html'
><IMG BORDER=
0 WIDTH=
19 HEIGHT=
19 SRC='../../../../doc/src/images/up.png'
></A>
84 <A HREF='finite_state_filters.html'
><IMG BORDER=
0 WIDTH=
19 HEIGHT=
19 SRC='../../../../doc/src/images/next.png'
></A>
94 <P CLASS=
"copyright">© Copyright
2008 <a href=
"http://www.coderage.com/" target=
"_top">CodeRage, LLC
</a><br/>© Copyright
2004-
2007 <a href=
"http://www.coderage.com/turkanis/" target=
"_top">Jonathan Turkanis
</a></P>
96 Use, modification, and distribution are subject to the Boost Software License, Version
2.0. (See accompanying file
<A HREF=
"../../../../LICENSE_1_0.txt">LICENSE_1_0.txt
</A> or copy at
<A HREF=
"http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt
</A>)