fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template <typename ...Args>
  5. struct type_list
  6. {};
  7.  
  8. using empty_list = type_list<>;
  9.  
  10. // identity
  11. template<typename T>
  12. struct identity
  13. {
  14. using type = T;
  15. };
  16.  
  17. // is_typelist
  18. template<typename T>
  19. struct is_typelist: std::false_type
  20. {};
  21.  
  22. template<typename ...Args>
  23. struct is_typelist<type_list<Args...>>: std::true_type
  24. {};
  25.  
  26. template<typename T>
  27. struct check_typelist
  28. {
  29. using type = void;
  30. static constexpr void *value = nullptr;
  31. static_assert(is_typelist<T>::value, "T is not a type_list!");
  32. };
  33.  
  34. // indexof
  35. namespace internal {
  36.  
  37. template<typename T, typename V, std::int64_t index>
  38. struct typelist_indexof_helper: check_typelist<T>
  39. {};
  40.  
  41. template<typename H, typename ...T, typename V, std::int64_t index>
  42. struct typelist_indexof_helper<type_list<H, T...>, V, index>:
  43. std::conditional<std::is_same<H, V>::value,
  44. std::integral_constant<std::int64_t, index>,
  45. typelist_indexof_helper<type_list<T...>, V, index + 1>
  46. >::type
  47. {};
  48.  
  49. template<typename V, std::int64_t index>
  50. struct typelist_indexof_helper<empty_list, V, index>: std::integral_constant<std::int64_t, -1>
  51. {};
  52.  
  53. }
  54.  
  55. template<typename T, typename V>
  56. using typelist_indexof = ::internal::typelist_indexof_helper<T, V, 0>;
  57.  
  58. template<typename T, typename V>
  59. struct typelist_exists: std::integral_constant<bool, typelist_indexof<T, V>::value >= 0>
  60. {};
  61.  
  62. // remove_duplicates
  63. namespace internal {
  64.  
  65. template<typename P, typename T>
  66. struct typelist_remove_duplicates_helper: check_typelist<T>
  67. {};
  68.  
  69. template<typename ...P, typename H, typename ...T>
  70. struct typelist_remove_duplicates_helper<type_list<P...>, type_list<H, T...>>:
  71. std::conditional<typelist_exists<type_list<T...>, H>::value,
  72. typelist_remove_duplicates_helper<type_list<P...>, type_list<T...>>,
  73. typelist_remove_duplicates_helper<type_list<P..., H>, type_list<T...>>
  74. >::type
  75. {};
  76.  
  77. template<typename ...P>
  78. struct typelist_remove_duplicates_helper<type_list<P...>, empty_list>: identity<type_list<P...>>
  79. {};
  80.  
  81. }
  82.  
  83. template<typename T>
  84. using typelist_remove_duplicates = ::internal::typelist_remove_duplicates_helper<empty_list, T>;
  85.  
  86.  
  87. template<typename ...Args>
  88. struct has_no_duplicates: std::integral_constant<bool, std::is_same<type_list<Args...>,
  89. typename typelist_remove_duplicates<type_list<Args...>>::type>::value>
  90. {};
  91.  
  92.  
  93.  
  94. int main() {
  95. std::cout << has_no_duplicates<int, double, char>::value << std::endl;
  96. std::cout << has_no_duplicates<int, double, int, char>::value << std::endl;
  97. return 0;
  98. }
Success #stdin #stdout 0s 3412KB
stdin
Standard input is empty
stdout
1
0