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でよいですね。