|
18 | 18 | #define AETHER_META_TYPE_LIST_H_ |
19 | 19 |
|
20 | 20 | #include <cstddef> |
21 | | -#include <utility> |
| 21 | +#include <type_traits> |
22 | 22 |
|
23 | 23 | namespace ae { |
24 | 24 | template <typename... T> |
25 | | -struct TypeList { |
26 | | - TypeList() = default; |
| 25 | +struct TypeList {}; |
| 26 | + |
| 27 | +template <typename... T> |
| 28 | +struct TypeListMaker { |
| 29 | + using type = TypeList<std::decay_t<T>...>; |
| 30 | + |
27 | 31 | template <typename... U> |
28 | | - explicit constexpr TypeList(U&&...) {} |
| 32 | + explicit constexpr TypeListMaker(U&&...) {} |
29 | 33 | }; |
30 | 34 |
|
31 | 35 | template <typename... T> |
32 | | -TypeList(T...) -> TypeList<T...>; |
| 36 | +TypeListMaker(T&&...) -> TypeListMaker<T...>; |
| 37 | + |
| 38 | +static inline constexpr std::size_t GetTypeAtChunkSize = 10; |
| 39 | + |
| 40 | +template <std::size_t I, typename T0, typename T1 = void, typename T2 = void, |
| 41 | + typename T3 = void, typename T4 = void, typename T5 = void, |
| 42 | + typename T6 = void, typename T7 = void, typename T8 = void, |
| 43 | + typename T9 = void> |
| 44 | +static constexpr auto GetTypeAtChunk() { |
| 45 | + static_assert(I < GetTypeAtChunkSize); |
| 46 | + if constexpr (I == 0) { |
| 47 | + return std::type_identity<T0>{}; |
| 48 | + } else if constexpr (I == 1) { |
| 49 | + return std::type_identity<T1>{}; |
| 50 | + } else if constexpr (I == 2) { |
| 51 | + return std::type_identity<T2>{}; |
| 52 | + } else if constexpr (I == 3) { |
| 53 | + return std::type_identity<T3>{}; |
| 54 | + } else if constexpr (I == 4) { |
| 55 | + return std::type_identity<T4>{}; |
| 56 | + } else if constexpr (I == 5) { |
| 57 | + return std::type_identity<T5>{}; |
| 58 | + } else if constexpr (I == 6) { |
| 59 | + return std::type_identity<T6>{}; |
| 60 | + } else if constexpr (I == 7) { |
| 61 | + return std::type_identity<T7>{}; |
| 62 | + } else if constexpr (I == 8) { |
| 63 | + return std::type_identity<T8>{}; |
| 64 | + } else if constexpr (I == 9) { |
| 65 | + return std::type_identity<T9>{}; |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | +template <std::size_t I, typename T0, typename T1 = void, typename T2 = void, |
| 70 | + typename T3 = void, typename T4 = void, typename T5 = void, |
| 71 | + typename T6 = void, typename T7 = void, typename T8 = void, |
| 72 | + typename T9 = void, typename... Ts> |
| 73 | +static constexpr auto GetTypeAt() { |
| 74 | + if constexpr (I < GetTypeAtChunkSize) { |
| 75 | + return GetTypeAtChunk<I, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>(); |
| 76 | + } else { |
| 77 | + return GetTypeAt<I - GetTypeAtChunkSize, Ts...>(); |
| 78 | + } |
| 79 | +} |
33 | 80 |
|
34 | 81 | template <std::size_t I, typename TList> |
35 | 82 | struct TypeAt; |
36 | 83 |
|
37 | | -template <std::size_t I, typename T, typename... Ts> |
38 | | -struct TypeAt<I, TypeList<T, Ts...>> { |
39 | | - using type = typename TypeAt<I - 1, TypeList<Ts...>>::type; |
40 | | -}; |
41 | | - |
42 | | -template <typename T, typename... Ts> |
43 | | -struct TypeAt<0, TypeList<T, Ts...>> { |
44 | | - using type = T; |
| 84 | +template <std::size_t I, typename... Ts> |
| 85 | +struct TypeAt<I, TypeList<Ts...>> { |
| 86 | + using type = typename decltype(GetTypeAt<I, Ts...>())::type; |
45 | 87 | }; |
46 | 88 |
|
47 | 89 | template <std::size_t I, typename TList> |
|
0 commit comments