[mdspan.layout.right] # 23 Containers library [[containers]](./#containers) ## 23.7 Views [[views]](views#mdspan.layout.right) ### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right) #### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right) #### 23.7.3.4.6 Class template layout_right​::​mapping [mdspan.layout.right] #### [23.7.3.4.6.1](#overview) Overview [[mdspan.layout.right.overview]](mdspan.layout.right.overview) [1](#overview-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22238) layout_right provides a layout mapping where the rightmost extent is stride 1, and strides increase right-to-left as the product of extents[.](#overview-1.sentence-1) namespace std {templateclass layout_right::mapping {public:using extents_type = Extents; 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 layout_type = layout_right; // [[mdspan.layout.right.cons]](#cons "23.7.3.4.6.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; templateconstexpr explicit(!is_convertible_v) mapping(const mapping&) noexcept; templateconstexpr explicit(!is_convertible_v) mapping(const layout_left::mapping&) noexcept; templateconstexpr explicit(!is_convertible_v) mapping(const LayoutRightPaddedMapping&) noexcept; templateconstexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.right.obs]](#obs "23.7.3.4.6.3 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const noexcept; templateconstexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept { return true; }static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }static constexpr bool is_exhaustive() noexcept { return true; }static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; templatefriend constexpr bool operator==(const mapping&, const mapping&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_­mapping"), submdspan mapping specializationtemplateconstexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; templatefriend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};} [2](#overview-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22312) If Extents is not a specialization of extents, then the program is ill-formed[.](#overview-2.sentence-1) [3](#overview-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22316) layout_right​::​mapping is a trivially copyable type that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#overview-3.sentence-1) [4](#overview-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22320) *Mandates*: If Extents​::​rank_dynamic() == 0 is true, then the size of the multidimensional index space Extents() is representable as a value of type typename Extents​::​index_type[.](#overview-4.sentence-1) #### [23.7.3.4.6.2](#cons) Constructors [[mdspan.layout.right.cons]](mdspan.layout.right.cons) [🔗](#lib:layout_right::mapping,constructor) `constexpr mapping(const extents_type& e) noexcept; ` [1](#cons-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22334) *Preconditions*: The size of the multidimensional index space e is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#cons-1.sentence-1) [2](#cons-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22339) *Effects*: Direct-non-list-initializes *extents_* with e[.](#cons-2.sentence-1) [🔗](#lib:layout_right::mapping,constructor_) `template constexpr explicit(!is_convertible_v) mapping(const mapping& other) noexcept; ` [3](#cons-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22352) *Constraints*: is_constructible_v is true[.](#cons-3.sentence-1) [4](#cons-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22356) *Preconditions*: other.required_span_size() is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#cons-4.sentence-1) [5](#cons-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22361) *Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-5.sentence-1) [🔗](#lib:layout_right::mapping,constructor__) `template constexpr explicit(!is_convertible_v) mapping(const layout_left::mapping& other) noexcept; ` [6](#cons-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22374) *Constraints*: - [(6.1)](#cons-6.1) extents_type​::​rank() <= 1 is true, and - [(6.2)](#cons-6.2) is_constructible_v is true[.](#cons-6.sentence-1) [7](#cons-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22383) *Preconditions*: other.required_span_size() is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#cons-7.sentence-1) [8](#cons-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22388) *Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-8.sentence-1) [🔗](#lib:layout_right::mapping,constructor___) `template constexpr explicit(!is_convertible_v) mapping(const LayoutRightPaddedMapping&) noexcept; ` [9](#cons-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22402) *Constraints*: - [(9.1)](#cons-9.1) *is-layout-right-padded-mapping-of* is true[.](#cons-9.1.sentence-1) - [(9.2)](#cons-9.2) is_constructible_v is true[.](#cons-9.2.sentence-1) [10](#cons-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22413) *Mandates*: If - [(10.1)](#cons-10.1) Extents​::​rank() is greater than one, - [(10.2)](#cons-10.2) Extents​::​static_extent(Extents​::​rank() - 1) does not equal dynamic_extent, and - [(10.3)](#cons-10.3) LayoutRightPaddedMapping​::​*static-padding-stride* does not equal dynamic_extent, then Extents​::​static_extent(Extents​::​rank() - 1) equalsLayoutRightPaddedMapping​::​*static-padding-stride*[.](#cons-10.sentence-1) [11](#cons-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22429) *Preconditions*: - [(11.1)](#cons-11.1) If extents_type​::​rank() > 1 is true, then other.stride(extents_type​::​rank() - 2) equalsother.extents().extent(extents_type​::​rank() - 1)[.](#cons-11.1.sentence-1) - [(11.2)](#cons-11.2) other.required_span_size() is representable as a value of type index_type[.](#cons-11.2.sentence-1) [12](#cons-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22441) *Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#cons-12.sentence-1) [🔗](#lib:layout_right::mapping,constructor____) `template constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping& other) noexcept; ` [13](#cons-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22454) *Constraints*: is_constructible_v is true[.](#cons-13.sentence-1) [14](#cons-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22458) *Preconditions*: - [(14.1)](#cons-14.1) If extents_type​::​rank() > 0 is true, then for all r in the range [0, extents_type​::​rank()),other.stride(r) equalsother.extents().*rev-prod-of-extents*(r)[.](#cons-14.1.sentence-1) - [(14.2)](#cons-14.2) other.required_span_size() is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#cons-14.2.sentence-1) [15](#cons-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22471) *Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-15.sentence-1) #### [23.7.3.4.6.3](#obs) Observers [[mdspan.layout.right.obs]](mdspan.layout.right.obs) [🔗](#lib:required_span_size,layout_right::mapping) `constexpr index_type required_span_size() const noexcept; ` [1](#obs-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22484) *Returns*: extents().*fwd-prod-of-extents*(extents_type​::​rank())[.](#obs-1.sentence-1) [🔗](#lib:operator(),layout_right::mapping) `template constexpr index_type operator()(Indices... i) const noexcept; ` [2](#obs-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22496) *Constraints*: - [(2.1)](#obs-2.1) sizeof...(Indices) == extents_type​::​rank() is true, - [(2.2)](#obs-2.2) (is_convertible_v && ...) is true, and - [(2.3)](#obs-2.3) (is_nothrow_constructible_v && ...) istrue[.](#obs-2.sentence-1) [3](#obs-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22508) *Preconditions*: extents_type​::​*index-cast*(i) is a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#obs-3.sentence-1) [4](#obs-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22513) *Effects*: Let P be a parameter pack such thatis_same_v, index_sequence> is true[.](#obs-4.sentence-1) Equivalent to:return ((static_cast(i) * stride(P)) + ... + 0); [🔗](#lib:stride,layout_right::mapping) `constexpr index_type stride(rank_type i) const noexcept; ` [5](#obs-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22531) *Constraints*: extents_type​::​rank() > 0 is true[.](#obs-5.sentence-1) [6](#obs-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22535) *Preconditions*: i < extents_type​::​rank() is true[.](#obs-6.sentence-1) [7](#obs-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22539) *Returns*: extents().*rev-prod-of-extents*(i)[.](#obs-7.sentence-1) [🔗](#lib:operator==,layout_right::mapping) `template friend constexpr bool operator==(const mapping& x, const mapping& y) noexcept; ` [8](#obs-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22551) *Constraints*: extents_type​::​rank() == OtherExtents​::​rank() is true[.](#obs-8.sentence-1) [9](#obs-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22555) *Effects*: Equivalent to: return x.extents() == y.extents();