Boost logo

Boost :

From: Jonathan Turkanis (technews_at_[hidden])
Date: 2005-01-31 19:50:30


christopher diggins wrote:
> I may finally have a good motivating example for stdio_filter:
>
> Consider the roman_numerals.cpp example from the Boost spirit library
> at http://tinyurl.com/3qw4k
>
> If I make a couple of minor modifications exclusively to the main,
> such as remove the superflous user prompting and rename it to
> something legal, i.e.:
>
> int RomanNumeralParse()
> {
> string str;
> while (getline(cin, str))
> {
> if (str[0] == 'q' || str[0] == 'Q')
> break;
>
> unsigned n = 0;
> roman roman_p(n);
> if (parse(str.c_str(), roman_p).full)
> {
> cout << n << endl;
> }
> else
> {
> cerr << "parsing failure" << endl;
> return 1;
> }
> }
> return 0;
> }
>
> Using my current version of my filters library (not available online
> yet) I can now reuse the entire program from another, such as the
> following:
>
> void RomanNumeralParserTest() {
> stringstream sIn("MCMLXXIV"), sOut;
> sIn > SimpleMainFilter(RomanNumeralParse) > sOut;
> int n;
> sOut >> n;
> TEST(n == 1974);
> }

Nice example!

This definitely answers my challenge to find a pre-existing program which can be
easily transformed into a stdio_filter. It also answers the question why you
might want to deal directly with streams rather than generic sources, since
formatted i/o is used.

> Many examples from the Spirit examples, can be refactored in this
> manner, to become reusable with relatively little effort. I suppose
> one of the calculators would be even more interesting.

This satisfies my "preferably more than one" qualification. ;-)

> Is this a good
> motivating example for introducing a stdio_filter into boost::iostreams?

I think so. I'm still a little worried that people will use this style of filter
writing for new filters and then discover that their filters are less reusable
[because they have higher memory use and can't be used with streams that have no
end]. However, I think it's sufficient to include a strong warning. Time will
tell whether the benefits outweight the costs.

The examples you mention also serve as a good motivating example for another
filter type: line-oriented filters. E.g.:

   struct roman_numeral_parser : line_filter<char> {
      void filter(const std::string line, std::ostream& out)
      {
        unsigned n = 0;
        roman roman_p(n);
        if (parse(line.c_str(), roman_p).full)
        {
            out << n << "\n";
        }
        else
        {
            throw std::ios::failure("bad roman numeral");
        }
      }
   };

> Christopher Diggins
> Object Oriented Template Library (OOTL)
> http://www.ootl.org

Jonathan


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk