渡された型のtemplate parametersを得るメタ関数

以前から渡された型のtemplate parametersを得るメタ関数が欲しいなと思っていて気が乗ったので書きました。
結果はその後扱いやすいようにboost::mpl::vectorにして返す事にしました。

tp_type<Type>::typeであればboost::mpl::vector<Type>を
tp_type<Type<Types...>>::typeであればboost::mpl::vector<Type, Types...>を得られるメタ関数です。

このようなコードは、普段あまり使われることのないTemplate Template Parametersの有用な例の1つだと思います。
再帰的に適用すればtemplate parameterを用いた木構造をparse出来るかもしれません。

#include <type_traits>
#include <boost/mpl/vector.hpp>

template<class... Types>
struct Foo {};

template<class T>
struct tp_type
{
private:
    template<template<class...> class Type, class... Args>
    static constexpr boost::mpl::vector<T, Args...> tp_type_impl(Type<Args...>)
    {
        return boost::mpl::vector<T, Args...>();
    }

    template<class Type>
    static constexpr boost::mpl::vector<Type> tp_type_impl(Type)
    {
        return boost::mpl::vector<Type>();
    }
    
public:
    using type = decltype(tp_type_impl(T()));
};

int main()
{
    static_assert(std::is_same<
                  tp_type<Foo<Foo<int>, double, char>>::type,
                  boost::mpl::vector<Foo<Foo<int>, double, char>, Foo<int>, double, char>
                  >::value, "");

    static_assert(std::is_same<
                  tp_type<char>::type,
                  boost::mpl::vector<char>
                  >::value, "");
}