Boost.Spirit BOOST_SPIRIT_NO_PREDEFINED_TERMINALS

Boost 1.47.0のBoost.Spiritでは、コンパイル時間を改善するための変更がいくつか入ります。


ひとつは、Boost.Protoのプリプロセス済みソースの提供で、これは何も考えなくても手に入ります。


もうひとつは、BOOST_SPIRIT_NO_PREDEFINED_TERMINALSマクロの提供です。これをBoost.Spiritのヘッダをインクルードする前にdefineすると、qi::int_等の型パーサーのインスタンス化が行われなくなり、ユーザーは必要なものを必要なだけインスタンス化することになります。
int型のパーサーが欲しいときには、qi::int_を使用する代わりにqi::int_type int_;のように自分でインスタンス化を書きます。

#include <iostream>
#include <string>
#include <boost/range/algorithm/for_each.hpp>

#define BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

void disp(int x) { std::cout << x << std::endl; }

int main()
{
    const std::string input = "123,456,789";
   
    qi::int_type int_; // 必要なパーサーをインスタンス化
   
    std::vector<int> result;
    std::string::const_iterator it = input.begin();
    if (!qi::parse(it, input.end(), int_ % ',', result)) {
        std::cout << "parse error" << std::endl;
        return 1;
    }
   
    boost::for_each(result, disp);
}
123
456
789

コンパイル時間がどうしても気になる人はBoost 1.47.0で使ってみてください。