]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix class mandate for extents.
authorLuc Grosheintz <luc.grosheintz@gmail.com>
Wed, 14 May 2025 19:13:52 +0000 (21:13 +0200)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 15 May 2025 15:36:03 +0000 (16:36 +0100)
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. Remove
leading underscores from names in static_assert message.
* testsuite/23_containers/mdspan/extents/class_mandates_neg.cc:
Check that extents<char,...> and extents<bool,...> are invalid.
Adjust dg-prune-output pattern.
* testsuite/23_containers/mdspan/extents/misc.cc: Update
tests to avoid `char` and `bool` as IndexType.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/include/std/mdspan
libstdc++-v3/testsuite/23_containers/mdspan/extents/class_mandates_neg.cc
libstdc++-v3/testsuite/23_containers/mdspan/extents/misc.cc

index aee96dda7cd0e47cf0dd3e8b27155cab133fd5e6..47cfa405e442008b1a7707c0a3f870e7f49ee5ca 100644 (file)
@@ -163,10 +163,11 @@ _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 type");
       static_assert(
          (__mdspan::__valid_static_extent<_Extents, _IndexType> && ...),
-         "Extents must either be dynamic or representable as _IndexType");
+         "Extents must either be dynamic or representable as IndexType");
 
     public:
       using index_type = _IndexType;
index b654e3920a8ae0bb49b032b6fea5a232808dabc4..f9c1c0196669d790db88ab55ce1449397f10b10f 100644 (file)
@@ -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" }
-// { dg-prune-output "dynamic or representable as _IndexType" }
-// { dg-prune-output "must be integral" }
+#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 "signed or unsigned integer" }
 // { dg-prune-output "invalid use of incomplete type" }
index 16204aaaa75aead87f9218e4561400ff3f8bfa6f..e71fdc5423052d022274335e663844741e6ff0b3 100644 (file)
@@ -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;
 }