[libcxx-commits] [libcxx] 488c3db - [libc++][mdspan] Fix uglification, categorize asserts and move tests
Christian Trott via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Jul 25 11:40:14 PDT 2023
Author: Christian Trott
Date: 2023-07-25T12:39:35-06:00
New Revision: 488c3db245ce0fe3b70357d6798ee91c5baa82a2
URL: https://github.com/llvm/llvm-project/commit/488c3db245ce0fe3b70357d6798ee91c5baa82a2
DIFF: https://github.com/llvm/llvm-project/commit/488c3db245ce0fe3b70357d6798ee91c5baa82a2.diff
LOG: [libc++][mdspan] Fix uglification, categorize asserts and move tests
Fixes uglification in mdspan deduction guides, which CI
did not test for until recently. The CI modification
and mdspan testing overlapped, so mdspan landed with green
CI, and the CI modification landed too.
Make most assertions in mdspan and its helper classes
trigger during a hardened build in order to catch
out of bounds access errors.
Also moves all mdspan assertions tests from libcxx/test/std
to libcxx/test/libcxx.
Differential Revision: https://reviews.llvm.org/156181
Added:
libcxx/test/libcxx/containers/views/mdspan/extents/assert.conversion.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.stride.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.stride.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp
Modified:
libcxx/include/__mdspan/extents.h
libcxx/include/__mdspan/layout_left.h
libcxx/include/__mdspan/layout_right.h
libcxx/include/__mdspan/mdspan.h
Removed:
libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp
libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_left/assert.stride.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
libcxx/test/std/containers/views/mdspan/layout_right/assert.stride.pass.cpp
libcxx/test/std/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
libcxx/test/std/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
libcxx/test/std/containers/views/mdspan/mdspan/assert.size.pass.cpp
################################################################################
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index 969204f6b55046..a510220d4096a2 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -171,11 +171,14 @@ struct __maybe_static_array {
_TStatic __static_val = _StaticValues::__get(__i);
if (__static_val == _DynTag) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = __values[__i];
- }
- // Precondition check
- else
- _LIBCPP_ASSERT_UNCATEGORIZED(__values[__i] == static_cast<_TDynamic>(__static_val),
- "extents construction: mismatch of provided arguments with static extents.");
+ } else
+ // Not catching this could lead to out of bounds errors later
+ // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[5], 5);
+ // Right-hand-side construction looks ok with allocation and size matching,
+ // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not 5
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __values[__i] == static_cast<_TDynamic>(__static_val),
+ "extents construction: mismatch of provided arguments with static extents.");
}
}
@@ -187,11 +190,14 @@ struct __maybe_static_array {
_TStatic __static_val = _StaticValues::__get(__i);
if (__static_val == _DynTag) {
__dyn_vals_[_DynamicIdxMap::__get(__i)] = static_cast<_TDynamic>(__vals[__i]);
- }
- // Precondition check
- else
- _LIBCPP_ASSERT_UNCATEGORIZED(static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
- "extents construction: mismatch of provided arguments with static extents.");
+ } else
+ // Not catching this could lead to out of bounds errors later
+ // e.g. using my_mdspan_t = mdspan<int, extents<int, 10>>; my_mdspan_t = m(new int[N], span<int,1>(&N));
+ // Right-hand-side construction looks ok with allocation and size matching,
+ // but since (potentially elsewhere defined) my_mdspan_t has static size m now thinks its range is 10 not N
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ static_cast<_TDynamic>(__vals[__i]) == static_cast<_TDynamic>(__static_val),
+ "extents construction: mismatch of provided arguments with static extents.");
}
}
@@ -310,8 +316,10 @@ class extents {
(sizeof...(_OtherIndexTypes) == __rank_ || sizeof...(_OtherIndexTypes) == __rank_dynamic_))
_LIBCPP_HIDE_FROM_ABI constexpr explicit extents(_OtherIndexTypes... __dynvals) noexcept
: __vals_(static_cast<index_type>(__dynvals)...) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan m(ptr, dextents<char, 1>(200u)); leads to an extent of -56 on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__dynvals...),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
template <class _OtherIndexType, size_t _Size>
@@ -321,8 +329,10 @@ class extents {
explicit(_Size != __rank_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr extents(const array<_OtherIndexType, _Size>& __exts) noexcept
: __vals_(span(__exts)) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan m(ptr, dextents<char, 1>(array<unsigned,1>(200))); leads to an extent of -56 on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(span(__exts)),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
template <class _OtherIndexType, size_t _Size>
@@ -332,8 +342,11 @@ class extents {
explicit(_Size != __rank_dynamic_)
_LIBCPP_HIDE_FROM_ABI constexpr extents(const span<_OtherIndexType, _Size>& __exts) noexcept
: __vals_(__exts) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__are_representable_as<index_type>(__exts),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. array a{200u}; mdspan<int, dextents<char,1>> m(ptr, extents(span<unsigned,1>(a))); leads to an extent of -56
+ // on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__are_representable_as<index_type>(__exts),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
private:
@@ -382,10 +395,16 @@ class extents {
for (size_t __r = 0; __r < rank(); __r++) {
if constexpr (static_cast<make_unsigned_t<index_type>>(numeric_limits<index_type>::max()) <
static_cast<make_unsigned_t<_OtherIndexType>>(numeric_limits<_OtherIndexType>::max())) {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
- "extents ctor: arguments must be representable as index_type and nonnegative");
+ // Not catching this could lead to out of bounds errors later
+ // e.g. dextents<char,1>> e(dextents<unsigned,1>(200)) leads to an extent of -56 on e
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __mdspan_detail::__is_representable_as<index_type>(__other.extent(__r)),
+ "extents ctor: arguments must be representable as index_type and nonnegative");
}
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan<int, extents<int, 10>> m = mdspan<int, dextents<int, 1>>(new int[5], 5);
+ // Right-hand-side construction was ok, but m now thinks its range is 10 not 5
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
(_Values::__static_value(__r) == dynamic_extent) ||
(static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(_Values::__static_value(__r))),
"extents construction: mismatch of provided arguments with static extents.");
diff --git a/libcxx/include/__mdspan/layout_left.h b/libcxx/include/__mdspan/layout_left.h
index d2930904834af8..f890c5ae025612 100644
--- a/libcxx/include/__mdspan/layout_left.h
+++ b/libcxx/include/__mdspan/layout_left.h
@@ -75,7 +75,9 @@ class layout_left::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept = default;
_LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
_LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // not catching this could lead to out-of-bounds access later when used inside mdspan
+ // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(10, 3) == -126
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__required_span_size_is_representable(__ext),
"layout_left::mapping extents ctor: product of extents must be representable as index_type.");
}
@@ -85,7 +87,9 @@ class layout_left::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
mapping(const mapping<_OtherExtents>& __other) noexcept
: __extents_(__other.extents()) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // not catching this could lead to out-of-bounds access later when used inside mdspan
+ // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(10, 3) == -126
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
"layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
@@ -95,7 +99,13 @@ class layout_left::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
mapping(const layout_right::mapping<_OtherExtents>& __other) noexcept
: __extents_(__other.extents()) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // not catching this could lead to out-of-bounds access later when used inside mdspan
+ // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first
+ // and thus this assertion should never be triggered, but keeping it here for consistency
+ // layout_left::mapping<dextents<char, 1>> map(
+ // layout_right::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) ==
+ // -56
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
"layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
@@ -123,8 +133,12 @@ class layout_left::mapping {
requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
(is_nothrow_constructible_v<index_type, _Indices> && ...))
_LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
- "layout_left::mapping: out of bounds indexing");
+ // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never
+ // return a value exceeding required_span_size(), which is used to know how large an allocation one needs
+ // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks
+ // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
+ _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
+ "layout_left::mapping: out of bounds indexing");
array<index_type, extents_type::rank()> __idx_a{static_cast<index_type>(__idx)...};
return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
index_type __res = 0;
@@ -145,7 +159,10 @@ class layout_left::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
requires(extents_type::rank() > 0)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__r < extents_type::rank(), "layout_left::mapping::stride(): invalid rank index");
+ // While it would be caught by extents itself too, using a too large __r
+ // is functionally an out of bounds access on the stored information needed to compute strides
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __r < extents_type::rank(), "layout_left::mapping::stride(): invalid rank index");
index_type __s = 1;
for (rank_type __i = extents_type::rank() - 1; __i > __r; __i--)
__s *= __extents_.extent(__i);
diff --git a/libcxx/include/__mdspan/layout_right.h b/libcxx/include/__mdspan/layout_right.h
index 6d144294789cb5..3d814554a1bed4 100644
--- a/libcxx/include/__mdspan/layout_right.h
+++ b/libcxx/include/__mdspan/layout_right.h
@@ -74,7 +74,9 @@ class layout_right::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr mapping() noexcept = default;
_LIBCPP_HIDE_FROM_ABI constexpr mapping(const mapping&) noexcept = default;
_LIBCPP_HIDE_FROM_ABI constexpr mapping(const extents_type& __ext) noexcept : __extents_(__ext) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // not catching this could lead to out-of-bounds access later when used inside mdspan
+ // mapping<dextents<char, 2>> map(dextents<char, 2>(40,40)); map(3, 10) == -126
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__required_span_size_is_representable(__ext),
"layout_right::mapping extents ctor: product of extents must be representable as index_type.");
}
@@ -84,7 +86,9 @@ class layout_right::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
mapping(const mapping<_OtherExtents>& __other) noexcept
: __extents_(__other.extents()) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // not catching this could lead to out-of-bounds access later when used inside mdspan
+ // mapping<dextents<char, 2>> map(mapping<dextents<int, 2>>(dextents<int, 2>(40,40))); map(3, 10) == -126
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
"layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
@@ -94,7 +98,13 @@ class layout_right::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr explicit(!is_convertible_v<_OtherExtents, extents_type>)
mapping(const layout_left::mapping<_OtherExtents>& __other) noexcept
: __extents_(__other.extents()) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // not catching this could lead to out-of-bounds access later when used inside mdspan
+ // Note: since this is constraint to rank 1, extents itself would catch the invalid conversion first
+ // and thus this assertion should never be triggered, but keeping it here for consistency
+ // layout_right::mapping<dextents<char, 1>> map(
+ // layout_left::mapping<dextents<unsigned, 1>>(dextents<unsigned, 1>(200))); map.extents().extent(0) ==
+ // -56
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
__mdspan_detail::__is_representable_as<index_type>(__other.required_span_size()),
"layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
}
@@ -122,8 +132,12 @@ class layout_right::mapping {
requires((sizeof...(_Indices) == extents_type::rank()) && (is_convertible_v<_Indices, index_type> && ...) &&
(is_nothrow_constructible_v<index_type, _Indices> && ...))
_LIBCPP_HIDE_FROM_ABI constexpr index_type operator()(_Indices... __idx) const noexcept {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
- "layout_right::mapping: out of bounds indexing");
+ // Mappings are generally meant to be used for accessing allocations and are meant to guarantee to never
+ // return a value exceeding required_span_size(), which is used to know how large an allocation one needs
+ // Thus, this is a canonical point in multi-dimensional data structures to make invalid element access checks
+ // However, mdspan does check this on its own, so for now we avoid double checking in hardened mode
+ _LIBCPP_ASSERT(__mdspan_detail::__is_multidimensional_index_in(__extents_, __idx...),
+ "layout_right::mapping: out of bounds indexing");
return [&]<size_t... _Pos>(index_sequence<_Pos...>) {
index_type __res = 0;
((__res = static_cast<index_type>(__idx) + __extents_.extent(_Pos) * __res), ...);
@@ -142,7 +156,10 @@ class layout_right::mapping {
_LIBCPP_HIDE_FROM_ABI constexpr index_type stride(rank_type __r) const noexcept
requires(extents_type::rank() > 0)
{
- _LIBCPP_ASSERT_UNCATEGORIZED(__r < extents_type::rank(), "layout_right::mapping::stride(): invalid rank index");
+ // While it would be caught by extents itself too, using a too large __r
+ // is functionally an out of bounds access on the stored information needed to compute strides
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
+ __r < extents_type::rank(), "layout_right::mapping::stride(): invalid rank index");
index_type __s = 1;
for (rank_type __i = extents_type::rank() - 1; __i > __r; __i--)
__s *= __extents_.extent(__i);
diff --git a/libcxx/include/__mdspan/mdspan.h b/libcxx/include/__mdspan/mdspan.h
index 47351f113cfa8b..58f3b9cf1b18a4 100644
--- a/libcxx/include/__mdspan/mdspan.h
+++ b/libcxx/include/__mdspan/mdspan.h
@@ -166,7 +166,10 @@ class mdspan {
// always construct its extents() only from the dynamic extents, instead of from the other extents.
if constexpr (rank() > 0) {
for (size_t __r = 0; __r < rank(); __r++) {
- _LIBCPP_ASSERT_UNCATEGORIZED(
+ // Not catching this could lead to out of bounds errors later
+ // e.g. mdspan<int, dextents<char,1>, non_checking_layout> m =
+ // mdspan<int, dextents<unsigned, 1>, non_checking_layout>(ptr, 200); leads to an extent of -56 on m
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
(static_extent(__r) == dynamic_extent) ||
(static_cast<index_type>(__other.extent(__r)) == static_cast<index_type>(static_extent(__r))),
"mdspan: conversion mismatch of source dynamic extents with static extents");
@@ -185,8 +188,10 @@ class mdspan {
(is_nothrow_constructible_v<index_type, _OtherIndexTypes> && ...) &&
(sizeof...(_OtherIndexTypes) == rank()))
_LIBCPP_HIDE_FROM_ABI constexpr reference operator[](_OtherIndexTypes... __indices) const {
- _LIBCPP_ASSERT_UNCATEGORIZED(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...),
- "mdspan: operator[] out of bounds access");
+ // Note the standard layouts would also check this, but user provided ones may not, so we
+ // check the precondition here
+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__mdspan_detail::__is_multidimensional_index_in(extents(), __indices...),
+ "mdspan: operator[] out of bounds access");
return __acc_.access(__ptr_, __map_(static_cast<index_type>(std::move(__indices))...));
}
@@ -209,6 +214,8 @@ class mdspan {
}
_LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept {
+ // Could leave this as only checked in debug mode: semantically size() is never
+ // guaranteed to be related to any accessible range
_LIBCPP_ASSERT_UNCATEGORIZED(
false == ([&]<size_t... _Idxs>(index_sequence<_Idxs...>) {
size_type __prod = 1;
@@ -260,13 +267,13 @@ template <class _ElementType, class... _OtherIndexTypes>
explicit mdspan(_ElementType*, _OtherIndexTypes...)
-> mdspan<_ElementType, dextents<size_t, sizeof...(_OtherIndexTypes)>>;
-template <class Pointer>
- requires(is_pointer_v<remove_reference_t<Pointer>>)
-mdspan(Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
+template <class _Pointer>
+ requires(is_pointer_v<remove_reference_t<_Pointer>>)
+mdspan(_Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<_Pointer>>, extents<size_t>>;
-template <class CArray>
- requires(is_array_v<CArray> && (rank_v<CArray> == 1))
-mdspan(CArray&) -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
+template <class _CArray>
+ requires(is_array_v<_CArray> && (rank_v<_CArray> == 1))
+mdspan(_CArray&) -> mdspan<remove_all_extents_t<_CArray>, extents<size_t, extent_v<_CArray, 0>>>;
template <class _ElementType, class _OtherIndexType, size_t _Size>
mdspan(_ElementType*, const array<_OtherIndexType, _Size>&) -> mdspan<_ElementType, dextents<size_t, _Size>>;
@@ -281,16 +288,16 @@ template <class _ElementType, class _OtherIndexType, size_t... _ExtentsPack>
mdspan(_ElementType*, const extents<_OtherIndexType, _ExtentsPack...>&)
-> mdspan<_ElementType, extents<_OtherIndexType, _ExtentsPack...>>;
-template <class _ElementType, class MappingType>
-mdspan(_ElementType*, const MappingType&)
- -> mdspan<_ElementType, typename MappingType::extents_type, typename MappingType::layout_type>;
+template <class _ElementType, class _MappingType>
+mdspan(_ElementType*, const _MappingType&)
+ -> mdspan<_ElementType, typename _MappingType::extents_type, typename _MappingType::layout_type>;
-template <class MappingType, class AccessorType>
-mdspan(const typename AccessorType::data_handle_type, const MappingType&, const AccessorType&)
- -> mdspan<typename AccessorType::element_type,
- typename MappingType::extents_type,
- typename MappingType::layout_type,
- AccessorType>;
+template <class _MappingType, class _AccessorType>
+mdspan(const typename _AccessorType::data_handle_type, const _MappingType&, const _AccessorType&)
+ -> mdspan<typename _AccessorType::element_type,
+ typename _MappingType::extents_type,
+ typename _MappingType::layout_type,
+ _AccessorType>;
#endif // _LIBCPP_STD_VER >= 23
diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.conversion.pass.cpp
similarity index 96%
rename from libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/extents/assert.conversion.pass.cpp
index dd012c43d907b2..3496f69d5dc89b 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.conversion.pass.cpp
@@ -6,7 +6,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
similarity index 96%
rename from libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
index 12251614ab3a9a..bef448aa609ed6 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp
@@ -6,7 +6,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
similarity index 96%
rename from libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
index a57f7aa249e743..17c29707a51378 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp
@@ -6,7 +6,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
similarity index 96%
rename from libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
index b47b8603b607f3..785720bf9b8900 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp
@@ -6,7 +6,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// Test construction from span:
diff --git a/libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
similarity index 97%
rename from libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
index 078d41358d8661..e20146f9ea5181 100644
--- a/libcxx/test/std/containers/views/mdspan/extents/assert.obs.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/extents/assert.obs.pass.cpp
@@ -6,7 +6,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_left/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
similarity index 97%
rename from libcxx/test/std/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
index ae2c59c9cf4879..d4aea962f19a0b 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
similarity index 95%
rename from libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
index 34b91c38185d30..4a122e09040849 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
similarity index 96%
rename from libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
index 791518063fa6ab..3750d71bd6dcc9 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
similarity index 100%
rename from libcxx/test/std/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.index_operator.pass.cpp
diff --git a/libcxx/test/std/containers/views/mdspan/layout_left/assert.stride.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.stride.pass.cpp
similarity index 94%
rename from libcxx/test/std/containers/views/mdspan/layout_left/assert.stride.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.stride.pass.cpp
index 822104a9f341c6..6fe792d5170fd4 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_left/assert.stride.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.stride.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_right/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
similarity index 97%
rename from libcxx/test/std/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
index 68fbba020ccfca..d44598b6282df5 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
similarity index 95%
rename from libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
index 0e523de847a7cc..a460a3a27b943a 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
similarity index 96%
rename from libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
index 6b5ea032b412d3..5f437e22b208a8 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
similarity index 100%
rename from libcxx/test/std/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.index_operator.pass.cpp
diff --git a/libcxx/test/std/containers/views/mdspan/layout_right/assert.stride.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.stride.pass.cpp
similarity index 94%
rename from libcxx/test/std/containers/views/mdspan/layout_right/assert.stride.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.stride.pass.cpp
index 7ba3f4e34c53bf..01b2891d93d770 100644
--- a/libcxx/test/std/containers/views/mdspan/layout_right/assert.stride.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.stride.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/assert.conversion.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
similarity index 94%
rename from libcxx/test/std/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
index a8ea360a9f59ae..d62c91ddc8b1c6 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.conversion.pass.cpp
@@ -6,7 +6,7 @@
//===----------------------------------------------------------------------===//
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
@@ -42,7 +42,7 @@
#include <mdspan>
#include "check_assertion.h"
-#include "CustomTestLayouts.h"
+#include "../../../../../std/containers/views/mdspan/mdspan/CustomTestLayouts.h"
// We use a funky mapping in this test that doesn't check the dynamic/static extents mismatch itself
int main(int, char**) {
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
similarity index 98%
rename from libcxx/test/std/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
index 11d013e18e93b8..073b7f3ed80924 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.index_operator.pass.cpp
@@ -8,7 +8,7 @@
// REQUIRES: has-unix-headers
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-// UNSUPPORTED: !libcpp-has-debug-mode
+// UNSUPPORTED: !libcpp-has-hardened-mode && !libcpp-has-debug-mode
// XFAIL: availability-verbose_abort-missing
// <mdspan>
diff --git a/libcxx/test/std/containers/views/mdspan/mdspan/assert.size.pass.cpp b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp
similarity index 95%
rename from libcxx/test/std/containers/views/mdspan/mdspan/assert.size.pass.cpp
rename to libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp
index 0266ec11c21f5f..a43ae5cefe9863 100644
--- a/libcxx/test/std/containers/views/mdspan/mdspan/assert.size.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp
@@ -22,7 +22,7 @@
#include <mdspan>
#include "check_assertion.h"
-#include "CustomTestLayouts.h"
+#include "../../../../../std/containers/views/mdspan/mdspan/CustomTestLayouts.h"
// We use a funky mapping in this test where required_span_size is much smaller than the size of the index space
int main(int, char**) {
More information about the libcxx-commits
mailing list