fork(1) download
  1. #include <type_traits>
  2.  
  3. namespace detail
  4. {
  5. // Type representing a class template taking any number of non-type template arguments.
  6. template <typename T, template <T...> class U>
  7. struct nontype_template {};
  8. }
  9.  
  10. // If T is an instantiation of a class template U taking non-type template arguments,
  11. // this has a tested typedef "type" that is a detail::nontype_template representing U.
  12. template <typename T>
  13. struct nontype_template_of {};
  14.  
  15. // Partial specializations for all of the builtin integral types.
  16. template <template <bool...> class T, bool... Vs>
  17. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<bool, T>; };
  18. template <template <char...> class T, char... Vs>
  19. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<char, T>; };
  20. template <template <signed char...> class T, signed char... Vs>
  21. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<signed char, T>; };
  22. template <template <unsigned char...> class T, unsigned char... Vs>
  23. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<unsigned char, T>; };
  24. template <template <short...> class T, short... Vs>
  25. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<short, T>; };
  26. template <template <unsigned short...> class T, unsigned short... Vs>
  27. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<unsigned short, T>; };
  28. template <template <int...> class T, int... Vs>
  29. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<int, T>; };
  30. template <template <unsigned int...> class T, unsigned int... Vs>
  31. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<unsigned int, T>; };
  32. template <template <long...> class T, long... Vs>
  33. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<long, T>; };
  34. template <template <unsigned long...> class T, unsigned long... Vs>
  35. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<unsigned long, T>; };
  36. template <template <long long...> class T, long long... Vs>
  37. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<long long, T>; };
  38. template <template <unsigned long long...> class T, unsigned long long... Vs>
  39. struct nontype_template_of<T<Vs...>> { using type = detail::nontype_template<unsigned long long, T>; };
  40.  
  41. // Alias template for nontype_template_of.
  42. template <typename T>
  43. using nontype_template_of_t = typename nontype_template_of<T>::type;
  44.  
  45. template <class A, class B>
  46. struct match_class : std::is_same<nontype_template_of_t<A>, nontype_template_of_t<B>> {};
  47.  
  48. template <int...>
  49. struct Foo{};
  50.  
  51. template <unsigned long...>
  52. struct Bar{};
  53.  
  54. int main()
  55. {
  56. using f1 = Foo<1, 2, 3>;
  57. using f2 = Foo<1>;
  58. using b1 = Bar<1, 2, 3>;
  59. using b2 = Bar<1>;
  60. static_assert(match_class<f1, f2>::value, "Fail");
  61. static_assert(match_class<b1, b2>::value, "Fail");
  62. static_assert(!match_class<f1, b1>::value, "Fail");
  63. }
  64.  
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
Standard output is empty