diff --git a/Framework/Foundation/include/Framework/StructToTuple.h b/Framework/Foundation/include/Framework/StructToTuple.h index 1c7aa62260bd3..1541449874c3b 100644 --- a/Framework/Foundation/include/Framework/StructToTuple.h +++ b/Framework/Foundation/include/Framework/StructToTuple.h @@ -174,6 +174,46 @@ consteval int nested_brace_constructible_size() return brace_constructible_size() - nesting; } +// Structured binding packs (P1061) are C++26, but clang implements them as an +// extension in every language mode and advertises them via the feature test +// macro, so we can use them while still compiling as C++20. +#if defined(__cpp_structured_bindings) && __cpp_structured_bindings >= 202411L +#define DPL_STRUCTURED_BINDING_PACKS 1 +#endif + +#ifdef DPL_STRUCTURED_BINDING_PACKS +namespace detail +{ +template +struct first_type; +template +struct first_type { + using type = First; +}; +template +using first_t = typename first_type::type; +} // namespace detail + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++26-extensions" +#endif +template +constexpr auto homogeneous_apply_refs(L l, T&& object) +{ + auto&& [... members] = object; + if constexpr (sizeof...(members) == 0) { + return std::array(); + } else { + return std::array, sizeof...(members)>{l(members)...}; + } +} +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +#else // DPL_STRUCTURED_BINDING_PACKS + template () / 10, typename L> requires(D == 9) constexpr auto homogeneous_apply_refs(L l, T&& object) @@ -373,6 +413,8 @@ constexpr auto homogeneous_apply_refs(L l, T&& object) // clang-format on } +#endif // DPL_STRUCTURED_BINDING_PACKS + template constexpr auto homogeneous_apply_refs_sized(L l, T&& object) {