+ while (__popmin(__idx, __getextent) == 1)
+ if (++__idx == __rank)
+ return true;
+
+ size_t __prev_span = 1;
+ for (; __idx < __rank; ++__idx)
{
- const size_t __next = __popmin(__i);
- if (_M_strides[__next] < _M_strides[__prev] *
_M_extents.extent(__prev))
+ const size_t __stride = __popmin(__idx, __getstride);
+ if (__stride < __prev_span)
return false;
- __prev = __next;
+ __prev_span += __stride * (__getextent(__perm[__idx]) - 1);
}
+#else
+ // Otherwise check obvious cases where stride is zero.
+ for (size_t __idx = 0; __idx < __rank; ++__idx)
+ if (!__stride_nonzero(__idx))
+ return false;
#endif
return true;
}
diff --git
a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_debug_neg.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_debug_neg.cc
new file mode 100644
index 00000000000..bc5f41489d7
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_debug_neg.cc
@@ -0,0 +1,42 @@
+// { dg-do compile { target c++23 } }
+#include <mdspan>
+#include <cstdint>
+
+using std::array;
+template<size_t Rank>
+ using mapping = std::layout_stride::mapping<std::dextents<size_t, Rank>>;
+
+// Only some permutations are valid, invalid permutations detected only in
debug mode.
+
+// Unique if stride 4 corresponds to extent 3
+constexpr auto m28 = mapping<2>(array{3, 4}, array{4, 10}); // { dg-bogus
"expansion of" }
+constexpr auto m29 = mapping<2>(array{3, 4}, array{10, 4}); // { dg-error "expansion of"
"" { target debug_mode } }
+constexpr auto m30 = mapping<2>(array{4, 3}, array{10, 4}); // { dg-bogus
"expansion of" }
+constexpr auto m31 = mapping<2>(array{4, 3}, array{4, 10}); // { dg-error "expansion of"
"" { target debug_mode } }
+
+// Unique if stride 11 corresponds to extent 3, 2 * (5-1) = 8 < 11, and 11 *
(3-1) + 8 = 30 < 35
+constexpr auto m32 = mapping<3>(array{3, 4, 5}, array{11, 2, 35}); // { dg-bogus
"expansion of" }
+constexpr auto m33 = mapping<3>(array{3, 4, 5}, array{11, 35, 2}); // { dg-bogus
"expansion of" }
+constexpr auto m34 = mapping<3>(array{3, 4, 5}, array{2, 11, 35}); // { dg-error "expansion
of" "" { target debug_mode } }
+constexpr auto m35 = mapping<3>(array{3, 4, 5}, array{35, 2, 11}); // { dg-error "expansion
of" "" { target debug_mode } }
+constexpr auto m36 = mapping<3>(array{5, 4, 3}, array{2, 35, 11}); // { dg-bogus
"expansion of" }
+constexpr auto m37 = mapping<3>(array{5, 4, 3}, array{2, 11, 35}); // { dg-error "expansion
of" "" { target debug_mode } }
+constexpr auto m38 = mapping<3>(array{5, 3, 4}, array{35, 11, 2}); // { dg-bogus
"expansion of" }
+constexpr auto m39 = mapping<3>(array{3, 5, 4}, array{35, 2, 11}); // { dg-error "expansion
of" "" { target debug_mode } }
+
+// Unique for stride -> extent mapping: 3 * (5-1) = 12 < 16, 15 * (4-1) + 12 = 57
< 65, 65 * (3-1) + 57 = 187 < 200
+constexpr auto m40 = mapping<4>(array{3, 4, 5, 6}, array{65, 16, 3, 200}); // { dg-bogus
"expansion of" }
+constexpr auto m41 = mapping<4>(array{3, 4, 5, 6}, array{3, 16, 65, 200}); // { dg-error
"expansion of" "" { target debug_mode } }
+constexpr auto m42 = mapping<4>(array{3, 4, 5, 6}, array{200, 65, 3, 16}); // { dg-error
"expansion of" "" { target debug_mode } }
+constexpr auto m43 = mapping<4>(array{5, 3, 6, 4}, array{3, 65, 200, 16}); // { dg-bogus
"expansion of" }
+constexpr auto m44 = mapping<4>(array{5, 3, 6, 4}, array{3, 16, 200, 65}); // { dg-error
"expansion of" "" { target debug_mode } }
+
+// Examples based on one from LWG 4606
+constexpr auto m45 = mapping<2>(array{2, 3}, array{5, 2}); // { dg-bogus "expansion
of" }
+constexpr auto m46 = mapping<3>(array{2, 3, 5}, array{5, 2, 10}); // { dg-bogus
"expansion of" }
+constexpr auto m47 = mapping<3>(array{2, 3, 1}, array{5, 2, 99}); // { dg-bogus
"expansion of" }
+constexpr auto m48 = mapping<4>(array{2, 3, 5, 4}, array{5, 2, 10, 50}); // { dg-bogus
"expansion of" }
+constexpr auto m49 = mapping<4>(array{2, 1, 3, 5}, array{5, 99, 2, 10}); // { dg-bogus
"expansion of" }
+
+// { dg-prune-output "non-constant condition for static assertion" }
+// { dg-prune-output "__glibcxx_assert_fail()" }
diff --git a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc
b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc
index 692caeac812..5a818042b5a 100644
--- a/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/mdspan/layouts/stride_neg.cc
@@ -19,12 +19,11 @@ constexpr bool
test_stride_negative()
{
auto exts = std::extents<std::size_t, dyn, dyn>(1, 3);
- auto m = std::layout_stride::mapping(exts, std::array{1, -4}); // { dg-error
"expansion of" }
+ auto m = std::layout_stride::mapping(exts, std::array{1, -4}); // { dg-error
"expansion of" }
(void) m;
return true;
}
-static_assert(test_stride_negative()); // { dg-error "expansion of" }
-
+static_assert(test_stride_negative()); // { dg-error "expansion of" }
using std::array;
template<size_t Rank>
@@ -34,17 +33,25 @@ constexpr auto m0 = mapping<0>(array<int, 0>{}, array<int,
0>{}); // { dg-bogus
// Zero strides allowed for empty mappings
constexpr auto m00 = mapping<1>(array{0}, array{0}); // { dg-bogus "expansion
of" }
-constexpr auto m01 = mapping<2>(array{0, 1}, array{3, 0}); // { dg-bogus "expansion
of" }
-constexpr auto m02 = mapping<2>(array{0, 1}, array{0, 0}); // { dg-bogus "expansion
of" }
-constexpr auto m03 = mapping<3>(array{0, 1, 2}, array{3, 0, 0}); // { dg-bogus
"expansion of" }
-constexpr auto m04 = mapping<3>(array{0, 1, 2}, array{3, 3, 0}); // { dg-bogus
"expansion of" }
-constexpr auto m05 = mapping<4>(array{0, 1, 2, 3}, array{5, 3, 0, 2}); // { dg-bogus
"expansion of" }
+constexpr auto m01 = mapping<2>(array{0, 2}, array{3, 0}); // { dg-bogus "expansion
of" }
+constexpr auto m02 = mapping<2>(array{0, 2}, array{0, 0}); // { dg-bogus "expansion
of" }
+constexpr auto m03 = mapping<3>(array{0, 2, 3}, array{3, 0, 0}); // { dg-bogus
"expansion of" }
+constexpr auto m04 = mapping<3>(array{0, 2, 3}, array{3, 3, 0}); // { dg-bogus
"expansion of" }
+constexpr auto m05 = mapping<4>(array{0, 2, 3, 4}, array{5, 3, 0, 2}); // { dg-bogus
"expansion of" }
+
+// On dimensions with stride equal to 1
+constexpr auto m0a = mapping<1>(array{1}, array{0}); // { dg-bogus "expansion
of" }
+constexpr auto m0b = mapping<2>(array{2, 1}, array{3, 0}); // { dg-bogus "expansion
of" }
+constexpr auto m0c = mapping<2>(array{1, 1}, array{0, 0}); // { dg-bogus "expansion
of" }
+constexpr auto m0d = mapping<3>(array{2, 1, 1}, array{3, 0, 0}); // { dg-bogus
"expansion of" }
+constexpr auto m0e = mapping<3>(array{2, 2, 1}, array{6, 3, 0}); // { dg-bogus
"expansion of" }
+constexpr auto m0f = mapping<4>(array{2, 2, 1, 2}, array{8, 4, 0, 2}); // { dg-bogus
"expansion of" }
// Otherwise leads to non-unique mappings.
-constexpr auto m06 = mapping<1>(array{1}, array{0}); // { dg-error
"expansion of" }
-constexpr auto m07 = mapping<2>(array{1, 2}, array{3, 0}); // { dg-error
"expansion of" }
-constexpr auto m08 = mapping<3>(array{1, 2, 3}, array{3, 3, 0}); // { dg-error
"expansion of" }
-constexpr auto m09 = mapping<4>(array{1, 2, 3, 5}, array{5, 3, 0, 2}); // { dg-error
"expansion of" }
+constexpr auto m06 = mapping<1>(array{2}, array{0}); // { dg-error "expansion
of" }
+constexpr auto m07 = mapping<2>(array{2, 3}, array{3, 0}); // { dg-error "expansion
of" }
+constexpr auto m08 = mapping<3>(array{2, 3, 4}, array{3, 3, 0}); // { dg-error
"expansion of" }
+constexpr auto m09 = mapping<4>(array{2, 3, 4, 5}, array{5, 3, 0, 2}); // { dg-error
"expansion of" }
// required_span_size is smaller size of multidimensional index space
constexpr auto m10 = mapping<2>(array{3, 4}, array{2, 3}); // { dg-error "expansion
of" }
@@ -61,39 +68,19 @@ constexpr auto m18 = mapping<3>(array{3, 4, 5}, array{1, 5,
12}); // { dg-error
constexpr auto m19 = mapping<4>(array{3, 4, 5, 6}, array{1, 2, 12, 100}); // { dg-error
"expansion of" "" { target debug_mode } }
constexpr auto m20 = mapping<4>(array{3, 4, 5, 6}, array{1, 5, 12, 60}); // { dg-error
"expansion of" "" { target debug_mode } }
-// Equal indicies allowed if extents are 1
-constexpr auto m21 = mapping<2>(array{5, 1}, array{1, 1}); // { dg-bogus "expansion
of" }
-constexpr auto m22 = mapping<3>(array{1, 5, 1}, array{1, 1, 1}); // { dg-bogus
"expansion of" }
-constexpr auto m23 = mapping<4>(array{1, 1, 5, 1}, array{1, 1, 1, 1}); // { dg-bogus
"expansion of" }
+// Any stride values are allowed for extents 1
+constexpr auto m21 = mapping<2>(array{1, 1}, array{88, 99}); // { dg-bogus
"expansion of" }
+constexpr auto m2a = mapping<2>(array{5, 1}, array{88, 99}); // { dg-bogus
"expansion of" }
+constexpr auto m22 = mapping<3>(array{1, 1, 1}, array{88, 99, 00}); // { dg-bogus
"expansion of" }
+constexpr auto m2b = mapping<3>(array{1, 5, 1}, array{88, 99, 77}); // { dg-bogus
"expansion of" }
+constexpr auto m23 = mapping<4>(array{1, 1, 1, 1}, array{77, 99, 00, 88}); // { dg-bogus
"expansion of" }
+constexpr auto m2c = mapping<4>(array{1, 1, 5, 1}, array{77, 99, 1, 88}); // { dg-bogus
"expansion of" }
constexpr auto m24 = mapping<5>(array{3, 4, 1, 1, 5}, array{3, 10, 3, 3, 45}); // {
dg-bogus "expansion of" }
constexpr auto m25 = mapping<5>(array{3, 4, 1, 1, 5}, array{3, 10, 3, 10, 45}); // {
dg-bogus "expansion of" }
-constexpr auto m26 = mapping<5>(array{3, 4, 1, 1, 5}, array{3, 10, 10, 3, 45}); // {
dg-bogus "expansion of" }
+constexpr auto m26 = mapping<5>(array{3, 4, 1, 1, 5}, array{3, 10, 10, 3, 45}); // {
dg-bogus "expansion of" }
constexpr auto m27 = mapping<5>(array{3, 4, 1, 1, 5}, array{3, 10, 10, 10, 45}); // {
dg-bogus "expansion of" }
-
-// Only some permutations are valid, invalid permutations detected only in
debug mode.
-
-// Unique if stride 3 corresponds to extent 3
-constexpr auto m28 = mapping<2>(array{3, 4}, array{3, 10}); // { dg-bogus
"expansion of" }
-constexpr auto m29 = mapping<2>(array{3, 4}, array{10, 3}); // { dg-error "expansion of"
"" { target debug_mode } }
-constexpr auto m30 = mapping<2>(array{4, 3}, array{10, 3}); // { dg-bogus
"expansion of" }
-constexpr auto m31 = mapping<2>(array{4, 3}, array{3, 10}); // { dg-error "expansion of"
"" { target debug_mode } }
-
-// Unique if stride 11 corresponds to extent 3, as 11 * 3 < 35, and 2 * 5 < 11
-constexpr auto m32 = mapping<3>(array{3, 4, 5}, array{11, 2, 35}); // { dg-bogus
"expansion of" }
-constexpr auto m33 = mapping<3>(array{3, 4, 5}, array{11, 35, 2}); // { dg-bogus
"expansion of" }
-constexpr auto m34 = mapping<3>(array{3, 4, 5}, array{2, 11, 35}); // { dg-error "expansion
of" "" { target debug_mode } }
-constexpr auto m35 = mapping<3>(array{3, 4, 5}, array{35, 2, 11}); // { dg-error "expansion
of" "" { target debug_mode } }
-constexpr auto m36 = mapping<3>(array{5, 4, 3}, array{2, 35, 11}); // { dg-bogus
"expansion of" }
-constexpr auto m37 = mapping<3>(array{5, 4, 3}, array{2, 11, 35}); // { dg-error "expansion
of" "" { target debug_mode } }
-constexpr auto m38 = mapping<3>(array{5, 3, 4}, array{35, 11, 2}); // { dg-bogus
"expansion of" }
-constexpr auto m39 = mapping<3>(array{3, 5, 4}, array{35, 2, 11}); // { dg-error "expansion
of" "" { target debug_mode } }
-
-// Unique for stride -> extent mapping: 3 * 5 < 16, 15 * 4 < 65, 65 * 3 < 200
-constexpr auto m40 = mapping<4>(array{3, 4, 5, 6}, array{65, 16, 3, 200}); // { dg-bogus
"expansion of" }
-constexpr auto m41 = mapping<4>(array{3, 4, 5, 6}, array{3, 16, 65, 200}); // { dg-error
"expansion of" "" { target debug_mode } }
-constexpr auto m42 = mapping<4>(array{3, 4, 5, 6}, array{200, 65, 3, 16}); // { dg-error
"expansion of" "" { target debug_mode } }
-constexpr auto m43 = mapping<4>(array{5, 3, 6, 4}, array{3, 65, 200, 16}); // { dg-bogus
"expansion of" }
-constexpr auto m44 = mapping<4>(array{5, 3, 6, 4}, array{3, 16, 200, 65}); // { dg-error
"expansion of" "" { target debug_mode } }
+constexpr auto m2d = mapping<5>(array{3, 4, 1, 1, 5}, array{3, 10, 00, 99, 45}); // {
dg-bogus "expansion of" }
+constexpr auto m2e = mapping<5>(array{1, 1, 1, 1, 1}, array{00, 77, 88, 99, 00}); // {
dg-bogus "expansion of" }
// { dg-prune-output "non-constant condition for static assertion" }
// { dg-prune-output "__glibcxx_assert_fail()" }
--
2.55.0