バグ取りとかメンバの追加とか

ここ数日の検討結果をコードに反映させました。

今日の成果物

日記に書いてない変更で大きなところは、multiplexer/demultiplexerのcomponent()メソッドでしょうか。

class multiplexer_impl
{
public:
    template<typename Source>
    void push(const Source& src, std::streamsize elm_size);

    template<typename T>
    const T* component(int n) const;

private:
    boost::ptr_vector<muxer_component_base> sources_;
};

push()で任意のSourceを追加可能で、component()は追加したときの型でSourceを取り出せます。boost::iostreams::chainのそれとほぼ同じです。
実装もほぼ同じで、

class muxer_component_base
{
public:
    virtual ~muxer_component_base() {}
    virtual std::streamsize read(char* s, std::streamsize n) = 0;
    virtual void close() = 0;
};

template<class Source>
class muxer_component : public muxer_component_base
{
    // 略
};

template<typename Source>
void multiplexer_impl::push(const Source& src, std::streamsize elm_size)
{
    sources_.push_back(new muxer_component<Source>(src, elm_size));
}

template<typename T>
const T* multiplexer_impl::component(int n) const
{
    typedef muxer_component<T> wrapper;

    if (const wrapper* ptr = dynamic_cast<const wrapper*>(&sources_[n]))
        return ptr->component();
    else
        return 0;
}

個々のSourceに継承関係はなくとも、即席で(ラッパークラスを通して)継承関係を作ってしまうので、dynamic_castで復元できるわけです。Boost.Anyと同じカラクリです。