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.

4217. Clarify mdspan layout mapping requirements for rank == 0

Section: 23.7.3.4.2 [mdspan.layout.reqmts] Status: New Submitter: Mark Hoemmen Opened: 2025-03-03 Last modified: 2025-03-09

Priority: Not Prioritized

View all issues with New status.

Discussion:

23.7.3.4.2 [mdspan.layout.reqmts] p19-21 says that a layout mapping needs to provide m.stride(r). However, 23.7.3.4.5.3 [mdspan.layout.left.obs] p5 constrains layout_left::mapping<Extents>::stride(r) on Extents::rank() > 0 being true. The same is true of layout_right::mapping (23.7.3.4.6.3 [mdspan.layout.right.obs] p5). (The other Standard mappings in 23.7.3 [views.multidim] and 29.9 [linalg] do not have this constraint.) This suggests that a rank-zero layout_{left,right}::mapping does not conform with the layout mapping requirements.

On the other hand, other parts of 23.7.3.4.2 [mdspan.layout.reqmts] imply that r must be in the range [0, rank()) for the layout mapping's extents type. If such an r does not exist, which is the case for a rank-zero layout mapping, then the m.stride(r) requirement is vacuous. This implies that a rank-zero layout_{left,right}::mapping fully conforms with the layout mapping requirements.

It is definitely the design intent for rank-zero mdspan to work, and for it to represent a view of a single element. Users can create rank-zero mdspan by invoking its constructor, or by using submdspan where all the slice arguments are convertible to index_type. Even though the normative wording permits this, adding a Note would clarify the design intent without making the wording redundant. This was the preferred change per LWG reflector discussion.

Proposed resolution:

This wording is relative to N5001.

  1. Modify 23.7.3.4.2 [mdspan.layout.reqmts] as indicated:

    m.stride(r)
    

    -19- Preconditions: m.is_strided() is true.

    -20- Result: typename M::index_type

    -21- Returns: sr as defined in m.is_strided() above.

    [Note ?: It is not required for m.stride(r) to be well-formed if m.extents().rank() is zero, even if m.is_always_strided() is true. — end note]