明日から使える boost/preprocessor/facilities/*

やったーC++ Advent Calendarすっかり忘れていました。
今日は数あるBoost.PPのマクロのうち今一つ何がしたいのか分からない連中にスポットを当ててみたいと思います。

BOOST_PP_IS_EMPTY

例えばコンパイルフラグとしてHOGEが定義されていたとします。gcc -DHOGEとか、#define HOGEとかそういう感じで。その時に、ある関数で何か特別なことをするには:

void f() {
…
#if defined HOGE
何か特別なこと
#endif
…
}

普通はこうですが、ワンライナーでやりましょう

#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/facilities/is_empty.hpp>

void f() {
…
BOOST_PP_EXPR_IIF(BOOST_PP_IS_EMPTY(HOGE), 何か特別なこと)
…
}

HOGEは、-DHOGEとあれば空に展開されるはずなので、BOOST_PP_IS_EMPTY(HOGE)は1になります。HOGEの定義がなければHOGEは展開されず、IS_EMPTYは0を返します。

BOOST_PP_IS_1

先と同じく、今度はHOGEが1と定義されていた場合:

void f() {
…
#if HOGE == 1
何か特別なこと
#endif
…
}

これは、

#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/facilities/is_1.hpp>

void f() {
…
BOOST_PP_EXPR_IIF(BOOST_PP_IS_1(HOGE), 何か特別なこと)
…
}

HOGEが1になるのであれば、何か特別なことがコードとして展開されます。

BOOST_PP_IS_EMPTY_OR_1

-DHOGEでも-DHOGE=1でもどちらでもOKとする場合:

#include <boost/preprocessor/control/expr_iif.hpp>
#include <boost/preprocessor/facilities/is_empty_or_1.hpp>

void f() {
…
BOOST_PP_EXPR_IIF(BOOST_PP_IS_EMPTY_OR_1(HOGE), 何か特別なこと)
…
}

BOOST_PP_INTERCEPT

struct hoge0 {}; struct hoge1 {}; … というのを量産したいとします。これはhogeNの後ろに{};があるので、BOOST_PP_ENUM_PARAMSではできませんね。そこでBOOST_PP_ENUM_BINARY_PARAMSを使います。

#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>

BOOST_PP_ENUM_BINARY_PARAMS(10, struct hoge, {}; BOOST_PP_INTERCEPT)

BOOST_PP_ENUM_BINARY_PARAMSはA1 a1, A2 a2, みたいなのを作るときによく使いますが、2番目のパラメータには数字いらんのじゃ、というときにBOOST_PP_INTERCEPTを入れてやると数字を消せます。
BINARYじゃないENUM系のマクロでも使えるので、

#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
BOOST_PP_ENUM_PARAMS(8, YO BOOST_PP_INTERCEPT)! Check it out!

とすればYO , YO , YO , YO , YO , YO , YO , YO ! Check it out!になりますYO! Check it out YO!

BOOST_PP_EXPAND

BOOST_PP_EMPTY BOOST_PP_EMPTY BOOST_PP_EMPTY() () ()

これは、BOOST_PP_EMPTY BOOST_PP_EMPTY () () と展開されますが、ただこう書いただけではこれ以上展開されません。マクロの引数にしてやれば、もっと展開できます。そこで、

BOOST_PP_EXPAND(BOOST_PP_EMPTY BOOST_PP_EMPTY BOOST_PP_EMPTY() () ())

BOOST_PP_EXPANDを使って展開を促進できます。

BOOST_PP_IDENTITY

工事中

おわり

というわけ痒いところに手が届くfacilitiesディレクトリの中身を紹介しました。今まで微妙に回りくどいことをしていた人も、これで幸せになれるかな!なれないですね!

おまけ・クリスマスを無くす

なんかクリスマスを無くしてやるのが流行りらしいのでとりあえず置いときますね

#undef Christmas
#undef Xmas
#define Christmas
#define Xmas