Files
2025-10-25 03:02:53 +03:00

16 KiB
Raw Permalink Blame History

[mdspan.extents]

23 Containers library [containers]

23.7 Views [views]

23.7.3 Multidimensional access [views.multidim]

23.7.3.3 Class template extents [mdspan.extents]

23.7.3.3.1 Overview [mdspan.extents.overview]

The class template extents represents a multidimensional index space of rank equal to sizeof...(Extents).

In [views],extents is used synonymously with multidimensional index space.

namespace std {template<class IndexType, size_t... Extents>class extents {public:using index_type = IndexType; using size_type = make_unsigned_t<index_type>; using rank_type = size_t; // [mdspan.extents.obs], observers of the multidimensional index spacestatic constexpr rank_type rank() noexcept { return sizeof...(Extents); }static constexpr rank_type rank_dynamic() noexcept { return dynamic-index(rank()); }static constexpr size_t static_extent(rank_type) noexcept; constexpr index_type extent(rank_type) const noexcept; // [mdspan.extents.cons], constructorsconstexpr extents() noexcept = default; template<class OtherIndexType, size_t... OtherExtents>constexpr explicit(see below) extents(const extents<OtherIndexType, OtherExtents...>&) noexcept; template<class... OtherIndexTypes>constexpr explicit extents(OtherIndexTypes...) noexcept; template<class OtherIndexType, size_t N>constexpr explicit(N != rank_dynamic()) extents(span<OtherIndexType, N>) noexcept; template<class OtherIndexType, size_t N>constexpr explicit(N != rank_dynamic()) extents(const array<OtherIndexType, N>&) noexcept; // [mdspan.extents.cmp], comparison operatorstemplate<class OtherIndexType, size_t... OtherExtents>friend constexpr bool operator==(const extents&, const extents<OtherIndexType, OtherExtents...>&) noexcept; // [mdspan.extents.expo], exposition-only helpersconstexpr size_t fwd-prod-of-extents(rank_type) const noexcept; // exposition onlyconstexpr size_t rev-prod-of-extents(rank_type) const noexcept; // exposition onlytemplatestatic constexpr auto index-cast(OtherIndexType&&) noexcept; // exposition onlyprivate:static constexpr rank_type dynamic-index(rank_type) noexcept; // exposition onlystatic constexpr rank_type dynamic-index-inv(rank_type) noexcept; // exposition only array<index_type, rank_dynamic()> dynamic-extents{}; // exposition only}; template<class... Integrals>explicit extents(Integrals...)-> see below;}

1

#

Mandates:

IndexType is a signed or unsigned integer type, and

each element of Extents is either equal to dynamic_extent, or is representable as a value of type IndexType.

2

#

Each specialization of extents models regular and is trivially copyable.

3

#

Let Er be the rth element of Extents.

Er is a dynamic extent if it is equal to dynamic_extent, otherwise Er is a static extent.

Let Dr be the value of dynamic-extents[dynamic-index(r)] if Er is a dynamic extent, otherwise Er.

4

#

The rth interval of the multidimensional index space represented by an extents object is [0,Dr).

23.7.3.3.2 Exposition-only helpers [mdspan.extents.expo]

🔗

static constexpr rank_type dynamic-index(rank_type i) noexcept;

1

#

Preconditions: i <= rank() is true.

2

#

Returns: The number of Er with r<i for which Er is a dynamic extent.

🔗

static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;

3

#

Preconditions: i < rank_dynamic() is true.

4

#

Returns: The minimum value of r such that dynamic-index(r + 1) == i + 1 is true.

🔗

constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;

5

#

Preconditions: i <= rank() is true.

6

#

Returns: If i > 0 is true, the product of extent(k) for all k in the range [0, i), otherwise 1.

🔗

constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;

7

#

Preconditions: i < rank() is true.

8

#

Returns: If i + 1 < rank() is true, the product of extent(k) for all k in the range [i + 1, rank()), otherwise 1.

🔗

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

9

#

Effects:

If OtherIndexType is an integral type other than bool, then equivalent to return i;,

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]

23.7.3.3.3 Constructors [mdspan.extents.cons]

🔗

template<class OtherIndexType, size_t... OtherExtents> constexpr explicit(see below) extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;

1

#

Constraints:

