vir-simd 0.4.189
Parallelism TS 2 extensions and simd fallback implementation
Loading...
Searching...
No Matches
struct_reflect.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-3.0-or-later */
2/* Copyright © 2018–2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
3 * Matthias Kretz <m.kretz@gsi.de>
4 */
5
6#ifndef VIR_STRUCT_SIZE_H_
7#define VIR_STRUCT_SIZE_H_
8
12
13#if defined DOXYGEN \
14 or (defined __cpp_structured_bindings && defined __cpp_concepts && __cpp_concepts >= 201907)
15#define VIR_HAVE_STRUCT_REFLECT 1
16#include <utility>
17#include <tuple>
18#include <climits>
19
20namespace vir
21{
23 namespace detail
24 {
25 using std::remove_cvref_t;
26 using std::size_t;
27
28 // struct_size implementation
29 template <typename Struct>
30 struct anything_but_base_of
31 {
32 anything_but_base_of() = default;
33
34 anything_but_base_of(const anything_but_base_of&) = delete;
35
36 template <typename T>
37 requires (not std::is_base_of_v<T, Struct>)
38 operator T&() const&;
39 };
40
41 template <typename Struct>
42 struct any_empty_base_of
43 {
44 template <typename T>
45 requires (std::is_base_of_v<T, Struct> and std::is_empty_v<T>)
46 operator T();
47 };
48
49 template <typename T, size_t... Indexes>
50 concept brace_constructible_impl
51 = requires { T{{((void)Indexes, anything_but_base_of<T>())}...}; }
52 or requires
53 {
54 T{any_empty_base_of<T>(), {((void)Indexes, anything_but_base_of<T>())}...};
55 }
56 or requires
57 {
58 T{any_empty_base_of<T>(), any_empty_base_of<T>(),
59 {((void)Indexes, anything_but_base_of<T>())}...};
60 }
61 or requires
62 {
63 T{any_empty_base_of<T>(), any_empty_base_of<T>(), any_empty_base_of<T>(),
64 {((void)Indexes, anything_but_base_of<T>())}...};
65 };
66
67 template <typename T, size_t N>
68 concept aggregate_with_n_members = []<size_t... Is>(std::index_sequence<Is...>) {
69 return brace_constructible_impl<T, Is...>;
70 }(std::make_index_sequence<N>());
71
72 template <typename T, size_t Lo = 0, size_t Hi = sizeof(T) * CHAR_BIT, size_t N = 8>
73 constexpr size_t
74 struct_size()
75 {
76 constexpr size_t left_index = Lo + (N - Lo) / 2;
77 constexpr size_t right_index = N + (Hi - N + 1) / 2;
78 if constexpr (aggregate_with_n_members<T, N>) // N is a valid size
79 {
80 if constexpr (N == Hi)
81 // we found the best valid size inside [Lo, Hi]
82 return N;
83 else
84 { // there may be a larger size in [N+1, Hi]
85 constexpr size_t right = struct_size<T, N + 1, Hi, right_index>();
86 if constexpr (right == 0)
87 // no, there isn't
88 return N;
89 else
90 // yes, there is
91 return right;
92 }
93 }
94 else if constexpr (N == Lo)
95 { // we can only look for a valid size in [N+1, Hi]
96 if constexpr (N == Hi)
97 // but [N+1, Hi] is empty
98 return 0; // no valid size found
99 else
100 // [N+1, Hi] is non-empty
101 return struct_size<T, N + 1, Hi, right_index>();
102 }
103 else
104 { // the answer could be in [Lo, N-1] or [N+1, Hi]
105 constexpr size_t left = struct_size<T, Lo, N - 1, left_index>();
106 if constexpr (left > 0)
107 // valid size in [Lo, N-1] => there can't be a valid size in [N+1, Hi] anymore
108 return left;
109 else if constexpr (N == Hi)
110 // [N+1, Hi] is empty => [Lo, Hi] has no valid size
111 return 0;
112 else
113 // there can only be a valid size in [N+1, Hi], if there is none the
114 // recursion returns 0 anyway
115 return struct_size<T, N + 1, Hi, right_index>();
116 }
117 }
118
119 // struct_get implementation
120 template <size_t Total>
121 struct struct_get;
122
123 template <typename T>
124 struct remove_ref_in_tuple;
125
126 template <typename... Ts>
127 struct remove_ref_in_tuple<std::tuple<Ts...>>
128 { using type = std::tuple<std::remove_reference_t<Ts>...>; };
129
130 template <typename T1, typename T2>
131 struct remove_ref_in_tuple<std::pair<T1, T2>>
132 { using type = std::pair<std::remove_reference_t<T1>, std::remove_reference_t<T2>>; };
133
134 template <>
135 struct struct_get<0>
136 {
137 template <typename T>
138 constexpr std::tuple<>
139 to_tuple_ref(T &&)
140 { return {}; }
141
142 template <typename T>
143 constexpr std::tuple<>
144 to_tuple(const T &)
145 { return {}; }
146 };
147
148 template <>
149 struct struct_get<1>
150 {
151 template <typename T>
152 constexpr auto
153 to_tuple_ref(T &&obj)
154 {
155 auto && [a] = obj;
156 return std::forward_as_tuple(a);
157 }
158
159 template <typename T>
160 constexpr auto
161 to_tuple(const T &obj)
162 -> typename remove_ref_in_tuple<decltype(to_tuple_ref(std::declval<T>()))>::type
163 {
164 const auto &[a] = obj;
165 return {a};
166 }
167
168 template <size_t N, typename T>
169 constexpr const auto &
170 get(const T &obj)
171 {
172 static_assert(N == 0);
173 auto && [a] = obj;
174 return a;
175 }
176
177 template <size_t N, typename T>
178 constexpr auto &
179 get(T &obj)
180 {
181 static_assert(N == 0);
182 auto && [a] = obj;
183 return a;
184 }
185 };
186
187 template <>
188 struct struct_get<2>
189 {
190 template <typename T>
191 constexpr auto
192 to_tuple_ref(T &&obj)
193 {
194 auto &&[a, b] = obj;
195 return std::forward_as_tuple(a, b);
196 }
197
198 template <typename T>
199 constexpr auto
200 to_tuple(const T &obj)
201 -> typename remove_ref_in_tuple<decltype(to_tuple_ref(std::declval<T>()))>::type
202 {
203 const auto &[a, b] = obj;
204 return {a, b};
205 }
206
207 template <typename T>
208 constexpr auto
209 to_pair_ref(T &&obj)
210 {
211 auto &&[a, b] = obj;
212 return std::pair<decltype((a)), decltype((b))>(a, b);
213 }
214
215 template <typename T>
216 constexpr auto
217 to_pair(const T &obj)
218 -> typename remove_ref_in_tuple<decltype(to_pair_ref(std::declval<T>()))>::type
219 {
220 const auto &[a, b] = obj;
221 return {a, b};
222 }
223
224 template <size_t N, typename T>
225 constexpr auto &
226 get(T &&obj)
227 {
228 static_assert(N < 2);
229 auto &&[a, b] = obj;
230 return std::get<N>(std::forward_as_tuple(a, b));
231 }
232 };
233
234#define VIR_STRUCT_GET_(size_, ...) \
235 template <> \
236 struct struct_get<size_> \
237 { \
238 template <typename T> \
239 constexpr auto \
240 to_tuple_ref(T &&obj) \
241 { \
242 auto &&[__VA_ARGS__] = obj; \
243 return std::forward_as_tuple(__VA_ARGS__); \
244 } \
245 \
246 template <typename T> \
247 constexpr auto \
248 to_tuple(const T &obj) \
249 -> typename remove_ref_in_tuple<decltype(to_tuple_ref(std::declval<T>()))>::type \
250 { \
251 const auto &[__VA_ARGS__] = obj; \
252 return {__VA_ARGS__}; \
253 } \
254 \
255 template <size_t N, typename T> \
256 constexpr auto & \
257 get(T &&obj) \
258 { \
259 static_assert(N < size_); \
260 auto &&[__VA_ARGS__] = obj; \
261 return std::get<N>(std::forward_as_tuple(__VA_ARGS__)); \
262 } \
263 }
264 VIR_STRUCT_GET_(3, x0, x1, x2);
265 VIR_STRUCT_GET_(4, x0, x1, x2, x3);
266 VIR_STRUCT_GET_(5, x0, x1, x2, x3, x4);
267 VIR_STRUCT_GET_(6, x0, x1, x2, x3, x4, x5);
268 VIR_STRUCT_GET_(7, x0, x1, x2, x3, x4, x5, x6);
269 VIR_STRUCT_GET_(8, x0, x1, x2, x3, x4, x5, x6, x7);
270 VIR_STRUCT_GET_(9, x0, x1, x2, x3, x4, x5, x6, x7, x8);
271 VIR_STRUCT_GET_(10, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9);
272 VIR_STRUCT_GET_(11, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10);
273 VIR_STRUCT_GET_(12, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11);
274 VIR_STRUCT_GET_(13, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12);
275 VIR_STRUCT_GET_(14, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13);
276 VIR_STRUCT_GET_(15, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14);
277 VIR_STRUCT_GET_(16, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15);
278 VIR_STRUCT_GET_(17, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
279 x16);
280 VIR_STRUCT_GET_(18, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
281 x16, x17);
282 VIR_STRUCT_GET_(19, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
283 x16, x17, x18);
284 VIR_STRUCT_GET_(20, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
285 x16, x17, x18, x19);
286 VIR_STRUCT_GET_(21, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
287 x16, x17, x18, x19, x20);
288 VIR_STRUCT_GET_(22, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
289 x16, x17, x18, x19, x20, x21);
290 VIR_STRUCT_GET_(23, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
291 x16, x17, x18, x19, x20, x21, x22);
292 VIR_STRUCT_GET_(24, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
293 x16, x17, x18, x19, x20, x21, x22, x23);
294 VIR_STRUCT_GET_(25, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
295 x16, x17, x18, x19, x20, x21, x22, x23, x24);
296 VIR_STRUCT_GET_(26, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
297 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25);
298 VIR_STRUCT_GET_(27, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
299 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26);
300 VIR_STRUCT_GET_(28, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
301 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27);
302 VIR_STRUCT_GET_(29, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
303 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28);
304 VIR_STRUCT_GET_(30, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
305 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29);
306 VIR_STRUCT_GET_(31, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
307 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29,
308 x30);
309 VIR_STRUCT_GET_(32, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
310 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
311 x31);
312 VIR_STRUCT_GET_(33, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
313 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
314 x31, x32);
315 VIR_STRUCT_GET_(34, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
316 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
317 x31, x32, x33);
318 VIR_STRUCT_GET_(35, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
319 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
320 x31, x32, x33, x34);
321 VIR_STRUCT_GET_(36, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
322 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
323 x31, x32, x33, x34, x35);
324 VIR_STRUCT_GET_(37, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
325 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
326 x31, x32, x33, x34, x35, x36);
327 VIR_STRUCT_GET_(38, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
328 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
329 x31, x32, x33, x34, x35, x36, x37);
330 VIR_STRUCT_GET_(39, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
331 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
332 x31, x32, x33, x34, x35, x36, x37, x38);
333 VIR_STRUCT_GET_(40, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
334 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
335 x31, x32, x33, x34, x35, x36, x37, x38, x39);
336 VIR_STRUCT_GET_(41, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
337 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
338 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40);
339 VIR_STRUCT_GET_(42, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
340 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
341 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41);
342 VIR_STRUCT_GET_(43, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
343 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
344 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42);
345 VIR_STRUCT_GET_(44, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
346 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
347 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43);
348 VIR_STRUCT_GET_(45, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
349 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
350 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44);
351 VIR_STRUCT_GET_(46, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
352 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
353 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44,
354 x45);
355 VIR_STRUCT_GET_(47, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
356 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
357 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45,
358 x46);
359 VIR_STRUCT_GET_(48, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
360 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
361 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45,
362 x46, x47);
363 VIR_STRUCT_GET_(49, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
364 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
365 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45,
366 x46, x47, x48);
367 VIR_STRUCT_GET_(50, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15,
368 x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30,
369 x31, x32, x33, x34, x35, x36, x37, x38, x39, x40, x41, x42, x43, x44, x45,
370 x46, x47, x48, x49);
371#undef VIR_STRUCT_GET_
372
373 // concept definitions
374 template <typename T>
375 concept has_tuple_size
376 = requires(T x, std::tuple_size<T> ts) { {static_cast<int>(ts)} -> std::same_as<int>; };
377
378 template <typename T>
379 concept aggregate_without_tuple_size
380 = std::is_aggregate_v<T> and not has_tuple_size<T>
381 and requires (const T& x) { detail::struct_size<T>(); };
382
383 // traits
384 template <typename From, typename To>
385 struct copy_cvref
386 {
387 using From2 = std::remove_reference_t<From>;
388 using with_const = std::conditional_t<std::is_const_v<From2>, const To, To>;
389 using with_volatile
390 = std::conditional_t<std::is_volatile_v<From2>, volatile with_const, with_const>;
391 using type = std::conditional_t<std::is_lvalue_reference_v<From>, with_volatile &,
392 std::conditional_t<std::is_rvalue_reference_v<From>,
393 with_volatile &&, with_volatile>>;
394 };
395 } // namespace detail
396
404 template <typename T>
405 concept reflectable_struct = detail::has_tuple_size<std::remove_cvref_t<T>>
406 or detail::aggregate_without_tuple_size<std::remove_cvref_t<T>>;
407
423 template <typename T>
424 requires (detail::aggregate_without_tuple_size<T> or detail::has_tuple_size<T>)
425 constexpr inline std::size_t struct_size_v = 0;
426
427 template <detail::aggregate_without_tuple_size T>
428 constexpr inline std::size_t struct_size_v<T> = detail::struct_size<T>();
429
430 template <detail::has_tuple_size T>
431 constexpr inline std::size_t struct_size_v<T> = std::tuple_size_v<T>;
432
436 template <std::size_t N, reflectable_struct T>
437 requires (N < struct_size_v<std::remove_cvref_t<T>>)
438 constexpr decltype(auto)
439 struct_get(T &&obj)
440 {
441 return detail::struct_get<struct_size_v<std::remove_cvref_t<T>>>()
442 .template get<N>(std::forward<T>(obj));
443 }
444
445 template <std::size_t N, reflectable_struct T>
446 struct struct_element
447 {
448 using type = std::remove_reference_t<decltype(struct_get<N>(std::declval<T &>()))>;
449 };
450
455 template <std::size_t N, reflectable_struct T>
457 = std::remove_reference_t<decltype(struct_get<N>(std::declval<T &>()))>;
458
462 template <reflectable_struct T>
463 constexpr auto
464 to_tuple(T &&obj)
465 {
466 return detail::struct_get<struct_size_v<std::remove_cvref_t<T>>>().to_tuple(
467 std::forward<T>(obj));
468 }
469
473 template <reflectable_struct T>
474 constexpr auto
475 to_tuple_ref(T &&obj)
476 {
477 return detail::struct_get<struct_size_v<std::remove_cvref_t<T>>>().to_tuple_ref(
478 std::forward<T>(obj));
479 }
480
485 template <reflectable_struct T>
486 struct as_tuple
487 : detail::copy_cvref<
488 T, decltype(detail::struct_get<struct_size_v<std::remove_cvref_t<T>>>().to_tuple(
489 std::declval<T>()))>
490 {};
491
495 template <typename T>
496 using as_tuple_t = typename as_tuple<T>::type;
497
501 template <typename T>
503 constexpr auto
504 to_pair(T &&obj)
505 { return detail::struct_get<2>().to_pair(std::forward<T>(obj)); }
506
510 template <typename T>
512 constexpr auto
513 to_pair_ref(T &&obj)
514 { return detail::struct_get<2>().to_pair_ref(std::forward<T>(obj)); }
515
520 template <typename T>
522 struct as_pair
523 : detail::copy_cvref<T, decltype(detail::struct_get<2>().to_pair(std::declval<T>()))>
524 {};
525
529 template <typename T>
530 using as_pair_t = typename as_pair<T>::type;
531
532} // namespace vir
533
534#endif // structured bindings & concepts
535#endif // VIR_STRUCT_SIZE_H_
536
537// vim: noet cc=101 tw=100 sw=2 ts=8
Satisfied if T can be used with the following functions and types.
Definition struct_reflect.h:405
This namespace collects libraries and tools authored by Matthias Kretz.
Definition constexpr_wrapper.h:21
constexpr auto to_pair_ref(T &&obj)
Returns a std::pair of lvalue references to all the non-static data members of obj.
Definition struct_reflect.h:512
typename as_pair< T >::type as_pair_t
Alias for a std::pair specialization matching the non-static data members of T.
Definition struct_reflect.h:529
std::remove_reference_t< decltype(struct_get< N >(std::declval< T & >()))> struct_element_t
struct_element_t<N, T> is an alias for the type of the N -th non-static data member of T.
Definition struct_reflect.h:456
constexpr decltype(auto) struct_get(T &&obj)
Returns a cv-qualified reference to the N -th non-static data member in obj.
Definition struct_reflect.h:439
constexpr auto to_tuple_ref(T &&obj)
Returns a std::tuple of lvalue references to all the non-static data members of obj.
Definition struct_reflect.h:474
constexpr auto to_pair(T &&obj)
Returns a std::pair with a copy of all the non-static data members of obj.
Definition struct_reflect.h:503
constexpr decltype(auto) get(const simd_tuple< T, N > &tup)
Definition simdize.h:504
typename as_tuple< T >::type as_tuple_t
Alias for a std::tuple specialization matching the non-static data members of T.
Definition struct_reflect.h:495
constexpr std::size_t struct_size_v
The number of non-static data members of T.
Definition struct_reflect.h:425
constexpr auto to_tuple(T &&obj)
Returns a std::tuple with a copy of all the non-static data members of obj.
Definition struct_reflect.h:463
Defines the member type type to a std::pair specialization matching the non-static data members of T.
Definition struct_reflect.h:523
Defines the member type type to a std::tuple specialization matching the non-static data members of T...
Definition struct_reflect.h:489