|
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