Variadic Templates で遊んでみた

と、いっても殆ど Boost.Fusion 回りの実装で時間を食ってしまいましたが。
Variadic Templates に対応した Boost.MPL Sequence が欲しかったので書いてみました。
ついでに Boost.Fusion も。

#include <boost/mpl/vector.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/push_front.hpp>

namespace mpl = boost::mpl;

namespace detail{

template<typename Seq, typename Inserter, typename ...Args>
struct variadic_sequence_impl;

template<typename Seq, typename Inserter, typename T, typename ...Args>
struct variadic_sequence_impl<Seq, Inserter, T, Args...>
    : mpl::apply<
        Inserter, variadic_sequence_impl<Seq, Inserter, Args...>, T
    >::type{};

template<typename Seq, typename Inserter, typename T>
struct variadic_sequence_impl<Seq, Inserter, T>
    : mpl::apply<Seq, T>::type{};

template<typename Seq, typename Inserter>
struct variadic_sequence_impl<Seq, Inserter>
    : mpl::vector<>{};

} // namespace detail{

template<typename Seq, typename Inserter, typename ...Args>
struct variadic_sequence : detail::variadic_sequence_impl<Seq, Inserter, Args...>{};


// Boost.MPL Sequence
template<typename ...Args>
struct variadic_vector :
    variadic_sequence<
        mpl::vector1<mpl::_1>,
        mpl::push_front<mpl::_1, mpl::_2>,
        Args...
    >{};


#include <boost/mpl/equal.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/push_back.hpp>

typedef variadic_vector<int, char, double> seq;

BOOST_MPL_ASSERT(( mpl::equal<
    seq,
    mpl::vector<int, char, double>
> ));

BOOST_MPL_ASSERT(( mpl::equal<
    mpl::push_back<seq, float>::type,
    mpl::vector<int, char, double, float>
> ));


// Boost.Fusion
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/push_front.hpp>
#include <boost/fusion/include/as_vector.hpp>
#include <utility>

namespace fusion = boost::fusion;

template<typename ...Args>
struct variadic_fusion_vector :
    fusion::result_of::as_vector<
        variadic_sequence<
            fusion::vector1<mpl::_1>,
            fusion::result_of::push_front<mpl::_1, mpl::_2>,
            Args...
        >
    >::type{
    
    typedef typename fusion::result_of::as_vector<
        variadic_sequence<
            fusion::vector1<mpl::_1>,
            fusion::result_of::push_front<mpl::_1, mpl::_2>,
            Args...
        >
    >::type base_type;
    
    template<typename ...UArgs>
    explicit variadic_fusion_vector(UArgs&&... args)
        : base_type(std::forward<UArgs>(args)...){}
};


#include <iostream>
#include <boost/fusion/include/io.hpp>

int
main(){
    variadic_fusion_vector<int, char, double> v(1, 'a', 3.14);
    std::cout << v << std::endl;
    return 0;
}

[出力]

(1 a 3.14)


Boost.Fusion が、やっつけだけど気にしない。
多分、decltype 使ったほうが楽。
あと書いてから気づいたんですけど Boost.MPL って Variadic Templates に対応していないんですかね。
Boost がどれぐらい C++0x に対応しているのかが気になります。


[boost]
ver 1.46.1
[参照]
http://blog.shandyba.com/2009/12/17/converting-variadic-template-arguments-pack-to-boost-mpl-sequence/
http://d.hatena.ne.jp/faith_and_brave/20110105/1294207038
http://d.hatena.ne.jp/faith_and_brave/20090820/1250765649