4020. extents::index-cast weirdness

Section: 23.7.3.3.2 [mdspan.extents.expo] Status: New Submitter: Casey Carter Opened: 2023-11-29 Last modified: 2023-12-02

Priority: Not Prioritized

View all issues with New status.

Discussion:

The exposition-only static member index-cast of extents is specified as (23.7.3.3.2 [mdspan.extents.expo]/9):

template<class OtherIndexType>
static constexpr auto index-cast(OtherIndexType&& i) noexcept;

-9- Effects:

  1. (9.1) — If OtherIndexType is an integral type other than bool, then equivalent to return i;,

  2. (9.2) — otherwise, equivalent to return static_cast<index_type>(i);.

[Note 1: This function will always return an integral type other than bool. Since this function's call sites are constrained on convertibility of OtherIndexType to index_type, integer-class types can use the static_cast branch without loss of precision. — end note]

This function returns T when passed an rvalue of cv-unqualified integral type T, but index_type when passed a cv-qualified and/or lvalue argument of any integral type. It would seem more consistent and easier to reason about if 9.1 was instead conditional on remove_cvref_t<OtherIndexType>.

Proposed resolution:

This wording is relative to N4964.

  1. Modify 23.7.3.3.2 [mdspan.extents.expo] as indicated:

    template<class OtherIndexType>
      static constexpr auto index-cast(OtherIndexType&& i) noexcept;
    

    -9- Effects:

    1. (9.1) — If remove_cvref_t<OtherIndexType> is an integral type other than bool, then equivalent to return i;,

    2. (9.2) — otherwise, equivalent to return static_cast<index_type>(i);.

    [Note 1: This function will always return an integral type other than bool. Since this function's call sites are constrained on convertibility of OtherIndexType to index_type, integer-class types can use the static_cast branch without loss of precision. — end note]