2#include "gaia/config/config.h"
8#include "gaia/core/utility.h"
13 GAIA_MSVC_WARNING_PUSH()
21 GAIA_MSVC_WARNING_DISABLE(4702)
27 constexpr operator T();
30 template <
typename T,
typename... TArgs>
31 decltype((void)T{std::declval<TArgs>()...}, std::true_type{}) is_braces_constructible(
int);
33 template <
typename,
typename...>
34 std::false_type is_braces_constructible(...);
36 template <
typename T,
typename... TArgs>
37 using is_braces_constructible_t =
decltype(detail::is_braces_constructible<T, TArgs...>(0));
44 template <
typename S,
size_t... Is,
typename Tuple>
45 GAIA_NODISCARD S tuple_to_struct(std::index_sequence<Is...> , Tuple&& tup) {
46 return {std::get<Is>(GAIA_FWD(tup))...};
49 template <
typename S,
typename Tuple>
50 GAIA_NODISCARD S tuple_to_struct(Tuple&& tup) {
51 using T = std::remove_reference_t<Tuple>;
53 return tuple_to_struct<S>(std::make_index_sequence<std::tuple_size<T>{}>{}, GAIA_FWD(tup));
61 static constexpr uint32_t StructToTupleMaxTypes_Bits = 4;
62 static constexpr uint32_t StructToTupleMaxTypes = (1 << StructToTupleMaxTypes_Bits) - 1;
66 auto struct_to_tuple(T&&
object)
noexcept {
67 using type = core::raw_t<T>;
69 if constexpr (std::is_empty_v<type>) {
70 return std::make_tuple();
71 }
else if constexpr (detail::is_braces_constructible_t<
72 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
73 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
74 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
75 detail::any_type>{}) {
76 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15] = GAIA_FWD(
object);
77 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
78 }
else if constexpr (detail::is_braces_constructible_t<
79 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
80 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
81 detail::any_type, detail::any_type, detail::any_type, detail::any_type,
82 detail::any_type>{}) {
83 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14] = GAIA_FWD(
object);
84 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
85 }
else if constexpr (detail::is_braces_constructible_t<
86 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
87 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
88 detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
89 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13] = GAIA_FWD(
object);
90 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
91 }
else if constexpr (detail::is_braces_constructible_t<
92 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
93 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
94 detail::any_type, detail::any_type, detail::any_type>{}) {
95 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12] = GAIA_FWD(
object);
96 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
97 }
else if constexpr (detail::is_braces_constructible_t<
98 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
99 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
100 detail::any_type, detail::any_type>{}) {
101 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11] = GAIA_FWD(
object);
102 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
103 }
else if constexpr (detail::is_braces_constructible_t<
104 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
105 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
106 detail::any_type>{}) {
107 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] = GAIA_FWD(
object);
108 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
109 }
else if constexpr (detail::is_braces_constructible_t<
110 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
111 detail::any_type, detail::any_type, detail::any_type, detail::any_type,
112 detail::any_type>{}) {
113 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9] = GAIA_FWD(
object);
114 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8, p9);
115 }
else if constexpr (detail::is_braces_constructible_t<
116 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
117 detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
118 auto&& [p1, p2, p3, p4, p5, p6, p7, p8] = GAIA_FWD(
object);
119 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7, p8);
120 }
else if constexpr (detail::is_braces_constructible_t<
121 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
122 detail::any_type, detail::any_type, detail::any_type>{}) {
123 auto&& [p1, p2, p3, p4, p5, p6, p7] = GAIA_FWD(
object);
124 return std::make_tuple(p1, p2, p3, p4, p5, p6, p7);
125 }
else if constexpr (detail::is_braces_constructible_t<
126 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
127 detail::any_type, detail::any_type>{}) {
128 auto&& [p1, p2, p3, p4, p5, p6] = GAIA_FWD(
object);
129 return std::make_tuple(p1, p2, p3, p4, p5, p6);
130 }
else if constexpr (detail::is_braces_constructible_t<
131 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
132 detail::any_type>{}) {
133 auto&& [p1, p2, p3, p4, p5] = GAIA_FWD(
object);
134 return std::make_tuple(p1, p2, p3, p4, p5);
135 }
else if constexpr (detail::is_braces_constructible_t<
136 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
137 auto&& [p1, p2, p3, p4] = GAIA_FWD(
object);
138 return std::make_tuple(p1, p2, p3, p4);
139 }
else if constexpr (detail::is_braces_constructible_t<
140 type, detail::any_type, detail::any_type, detail::any_type>{}) {
141 auto&& [p1, p2, p3] = GAIA_FWD(
object);
142 return std::make_tuple(p1, p2, p3);
143 }
else if constexpr (detail::is_braces_constructible_t<type, detail::any_type, detail::any_type>{}) {
144 auto&& [p1, p2] = GAIA_FWD(
object);
145 return std::make_tuple(p1, p2);
146 }
else if constexpr (detail::is_braces_constructible_t<type, detail::any_type>{}) {
147 auto&& [p1] = GAIA_FWD(
object);
148 return std::make_tuple(p1);
151 GAIA_ASSERT2(
false,
"Unsupported number of members");
158 template <
typename T>
159 auto struct_member_count() {
160 using type = core::raw_t<T>;
162 if constexpr (std::is_empty_v<type>) {
164 }
else if constexpr (detail::is_braces_constructible_t<
165 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
166 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
167 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
168 detail::any_type>{}) {
170 }
else if constexpr (detail::is_braces_constructible_t<
171 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
172 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
173 detail::any_type, detail::any_type, detail::any_type, detail::any_type,
174 detail::any_type>{}) {
176 }
else if constexpr (detail::is_braces_constructible_t<
177 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
178 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
179 detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
181 }
else if constexpr (detail::is_braces_constructible_t<
182 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
183 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
184 detail::any_type, detail::any_type, detail::any_type>{}) {
186 }
else if constexpr (detail::is_braces_constructible_t<
187 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
188 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
189 detail::any_type, detail::any_type>{}) {
191 }
else if constexpr (detail::is_braces_constructible_t<
192 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
193 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
194 detail::any_type>{}) {
196 }
else if constexpr (detail::is_braces_constructible_t<
197 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
198 detail::any_type, detail::any_type, detail::any_type, detail::any_type,
199 detail::any_type>{}) {
201 }
else if constexpr (detail::is_braces_constructible_t<
202 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
203 detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
205 }
else if constexpr (detail::is_braces_constructible_t<
206 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
207 detail::any_type, detail::any_type, detail::any_type>{}) {
209 }
else if constexpr (detail::is_braces_constructible_t<
210 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
211 detail::any_type, detail::any_type>{}) {
213 }
else if constexpr (detail::is_braces_constructible_t<
214 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
215 detail::any_type>{}) {
217 }
else if constexpr (detail::is_braces_constructible_t<
218 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
220 }
else if constexpr (detail::is_braces_constructible_t<
221 type, detail::any_type, detail::any_type, detail::any_type>{}) {
223 }
else if constexpr (detail::is_braces_constructible_t<type, detail::any_type, detail::any_type>{}) {
225 }
else if constexpr (detail::is_braces_constructible_t<type, detail::any_type>{}) {
229 GAIA_ASSERT2(
false,
"Unsupported number of members");
232 template <
typename T,
typename Func>
233 auto each_member(T&&
object, Func&& visitor) {
234 using type = core::raw_t<T>;
236 if constexpr (std::is_empty_v<type>) {
238 }
else if constexpr (detail::is_braces_constructible_t<
239 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
240 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
241 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
242 detail::any_type>{}) {
243 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15] = object;
244 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15);
245 }
else if constexpr (detail::is_braces_constructible_t<
246 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
247 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
248 detail::any_type, detail::any_type, detail::any_type, detail::any_type,
249 detail::any_type>{}) {
250 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14] = object;
251 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14);
252 }
else if constexpr (detail::is_braces_constructible_t<
253 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
254 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
255 detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
256 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13] = object;
257 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13);
258 }
else if constexpr (detail::is_braces_constructible_t<
259 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
260 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
261 detail::any_type, detail::any_type, detail::any_type>{}) {
262 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12] = object;
263 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12);
264 }
else if constexpr (detail::is_braces_constructible_t<
265 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
266 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
267 detail::any_type, detail::any_type>{}) {
268 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11] = object;
269 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11);
270 }
else if constexpr (detail::is_braces_constructible_t<
271 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
272 detail::any_type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
273 detail::any_type>{}) {
274 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10] = object;
275 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
276 }
else if constexpr (detail::is_braces_constructible_t<
277 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
278 detail::any_type, detail::any_type, detail::any_type, detail::any_type,
279 detail::any_type>{}) {
280 auto&& [p1, p2, p3, p4, p5, p6, p7, p8, p9] = object;
281 return visitor(p1, p2, p3, p4, p5, p6, p7, p8, p9);
282 }
else if constexpr (detail::is_braces_constructible_t<
283 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
284 detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
285 auto&& [p1, p2, p3, p4, p5, p6, p7, p8] = object;
286 return visitor(p1, p2, p3, p4, p5, p6, p7, p8);
287 }
else if constexpr (detail::is_braces_constructible_t<
288 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
289 detail::any_type, detail::any_type, detail::any_type>{}) {
290 auto&& [p1, p2, p3, p4, p5, p6, p7] = object;
291 return visitor(p1, p2, p3, p4, p5, p6, p7);
292 }
else if constexpr (detail::is_braces_constructible_t<
293 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
294 detail::any_type, detail::any_type>{}) {
295 auto&& [p1, p2, p3, p4, p5, p6] = object;
296 return visitor(p1, p2, p3, p4, p5, p6);
297 }
else if constexpr (detail::is_braces_constructible_t<
298 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type,
299 detail::any_type>{}) {
300 auto&& [p1, p2, p3, p4, p5] = object;
301 return visitor(p1, p2, p3, p4, p5);
302 }
else if constexpr (detail::is_braces_constructible_t<
303 type, detail::any_type, detail::any_type, detail::any_type, detail::any_type>{}) {
304 auto&& [p1, p2, p3, p4] = object;
305 return visitor(p1, p2, p3, p4);
306 }
else if constexpr (detail::is_braces_constructible_t<
307 type, detail::any_type, detail::any_type, detail::any_type>{}) {
308 auto&& [p1, p2, p3] = object;
309 return visitor(p1, p2, p3);
310 }
else if constexpr (detail::is_braces_constructible_t<type, detail::any_type, detail::any_type>{}) {
311 auto&& [p1, p2] = object;
312 return visitor(p1, p2);
313 }
else if constexpr (detail::is_braces_constructible_t<type, detail::any_type>{}) {
314 auto&& [p1] = object;
318 GAIA_ASSERT2(
false,
"Unsupported number of members");
321 GAIA_MSVC_WARNING_POP()
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9