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