On Fri, Oct 24, 2025 at 5:34 PM Matthias Kretz <[email protected]> wrote:
> - Moved out of #if __glibcxx_integer_sequence into #if > __cpp_structured_bindings >= 202411L. > - Renamed to _IotaArray. Renamed test accordingly. > > Tested on x86_64-linux. (__integer_pack else branch tested, too) > OK for trunk? > > ------------------------- 8< ------------------ > > This patch introduces the internal helper type _IotaArray to simplify > defining a pack of indices via a structured binding declaration: > constexpr auto [...__is] = _IotaArray<N>; > > _IotaArray is a C-array for lowest overhead in terms of template > instantiations. Non-GCC compilers that do not implement > __integer_pack have a slightly higher overhead. > > libstdc++-v3/ChangeLog: > > * include/bits/utility.h (_IotaArray): Define. > * testsuite/ext/iotaarray.cc: New test. > > Signed-off-by: Matthias Kretz <[email protected]> > --- > libstdc++-v3/include/bits/utility.h | 16 ++++++++++++++++ > libstdc++-v3/testsuite/ext/iotaarray.cc | 20 ++++++++++++++++++++ > 2 files changed, 36 insertions(+) > create mode 100644 libstdc++-v3/testsuite/ext/iotaarray.cc > > diff --git a/libstdc++-v3/include/bits/utility.h > b/libstdc++-v3/include/bits/ > utility.h > index 4e574658eba..2a613082960 100644 > --- a/libstdc++-v3/include/bits/utility.h > +++ b/libstdc++-v3/include/bits/utility.h > @@ -172,6 +172,22 @@ struct integer_sequence > using index_sequence_for = make_index_sequence<sizeof...(_Types)>; > #endif // __glibcxx_integer_sequence > > +#if __cpp_structured_bindings >= 202411L > +#if __has_builtin(__integer_pack) > + template <auto _Num, typename _Tp = decltype(_Num)> > + inline constexpr _Tp > + _IotaArray[_Num] = {__integer_pack(_Tp(_Num))...}; > +#else > This should be #elif __glibcxx_integer_sequence, we dependent on that., Otherwise this looks good to me. > + template <auto _Num, typename _Tp = decltype(_Num), typename = > make_integer_sequence<_Tp, _Num>> > + inline constexpr _Tp > + _IotaArray[_Num]; > + > + template <auto _Num, typename _Tp, _Tp... _Is> > + inline constexpr _Tp > + _IotaArray<_Num, _Tp, integer_sequence<_Tp, _Is...>>[_Num] = {_Is...}; > +#endif // __integer_pack > +#endif // __cpp_structured_bindings >= 202411L > + > #if __cplusplus >= 201703L > > struct in_place_t { > diff --git a/libstdc++-v3/testsuite/ext/iotaarray.cc > b/libstdc++-v3/testsuite/ > ext/iotaarray.cc > new file mode 100644 > index 00000000000..b259602c42b > --- /dev/null > +++ b/libstdc++-v3/testsuite/ext/iotaarray.cc > @@ -0,0 +1,20 @@ > +// { dg-do compile { target c++26 } } > + > +#include <utility> > +#include <type_traits> > + > +template<auto N> > +void test() > +{ > + constexpr auto [id0, ...ids] = std::_IotaArray<N>; > + static_assert( std::is_same_v<decltype(id0), const decltype(N)> ); > + static_assert( sizeof...(ids) == N - 1 ); > + static_assert( (id0 + ... + ids) == N*(N-1)/2 ); > +} > + > +int main() > +{ > + test<1>(); > + test<4u>(); > + test<8ull>(); > +} > -- > ────────────────────────────────────────────────────────────────────────── > Dr. Matthias Kretz https://mattkretz.github.io > GSI Helmholtz Center for Heavy Ion Research https://gsi.de > std::simd > ────────────────────────────────────────────────────────────────────────── > > > > >
