fork download
  1. #include <cstddef>
  2. #include <type_traits>
  3. #include <iostream>
  4.  
  5. namespace detail {
  6. template<typename>
  7. constexpr std::size_t locate(std::size_t ind) {
  8. return static_cast<std::size_t>(-1);
  9. }
  10.  
  11. template<typename IndexedType, typename T, typename... Ts>
  12. constexpr std::size_t locate(std::size_t ind = 0) {
  13. if (std::is_same<IndexedType, T>::value) {
  14. return ind;
  15. } else {
  16. return locate<IndexedType, Ts...>(ind + 1);
  17. }
  18. }
  19.  
  20. // This could also be useful.
  21. // From a previous version of IndexOf, not used in the current version.
  22. /*
  23.   template<typename IndexedType, typename...>
  24.   struct is_in : std::false_type {};
  25.  
  26.   template<typename IndexedType, typename Item, typename... Items>
  27.   struct is_in<IndexedType, Item, Items...>
  28.   : std::integral_constant<bool,
  29.   std::is_same<IndexedType, Item>::value ||
  30.   is_in<IndexedType, Items...>::value> {};
  31.  */
  32. } // namespace detail
  33.  
  34.  
  35. namespace mpl {
  36. template<typename... Ts>
  37. struct TypeList
  38. {
  39. static constexpr std::size_t size{ sizeof... (Ts) };
  40. };
  41.  
  42. // -----
  43.  
  44. template<typename T, typename>
  45. struct IndexOf;
  46.  
  47. template<typename T, typename... ListedTypes>
  48. struct IndexOf<T, mpl::TypeList<ListedTypes...>>
  49. : std::integral_constant<std::size_t, detail::locate<T, ListedTypes...>()>
  50. {
  51. };
  52. } // namespace mpl
  53.  
  54. struct T1
  55. {
  56. };
  57.  
  58. struct T2
  59. {
  60. };
  61.  
  62. struct T3
  63. {
  64. };
  65.  
  66. using Types = mpl::TypeList<T1, T2, T3>;
  67.  
  68. int main() {
  69. using namespace mpl;
  70.  
  71. std::cout << "Given TypeList<T1, T2, T3>..."
  72. << "\nT1 is type #" << IndexOf<T1, Types>::value
  73. << "\nT2 is type #" << IndexOf<T2, Types>::value
  74. << "\nT3 is type #" << IndexOf<T3, Types>::value
  75. << "\nint is type #" << IndexOf<int, Types>::value
  76. << std::endl;
  77.  
  78. // Double-checking with a different TypeList.
  79. if (IndexOf<int, TypeList<char, bool, int, double>>::value == 2) {
  80. std::cout << "Huzzah!\n";
  81. }
  82. }
Success #stdin #stdout 0s 3468KB
stdin
Standard input is empty
stdout
Given TypeList<T1, T2, T3>...
T1 is type #0
T2 is type #1
T3 is type #2
int is type #4294967295
Huzzah!