|
Boost : |
From: christopher diggins (cdiggins_at_[hidden])
Date: 2005-01-09 12:25:00
> Hi Christopher,
>
> I don't have much time to write today but I'd like to make several
> observations
> about this discussion.
>
> It seems to me that what you are trying to achieve is something that is
> already
> well-supported by the iostreams library. The iostreams library offers
> users a
> number of different ways to write filters, with the understanding that
> some
> methods will be more efficient or convenient for a particular purpose than
> another.
Hi Jonathan,
Thanks for responding. I have now managed to get the iostreams library to do
what I wanted (see my code below). The only thing missing now is the ability
to chain sequences of filters.
> Given the above definition, if you write a class which derives from
> co_filter
> and override the pure virtual function do_filter, you can add it to the
> filtering streams from the iostreams library and it will work as you have
> described, if I understand you correctly.
Using what you provided, here is the code which enables us to use an
arbitrary procedure as an iostream filter:
typedef void(*procedure)();
class proc_as_filter : public co_filter<char> {
public:
proc_as_filter(procedure x) : proc(x) { }
virtual void do_filter(
basic_istream<char>& in,
basic_ostream<char>& out)
{
streambuf* inbuf = cin.rdbuf();
streambuf* outbuf = cout.rdbuf();
cin.rdbuf(in.rdbuf());
cout.rdbuf(out.rdbuf());
proc();
cin.rdbuf(inbuf);
cout.rdbuf(outbuf);
}
private:
procedure proc;
};
void ToUpperFilterFxn() {
char ch;
while (cin.get(ch)) {
cout.put(toupper(ch));
}
}
int main()
{
string s = "hello jonathan\n";
filtering_ostream out;
out.push(proc_as_filter(ToUpperFilterFxn));
out.push(cout);
boost::io::copy(stringstream(s), out);
return 0;
}
I compiled and successfuly ran this on Visual C++ 7.1. What are the chances
something like this could find its way into the iostreams library?
> However, I should be able to extend it so that if a chain contains both a
> source
> and a sink, boost::io::copy is invoked. E.g.,
>
> source() | filter1() | filter2() | filter3() | sink()
>
> would be equivalent to
>
> filtering_ostream out(filter1() | filter2() | filter3() | sink());
> boost::io::copy(source, out);
>
> If I can make this work, and there are no objections, I'll add it.
This is what I am ultimately striving for. Is there any reason why the
source() and sink() can not be assumed to be cin and cout respectively when
absent?
>> 7) allow threading of functions
>
> Do you mean this: support filters which think they are processing an
> entire
> stream at once, but really their threads are waiting on some
> syncronization
> object whenever there is no more input available, or output buffers are
> full?
What I want is to allow two proc_as_filter objects to be executed
simultaneously, so that this code:
proc_as_filter(Proc1) | proc_as_filter(Proc2)
Runs optimally on a multi-processor machine. I don't know how hard this is,
I am quite inexperienced in multithreaded code.
Christopher Diggins
http://www.cdiggins.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk