C++で定義したenumをそのままの名前でLuaで使いたい(Boost.Preprocessor)

例えばC++で次のように列挙体を定義して、そのままの名前でLuaスクリプト側でも使いたいわけです。

enum Enum1 {
    E1 = 0x200,
    E2,
    E3,
    E4,
};

↓↓↓こう書きたい↓↓↓

if foo == E2 then
    bar()
end

でもそれをやるには、定義した列挙体を全部Luaのグローバル変数として登録しなければなりません。

luabind::object g = luabind::globals(L);
g["E1"] = E1;
g["E2"] = E2;
g["E3"] = E2;
…

enum定義した後で、Luaの方にも登録しなければなりません。
列挙体を1個増やすと、ソースを2箇所直さないといけない…。
これをいちいちやるのは、列挙体がたくさんあるととても面倒なので、なんとかならないものかと思っていたのですが、Boost.Preprocessorを使って楽になりそうだったので試してみました。

続きを読む →

Boost.Preprocessorを少しだけ使ってみる

使ったこと無いなーと思いまして、触り程度にちょっとだけ

例えば以下のように、ある一部分を除いてほぼ同じ内容の関数をたくさん定義しなきゃいけない場合


void test1() {
cout << "A" << endl; } void test2() { cout << "B" << endl; } …(以下延々と続く)… [/cpp] Boost.Preprocessorのリファレンスをだらだら眺めながら、以下のように書いてみました。 ちゃんと上記のように展開されるようです。 [cpp] #define SEQ1 (test1) (test2) (test3) (test4) #define SEQ2 (A) (B) (C) (D) #define MACRO(r,data,i,elem) \ void elem () { \ cout << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(i,SEQ2)) << endl; \ } BOOST_PP_SEQ_FOR_EACH_I(MACRO, _, SEQ1) [/cpp] BOOST_PP_SEQ_FOR_EACH_Iを使ってMACROをSEQ1の数だけ展開して、 そのMACROの中ではインデックスiを使ってSEQ2にアクセスする感じで。 STRINGIZEは、標準の#xみたいなやつですね。 今の自分には使う機会が思いつきませんが、いつか必要になった時のとっかかりになればという事で。