On Wed, 14 May 2025 at 20:18, Luc Grosheintz <luc.groshei...@gmail.com> wrote: > > The standard states that the IndexType must be a signed or unsigned > integer. This mandate was implemented using `std::is_integral_v`. Which > also includes (among others) char and bool, which neither signed nor > unsigned integers. > > libstdc++-v3/ChangeLog: > > * include/std/mdspan: Implement the mandate for extents as > signed or unsigned integer and not any interal type. > * testsuite/23_containers/mdspan/extents/class_mandates_neg.cc: Check > that extents<char,...> and extents<bool,...> are invalid. > * testsuite/23_containers/mdspan/extents/misc.cc: Update > tests to avoid `char` and `bool` as IndexType. > --- > libstdc++-v3/include/std/mdspan | 3 ++- > .../23_containers/mdspan/extents/class_mandates_neg.cc | 10 +++++++--- > .../testsuite/23_containers/mdspan/extents/misc.cc | 8 ++++---- > 3 files changed, 13 insertions(+), 8 deletions(-) > > diff --git a/libstdc++-v3/include/std/mdspan b/libstdc++-v3/include/std/mdspan > index aee96dda7cd..22509d9c8f4 100644 > --- a/libstdc++-v3/include/std/mdspan > +++ b/libstdc++-v3/include/std/mdspan > @@ -163,7 +163,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > template<typename _IndexType, size_t... _Extents> > class extents > { > - static_assert(is_integral_v<_IndexType>, "_IndexType must be > integral."); > + static_assert(__is_standard_integer<_IndexType>::value, > + "_IndexType must be a signed or unsigned integer.");
GCC's diagnostics never end with a full stop (aka period), and we follow that convention for our static assertions. So I'll remove the '.' at the end of the string literal, and then push this to trunk. > static_assert( > (__mdspan::__valid_static_extent<_Extents, _IndexType> && ...), > "Extents must either be dynamic or representable as _IndexType"); > diff --git > a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > index b654e3920a8..63a2db77c08 100644 > --- > a/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > +++ > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc > @@ -1,8 +1,12 @@ > // { dg-do compile { target c++23 } } > #include<mdspan> > > -std::extents<char, size_t(1) << 9> e1; // { dg-error "from here" } > -std::extents<double, 1> e2; // { dg-error "from here" } > +#include <cstdint> > + > +std::extents<uint8_t, size_t(1) << 9> e1; // { dg-error "from here" } > +std::extents<char, 1> e2; // { dg-error "from here" } > +std::extents<bool, 1> e3; // { dg-error "from here" } > +std::extents<double, 1> e4; // { dg-error "from here" } > // { dg-prune-output "dynamic or representable as _IndexType" } > -// { dg-prune-output "must be integral" } > +// { dg-prune-output "signed or unsigned integer" } > // { dg-prune-output "invalid use of incomplete type" } > diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc > b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc > index 16204aaaa75..e71fdc54230 100644 > --- a/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc > +++ b/libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc > @@ -1,6 +1,7 @@ > // { dg-do run { target c++23 } } > #include <mdspan> > > +#include <cstdint> > #include <testsuite_hooks.h> > > constexpr size_t dyn = std::dynamic_extent; > @@ -20,7 +21,6 @@ static_assert(std::is_same_v<std::extents<int, 1, > 2>::rank_type, size_t>); > static_assert(std::is_unsigned_v<std::extents<int, 2>::size_type>); > static_assert(std::is_unsigned_v<std::extents<unsigned int, 2>::size_type>); > > -static_assert(std::is_same_v<std::extents<char, 2>::index_type, char>); > static_assert(std::is_same_v<std::extents<int, 2>::index_type, int>); > static_assert(std::is_same_v<std::extents<unsigned int, 2>::index_type, > unsigned int>); > @@ -49,7 +49,7 @@ static_assert(check_rank_return_types<int, 1>()); > > // Check that the static extents don't take up space. > static_assert(sizeof(std::extents<int, 1, dyn>) == sizeof(int)); > -static_assert(sizeof(std::extents<char, 1, dyn>) == sizeof(char)); > +static_assert(sizeof(std::extents<short, 1, dyn>) == sizeof(short)); > > template<typename Extents> > class Container > @@ -58,7 +58,7 @@ class Container > [[no_unique_address]] std::extents<size_t> b0; > }; > > -static_assert(sizeof(Container<std::extents<char, 1, 2>>) == sizeof(int)); > +static_assert(sizeof(Container<std::extents<short, 1, 2>>) == sizeof(int)); > static_assert(sizeof(Container<std::extents<size_t, 1, 2>>) == sizeof(int)); > > // operator= > @@ -103,7 +103,7 @@ test_deduction_all() > test_deduction<0>(); > test_deduction<1>(1); > test_deduction<2>(1.0, 2.0f); > - test_deduction<3>(int(1), char(2), size_t(3)); > + test_deduction<3>(int(1), short(2), size_t(3)); > return true; > } > > -- > 2.49.0 >