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

622 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[mdspan.mdspan]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#mdspan.mdspan)
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.mdspan)
#### 23.7.3.6 Class template mdspan [mdspan.mdspan]
#### [23.7.3.6.1](#overview) Overview [[mdspan.mdspan.overview]](mdspan.mdspan.overview)
[1](#overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24629)
mdspan is a view of a multidimensional array of elements[.](#overview-1.sentence-1)
namespace std {template<class ElementType, class Extents, class LayoutPolicy = layout_right, class AccessorPolicy = default_accessor<ElementType>>class mdspan {public:using extents_type = Extents; using layout_type = LayoutPolicy; using accessor_type = AccessorPolicy; using mapping_type = typename layout_type::template mapping<extents_type>; using element_type = ElementType; using value_type = remove_cv_t<element_type>; using index_type = typename extents_type::index_type; using size_type = typename extents_type::size_type; using rank_type = typename extents_type::rank_type; using data_handle_type = typename accessor_type::data_handle_type; using reference = typename accessor_type::reference; static constexpr rank_type rank() noexcept { return extents_type::rank(); }static constexpr rank_type rank_dynamic() noexcept { return extents_type::rank_dynamic(); }static constexpr size_t static_extent(rank_type r) noexcept{ return extents_type::static_extent(r); }constexpr index_type extent(rank_type r) const noexcept { return extents().extent(r); }// [[mdspan.mdspan.cons]](#cons "23.7.3.6.2Constructors"), constructorsconstexpr mdspan(); constexpr mdspan(const mdspan& rhs) = default; constexpr mdspan(mdspan&& rhs) = default; template<class... OtherIndexTypes>constexpr explicit mdspan(data_handle_type ptr, OtherIndexTypes... exts); template<class OtherIndexType, size_t N>constexpr explicit(N != rank_dynamic()) mdspan(data_handle_type p, span<OtherIndexType, N> exts); template<class OtherIndexType, size_t N>constexpr explicit(N != rank_dynamic()) mdspan(data_handle_type p, const array<OtherIndexType, N>& exts); constexpr mdspan(data_handle_type p, const extents_type& ext); constexpr mdspan(data_handle_type p, const mapping_type& m); constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a); template<class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherAccessorPolicy>constexpr explicit(*see below*) mdspan(const mdspan<OtherElementType, OtherExtents,
OtherLayoutPolicy, OtherAccessorPolicy>& other); constexpr mdspan& operator=(const mdspan& rhs) = default; constexpr mdspan& operator=(mdspan&& rhs) = default; // [[mdspan.mdspan.members]](#members "23.7.3.6.3Members"), memberstemplate<class... OtherIndexTypes>constexpr reference operator[](OtherIndexTypes... indices) const; template<class OtherIndexType>constexpr reference operator[](span<OtherIndexType, rank()> indices) const; template<class OtherIndexType>constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const; template<class... OtherIndexTypes>constexpr reference
at(OtherIndexTypes... indices) const; // freestanding-deletedtemplate<class OtherIndexType>constexpr reference
at(span<OtherIndexType, rank()> indices) const; // freestanding-deletedtemplate<class OtherIndexType>constexpr reference
at(const array<OtherIndexType, rank()>& indices) const; // freestanding-deletedconstexpr size_type size() const noexcept; constexpr bool empty() const noexcept; friend constexpr void swap(mdspan& x, mdspan& y) noexcept; constexpr const extents_type& extents() const noexcept { return *map_*.extents(); }constexpr const data_handle_type& data_handle() const noexcept { return *ptr_*; }constexpr const mapping_type& mapping() const noexcept { return *map_*; }constexpr const accessor_type& accessor() const noexcept { return *acc_*; }static constexpr bool is_always_unique(){ return mapping_type::is_always_unique(); }static constexpr bool is_always_exhaustive(){ return mapping_type::is_always_exhaustive(); }static constexpr bool is_always_strided(){ return mapping_type::is_always_strided(); }constexpr bool is_unique() const{ return *map_*.is_unique(); }constexpr bool is_exhaustive() const{ return *map_*.is_exhaustive(); }constexpr bool is_strided() const{ return *map_*.is_strided(); }constexpr index_type stride(rank_type r) const{ return *map_*.stride(r); }private: accessor_type *acc_*; // *exposition only* mapping_type *map_*; // *exposition only* data_handle_type *ptr_*; // *exposition only*}; template<class CArray>requires (is_array_v<CArray> && rank_v<CArray> == 1) mdspan(CArray&)-> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>; template<class Pointer>requires (is_pointer_v<remove_reference_t<Pointer>>) mdspan(Pointer&&)-> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>; template<class ElementType, class... Integrals>requires ((is_convertible_v<Integrals, size_t> && ...) && sizeof...(Integrals) > 0)explicit mdspan(ElementType*, Integrals...)-> mdspan<ElementType, extents<size_t, [*maybe-static-ext*](span.syn#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]")<Integrals>...>>; template<class ElementType, class OtherIndexType, size_t N> mdspan(ElementType*, span<OtherIndexType, N>)-> mdspan<ElementType, dextents<size_t, N>>; template<class ElementType, class OtherIndexType, size_t N> mdspan(ElementType*, const array<OtherIndexType, N>&)-> mdspan<ElementType, dextents<size_t, N>>; template<class ElementType, class IndexType, size_t... ExtentsPack> mdspan(ElementType*, const extents<IndexType, ExtentsPack...>&)-> mdspan<ElementType, extents<IndexType, ExtentsPack...>>; template<class ElementType, class MappingType> mdspan(ElementType*, const MappingType&)-> mdspan<ElementType, typename MappingType::extents_type, typename MappingType::layout_type>; template<class MappingType, class AccessorType> mdspan(const typename AccessorType::data_handle_type&, const MappingType&, const AccessorType&)-> mdspan<typename AccessorType::element_type, typename MappingType::extents_type, typename MappingType::layout_type, AccessorType>;}
[2](#overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24772)
*Mandates*:
- [(2.1)](#overview-2.1)
ElementType is a complete object type
that is neither an abstract class type nor an array type,
- [(2.2)](#overview-2.2)
Extents is a specialization of extents, and
- [(2.3)](#overview-2.3)
is_same_v<ElementType, typename AccessorPolicy::element_type> is true[.](#overview-2.sentence-1)
[3](#overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24785)
LayoutPolicy shall meet
the layout mapping policy requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3Layout mapping policy requirements")), andAccessorPolicy shall meet
the accessor policy requirements ([[mdspan.accessor.reqmts]](mdspan.accessor.reqmts "23.7.3.5.2Requirements"))[.](#overview-3.sentence-1)
[4](#overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24791)
Each specialization MDS of mdspan models [copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]") and
- [(4.1)](#overview-4.1)
is_nothrow_move_constructible_v<MDS> is true,
- [(4.2)](#overview-4.2)
is_nothrow_move_assignable_v<MDS> is true, and
- [(4.3)](#overview-4.3)
is_nothrow_swappable_v<MDS> is true[.](#overview-4.sentence-1)
[5](#overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24802)
A specialization of mdspan is a trivially copyable type if
its accessor_type, mapping_type, and data_handle_type are trivially copyable types[.](#overview-5.sentence-1)
#### [23.7.3.6.2](#cons) Constructors [[mdspan.mdspan.cons]](mdspan.mdspan.cons)
[🔗](#lib:mdspan,constructor)
`constexpr mdspan();
`
[1](#cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24815)
*Constraints*:
- [(1.1)](#cons-1.1)
rank_dynamic() > 0 is true[.](#cons-1.1.sentence-1)
- [(1.2)](#cons-1.2)
is_default_constructible_v<data_handle_type> is true[.](#cons-1.2.sentence-1)
- [(1.3)](#cons-1.3)
is_default_constructible_v<mapping_type> is true[.](#cons-1.3.sentence-1)
- [(1.4)](#cons-1.4)
is_default_constructible_v<accessor_type> is true[.](#cons-1.4.sentence-1)
[2](#cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24828)
*Preconditions*: [0, *map_*.required_span_size()) is
an accessible range of *ptr_* and *acc_* for the values of *map_* and *acc_* after the invocation of this constructor[.](#cons-2.sentence-1)
[3](#cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24835)
*Effects*: Value-initializes *ptr_*, *map_*, and *acc_*[.](#cons-3.sentence-1)
[🔗](#lib:mdspan,constructor_)
`template<class... OtherIndexTypes>
constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts);
`
[4](#cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24847)
Let N be sizeof...(OtherIndexTypes)[.](#cons-4.sentence-1)
[5](#cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24850)
*Constraints*:
- [(5.1)](#cons-5.1)
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
- [(5.2)](#cons-5.2)
(is_nothrow_constructible<index_type, OtherIndexTypes> && ...) is true,
- [(5.3)](#cons-5.3)
N == rank() || N == rank_dynamic() is true,
- [(5.4)](#cons-5.4)
is_constructible_v<mapping_type, extents_type> is true, and
- [(5.5)](#cons-5.5)
is_default_constructible_v<accessor_type> is true[.](#cons-5.sentence-1)
[6](#cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24865)
*Preconditions*: [0, *map_*.required_span_size()) is
an accessible range of p and *acc_* for the values of *map_* and *acc_* after the invocation of this constructor[.](#cons-6.sentence-1)
[7](#cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24872)
*Effects*:
- [(7.1)](#cons-7.1)
Direct-non-list-initializes *ptr_* with std::move(p),
- [(7.2)](#cons-7.2)
direct-non-list-initializes *map_* withextents_type(static_cast<index_type>(std::move(exts))...), and
- [(7.3)](#cons-7.3)
value-initializes *acc_*[.](#cons-7.sentence-1)
[🔗](#lib:mdspan,constructor__)
`template<class OtherIndexType, size_t N>
constexpr explicit(N != rank_dynamic())
mdspan(data_handle_type p, span<OtherIndexType, N> exts);
template<class OtherIndexType, size_t N>
constexpr explicit(N != rank_dynamic())
mdspan(data_handle_type p, const array<OtherIndexType, N>& exts);
`
[8](#cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24896)
*Constraints*:
- [(8.1)](#cons-8.1)
is_convertible_v<const OtherIndexType&, index_type> is true,
- [(8.2)](#cons-8.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true,
- [(8.3)](#cons-8.3)
N == rank() || N == rank_dynamic() is true,
- [(8.4)](#cons-8.4)
is_constructible_v<mapping_type, extents_type> is true, and
- [(8.5)](#cons-8.5)
is_default_constructible_v<accessor_type> is true[.](#cons-8.sentence-1)
[9](#cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24911)
*Preconditions*: [0, *map_*.required_span_size()) is
an accessible range of p and *acc_* for the values of *map_* and *acc_* after the invocation of this constructor[.](#cons-9.sentence-1)
[10](#cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24918)
*Effects*:
- [(10.1)](#cons-10.1)
Direct-non-list-initializes *ptr_* with std::move(p),
- [(10.2)](#cons-10.2)
direct-non-list-initializes *map_* with extents_type(exts), and
- [(10.3)](#cons-10.3)
value-initializes *acc_*[.](#cons-10.sentence-1)
[🔗](#lib:mdspan,constructor___)
`constexpr mdspan(data_handle_type p, const extents_type& ext);
`
[11](#cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24936)
*Constraints*:
- [(11.1)](#cons-11.1)
is_constructible_v<mapping_type, const extents_type&> is true, and
- [(11.2)](#cons-11.2)
is_default_constructible_v<accessor_type> is true[.](#cons-11.sentence-1)
[12](#cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24945)
*Preconditions*: [0, *map_*.required_span_size()) is
an accessible range of p and *acc_* for the values of *map_* and *acc_* after the invocation of this constructor[.](#cons-12.sentence-1)
[13](#cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24952)
*Effects*:
- [(13.1)](#cons-13.1)
Direct-non-list-initializes *ptr_* with std::move(p),
- [(13.2)](#cons-13.2)
direct-non-list-initializes *map_* with ext, and
- [(13.3)](#cons-13.3)
value-initializes *acc_*[.](#cons-13.sentence-1)
[🔗](#lib:mdspan,constructor____)
`constexpr mdspan(data_handle_type p, const mapping_type& m);
`
[14](#cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24970)
*Constraints*: is_default_constructible_v<accessor_type> is true[.](#cons-14.sentence-1)
[15](#cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24974)
*Preconditions*: [0, m.required_span_size()) is
an accessible range of p and *acc_* for the value of *acc_* after the invocation of this constructor[.](#cons-15.sentence-1)
[16](#cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24980)
*Effects*:
- [(16.1)](#cons-16.1)
Direct-non-list-initializes *ptr_* with std::move(p),
- [(16.2)](#cons-16.2)
direct-non-list-initializes *map_* with m, and
- [(16.3)](#cons-16.3)
value-initializes *acc_*[.](#cons-16.sentence-1)
[🔗](#lib:mdspan,constructor_____)
`constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
`
[17](#cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24998)
*Preconditions*: [0, m.required_span_size()) is
an accessible range of p and a[.](#cons-17.sentence-1)
[18](#cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25003)
*Effects*:
- [(18.1)](#cons-18.1)
Direct-non-list-initializes *ptr_* with std::move(p),
- [(18.2)](#cons-18.2)
direct-non-list-initializes *map_* with m, and
- [(18.3)](#cons-18.3)
direct-non-list-initializes *acc_* with a[.](#cons-18.sentence-1)
[🔗](#lib:mdspan,constructor______)
`template<class OtherElementType, class OtherExtents,
class OtherLayoutPolicy, class OtherAccessor>
constexpr explicit(see below)
mdspan(const mdspan<OtherElementType, OtherExtents,
OtherLayoutPolicy, OtherAccessor>& other);
`
[19](#cons-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25025)
*Constraints*:
- [(19.1)](#cons-19.1)
is_constructible_v<mapping_type, const OtherLayoutPolicy::template mapping<Oth-
erExtents>&> is true, and
- [(19.2)](#cons-19.2)
is_constructible_v<accessor_type, const OtherAccessor&> is true[.](#cons-19.sentence-1)
[20](#cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25035)
*Mandates*:
- [(20.1)](#cons-20.1)
is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&> is
true, and
- [(20.2)](#cons-20.2)
is_constructible_v<extents_type, OtherExtents> is true[.](#cons-20.sentence-1)
[21](#cons-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25044)
*Preconditions*: [0, *map_*.required_span_size()) is
an accessible range of *ptr_* and *acc_* for values of *ptr_*, *map_*, and *acc_* after the invocation of this constructor[.](#cons-21.sentence-1)
[22](#cons-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25051)
*Hardened preconditions*: For each rank index r of extents_type,static_extent(r) == dynamic_extent || static_extent(r) == other.extent(r) is true[.](#cons-22.sentence-1)
[23](#cons-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25057)
*Effects*:
- [(23.1)](#cons-23.1)
Direct-non-list-initializes *ptr_* with other.*ptr_*,
- [(23.2)](#cons-23.2)
direct-non-list-initializes *map_* with other.*map_*, and
- [(23.3)](#cons-23.3)
direct-non-list-initializes *acc_* with other.*acc_*[.](#cons-23.sentence-1)
[24](#cons-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25068)
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<const OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type>|| !is_convertible_v<const OtherAccessor&, accessor_type>
#### [23.7.3.6.3](#members) Members [[mdspan.mdspan.members]](mdspan.mdspan.members)
[🔗](#lib:operator%5b%5d,mdspan)
`template<class... OtherIndexTypes>
constexpr reference operator[](OtherIndexTypes... indices) const;
`
[1](#members-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25086)
*Constraints*:
- [(1.1)](#members-1.1)
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
- [(1.2)](#members-1.2)
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
- [(1.3)](#members-1.3)
sizeof...(OtherIndexTypes) == rank() is true[.](#members-1.sentence-1)
[2](#members-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25097)
Let I be extents_type::*index-cast*(std::move(indices))[.](#members-2.sentence-1)
[3](#members-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25100)
*Hardened preconditions*: I is a multidimensional index in extents()[.](#members-3.sentence-1)
[*Note [1](#members-note-1)*:
This implies that*map_*(I) < *map_*.required_span_size() is true[.](#members-3.sentence-2)
— *end note*]
[4](#members-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25109)
*Effects*: Equivalent to:return *acc_*.access(*ptr_*, *map_*(static_cast<index_type>(std::move(indices))...));
[🔗](#lib:operator%5b%5d,mdspan_)
`template<class OtherIndexType>
constexpr reference operator[](span<OtherIndexType, rank()> indices) const;
template<class OtherIndexType>
constexpr reference operator[](const array<OtherIndexType, rank()>& indices) const;
`
[5](#members-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25126)
*Constraints*:
- [(5.1)](#members-5.1)
is_convertible_v<const OtherIndexType&, index_type> is true, and
- [(5.2)](#members-5.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#members-5.sentence-1)
[6](#members-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25135)
*Effects*: Let P be a parameter pack such thatis_same_v<make_index_sequence<rank()>, index_sequence<P...>> is true[.](#members-6.sentence-1)
Equivalent to:return operator[](extents_type::*index-cast*(as_const(indices[P]))...);
[🔗](#lib:at,mdspan)
`template<class... OtherIndexTypes>
constexpr reference at(OtherIndexTypes... indices) const;
`
[7](#members-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25155)
*Constraints*:
- [(7.1)](#members-7.1)
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
- [(7.2)](#members-7.2)
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
- [(7.3)](#members-7.3)
sizeof...(OtherIndexTypes) == rank() is true[.](#members-7.sentence-1)
[8](#members-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25166)
Let I be extents_type::*index-cast*(std::move(indices))[.](#members-8.sentence-1)
[9](#members-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25169)
*Returns*: (*this)[I...][.](#members-9.sentence-1)
[10](#members-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25173)
*Throws*: out_of_range if I is not a multidimensional index in extents()[.](#members-10.sentence-1)
[🔗](#lib:at,mdspan_)
`template<class OtherIndexType>
constexpr reference at(span<OtherIndexType, rank()> indices) const;
template<class OtherIndexType>
constexpr reference at(const array<OtherIndexType, rank()>& indices) const;
`
[11](#members-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25187)
*Constraints*:
- [(11.1)](#members-11.1)
is_convertible_v<const OtherIndexType&, index_type> is true, and
- [(11.2)](#members-11.2)
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#members-11.sentence-1)
[12](#members-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25196)
*Effects*: Let P be a parameter pack such thatis_same_v<make_index_sequence<rank()>, index_sequence<P...>> is true[.](#members-12.sentence-1)
Equivalent to:return at(extents_type::*index-cast*(as_const(indices[P]))...);
[🔗](#lib:size,mdspan)
`constexpr size_type size() const noexcept;
`
[13](#members-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25215)
*Preconditions*: The size of the multidimensional index space extents() is representable as a value of type size_type ([[basic.fundamental]](basic.fundamental "6.9.2Fundamental types"))[.](#members-13.sentence-1)
[14](#members-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25220)
*Returns*: extents().*fwd-prod-of-extents*(rank())[.](#members-14.sentence-1)
[🔗](#lib:empty,mdspan)
`constexpr bool empty() const noexcept;
`
[15](#members-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25231)
*Returns*: true if the size of the multidimensional index space extents() is 0,
otherwise false[.](#members-15.sentence-1)
[🔗](#lib:swap,mdspan)
`friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
`
[16](#members-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25244)
*Effects*: Equivalent to:swap(x.*ptr_*, y.*ptr_*);
swap(x.*map_*, y.*map_*);
swap(x.*acc_*, y.*acc_*);