Created on 2026-03-18.00:00:00 last changed 1 week ago
Proposed resolution:
This wording is relative to N5032.
Modify [mdspan.layout.leftpad.cons] as indicated:
template<class OtherExtents> constexpr explicit(see below) mapping(const layout_stride::mapping<OtherExtents>& other);-10- Constraints: […]
-11- Preconditions:
(11.1) — […]
(11.2) — […]
(11.3) — […]
(11.4) — `other.required_span_size()` is representable as a value of type index_type.
(11.5) — If rank_ is greater than `1` and static-padding-stride equals `dynamic_extent`, `other.stride(1)` is representable as a value of type index_type.
-12- Effects: […]
-13- Remarks: […]template<class LayoutLeftPaddedMapping> constexpr explicit(see below) mapping(const LayoutLeftPaddedMapping& other);-14- Constraints: […]
-15- Mandates: […] -16- Preconditions:
(16.1) — […]
(16.2) — `other.required_span_size()` is representable as a value of type index_type.
(16.3) — If rank_ is greater than `1` and static-padding-stride equals `dynamic_extent`, `other.stride(1)` is representable as a value of type index_type.
-17- Effects: […]
-18- Remarks: […]
Modify [mdspan.layout.rightpad.cons] as indicated:
template<class OtherExtents> constexpr explicit(see below) mapping(const layout_stride::mapping<OtherExtents>& other);-10- Constraints: […]
-11- Preconditions:
(11.1) — […]
(11.2) — […]
(11.3) — […]
(11.4) — `other.required_span_size()` is representable as a value of type index_type.
(11.5) — If rank_ is greater than `1` and static-padding-stride equals `dynamic_extent`, other.stride(rank_ - 2) is representable as a value of type index_type.
-12- Effects: […]
-13- Remarks: […]template<class LayoutRightPaddedMapping> constexpr explicit(see below) mapping(const LayoutRightPaddedMapping& other);-14- Constraints: […]
-15- Mandates: […] -16- Preconditions:
(16.1) — […]
(16.2) — `other.required_span_size()` is representable as a value of type index_type.
(16.3) — If rank_ is greater than `1` and static-padding-stride equals `dynamic_extent`, other.stride(rank_ - 2) is representable as a value of type index_type.
-17- Effects: […]
-18- Remarks: […]
It appears that these constructors are missing a precondition requiring the incoming padded stride to be representable as a value of the destination `index_type`.
The existing preconditions check that `other.required_span_size()` is representable as a value of type `index_type`, but that is not sufficient when the source mapping is empty. In that case, `other.required_span_size()` can be `0` even though the source padded stride is too large for the destination `index_type`. The padded stride is then silently truncated, and that truncation is observable through `stride()`. Example:
#include <mdspan>
#include <cstdint>
#include <cassert>
void test() {
using Src = std::layout_left_padded<std::dynamic_extent>::mapping<std::extents<uint32_t, 1, 0>>;
using Dst = std::layout_left_padded<std::dynamic_extent>::mapping<std::extents<uint8_t, 1, 0>>;
// src.stride(1) == 256.
Src src(std::extents<uint32_t, 1, 0>(), 256);
// other.required_span_size() is 0, so the existing preconditions are met.
// The stored padded stride is then converted to uint8_t and truncated to 0.
Dst dst(src);
assert(dst.stride(1) == 0);
}
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2026-03-21 13:39:04 | admin | set | messages: + msg16032 |
| 2026-03-18 00:00:00 | admin | create | |