詳細は明日とか言っときながら全然書いてなかったけど明日を定義してなかったから問題なかった
ということでとりえあえずTrance.Configの説明 http://d.hatena.ne.jp/Flast/20110506/1304696074
ファイルは https://github.com/Flast/trance/blob/master/trance/config.hpp です
細かい説明が面倒なんで、Boost.Configのdoc Macros that describe possible C++0x features を読んだ前提で進めます。
例えば、現状Boost.Config 1.46.1では先に挙げたドキュメントに書かれてるマクロが定義されています。(BOOST_NO_0X_HDR_*_CONCEPTSに関しては未定義ですが、trunkでは削除されてるようなので無視してください。)
(std::tupleに関するconfigはまた別のマクロを使いますが、以下簡略化為にstd::tupleをサポートしているものとします。
この中にある BOOST_NO_VARIADIC_MACROS はC99/C++0x(operator/で無いことに注意)で追加された可変長マクロをサポートしているかのフラグですが、このマクロはBoost 1.45.0以降でのみ正常に動作します。
つまり、以下のコードは暗黙的にBoost 1.45.0を要求されるのです。(こんなマクロ使うかっ!!ってのは言わないで...
あっ、ちなみに適当なBoostのヘッダをインクルードすればboost/config.hppは大抵インクルードされてるはずですけど、不安なら明示的にインクルードしてください。(確かユーザーはインクルードしてはいけないって書いてなかったはず...
#include <boost/config.hpp> #ifdef BOOST_NO_VARIADIC_MACROS # error "Your compiler does not support Variadic Macros." #else # include <tuple> # define TUPLE( ... ) ::std::tuple< __VA_ARGS__ > #endif typedef TUPLE( int, float, const char * ) some_data_t;
前述の通り、上記のコードはBoost 1.45.0以降ならば BOOST_NO_VARIADIC_MACROS が適切に定義されエラーメッセージで止まるか正常に動作します。
しかし、1.45.0以前のBoostを使っていた場合はどうでしょうか。つまりサポートされていなくてもこのマクロは定義されません。その為、常にTUPLEを使用しようとしてエラーを吐くことになります。
これを防ぐにはそのマクロがいつのBoostからサポートされているか知る必要がありますが、そんな事いちいちユーザーに要求することは面倒です。
つまりこう言うことです。
#include <boost/config.hpp> #include <boost/version.hpp> #if ( BOOST_VERSION < 104500 ) || defined( BOOST_NO_VARIADIC_MACROS ) # error "Your compiler does not support Variadic Macros." #else # include <tuple> # define TUPLE( ... ) ::std::tuple< __VA_ARGS__ > #endif typedef TUPLE( int, float, const char * ) some_data_t;
やってられないですね。
ってことで頑張りました。Trance.Configを使用すれば上のコードは
#include <trance/config.hpp> #ifndef TRANCE_HAS_VARIADIC_MACROS # error "Your compiler does not support Variadic Macros." #else # include <tuple> # define TUPLE( ... ) ::std::tuple< __VA_ARGS__ > #endif typedef TUPLE( int, float, const char * ) some_data_t;
基本的に BOOST_NO_* を TRANCE_HAS_* にリネームしています。
無いことを示すNoから、あることを示すHasに変わっているので意味もわかり易くなるでしょう。
他に代替ヘッダ用のマクロもいくつかありますが、こちらはどうしようかいろいろ考えてるので説明はやめときます。
もし、Boostのtrunkを使っていて、そのConfigを使用したいというのであれば trance/config.hpp をインクルードする前に TRANCE_CONFIG_USE_AS_TRUNK を定義すればリリースには無いものも使用することが可能です。(ex. TRANCE_HAS_NOEXCEPT
ただし、こちらの使用はあくまで自己責任で。