This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
rank == 0
, layout_stride
is atypically convertibleSection: 23.7.3.4 [mdspan.layout] Status: New Submitter: Luc Grosheintz Opened: 2025-06-02 Last modified: 2025-06-12
Priority: 2
View all other issues in [mdspan.layout].
View all issues with New status.
Discussion:
Commonly, two layouts are considered convertible, if the underlying
extent_types
are convertible.
layout_left(layout_stride)
and
layout_right(layout_stride)
, the condition is rank > 0
. Therefore,
using E1 = std::extents<int>; using E2 = std::extents<unsigned int>; static_assert(std::is_convertible_v< std::layout_stride::mapping<E2>, std::layout_right::mapping<E1> >);
even though:
static_assert(!std::is_convertible_v<E2, E1>);
Moreover, for rank 0 layout_stride
can be converted to any
specialization of layout_left
or layout_right
; but not to every
specialization of layout_stride
.
[2025-06-12; Reflector poll]
Set priority to 2 after reflector poll.
Proposed resolution:
This wording is relative to N5008.
[Drafting note: As drive-by fixes the edits for
layout_left_padded<>::mapping
andlayout_right_padded<>::mapping
also correct an editorial asymmetry between class header synopsis declaration form and prototype specification form of the corresponding constructors and adjust to the correct spelling of the exposition-only data memberrank_
.]
Modify 23.7.3.4.5.1 [mdspan.layout.left.overview] as indicated:
namespace std { template<class Extents> class layout_left::mapping { […] // 23.7.3.4.5.2 [mdspan.layout.left.cons], constructors […] template<class OtherExtents> constexpr explicit(extents_type::rank() > 0see below) mapping(const layout_stride::mapping<OtherExtents>&); constexpr mapping& operator=(const mapping&) noexcept = default; […] }; }
Modify 23.7.3.4.5.2 [mdspan.layout.left.cons] as indicated:
template<class OtherExtents> constexpr explicit(extents_type::rank() > 0see below) mapping(const layout_stride::mapping<OtherExtents>& other);-13- Constraints: […]
-14- Preconditions: […] -15- Effects: […] -?- Remarks: The expression insideexplicit
is equivalent to:!(extents_type::rank() == 0 && is_convertible_v<OtherExtents, extents_type>)
Modify 23.7.3.4.6.1 [mdspan.layout.right.overview] as indicated:
namespace std { template<class Extents> class layout_right::mapping { […] // 23.7.3.4.6.2 [mdspan.layout.right.cons], constructors […] template<class OtherExtents> constexpr explicit(extents_type::rank() > 0see below) mapping(const layout_stride::mapping<OtherExtents>&); constexpr mapping& operator=(const mapping&) noexcept = default; […] }; }
Modify 23.7.3.4.6.2 [mdspan.layout.right.cons] as indicated:
template<class OtherExtents> constexpr explicit(extents_type::rank() > 0see below) mapping(const layout_stride::mapping<OtherExtents>& other);-13- Constraints: […]
-14- Preconditions: […] -15- Effects: […] -?- Remarks: The expression insideexplicit
is equivalent to:!(extents_type::rank() == 0 && is_convertible_v<OtherExtents, extents_type>)
Modify 23.7.3.4.8.1 [mdspan.layout.leftpad.overview] as indicated:
namespace std { template<size_t PaddingValue> template<class Extents> class layout_left_padded<PaddingValue>::mapping { […] // 23.7.3.4.8.3 [mdspan.layout.leftpad.cons], constructors […] template<class OtherExtents> constexpr explicit(extents_type::rank() > 0see below) mapping(const layout_stride::mapping<OtherExtents>&); […] }; }
Modify 23.7.3.4.8.3 [mdspan.layout.leftpad.cons] as indicated:
template<class OtherExtents> constexpr explicit(rank_ > 0see below) mapping(const layout_stride::mapping<OtherExtents>& other);-10- Constraints: […]
-11- Preconditions: […] -12- Effects: […] -?- Remarks: The expression insideexplicit
is equivalent to:!(rank_ == 0 && is_convertible_v<OtherExtents, extents_type>)
Modify 23.7.3.4.9.1 [mdspan.layout.rightpad.overview] as indicated:
namespace std { template<size_t PaddingValue> template<class Extents> class layout_right_padded<PaddingValue>::mapping { […] // 23.7.3.4.9.3 [mdspan.layout.rightpad.cons], constructors […] template<class OtherExtents> constexpr explicit(rank_ > 0see below) mapping(const layout_stride::mapping<OtherExtents>&); […] }; }
Modify 23.7.3.4.9.3 [mdspan.layout.rightpad.cons] as indicated:
template<class OtherExtents> constexpr explicit(rank_ > 0see below) mapping(const layout_stride::mapping<OtherExtents>& other);-10- Constraints: […]
-11- Preconditions: […] -12- Effects: […] -?- Remarks: The expression insideexplicit
is equivalent to:!(rank_ == 0 && is_convertible_v<OtherExtents, extents_type>)