1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
# include <type_traits>
# include <utility>
template <typename...> struct tiny;
template <typename T1> struct tiny<T1> {};
template <typename T1, typename T2> struct tiny<T1, T2> {};
template <typename T1, typename T2, typename T3>
struct tiny<T1, T2, T3> {};
namespace detail {
template <typename T, std::size_t I>
using strip_index = T;
// The following uses the fact that taking the sizeof an incomplete
// (or ill-formed) type is ill-formed.
template <template <typename...> class Tl, typename...Args,
std::size_t = sizeof(Tl<Args...>)>
std::true_type repeat_inst(int);
template <template <typename...> class Tl, typename...Args>
std::false_type repeat_inst(long);
}
template<template<typename...> class Tl, std::size_t N,
typename Is = std::make_index_sequence<N>>
struct accepts_n_template_args;
template<template<typename...> class Tl, std::size_t N, std::size_t... Is>
struct accepts_n_template_args<Tl, N, std::index_sequence<Is...>>
: decltype(detail::repeat_inst<Tl, detail::strip_index<int, Is>...>(0))
{};
int main() {
static_assert( accepts_n_template_args<tiny, 2>());
static_assert(! accepts_n_template_args<tiny, 4>());
}
|