  • (1.1)

    sizeof...(OtherExtents) == rank() is true.

  • (1.2)

    ((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents ==
    Extents) && ...) is true.

2

#

Preconditions:

other.extent(r) equals Er for each r for which Er is a static extent, and

either

sizeof...(OtherExtents) is zero, or

other.extent(r) is representable as a value of type index_type for every rank index r of other.

3

#

Postconditions: *this == other is true.

4

#

Remarks: The expression inside explicit is equivalent to:(((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||(numeric_limits<index_type>::max() < numeric_limits::max())

🔗

template<class... OtherIndexTypes> constexpr explicit extents(OtherIndexTypes... exts) noexcept;

5

#

Let N be sizeof...(OtherIndexTypes), and let exts_arr bearray<index_type, N>{static_cast<
index_type>(std::move(exts))...}.

6

#

Constraints:

(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,

(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and

N == rank_dynamic() || N == rank() is true. [Note 1: One can construct extents from just dynamic extents, which are all the values getting stored, or from all the extents with a precondition. — end note]

7

#

Preconditions:

If N != rank_dynamic() is true,exts_arr[r] equals Er for each r for which Er is a static extent, and

either

sizeof...(exts) == 0 is true, or

each element of exts is representable as a nonnegative value of type index_type.

8

#

Postconditions: *this == extents(exts_arr) is true.

🔗

template<class OtherIndexType, size_t N> constexpr explicit(N != rank_dynamic()) extents(span<OtherIndexType, N> exts) noexcept; template<class OtherIndexType, size_t N> constexpr explicit(N != rank_dynamic()) extents(const array<OtherIndexType, N>& exts) noexcept;

9

#

Constraints:

is_convertible_v<const OtherIndexType&, index_type> is true,

is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and

N == rank_dynamic() || N == rank() is true.

10

#

Preconditions:

If N != rank_dynamic() is true,exts[r] equals Er for each r for which Er is a static extent, and

either

N is zero, or

exts[r] is representable as a nonnegative value of type index_type for every rank index r.

11

#

Effects:

  • (11.1)

    If N equals rank_dynamic(), for all d in the range [0, rank_dynamic()), direct-non-list-initializes dynamic-extents[d] with as_const(exts[d]).

  • (11.2)

    Otherwise, for all d in the range [0, rank_dynamic()), direct-non-list-initializes dynamic-extents[d] with as_const(exts[dynamic-index-inv(d)]).

🔗

template<class... Integrals> explicit extents(Integrals...) -> see below;

12

#

Constraints: (is_convertible_v<Integrals, size_t> && ...) is true.

13

#

Remarks: The deduced type is extents<size_t, maybe-static-ext...>.

23.7.3.3.4 Observers of the multidimensional index space [mdspan.extents.obs]

🔗

static constexpr size_t static_extent(rank_type i) noexcept;

1

#

Preconditions: i < rank() is true.

2

#

Returns: Ei.

🔗

constexpr index_type extent(rank_type i) const noexcept;

3

#

Preconditions: i < rank() is true.

4

#

Returns: Di.

23.7.3.3.5 Comparison operators [mdspan.extents.cmp]

🔗

template<class OtherIndexType, size_t... OtherExtents> friend constexpr bool operator==(const extents& lhs, const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;

1

#

Returns: true if lhs.rank() equals rhs.rank() and if lhs.extent(r) equals rhs.extent(r) for every rank index r of rhs, otherwise false.

23.7.3.3.6 Alias template dextents [mdspan.extents.dextents]

🔗

template<class IndexType, size_t Rank> using dextents = see below;

1

#

Result: A type E that is a specialization of extents such that E::rank() == Rank && E::rank() == E::rank_dynamic() is true, andE::index_type denotes IndexType.

23.7.3.3.7 Alias template dims [mdspan.extents.dims]

🔗

template<size_t Rank, class IndexType = size_t> using dims = see below;

1

#

Result: A type E that is a specialization of extents such that E::rank() == Rank && E::rank() == E::rank_dynamic() is true, andE::index_type denotes IndexType.