|
Boost : |
From: Larry Evans (cppljevans_at_[hidden])
Date: 2004-09-02 09:31:37
On 08/31/2004 11:36 PM, Jonathan Turkanis wrote:
> "Larry Evans" <cppljevans_at_[hidden]> wrote in:
[snip]
>
http://www.tcpipguide.com/free/t_TCPOperationalOverviewandtheTCPFiniteStateMachineF.htm
>
> This is getting pretty far afield, isn't it, Larry? ;-)
Yep. Sorry. No more.
[snip]
>
>
http://cvs.sourceforge.net/viewcvs.py/boost-sandbox/boost-sandbox/boost/io/filters/ofilter_leftmargin_adjustable.hpp?view=markup
>
>>Jonathan, I'll be trying to rewrite the above code with IOStreams.
[snip]
> I look forward to this. Maybe I can make it one of the examples, or
part of the
> library in the 'text-processing' category.
As you know, I've sent you a copy of the rewrite with IOStreams;
however, I had some problem with using the documentation during the
rewrite. Figuring out the filter was the easy part:
struct margin_output_filter {
template<typename Sink>
void put(Sink& snk, char c)
{
if(at_bol_)
{
for(unsigned i=marg_len_; 0<i; --i)
{
boost::io::put(snk,' ');
}
}
boost::io::put(snk, c);
at_bol_ = c == '\n';
}
bool at_bol_; //indicates at Beginning-Of-Line
unsigned marg_len_; //margin length
};
However, understanding how to connect it to the stream was more
difficult. At first I thought just using the example code from:
libs/io/doc/tutorial.html#tutorial_output_filter
or, more specifically:
filtered_streambuf<output> out;
out.push(toupper_output_filter());
out.push(cout);
but then I had to figure out if the filter was copied or not. From the
above, since the filter was a temporary, it had to be. This seemed
a needless copy; hence, I kept looking for other examples. I found
the file:
libs/io/example/tab_expanding_example.cpp
much more helpful since it allowed:
out<<" a string";
where:
filtering_ostream out;
which is almost what I needed. I also needed methods allowing the
expressions:
++out;
--out;
to increase and decrease the margin width. I also wanted to know that
filtering_ostream could be used everywhere that ostream could be used;
hence, I looked further at the docs:
doc/tutorial.html#tutorial_sink
- made no mention of ostream
doc/filtering_streams.html
- made no mention of ostream
So, I perused the source code in filtering_stream.hpp. Well, with all
the macros, that got pretty difficult, but it did have the comment:
// Description: Defines a template derived from std::basic_streambuf
which uses
// a chain to perform i/o. The template has the following
parameters:
So, I concluded that it wasn't derived from ostream, but then why did
it work with operator<< in tab_expanding_example.cpp? Looking a
little further down, it appears publicly derived from the template
parameter, Stream, whose default value is:
BOOST_DEDUCED_TYPENAME \
boost::io::detail::filter_stream_traits< \
Mode, Ch, Tr \
>::type
I looked above at the definition of filter_stream_traits
( which BTW, is underneath:
//--------------Definition of
filtered_istream--------------------------------//
which is misleading since filtered_ostream is also defined there
)
and saw std::basic_ostream<Ch, Tr>, so I was pretty sure the Stream
default value, when Mode=output, was std::basic_ostream<Ch, Tr>. I
also remember reading somewhere (I forget where) that the filter was
actually stored by reference instead of by value as suggested by:
out.push(toupper_output_filter());
as mentioned previously. Thus the outline of marg_ostream would be:
class marg_ostream: public filtered_ostream
{
public:
...
marg_ostream(std::ostream& a_ostrm)
{
push(marg_filt_);
push(a_ostrm);
}
void adjust_margin(int delta)
{
marg_filt_.marg_len_+=delta;
}
...
private:
margin_output_filter marg_filt_ ;
};
Also, doc/filtering_streams.html contains:
filtering_stream contains a chain of instances of streambuf_facade,
accessed with an interface similar to that of std::stack.
and from that at the initially wrong conclusion about storing the
value of filters instead of just a reference, I thought I'd have to
access the stack of filters by some member function of
filtered_stream. That lead me to look at chain.hpp before I gave up.
Obviously, I was hoping it would be a little easier. Maybe more
examples, and explicitly showing the superclasses of each
xxx_<m>stream where m = 'o' or 'i' or whatever, would have helped as
well as emphasizing that each filter was stored as a reference.
I heartily recommend inclusion of the library in boost and will begin
using it instead of my marg_ostream as soon as it is.
Cheers,
Larry
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk