1414#include < Framework/Traits.h>
1515#include < array>
1616
17+ // Structured binding packs (P1061) are C++26, but clang implements them as an
18+ // extension in every language mode and advertises them via the feature test
19+ // macro, so we can use them while still compiling as C++20.
20+ #if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 202411L
21+ #define DPL_STRUCTURED_BINDING_PACKS 1
22+ #endif
23+
24+ #ifndef DPL_STRUCTURED_BINDING_PACKS
1725namespace
1826{
1927template <class T , typename ... Args>
@@ -24,9 +32,11 @@ template <class T, typename... Args>
2432std::false_type
2533 brace_test (...);
2634} // namespace
35+ #endif
2736
2837namespace o2 ::framework
2938{
39+ #ifndef DPL_STRUCTURED_BINDING_PACKS
3040struct any_type {
3141 template <class T >
3242 constexpr operator T (); // non explicit
@@ -35,19 +45,67 @@ struct any_type {
3545template <class T , typename ... Args>
3646struct is_braces_constructible : decltype (brace_test<T, Args...>(0 )) {
3747};
48+ #endif
3849
39- #define DPL_REPEAT_0 (x )
40- #define DPL_REPEAT_1 (x ) x
41- #define DPL_REPEAT_2 (x ) x, x
42- #define DPL_REPEAT_3 (x ) x, x, x
43- #define DPL_REPEAT_4 (x ) x, x, x, x
44- #define DPL_REPEAT_5 (x ) x, x, x, x, x
45- #define DPL_REPEAT_6 (x ) x, x, x, x, x, x
46- #define DPL_REPEAT_7 (x ) x, x, x, x, x, x, x
47- #define DPL_REPEAT_8 (x ) x, x, x, x, x, x, x, x
48- #define DPL_REPEAT_9 (x ) x, x, x, x, x, x, x, x, x
49- #define DPL_REPEAT_10 (x ) x, x, x, x, x, x, x, x, x, x
50- #define DPL_REPEAT (x, d, u ) DPL_REPEAT_ ##d(DPL_REPEAT_10 (x)), DPL_REPEAT_ ##u(x)
50+ struct UniversalType {
51+ template <typename T>
52+ operator T ()
53+ {
54+ }
55+ };
56+
57+ template <typename T>
58+ consteval auto brace_constructible_size (auto ... Members)
59+ {
60+ if constexpr (requires { T{Members...}; } == false ) {
61+ static_assert (sizeof ...(Members) != 0 , " You need to make sure that you have implicit constructors or that you call the explicit constructor correctly." );
62+ return sizeof ...(Members) - 1 ;
63+ } else {
64+ return brace_constructible_size<T>(Members..., UniversalType{});
65+ }
66+ }
67+
68+ template <bool B, typename T>
69+ consteval int nested_brace_constructible_size ()
70+ {
71+ using type = std::decay_t <T>;
72+ constexpr int nesting = B ? 1 : 0 ;
73+ return brace_constructible_size<type>() - nesting;
74+ }
75+
76+ // / The size to be passed to homogeneous_apply_refs_sized for T. Structured
77+ // / binding packs do not need to know how many members T has, so we can skip
78+ // / counting them altogether.
79+ template <bool B, typename T>
80+ consteval int homogeneous_apply_refs_size ()
81+ {
82+ #ifdef DPL_STRUCTURED_BINDING_PACKS
83+ return 0 ;
84+ #else
85+ return nested_brace_constructible_size<B, T>() / 10 ;
86+ #endif
87+ }
88+
89+ #ifdef DPL_STRUCTURED_BINDING_PACKS
90+ #ifdef __clang__
91+ #pragma clang diagnostic push
92+ #pragma clang diagnostic ignored "-Wc++26-extensions"
93+ #endif
94+ template <bool B = false , class T , int D = 0 , typename L>
95+ constexpr auto homogeneous_apply_refs (L l, T&& object)
96+ {
97+ auto && [... members] = object;
98+ if constexpr (sizeof ...(members) == 0 ) {
99+ return std::array<bool , 0 >();
100+ } else {
101+ return std::array{l (members)...};
102+ }
103+ }
104+ #ifdef __clang__
105+ #pragma clang diagnostic pop
106+ #endif
107+
108+ #else // DPL_STRUCTURED_BINDING_PACKS
51109
52110#define DPL_ENUM_0 (pre, post )
53111#define DPL_ENUM_1 (pre, post ) pre ##0 ##post
@@ -97,54 +155,6 @@ struct is_braces_constructible : decltype(brace_test<T, Args...>(0)) {
97155
98156#define DPL_FENUM (f, pre, post, d, u ) DPL_FENUM_ ##d##0 (f, pre , post ), DPL_FENUM_ ##u(f, pre ##d, post )
99157
100- #define DPL_10_As DPL_REPEAT_10 (A)
101- #define DPL_20_As DPL_10_As, DPL_10_As
102- #define DPL_30_As DPL_20_As, DPL_10_As
103- #define DPL_40_As DPL_30_As, DPL_10_As
104- #define DPL_50_As DPL_40_As, DPL_10_As
105- #define DPL_60_As DPL_50_As, DPL_10_As
106- #define DPL_70_As DPL_60_As, DPL_10_As
107- #define DPL_80_As DPL_70_As, DPL_10_As
108- #define DPL_90_As DPL_80_As, DPL_10_As
109- #define DPL_100_As DPL_90_As, DPL_10_As
110-
111- #define DPL_0_9 (pre, po ) pre ##0 ##po, pre ##1 ##po, pre ##2 ##po, pre ##3 ##po, pre ##4 ##po, pre ##5 ##po, pre ##6 ##po, pre ##7 ##po, pre ##8 ##po, pre ##9 ##po
112-
113- #define BRACE_CONSTRUCTIBLE_ENTRY_LOW (u ) \
114- constexpr (is_braces_constructible<type, DPL_REPEAT_ ##u(A)>{}) \
115- { \
116- return u; \
117- }
118- #define BRACE_CONSTRUCTIBLE_ENTRY (d, u ) \
119- constexpr (is_braces_constructible<type, DPL_REPEAT (A, d, u)>{}) \
120- { \
121- return d##u; \
122- }
123-
124- #define BRACE_CONSTRUCTIBLE_ENTRY_TENS (d ) \
125- constexpr (is_braces_constructible<type, DPL_ ##d##0_As>{}) \
126- { \
127- return d##0 ; \
128- }
129-
130- struct UniversalType {
131- template <typename T>
132- operator T ()
133- {
134- }
135- };
136-
137- template <typename T>
138- consteval auto brace_constructible_size (auto ... Members)
139- {
140- if constexpr (requires { T{Members...}; } == false ) {
141- static_assert (sizeof ...(Members) != 0 , " You need to make sure that you have implicit constructors or that you call the explicit constructor correctly." );
142- return sizeof ...(Members) - 1 ;
143- } else {
144- return brace_constructible_size<T>(Members..., UniversalType{});
145- }
146- }
147-
148158#define DPL_HOMOGENEOUS_APPLY_ENTRY_LOW (u ) \
149159 constexpr (numElements == u) \
150160 { \
@@ -166,14 +176,6 @@ consteval auto brace_constructible_size(auto... Members)
166176 return std::array<decltype (l (p0)), d##0 >{DPL_FENUM_ ##d##0 (l, p, )}; \
167177 }
168178
169- template <bool B, typename T>
170- consteval int nested_brace_constructible_size ()
171- {
172- using type = std::decay_t <T>;
173- constexpr int nesting = B ? 1 : 0 ;
174- return brace_constructible_size<type>() - nesting;
175- }
176-
177179template <bool B = false , class T , int D = nested_brace_constructible_size<B, T>() / 10 , typename L>
178180 requires (D == 9 )
179181constexpr auto homogeneous_apply_refs(L l, T&& object)
@@ -373,6 +375,8 @@ constexpr auto homogeneous_apply_refs(L l, T&& object)
373375 // clang-format on
374376}
375377
378+ #endif // DPL_STRUCTURED_BINDING_PACKS
379+
376380template <int D, typename T, typename L>
377381constexpr auto homogeneous_apply_refs_sized (L l, T&& object)
378382{
0 commit comments