バグ取りとかメンバの追加とか
ここ数日の検討結果をコードに反映させました。
日記に書いてない変更で大きなところは、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と同じカラクリです。