template 引数を MPL の Sequence として扱う

template class の引数を MPL Sequence としてアダプトしてみた。


[ソース]

template<typename T>
struct template_args;

#include <boost/mpl/equal.hpp>
#include <boost/mpl/assert.hpp>
#include <vector>
#include <utility>

namespace mpl = boost::mpl;

template<typename T, typename U>
struct hoge{};

BOOST_MPL_ASSERT(( mpl::equal<
    template_args<hoge<int, float> >,
    mpl::vector<int, float>
> ));

BOOST_MPL_ASSERT(( mpl::equal<
    template_args<std::pair<int, float> >,
    mpl::vector<int, float>
> ));

// oh...
BOOST_MPL_ASSERT(( mpl::equal<
    template_args<std::pair<int, float> >,
    template_args<hoge<int, float> >
> ));

int main(){}


とりあえず、引数は3つまで。
本当は、件の is_same で使おうと思ったんだけども template T 型で比較出来ない事に気が付きあえなく撃沈。
template 引数のみで比較は出来るんだけどね……。
そんな理由でイマイチ使いどころがなくなってしまた。
ぐぬぬ……。


[boost]
ver 1.46.1


そんな感じで全体のソースはイカから。

#include <boost/mpl/vector.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/copy.hpp>

namespace detail{

namespace mpl = boost::mpl;

template<typename T, typename Seq, typename Inserter>
struct template_sequence_impl : Seq{};

template<
    template<typename> class T,
    typename Arg1,
    typename Seq, typename Inserter
>
struct template_sequence_impl<T<Arg1>, Seq, Inserter> :
    mpl::copy<Seq,
        typename mpl::apply1<Inserter, mpl::vector<Arg1> >::type
    >::type
{};

template<
    template<int> class T,
    int Arg1,
    typename Seq, typename Inserter
>
struct template_sequence_impl<T<Arg1>, Seq, Inserter> :
    mpl::copy<Seq,
        typename mpl::apply1<Inserter, mpl::vector<mpl::int_<Arg1> > >::type
    >::type
{};

template<
    template<typename, typename> class T,
    typename Arg1, typename Arg2,
    typename Seq, typename Inserter
>
struct template_sequence_impl<T<Arg1, Arg2>, Seq, Inserter> :
    mpl::copy<Seq,
        typename mpl::apply1<Inserter, mpl::vector<Arg1, Arg2> >::type
    >::type
{};

// typename T 以外の場合をどうしようか……
// template<
//     template<typename, int> class T,
//     typename Arg1, int Arg2,
//     typename Seq, typename Inserter
// >
// struct template_sequence_impl<T<Arg1, Arg2>, Seq, Inserter> :
//     mpl::copy<Seq,
//         typename mpl::apply1<Inserter, mpl::vector<Arg1, mpl::int_<Arg2> > >::type
//     >::type
// {};
// 
// template<
//     template<int, typename> class T,
//     int Arg1, typename Arg2,
//     typename Seq, typename Inserter
// >
// struct template_sequence_impl<T<Arg1, Arg2>, Seq, Inserter> :
//     mpl::copy<Seq,
//         typename mpl::apply1<Inserter, mpl::vector<mpl::int_<Arg1>, Arg2> >::type
//     >::type
// {};
// 
// template<
//     template<int, int> class T,
//     int Arg1, int Arg2,
//     typename Seq, typename Inserter
// >
// struct template_sequence_impl<T<Arg1, Arg2>, Seq, Inserter> :
//     mpl::copy<Seq,
//         typename mpl::apply1<Inserter, mpl::vector<mpl::int_<Arg1>, mpl::int_<Arg2> > >::type
//     >::type
// {};

template<
    template<typename, typename, typename> class T,
    typename Arg1, typename Arg2, typename Arg3,
    typename Seq, typename Inserter
>
struct template_sequence_impl<T<Arg1, Arg2, Arg3>, Seq, Inserter> :
    mpl::copy<Seq,
        typename mpl::apply1<Inserter, mpl::vector<Arg1, Arg2, Arg3> >::type
    >::type
{};

} // namespace detail{

template<typename T, typename Seq,
    typename Inserter = boost::mpl::back_inserter<boost::mpl::_1>
>
struct template_sequence : detail::template_sequence_impl<T, Seq, Inserter>{};

template<typename T>
struct template_vector : template_sequence<T, boost::mpl::vector<> >{};

template<typename T>
struct template_args : template_vector<T>{};


#include <boost/mpl/equal.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/if.hpp>
#include <vector>
#include <utility>

namespace mpl = boost::mpl;

template<typename T, typename U>
struct hoge{};

BOOST_MPL_ASSERT(( mpl::equal<
    template_args<hoge<int, float> >,
    mpl::vector<int, float>
> ));

BOOST_MPL_ASSERT(( mpl::equal<
    template_args<std::pair<int, float> >,
    mpl::vector<int, float>
> ));

BOOST_MPL_ASSERT(( mpl::equal<
    template_args<std::pair<int, float> >,
    template_args<hoge<int, float> >
> ));

int main(){}