Skip to content

Commit 21dc95f

Browse files
make TypeAt instantiate less templates
1 parent 5fab57b commit 21dc95f

3 files changed

Lines changed: 63 additions & 18 deletions

File tree

aether/meta/type_list.h

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,72 @@
1818
#define AETHER_META_TYPE_LIST_H_
1919

2020
#include <cstddef>
21-
#include <utility>
21+
#include <type_traits>
2222

2323
namespace ae {
2424
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+
2731
template <typename... U>
28-
explicit constexpr TypeList(U&&...) {}
32+
explicit constexpr TypeListMaker(U&&...) {}
2933
};
3034

3135
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+
}
3380

3481
template <std::size_t I, typename TList>
3582
struct TypeAt;
3683

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;
4587
};
4688

4789
template <std::size_t I, typename TList>

aether/reflect/reflect_impl.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,10 @@ struct IsReflectable<T,
248248
constexpr auto FieldList() const { \
249249
using SelfType = std::decay_t<decltype(*this)>; \
250250
static_assert(sizeof(SelfType) != 0); \
251-
constexpr auto fields = ::ae::TypeList{__VA_ARGS__}; \
251+
auto fields = ::ae::TypeListMaker{__VA_ARGS__}; \
252252
using TypeFieldTypeList = \
253-
::ae::JoinedTypeList_t<::ae::TypeList<SelfType>, decltype(fields)>; \
253+
::ae::JoinedTypeList_t<::ae::TypeList<SelfType>, \
254+
typename decltype(fields)::type>; \
254255
using FL = typename ::ae::TypeListToTemplate< \
255256
::ae::reflect::reflect_internal::FieldList, TypeFieldTypeList>::type; \
256257
return FL{}; \
@@ -264,10 +265,10 @@ struct IsReflectable<T,
264265
constexpr auto FieldList() const { \
265266
using SelfType = std::decay_t<decltype(*this)>; \
266267
static_assert(sizeof(SelfType) != 0); \
267-
constexpr auto fields = \
268-
::ae::TypeList{_AE_APPLY_MACRO(AE_MMBR, __VA_ARGS__)}; \
268+
auto fields = ::ae::TypeListMaker{_AE_APPLY_MACRO(AE_MMBR, __VA_ARGS__)}; \
269269
using TypeFieldTypeList = \
270-
::ae::JoinedTypeList_t<::ae::TypeList<SelfType>, decltype(fields)>; \
270+
::ae::JoinedTypeList_t<::ae::TypeList<SelfType>, \
271+
typename decltype(fields)::type>; \
271272
using FL = typename ::ae::TypeListToTemplate< \
272273
::ae::reflect::reflect_internal::FieldList, TypeFieldTypeList>::type; \
273274
return FL{}; \

tests/test-meta/test-type-list.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <unity.h>
1818

19+
#include <utility>
1920
#include "aether/meta/type_list.h"
2021

2122
#if defined __GNUC__
@@ -112,6 +113,7 @@ void TestNTypesReverse() {
112113
void test_Ntypes() {
113114
RUN_TEST(TestNTypes<1>);
114115
RUN_TEST(TestNTypes<10>);
116+
115117
RUN_TEST(TestNTypes<100>);
116118
RUN_TEST(TestNTypes<450>);
117119

0 commit comments

Comments
 (0)