一般に「入力」や「出力」を受けるインターフェースは何を受けるべきか?という問題.
たとえば,今考えている入力はファイルだからファイルストリームを受ければ良いかなぁ,でもファイルのパスを受けるっつーのもあるかにゃー?ファイルポインタはどうだろう?でも将来メモリ内のバッファを受けるような可変性も許したいしにゃー,イテレータを受ける?でも,イテレータによるストリームのアクセスって制限あるし,ストリームなままで色々いぢることができにくくなるし,あ〜もしかしたら将来的にネットワークソケットを直接つなぎたくなるかも…….
なんて迷うこと良くあるけれど, Device (Source/Sink)のモデルを受けるのが一番汎用な気がしてきた.in-memory データ列に対応しようとする場合でも, Direct コンセプトがあるので効率をそう落とさずに対応することもできる.というか,ストリームは in-memory なデータ列より汎用な概念(少なくとも in-memory なデータ列はストリームとして扱うことができる)だしにゃ.このままだと, Device の型が残るのでテンプレートで型を引きずり回さないといけない(テンプレートなのでヘッダに実装しないといけない・コードブロートがマズー)けれど,それを嫌うなら中で boost::iostreams::stream 使って std::iostream/std::istream/std::ostream にして型を消すという選択肢もあるし.っていうかこんなところにも Type Erasure Pattern がっ!!
こういうの考えるたんびに Boost ウマーと思ってしまう. Boost の何がうれしいかって,やっぱりきちんとしたコンセプトが策定されているところがウマーなところじゃにゃいですにゃ.そのコンセプトで何が想定されていて何が想定されていないのかがはっきり分かっているので安心して乗っかっていられるというか.もちろん実装があることもうれしいことには違いないけれど.ま〜,もちろんそのコンセプトのモデルが実装されればそれがそのまんま何もせずに自分とこで使えるっつーのも大きいけれど.後者は要するに Reusability だにゃ.
http://d.hatena.ne.jp/Cryolite/20040426#p2
#うひゃ,今読んだら何か恥ずかしいw
Device コンセプトは Asynchronous や Non-Blocking も見据えて設計されてるからコタツに座ってお茶飲んで待ってたら,どうせそのうちネットワークデバイスとか色々出てくるだろうし.
#あ,でも std::[i|o]stream 系って Asynchronous や Non-Blocking 見据えた設計になってないよ〜な?型消せない?どうするんだろ?
ずがーん. Non-Blocking/Asynchronous 対応でかつ型消ししたい場合はどうすれば……. Asynchronous はともかく, Non-Blocking はコード変換なんかで普通に必要になるのににゃ…….
Although the Boost.Iostreams Filter and Device concepts can accommodate non-blocking i/o, the C++ standard library stream and stream buffer interfaces cannot, since they lack a means to distinguish between temporary and permanent failures to satisfy a read or write request. As a result, non-blocking Devices do not work properly with the templates stream, stream_buffer, filtering_stream and filtering_streambuf.