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]

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

23.7.3.3.3 Constructors [mdspan.extents.cons]

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

23.7.3.3.5 Comparison operators [mdspan.extents.cmp]

23.7.3.3.6 Alias template dextents [mdspan.extents.dextents]

23.7.3.3.7 Alias template dims [mdspan.extents.dims]


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 space static 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], constructors constexpr 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 operators template<class OtherIndexType, size_t.. OtherExtents> friend constexpr bool operator=(const extents&, const extents<OtherIndexType, OtherExtents..>&) noexcept; / [mdspan.extents.expo], exposition-only helpers constexpr size_t fwd-prod-of-extents(rank_type) const noexcept; / exposition only constexpr size_t rev-prod-of-extents(rank_type) const noexcept; / exposition only template<class OtherIndexType> static constexpr auto index-cast(OtherIndexType&&) noexcept; / exposition only private: static constexpr rank_type dynamic-index(rank_type) noexcept; / exposition only static 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; }
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.
Each specialization of extents models regular and is trivially copyable.
Let
Let
The

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

static constexpr rank_type dynamic-index(rank_type i) noexcept;
Returns: The number of
static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
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;
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;
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;
Effects:
  • If remove_cvref_t<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]
template<class OtherIndexType, size_t.. OtherExtents> constexpr explicit(see below) extents(const extents<OtherIndexType, OtherExtents..>& other) noexcept;
Preconditions:
  • other.extent(r) equals
  • 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.
Remarks: The expression inside explicit is equivalent to: ((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || .. ) || (numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max()
template<class. OtherIndexTypes> constexpr explicit extents(OtherIndexTypes.. exts) noexcept;
Let N be sizeof.(OtherIndexTypes), and let exts_arr be array<index_type, N>{static_cast<
index_type>(std​::​move(exts)).}
.
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]
Preconditions:
  • If N != rank_dynamic() is true, exts_arr[r] equals
  • either
    • sizeof.(exts) == 0 is true, or
    • each element of exts is representable as a nonnegative value of type index_type.
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;
Preconditions:
  • If N != rank_dynamic() is true, exts[r] equals
  • either
    • N is zero, or
    • exts[r] is representable as a nonnegative value of type index_type for every rank index r.
Effects:
  • 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]).
  • 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;
Remarks: The deduced type is extents<size_t, maybe-static-ext<Integrals>.>.

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

static constexpr size_t static_extent(rank_type i) noexcept;
Returns:
constexpr index_type extent(rank_type i) const noexcept;
Returns:

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;
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;
Result: A type E that is a specialization of extents such that E​::​rank() == Rank && E​::​rank() == E​::​rank_dynamic() is true, and E​::​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;
Result: A type E that is a specialization of extents such that E​::​rank() == Rank && E​::​rank() == E​::​rank_dynamic() is true, and E​::​index_type denotes IndexType.

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant