parse_system_use_field
昨日の案でSystem Use Fieldのパーサー部分を実装してみました。
<hamigaki/archivers/rrip/parser_map.hpp>
<hamigaki/archivers/susp/parser.hpp>
// mpl::for_eachから呼ぶためのラッパー template<class State, class Header> class call_parser { public: call_parser(State& state, const char* signature, bool& result, Header& head, const char* data, std::size_t size) { } template<class Signature, class Parser> void operator()(const boost::mpl::pair<Signature, Parser>&) const { if ((Signature::first_value == signature_[0]) && (Signature::second_value == signature_[1]) ) { result_ = field<Parser>(state_)(head_, data_, size_); } } // ... }; template<class Map> struct parser { private: // MapのValue(=パーサー)だけのリスト typedef boost::mpl::transform_view< Map, boost::mpl::second<boost::mpl::_> > values_type; // パーサーのインスタンスをひとつにまとめたクラス typedef typename boost::mpl::inherit_linearly< values_type, boost::mpl::inherit< boost::mpl::_1, parser_field<boost::mpl::_2> > >::type state_type; public: template<class Header> bool operator()(Header& head, const char* signature, const char* data, std::size_t size) { bool result = true; call_parser<state_type,Header> f(state_, signature, result, head, data, size); boost::mpl::for_each<Map>(f); return result; } private: state_type state_; };
System Use Fieldのパーサーは状態を持つので、mpl::inherit_linearlyで各パーサーをまとめたクラスを生成し、mpl::for_eachで一つずつシグネチャの一致を確認して、一致したものを呼んでいます。
う〜ん。このコードだとmpl::mapじゃなくて、mpl::listでよいですね。