続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>は標準のファセットではないので、グローバルロケールに含まれない可能性があります。そのため、コンストラクタの処理が少し増えています。