Observations from implementing layout_left_padded.
Luc Grosheintz
luc.grosheintz@gmail.com
Mon Jun 30 08:33:38 GMT 2025
Dear libstdc++ developers,
while implementing layout_left_padded, I noticed some unexpected
behaviour and I'd like to ask for your input.
1. Odd mandate/prerequisite for padding value.
The standard says the padding_value must be representable as
index_type. This immediately precludes using `padding_value ==
dynamic_extent` for any index_type < size_t [1]. Something
similar happens in the ctors that accepts a padding value at
runtime [2].
Resolution: If padding_value != dynamic_extent, then ...
[1]: https://eel.is/c++draft/mdspan.layout.leftpad#overview-5.2
[2]: https://eel.is/c++draft/mdspan.layout.leftpad#cons-4.1
2. Not commonly-convertible.
Usually, `Layout::mapping<E1>` can be converted to
`Layout::mapping<E2>` if and only if `E1` can be converted to
`E2`. Note that this is for different mappings of the same
Layout.
For layout_left_padded, the situation is different. If the
extents differ, the following ctor [3] will be used:
template<typename _LeftPaddedMapping>
requires (...)
constexpr explicit(_S_rank > 1
&& (padding_value != dynamic_extent
|| _LeftPaddedMapping::padding_value == dynamic_extent))
mapping(const _LeftPaddedMapping& __other)
Which means that, for rank > 1:
static_assert(!is_convertible_v<
layout_left_padded<2>::mapping<E1>,
layout_left_padded<2>::mapping<E2>);
even if E1 and E2 are convertible.
At the same time that ctor allows too many conversions if rank <= 1,
including:
static_assert(!is_convertible_v<
layout_left_padded<2>::mapping<std::extents<int, dyn>>,
layout_left_padded<2>::mapping<std::extents<int, 1>>>);
static_assert(!is_convertible_v<
layout_left_padded<2>::mapping<std::extents<unsigned int, 1>>,
layout_left_padded<2>::mapping<std::extents<int, 1>>>);
This second half, I've included in:
https://cplusplus.github.io/LWG/issue4272
But the issue that they don't convert regularly is unaddressed.
Resolution 1: Allow conversion if:
- __is_layout_left_padded_mapping_of<_LeftPaddedMapping> is
true,
- same_as<layout_type,
typename _LeftPaddedMapping::layout_type> is true.
and keep the current conditions otherwise.
Resolution 2: Leave as is.
[3]: https://eel.is/c++draft/mdspan.layout.leftpad.cons#17
3. Generic Observation: Missing CTADs
There's no deduction guides for mappings, e.g.:
std::layout_left::mapping(std::extents<int, 2>{});
std::layout_left_padded<1>::mapping m(ml); # Ugly error.
Kind regards,
Luc
More information about the Libstdc++
mailing list