
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