どうにも同じようなC++コードを延々書かなければいけない→プリプロセサが在るじゃない!
という事で、C/C++でメタプログラミングをこなす為のライブラリであるBoost.Preprocessorに手を出した。
4つの型
さて、Boost.Preprocessorには4つの型が存在するようだ。全てマクロアーギュメントを複数格納するコンテナらしい。
オンラインリファレンスと、偶然図書館から借りていたC++テンプレートメタプログラミング(以下、単に『書籍』と表記)の付録Aを元にまとめてみる。同書籍に記述されている型名も括弧で囲って併記している。
- sequences (列)
-
(a)(b)(c)のような、()で囲ったマクロアーギュメントの連続。書籍によると、
このライブラリのデータ構造の中で最も効率的で、最も柔軟性に富み、かつ最も使いやすいものである
とある。要素数に制限無し。ただし、引数に数値を取るマクロでは256以下の値しか機能しない。尤も、BOOST_PP_SEQ_SUBSEQがあるし、それほど問題にはならないんじゃないだろうか?
- tuples (タプル)
-
(a,b,c)のような、()の中でマクロアーギュメントを,で区切って記述したもの。ランダムアクセスなど、いくつかの基本的な操作が用意されている
らしいが、マクロの数も少なく(後述)、それ程実用的とは思えない……関数やマクロの引数記述部分と同じ書き方というのが利点だろうか?
また、このデータ構造を操作する全てのマクロには、必ずtupleの要素数を指定しなければならない。つまりそれは、tupleの要素数を計算する方法がない、という事だろう。 - arrays (配列)
-
(3, (a, b, c))のような、要素数と要素のtupleで構成されたもの。tupleの亜種と言えそうだ。tupleと異なり、データ構造中にサイズを持つ。
- lists (リスト)
-
(a, (b, (c, BOOST_PP_NIL)))のような、『先頭要素とそれ以降のlist』で構成されたtuple亜種。終端にはBOOST_PP_NILを用いる必要がある。LispのS式のように()の嵐になりそう。
これも、長さの制限は存在しない。
書籍によると、
他の構造に比べて操作が遅くなりがちで、読みにくくなりがちなので、普通、最後の拠り所としてしか使われない
とある。が、実はこのデータ構造を操作するマクロが一番多い(後述)。
データ構造中、或いはそれを扱うマクロの引数として、そのサイズが必要となるのがtuplesとarrays。それはつまり、自作マクロの引数としての利用は現実的ではないということだろう。その逆がsequencesとlists。
tuplesが一番C/C++の記述に近い。エディタ上での自動インデントの誤動作も少なくすみそう。これで、サイズを求める事さえ出来れば最高なのだが……
各型で可能な処理
……うーん、やっぱりよく分からない。いや表記の違いはよく分かったが、それぞれどういう時に使うのかがハッキリしない。
例えば、STL連接コンテナのvectorとlistは違いがハッキリ分かる。vectorは要素の参照が素早く行える、listは要素の追加削除が容易。
Boost.Preprocessorの4つの型も、それぞれ何らかの長所短所がある筈だ。そうでなければ1つの型で充分な筈だし。
そこら辺をハッキリさせる為に、各型の操作を行うマクロをまとめてみた。『特定の操作を行うマクロが多ければ、その型はそれが得意と言う事だろう』という理屈。一つ一つ確認する余裕はないので、同じ名前のマクロは別の型を対象としていても同じ操作を提供する物と仮定。
おい用意されているマクロ数に差が在りすぎるぞ。一番マクロが多いのがlists、一番少ないのがtuples。その差6倍。
さて、表にまとめてざっと眺めてみるに、次のような特徴が在りそうだ。
- arrays
- 要素の追加削除に強い?
- lists
- その名の通り、順次処理に強いのだろうか。fold、for each、或いはreverseといった物が目立つ。
- sequences
- arraysとlistsの両方の特徴を併せ持っているように見える。ただし、それぞれの型で行える処理全てが可能という訳ではなさそうだ。
- tuples
- なにこれ。
tuplesの存在価値が謎。というかtuplesを操作するマクロの数が少な過ぎて判断が付かない。
各型の変換
表をまとめていて気づいたが、どうも、それぞれの型は相互変換可能という訳ではなさそうだ。図にまとめてみた。
tuplesとlists、tuplesとsequencesは相互変換が可能。しかし、それ以外の変換は片方向のみ、或いは全く用意されていない。また、arraysに関してはtuplesへの変換しか用意されておらず、名称も他のものとは異なる。
- マクロアーギュメント
-
書籍C++テンプレートメタプログラミングから用語を拝借。
マクロアーギュメントとは、次のものの空でない列である。
- コンマでも括弧でもない、1つ以上のプリプロセッサトークン、および(または)
- 左右の括弧に囲まれた、1つ以上のプリプロセッサトークン。
- それ以外の変換は片方向のみ、或いは全く用意されていない
- 例えばlistsとsequencesの変換であれば、tuplesへの変換を経由すれば可能ではある。

