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 なら問題なかったけど)。
回避方法とかあるのかしら。

[boost]

  • ver 1.47.0 beta1