続code_converter for float
今回はstate_typeを使う必要がなさそうなので、state_typeをmbstate_tに戻しました。
codecvt<float_type,char,mbstate_t>の派生クラスとして、codecvt_u8とcodecvt_s16_leを作ることにします。
namespace std { // デフォルト template<> class codecvt<hamigaki::audio::float_type,char,mbstate_t> { // 略 }; } // namespace std namespace hamigaki { namespace audio { // 符号なし8ビット class codecvt_u8 : public std::codecvt<float_type,char,std::mbstate_t> { // 略 }; // 符号あり16ビット(リトルエンディアン) class codecvt_s16_le : public std::codecvt<float_type,char,std::mbstate_t> { // 略 }; } } // End namespaces audio, hamigaki. // codecvt_holderの特殊化 namespace boost { namespace iostreams { namespace detail { template<> struct codecvt_holder< std::codecvt<hamigaki::audio::float_type,char,std::mbstate_t> > { typedef std::codecvt< hamigaki::audio::float_type,char,std::mbstate_t> codecvt_type; codecvt_holder() { if (!std::has_facet<codecvt_type>(loc_)) loc_ = std::locale(loc_, new codecvt_type); reset_codecvt(); } const codecvt_type& get() const { return *codecvt_; } void imbue(const std::locale& loc) { loc_ = loc; reset_codecvt(); } void reset_codecvt() { codecvt_ = &std::use_facet<codecvt_type>(loc_); } std::locale loc_; const codecvt_type* codecvt_; }; } } } // End namespaces detail, iostreams, boost.
code_converterの実装に使われているcodecvt_holderはcodecvt<wchar_t,char,mbstate_t>でのみ特殊化されていて、デフォルト実装はファセットがコピー可能であることを要求します。また、imbue()の実装も空なので、コンパイル時にファセットが固定されてしまいます。
このままではファセットの意味がないので、独自に特殊化しています。codecvt<wchar_t,char,mbstate_t>と違い、codecvt<float_type,char,mbstate_t>は標準のファセットではないので、グローバルロケールに含まれない可能性があります。そのため、コンストラクタの処理が少し増えています。