非互換性
以前のBoostのリリース(1.28)とはいくつか非互換な部分がある。
それらは大雑把に言って三つのカテゴリにわけられる。
- BOOST_PP_REPEATに基づく水平反復
- 再入構文
- list の畳み込み
反復ターゲット
まず、最も広く使われていると思われるのは、BOOST_PP_REPEATへ渡されるターゲットマクロと、BOOST_PP_REPEATを使った水平反復の構成である。
これはターゲットマクロを必要とするような全てのBOOST_PP_REPEAT_* と全てのBOOST_PP_ENUM_* を含む。
非互換性は自明であるが、それはソースの変更を必要とする。
これらのターゲットマクロは第3の引数を期待するようになった。
追加されたのは各ターゲットマクロの最初のパラメータである。
It represents the next repetition dimension and brings BOOST_PP_REPEAT inline with rest of the library.
したがって次のようであったものは:
#define macro(n, data) ...
BOOST_PP_REPEAT(5, macro, data)
...次のようになる:
#define macro(z, n, data) ...
BOOST_PP_REPEAT(5, macro, data)
このパラメータはBOOST_PP_REPEATメカニズムへの非常に効率的な再入に利用できる。
しかしながら、ライブラリは自動的に次の反復次元を見つけるため、それを必ずしも使う必要はない。
次元の順序付け
しかしこの自動的な検知により、BOOST_PP_REPEAT_1ST、BOOST_PP_REPEAT_2ND、BOOST_PP_3RDを順序からはずれて使うことは安全でない。
これらのマクロは自動再帰メカニズムをバイパスし、また自動再帰メカニズムは適切な順序でマクロが使われることに依存している。
これらのバイパスマクロを使うなら、一番外側の反復はBOOST_PP_REPEAT_1ST、次がBOOST_PP_REPEAT_2ND、最後がBOOST_PP_REPEAT_3RDでなければならない。
それ以外の使いかたはライブラリによってサポートされない。
時々は動作するかもしれないが、動作しないこともあるかもしれない。
再入構文
自動再帰も同様の問題がある。以前はBOOST_PP_WHILEの再帰構文(と同様にBOOST_PP_FOR)は次のようであった:
BOOST_PP_WHILE ## d(pred, op, state)
...あるいは:
BOOST_PP_CAT(BOOST_PP_WHILE, d)(pred, op, state)
自動再帰モデルにおいて、BOOST_PP_CATバージョンは使えない。
なぜならBOOST_PP_CATは連結の前に引数の展開を許すが、BOOST_PP_WHILEは引数無しで展開するからである。
このライブラリでそれは3つのパラメータを取るように見えるが、しかしそれは自動再帰のトリックである。
それは次のようなものと同様である:
#define A(x, y) ...
#define B A
// ...
B(2, 3)
この構文はBマクロが2つの引数をとるように見えるが、実際はそうではない。
このBマクロがAに推移することを除いては、自動再帰メカニズムも同様の流儀で動作する。
いくつかのプリプロセッサは動作が遅いため、直接的な再入(自動再帰無しの)がいくつかの非自明なケースでいまだに必要とされる。
その結果、ライブラリは再入のために新しい構文を使う:
BOOST_PP_FOR_ ## r(state, pred, op, macro)
BOOST_PP_REPEAT_ ## z(count, macro, data)
BOOST_PP_WHILE_ ## d(pred, op, state)
畳み込み
以前はBOOST_PP_LIST_FOLD_RIGHTマクロの引数はBOOST_PP_LIST_FOLD_LEFTの逆順であった。
また、BOOST_PP_LIST_FOLD_RIGHTへ渡される集積マクロも逆の引数で呼ばれていた。
この食い違いは解消された。
例示すると、BOOST_PP_LIST_FOLD_RIGHTは次のようであった:
#define macro(d, elem, state)
BOOST_PP_LIST_FOLD_RIGHT(macro, list, state)
これは次のように置き換わった...
#define macro(d, state, elem)
BOOST_PP_LIST_FOLD_RIGHT(macro, state, list)
概要
このライブラリは1.28リリースには無い新しい機能をたくさん持っていて、このリストはそれら全てを列挙するものではない。
これは単に、新しいリリースに互換となるためにコードを変更したければならないもののリストである。
See Also
- Paul Mensonides