diff --git a/stl/inc/mdspan b/stl/inc/mdspan index b9df1952c8..bcca7f9056 100644 --- a/stl/inc/mdspan +++ b/stl/inc/mdspan @@ -456,7 +456,7 @@ struct _Maybe_fully_static_extents<_Extents> { template constexpr explicit _Maybe_fully_static_extents([[maybe_unused]] const _OtherExtents& _Exts_) { #if _CONTAINER_DEBUG_LEVEL > 0 - (void) _Extents{_Exts_}; // NB: temporary created for preconditions check + (void) _Extents(_Exts_); // NB: temporary created for preconditions check #endif // _CONTAINER_DEBUG_LEVEL > 0 } }; @@ -471,7 +471,7 @@ public: using layout_type = layout_left; private: - using _Base = _Maybe_fully_static_extents; + using _Base = _Maybe_fully_static_extents<_Extents>; static_assert(_Is_extents, "Extents must be a specialization of std::extents (N4950 [mdspan.layout.left.overview]/2)."); @@ -623,7 +623,7 @@ public: using layout_type = layout_right; private: - using _Base = _Maybe_fully_static_extents; + using _Base = _Maybe_fully_static_extents<_Extents>; static_assert(_Is_extents, "Extents must be a specialization of std::extents (N4950 [mdspan.layout.right.overview]/2)."); @@ -777,8 +777,7 @@ concept _Layout_mapping_alike = requires { }; template -class layout_stride::mapping : private _Maybe_fully_static_extents<_Extents>, - private _Maybe_empty_array { +class layout_stride::mapping { public: using extents_type = _Extents; using index_type = extents_type::index_type; @@ -786,10 +785,6 @@ public: using rank_type = extents_type::rank_type; using layout_type = layout_stride; -private: - using _Extents_base = _Maybe_fully_static_extents; - using _Strides_base = _Maybe_empty_array; - static_assert(_Is_extents, "Extents must be a specialization of std::extents (N4950 [mdspan.layout.stride.overview]/2)."); static_assert( @@ -797,14 +792,12 @@ private: "If Extents::rank_dynamic() == 0 is true, then the size of the multidimensional index space Extents() must be " "representable as a value of type typename Extents::index_type (N4950 [mdspan.layout.stride.overview]/4)."); -public: - constexpr mapping() noexcept : _Extents_base(extents_type{}) { + constexpr mapping() noexcept : _Exts(extents_type{}) { if constexpr (extents_type::rank() != 0) { - this->_Array.back() = 1; + _Strides.back() = 1; for (rank_type _Idx = extents_type::_Rank - 1; _Idx-- > 0;) { #if _CONTAINER_DEBUG_LEVEL > 0 - const bool _Overflow = - _Mul_overflow(this->_Array[_Idx + 1], this->_Exts.extent(_Idx + 1), this->_Array[_Idx]); + const bool _Overflow = _Mul_overflow(_Strides[_Idx + 1], _Exts.extent(_Idx + 1), _Strides[_Idx]); // NB: N4950 requires value of 'layout_right::mapping().required_span_size()' to be // representable as value of type 'index_type', but this is not enough. We need to require every single // stride to be representable as value of type 'index_type', so we can get desired effects. @@ -812,7 +805,7 @@ public: "Value of layout_right::mapping().required_span_size() must be " "representable as a value of type index_type (N4950 [mdspan.layout.stride.cons]/1)."); #else // ^^^ _CONTAINER_DEBUG_LEVEL > 0 / _CONTAINER_DEBUG_LEVEL == 0 vvv - this->_Array[_Idx] = static_cast(this->_Array[_Idx + 1] * this->_Exts.extent(_Idx + 1)); + _Strides[_Idx] = static_cast(_Strides[_Idx + 1] * _Exts.extent(_Idx + 1)); #endif // _CONTAINER_DEBUG_LEVEL > 0 } } @@ -825,17 +818,17 @@ public: && is_nothrow_constructible_v constexpr mapping(const extents_type& _Exts_, span<_OtherIndexType, extents_type::rank()> _Strides_, index_sequence<_Indices...>) noexcept - : _Extents_base(_Exts_), _Strides_base{static_cast(_STD as_const(_Strides_[_Indices]))...} { + : _Exts(_Exts_), _Strides{static_cast(_STD as_const(_Strides_[_Indices]))...} { #if _CONTAINER_DEBUG_LEVEL > 0 if constexpr (extents_type::rank() != 0) { bool _Found_zero = false; bool _Overflow = false; index_type _Req_span_size = 0; for (rank_type _Idx = 0; _Idx < extents_type::_Rank; ++_Idx) { - const index_type _Stride = this->_Array[_Idx]; + const index_type _Stride = _Strides[_Idx]; _STL_VERIFY(_Stride > 0, "Value of s[i] must be greater than 0 for all i in the range [0, rank_) " "(N4950 [mdspan.layout.stride.cons]/4.1)."); - const index_type _Ext = this->_Exts.extent(_Idx); + const index_type _Ext = _Exts.extent(_Idx); if (_Ext == 0) { _Found_zero = true; } @@ -888,7 +881,7 @@ public: && (_Is_mapping_of || _Is_mapping_of || _Is_mapping_of) )) mapping(const _StridedLayoutMapping& _Other) noexcept - : _Extents_base(_Other.extents()) { + : _Exts(_Other.extents()) { #if _CONTAINER_DEBUG_LEVEL > 0 _STL_VERIFY(_STD in_range(_Other.required_span_size()), "Value of other.required_span_size() must be representable as a value of type index_type (N4950 " @@ -902,18 +895,18 @@ public: _STL_VERIFY(_Stride > 0, "Value of other.stride(r) must be greater than 0 for every rank index r of " "extents() (N4950 [mdspan.layout.stride.cons]/7.2)."); #endif // _CONTAINER_DEBUG_LEVEL > 0 - this->_Array[_Idx] = static_cast(_Stride); + _Strides[_Idx] = static_cast(_Stride); } } constexpr mapping& operator=(const mapping&) noexcept = default; _NODISCARD constexpr const extents_type& extents() const noexcept { - return this->_Exts; + return _Exts; } _NODISCARD constexpr array strides() const noexcept { - return this->_Array; + return _Strides; } _NODISCARD constexpr index_type required_span_size() const noexcept { @@ -922,12 +915,12 @@ public: } else { index_type _Result = 1; for (rank_type _Idx = 0; _Idx < extents_type::_Rank; ++_Idx) { - const index_type _Ext = this->_Exts.extent(_Idx); + const index_type _Ext = _Exts.extent(_Idx); if (_Ext == 0) { return 0; } - _Result += (_Ext - 1) * this->_Array[_Idx]; + _Result += (_Ext - 1) * _Strides[_Idx]; } return _Result; @@ -961,8 +954,7 @@ public: if constexpr (extents_type::rank() == 0) { return true; } else { - return required_span_size() - == _Fwd_prod_of_extents::_Calculate(this->_Exts, extents_type::_Rank); + return required_span_size() == _Fwd_prod_of_extents::_Calculate(_Exts, extents_type::_Rank); } } @@ -971,7 +963,7 @@ public: } _NODISCARD constexpr index_type stride(const rank_type _Idx) const noexcept { - return this->_Array[_Idx]; + return _Strides[_Idx]; } template @@ -994,6 +986,9 @@ public: } private: + extents_type _Exts{}; + array _Strides{}; + template _NODISCARD static constexpr _OtherMapping::index_type _Offset(_OtherMapping& _Mapping) noexcept { if constexpr (extents_type::rank() == 0) { @@ -1015,12 +1010,12 @@ private: [[maybe_unused]] index_sequence<_Seq...> _Index_seq, _IndexTypes... _Indices) const noexcept { _STL_INTERNAL_STATIC_ASSERT((same_as<_IndexTypes, index_type> && ...)); #if _CONTAINER_DEBUG_LEVEL > 0 - _STL_VERIFY(this->_Exts._Contains_multidimensional_index(_Index_seq, _Indices...), + _STL_VERIFY(_Exts._Contains_multidimensional_index(_Index_seq, _Indices...), "Value of extents_type::index-cast(i) must be a multidimensional index in extents_ (N4950 " "[mdspan.layout.stride.obs]/3)."); #endif // _CONTAINER_DEBUG_LEVEL > 0 - return static_cast(((_Indices * this->_Array[_Seq]) + ... + 0)); + return static_cast(((_Indices * _Strides[_Seq]) + ... + 0)); } }; diff --git a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp index 13f6ea3032..ab20ad5c87 100644 --- a/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp +++ b/tests/std/tests/P0009R18_mdspan_layout_stride/test.cpp @@ -821,12 +821,6 @@ constexpr void check_correctness() { } } -// When 'M::extents_type::rank()' is equal to 0 then 'is_empty_v' should be true (MSVC STL specific behavior) -static_assert(!is_empty_v>>); -static_assert(!is_empty_v>>); -static_assert(!is_empty_v>>); -static_assert(is_empty_v>>); - constexpr bool test() { // Check signed integers check_members(extents{5}, array{1});