BOOST_PP_ITERATE で遊んでみた
巷では、空前絶後の Boost.PP ブームらしいですね。
え、知らない?
STL のコンテナを初期化する initial_values の可変長引数を実装してみました。
[main.cpp]
#include <boost/range/algorithm/for_each.hpp> #include <boost/lambda/lambda.hpp> #include <iostream> #include <vector> #include <string> #include "initial_values.hpp" int main(){ std::vector<int> v = initial_values(3, 1, 5, 4, 0, 2); boost::for_each(v, std::cout << boost::lambda::_1 << ","); std::vector<std::string> v2 = initial_values<std::string>("yaki","niku","tabetai"); boost::for_each(v2, std::cout << boost::lambda::_1); return 0; }
[initial_values.hpp]
#ifndef BOOST_PP_IS_ITERATING #ifndef INITIAL_VALUES_H #define INITIAL_VALUES_H #include <boost/array.hpp> #include <boost/preprocessor/iteration/iterate.hpp> #include <boost/preprocessor/repetition.hpp> #include <boost/preprocessor/cat.hpp> // 型推論で、コンテナに代入 template<typename T> struct initial_values_impl{ typedef T container_type; initial_values_impl(T const& rhs) : container_(rhs){} template<typename U> operator U() const{ return U(container_.begin(), container_.end());; } private: container_type container_; }; #ifndef INITIAL_VALUES_MAX_ARITY #define INITIAL_VALUES_MAX_ARITY 10 #endif #define BOOST_PP_ITERATION_LIMITS (0, INITIAL_VALUES_MAX_ARITY) #define BOOST_PP_FILENAME_1 "initial_values.hpp" #include BOOST_PP_ITERATE() #endif // INITIAL_VALUES_H #else // BOOST_PP_IS_ITERATIN #define pp_n BOOST_PP_ITERATION() // 可変長引数で受け取る関数の実装 // pp_n( BOOST_PP_ITERATION() ) で、展開回数を取得する template<typename T> initial_values_impl<boost::array<T, pp_n> > initial_values( BOOST_PP_ENUM_PARAMS(pp_n, T const& t) ){ boost::array<T, pp_n> v = { BOOST_PP_ENUM_PARAMS(pp_n, t) }; return initial_values_impl<boost::array<T, pp_n> >(v); } #undef pp_n #endif // BOOST_PP_IS_ITERATING
こんな感じ。
難しいようで、そんなに難しいことをやってない、ような?
BOOST_PP_ITERATION() で、展開回数の取得が出来ます。
initial_values の可変長引数を実装している部分をマクロで定義していないので、読みやすいとは思います。
あとデバッグもしやすいかな?
思ったよりも簡単だったので、次から使っていこう。
[注意]
BOOST_PP_FILENAME_1 に設定したヘッダーファイルは、-I 等でヘッダーファイルへのパスを設定しないとダメみたいです(msvc なら問題なかったけど)。
回避方法とかあるのかしら。
[参照]
http://boost.2283326.n4.nabble.com/Preprocessor-Relative-Addresses-in-BOOST-PP-FILENAME-1-td3232830.html
http://efreedom.com/Question/1-3826082/BOOST-PP-ITERATE-Result-File-Directory
http://d.hatena.ne.jp/faith_and_brave/20080222/1203670672
http://d.hatena.ne.jp/iorate/20101231/1293806776
[boost]
- ver 1.47.0 beta1