読者です 読者をやめる 読者になる 読者になる

ユーザー定義型を直接Fusionシーケンスにしない選択肢

C++

ユーザー定義型を直接Boost.Spirit.Qiのパース結果として使いたい場合には通常、ユーザー定義型をBOOST_FUSION_ADAPT_STRUCTでFusionシーケンスとして見なせるようにします。

最近、ユーザー定義型をFusionシーケンスに変換する関数を用意するのもアリじゃないかと思えてきました。以下のプログラムでは、Point型をFusionシーケンスに変換するas_fusion_sequence()関数を持たせています。

#include <iostream>
#include <string>
#include <boost/fusion/include/vector_tie.hpp>
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;
namespace fusion = boost::fusion;

struct Point {
    int x, y;

    fusion::vector<int&, int&> as_fusion_sequence()
    {
        return fusion::vector_tie(x, y);
    }
};

int main()
{
    const std::string input = "3,1";
    auto rule = boost::proto::deep_copy(qi::int_ >> ',' >> qi::int_);

    Point result;
    auto fused_result = result.as_fusion_sequence();

    std::string::const_iterator first = input.begin();
    if (qi::parse(first, input.end(), rule, fused_result)) {
        std::cout << result.x << ", " << result.y << std::endl;
    }
    else {
        std::cout << "parse error!" << std::endl;
    }
}

出力:

3, 1

こうしておくと、一つのユーザー定義型に対して、複数の解析方法(要素の順番を入れ替えたり)が定義できていい気がします。