Boost logo

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:


> This is getting pretty far afield, isn't it, Larry? ;-)

Yep. Sorry. No more.


>>Jonathan, I'll be trying to rewrite the above code with IOStreams.


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


or, more specifically:

     filtered_streambuf<output> out;

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:


much more helpful since it allowed:

   out<<" a string";


     filtering_ostream out;

which is almost what I needed. I also needed methods allowing the


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:

      - made no mention of ostream

      - 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

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::io::detail::filter_stream_traits< \
                       Mode, Ch, Tr \

I looked above at the definition of filter_stream_traits
( which BTW, is underneath:

//--------------Definition of

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:


as mentioned previously. Thus the outline of marg_ostream would be:

   class marg_ostream: public filtered_ostream

       marg_ostream(std::ostream& a_ostrm)

       void adjust_margin(int delta)
       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.


Boost list run by bdawes at, gregod at, cpdaniel at, john at