
Rob Stewart wrote:
From: "Jonathan Turkanis":
I've started writing some non-blocking filters, and they don't look so bad, as long as they process one character at a time. So my inclination is to make all filters non-blocking except for a couple of convenience filters which process an entire document at a time. In that case, get will always return basic_character.
You gave the caveat, "as long as they process one character at a time." What about the other case? read() and write() return numbers, not characters, right? basic_character doesn't come into play there. Are you talking about something else?
Oops -- I forgot to finish my overview. Right now I have InputFilter, MulticharInputFilter, OutputFilter and MulticharOutputFilter. On top of these are built one_step_filter (a convenience class) and symmetric_filter_adapter (useful for converting C interfaces). I'm thinking I'll promote symmetric_filter_adapter to a full-fledged concept SymmetricFilter, and recommend it as the filter concept to use for high-performance applications. I'll get rid of the Multichar filters, because I've found writing non-blocking Multichar filters to be extremely messy; it's just as easy to write a SymmetricFilter in that case. So there will be three types of non-blocking filters: InputFilter (renamed PullFilter), OutputFilter (renamed PushFilter) and SymmetricFilter. There will also be two kinds of filters for beginners: one_step_filter, in which an entire document is presented in a vector, and filtered version must be appended to a second vector, and stdio_filter, in which the filter reads from std::cin and writes to std::cout. In the tutorial, I'll analyze each of the current example filters in detail (except that the presidential one will just be called dictionary_filter). I'll start by showing how to implement the algorithm using a stdio_filter, then I'll show how to modify it to implement the more advanced filter concepts.
One more possibility is this:
enum eof_type { eof };
enum would_block_type { would_block };
template<typename Ch> class basic_character { basic_character(Ch = Ch()); basic_character(eof_type); basic_character(would_block_type); operator Ch () const; operator safe_bool () const; bool operator==(eof_type) const; bool operator!=(eof_type) const; bool operator==(would_block_type) const; bool operator!=(would_block_type) const;
// All the other operators we discussed };
This would allow the usage:
if (c == eof) { ... } if (c == would_block) { ... }
How do you like this?
Hmmm. You've complicated the interface still more to get that syntax, which is more verbose besides. I don't care for it since I'm happy with the look of this:
if (eof(c)) ... if (would_block(c)) ...
Okay, I just wanted to get your opinion. I think I like the functions better too.
Still, if there are folks firmly entrenched in the camp that prefers the (in)equality operator for those tests, it is an excellent approach. (If you're going to fatten the interface to provide this, I suggest keeping the non-member functions, too.)
I think it should be one or the other. So I'll use the functions. Jonathan