optional が欲しい
LHA用にビット単位の読み書きクラスを書いています。
ビット単位の書き込みといえばBoost.CRCにあったなと思い、インタフェースを確認したところ、こうなっていました。
template < std::size_t Bits > class crc_basic { public: void process_bit( bool bit ); void process_bits( unsigned char bits, std::size_t bit_count ); };
LHAの場合、16ビット書き込む場合があるのでunsigned charでは足りません。
なので、最初はこうしました。
// ビットを埋める方向 enum bit_flow { left_to_right, // 左(msb)から右(lsb)へ right_to_left // 右(lsb)から左(msb)へ }; template<bit_flow Flow, class Sink> class output_bit_stream; // LHA用 template<class Sink> class output_bit_stream<left_to_right, Sink> { public: void put_bit(bool bit); void write_bits(unsigned bits, std::size_t bit_count); };
ところが同じようにinput_bit_streamを作ると、
template<class Source> class input_bit_stream<left_to_right, Source> { public: bool get_bit(); unsigned read_bits(std::size_t bit_count); };
となってEOFを返せないんですよね。
この場合、Boost.OptionalやBoost.Triboolを使うか、unsignedをint32_tに変えるかなんですが、迷ってしまいます。
整数1個にBoost.Optionalはちょっと大げさな感じです。
やっぱint32_tかなぁ。
少し違うパターンとしてread(2)とかboost::iostreams::read()の戻り値があります。
これは例えば32ビットの場合、-1〜0x7FFFFFFFの値をとるわけですが、optional<int32_t>やoptional<uint32_t>は値の範囲が無駄に広がる上に、オブジェクトのサイズも増えてしまい、おいしくありません。
で、32ビットのoptional<uint31_t>が欲しいなぁと。ついでにuint31_tも。