Init
This commit is contained in:
469
cppdraft/mdspan/accessor.md
Normal file
469
cppdraft/mdspan/accessor.md
Normal file
@@ -0,0 +1,469 @@
|
||||
[mdspan.accessor]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [mdspan.accessor]
|
||||
|
||||
#### [23.7.3.5.1](#general) General [[mdspan.accessor.general]](mdspan.accessor.general)
|
||||
|
||||
[1](#general-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24204)
|
||||
|
||||
An [*accessor policy*](#def:accessor_policy "23.7.3.5.1 General [mdspan.accessor.general]") defines types and operations by which
|
||||
a reference to a single object is created
|
||||
from an abstract data handle to a number of such objects and an index[.](#general-1.sentence-1)
|
||||
|
||||
[2](#general-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24209)
|
||||
|
||||
A range of indices [0,N) is an [*accessible range*](#def:range,accessible "23.7.3.5.1 General [mdspan.accessor.general]") of
|
||||
a given data handle and an accessor
|
||||
if, for each i in the range,
|
||||
the accessor policy's access function produces a valid reference to an object[.](#general-2.sentence-1)
|
||||
|
||||
[3](#general-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24215)
|
||||
|
||||
In [[mdspan.accessor.reqmts]](#reqmts "23.7.3.5.2 Requirements"),
|
||||
|
||||
- [(3.1)](#general-3.1)
|
||||
|
||||
A denotes an accessor policy[.](#general-3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#general-3.2)
|
||||
|
||||
a denotes a value of type A or const A[.](#general-3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#general-3.3)
|
||||
|
||||
p denotes a value of type A::data_handle_type or const A::data_handle_type[.](#general-3.3.sentence-1)
|
||||
[*Note [1](#general-note-1)*:
|
||||
The type A::data_handle_type need not be dereferenceable[.](#general-3.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(3.4)](#general-3.4)
|
||||
|
||||
n, i, and j each denote values of type size_t[.](#general-3.4.sentence-1)
|
||||
|
||||
#### [23.7.3.5.2](#reqmts) Requirements [[mdspan.accessor.reqmts]](mdspan.accessor.reqmts)
|
||||
|
||||
[1](#reqmts-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24234)
|
||||
|
||||
A type A meets the accessor policy requirements if
|
||||
|
||||
- [(1.1)](#reqmts-1.1)
|
||||
|
||||
A models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]"),
|
||||
|
||||
- [(1.2)](#reqmts-1.2)
|
||||
|
||||
is_nothrow_move_constructible_v<A> is true,
|
||||
|
||||
- [(1.3)](#reqmts-1.3)
|
||||
|
||||
is_nothrow_move_assignable_v<A> is true,
|
||||
|
||||
- [(1.4)](#reqmts-1.4)
|
||||
|
||||
is_nothrow_swappable_v<A> is true, and
|
||||
|
||||
- [(1.5)](#reqmts-1.5)
|
||||
|
||||
the following types and expressions
|
||||
are well-formed and have the specified semantics[.](#reqmts-1.sentence-1)
|
||||
|
||||
[ð](#reqmts-itemdecl:1)
|
||||
|
||||
`typename A::element_type
|
||||
`
|
||||
|
||||
[2](#reqmts-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24255)
|
||||
|
||||
*Result*: A complete object type that is not an abstract class type[.](#reqmts-2.sentence-1)
|
||||
|
||||
[ð](#reqmts-itemdecl:2)
|
||||
|
||||
`typename A::data_handle_type
|
||||
`
|
||||
|
||||
[3](#reqmts-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24265)
|
||||
|
||||
*Result*: A type that models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]"), and
|
||||
for which is_nothrow_move_constructible_v<A::data_handle_type> is true,is_nothrow_move_assignable_v<A::data_handle_type> is true, andis_nothrow_swappable_v<A::data_handle_type> is true[.](#reqmts-3.sentence-1)
|
||||
|
||||
[*Note [1](#reqmts-note-1)*:
|
||||
|
||||
The type of data_handle_type need not be element_type*[.](#reqmts-3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#reqmts-itemdecl:3)
|
||||
|
||||
`typename A::reference
|
||||
`
|
||||
|
||||
[4](#reqmts-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24281)
|
||||
|
||||
*Result*: A type that models[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_reference_with [concept.commonref]")<A::reference&&, A::element_type&>[.](#reqmts-4.sentence-1)
|
||||
|
||||
[*Note [2](#reqmts-note-2)*:
|
||||
|
||||
The type of reference need not be element_type&[.](#reqmts-4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#reqmts-itemdecl:4)
|
||||
|
||||
`typename A::offset_policy
|
||||
`
|
||||
|
||||
[5](#reqmts-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24295)
|
||||
|
||||
*Result*: A type OP such that:
|
||||
|
||||
- [(5.1)](#reqmts-5.1)
|
||||
|
||||
OP meets the accessor policy requirements,
|
||||
|
||||
- [(5.2)](#reqmts-5.2)
|
||||
|
||||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<OP, const A&> is modeled, and
|
||||
|
||||
- [(5.3)](#reqmts-5.3)
|
||||
|
||||
is_same_v<typename OP::element_type, typename A::element_type> is true[.](#reqmts-5.sentence-1)
|
||||
|
||||
[ð](#reqmts-itemdecl:5)
|
||||
|
||||
`a.access(p, i)
|
||||
`
|
||||
|
||||
[6](#reqmts-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24313)
|
||||
|
||||
*Result*: A::reference
|
||||
|
||||
[7](#reqmts-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24317)
|
||||
|
||||
*Remarks*: The expression is equality preserving[.](#reqmts-7.sentence-1)
|
||||
|
||||
[8](#reqmts-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24321)
|
||||
|
||||
[*Note [3](#reqmts-note-3)*:
|
||||
|
||||
Concrete accessor policies can impose preconditions for their access function[.](#reqmts-8.sentence-1)
|
||||
|
||||
However, they might not[.](#reqmts-8.sentence-2)
|
||||
|
||||
For example, an accessor wherep is span<A::element_type, dynamic_extent> andaccess(p, i) returns p[i % p.size()] does not need to impose a precondition on i[.](#reqmts-8.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#reqmts-itemdecl:6)
|
||||
|
||||
`a.offset(p, i)
|
||||
`
|
||||
|
||||
[9](#reqmts-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24337)
|
||||
|
||||
*Result*: A::offset_policy::data_handle_type
|
||||
|
||||
[10](#reqmts-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24341)
|
||||
|
||||
*Returns*: q such that for b being A::offset_policy(a), and
|
||||
any integer n for which [0, n) is
|
||||
an accessible range of p and a:
|
||||
|
||||
- [(10.1)](#reqmts-10.1)
|
||||
|
||||
[0,nâi) is an accessible range of q and b; and
|
||||
|
||||
- [(10.2)](#reqmts-10.2)
|
||||
|
||||
b.access(q, j) provides access to
|
||||
the same element as a.access(p, i + j),
|
||||
for every j in the range [0,nâi)[.](#reqmts-10.sentence-1)
|
||||
|
||||
[11](#reqmts-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24355)
|
||||
|
||||
*Remarks*: The expression is equality-preserving[.](#reqmts-11.sentence-1)
|
||||
|
||||
#### [23.7.3.5.3](#default) Class template default_accessor [[mdspan.accessor.default]](mdspan.accessor.default)
|
||||
|
||||
#### [23.7.3.5.3.1](#default.overview) Overview [[mdspan.accessor.default.overview]](mdspan.accessor.default.overview)
|
||||
|
||||
namespace std {template<class ElementType>struct default_accessor {using offset_policy = default_accessor; using element_type = ElementType; using reference = ElementType&; using data_handle_type = ElementType*; constexpr default_accessor() noexcept = default; template<class OtherElementType>constexpr default_accessor(default_accessor<OtherElementType>) noexcept; constexpr reference access(data_handle_type p, size_t i) const noexcept; constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; };}
|
||||
|
||||
[1](#default.overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24382)
|
||||
|
||||
default_accessor meets the accessor policy requirements[.](#default.overview-1.sentence-1)
|
||||
|
||||
[2](#default.overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24385)
|
||||
|
||||
ElementType is required to be a complete object type
|
||||
that is neither an abstract class type nor an array type[.](#default.overview-2.sentence-1)
|
||||
|
||||
[3](#default.overview-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24389)
|
||||
|
||||
Each specialization of default_accessor is
|
||||
a trivially copyable type that models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#default.overview-3.sentence-1)
|
||||
|
||||
[4](#default.overview-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24393)
|
||||
|
||||
[0,n) is an accessible range for
|
||||
an object p of type data_handle_type and
|
||||
an object of type default_accessor if and only if [p, p + n) is a valid range[.](#default.overview-4.sentence-1)
|
||||
|
||||
#### [23.7.3.5.3.2](#default.members) Members [[mdspan.accessor.default.members]](mdspan.accessor.default.members)
|
||||
|
||||
[ð](#lib:default_accessor,constructor)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
|
||||
`
|
||||
|
||||
[1](#default.members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24408)
|
||||
|
||||
*Constraints*: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#default.members-1.sentence-1)
|
||||
|
||||
[ð](#lib:access,default_accessor)
|
||||
|
||||
`constexpr reference access(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#default.members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24420)
|
||||
|
||||
*Effects*: Equivalent to: return p[i];
|
||||
|
||||
[ð](#lib:offset,default_accessor)
|
||||
|
||||
`constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[3](#default.members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24431)
|
||||
|
||||
*Effects*: Equivalent to: return p + i;
|
||||
|
||||
#### [23.7.3.5.4](#aligned) Class template aligned_accessor [[mdspan.accessor.aligned]](mdspan.accessor.aligned)
|
||||
|
||||
#### [23.7.3.5.4.1](#aligned.overview) Overview [[mdspan.accessor.aligned.overview]](mdspan.accessor.aligned.overview)
|
||||
|
||||
namespace std {template<class ElementType, size_t ByteAlignment>struct [aligned_accessor](#lib:aligned_accessor "23.7.3.5.4.1 Overview [mdspan.accessor.aligned.overview]") {using offset_policy = default_accessor<ElementType>; using element_type = ElementType; using reference = ElementType&; using data_handle_type = ElementType*; static constexpr size_t byte_alignment = ByteAlignment; constexpr aligned_accessor() noexcept = default; template<class OtherElementType, size_t OtherByteAlignment>constexpr aligned_accessor( aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept; template<class OtherElementType>constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept; template<class OtherElementType>constexpr operator default_accessor<OtherElementType>() const noexcept; constexpr reference access(data_handle_type p, size_t i) const noexcept; constexpr typename offset_policy::data_handle_type offset( data_handle_type p, size_t i) const noexcept; };}
|
||||
|
||||
[1](#aligned.overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24469)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(1.1)](#aligned.overview-1.1)
|
||||
|
||||
byte_alignment is a power of two, and
|
||||
|
||||
- [(1.2)](#aligned.overview-1.2)
|
||||
|
||||
byte_alignment >= alignof(ElementType) is true[.](#aligned.overview-1.sentence-1)
|
||||
|
||||
[2](#aligned.overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24476)
|
||||
|
||||
aligned_accessor meets the accessor policy requirements[.](#aligned.overview-2.sentence-1)
|
||||
|
||||
[3](#aligned.overview-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24479)
|
||||
|
||||
ElementType is required to be a complete object type
|
||||
that is neither an abstract class type nor an array type[.](#aligned.overview-3.sentence-1)
|
||||
|
||||
[4](#aligned.overview-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24483)
|
||||
|
||||
Each specialization of aligned_accessor is
|
||||
a trivially copyable type that models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#aligned.overview-4.sentence-1)
|
||||
|
||||
[5](#aligned.overview-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24487)
|
||||
|
||||
[0, n) is an accessible range
|
||||
for an object p of type data_handle_type and
|
||||
an object of type aligned_accessor if and only if
|
||||
|
||||
- [(5.1)](#aligned.overview-5.1)
|
||||
|
||||
[p, p + n) is a valid range, and,
|
||||
|
||||
- [(5.2)](#aligned.overview-5.2)
|
||||
|
||||
if n is greater than zero,
|
||||
then is_sufficiently_aligned<byte_alignment>(p) is true[.](#aligned.overview-5.sentence-1)
|
||||
|
||||
[6](#aligned.overview-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24499)
|
||||
|
||||
[*Example [1](#aligned.overview-example-1)*:
|
||||
|
||||
The following function compute uses is_sufficiently_aligned to check
|
||||
whether a given mdspan with default_accessor has
|
||||
a data handle with sufficient alignment
|
||||
to be used with aligned_accessor<float, 4 * sizeof(float)>[.](#aligned.overview-6.sentence-1)
|
||||
|
||||
If so, the function dispatches to
|
||||
a function compute_using_fourfold_overalignment that requires fourfold over-alignment of arrays,
|
||||
but can therefore use hardware-specific instructions,
|
||||
such as four-wide SIMD (Single Instruction Multiple Data) instructions[.](#aligned.overview-6.sentence-2)
|
||||
|
||||
Otherwise, compute dispatches to a
|
||||
possibly less optimized function compute_without_requiring_overalignment that has no over-alignment requirement[.](#aligned.overview-6.sentence-3)
|
||||
|
||||
void compute_using_fourfold_overalignment( std::mdspan<float, std::dims<1>, std::layout_right,
|
||||
std::aligned_accessor<float, 4 * alignof(float)>> x);
|
||||
|
||||
void compute_without_requiring_overalignment( std::mdspan<float, std::dims<1>, std::layout_right> x);
|
||||
|
||||
void compute(std::mdspan<float, std::dims<1>> x) {constexpr auto byte_alignment = 4 * sizeof(float); auto accessor = std::aligned_accessor<float, byte_alignment>{}; auto x_handle = x.data_handle(); if (std::is_sufficiently_aligned<byte_alignment>(x_handle)) { compute_using_fourfold_overalignment(std::mdspan{x_handle, x.mapping(), accessor}); } else { compute_without_requiring_overalignment(x); }} â *end example*]
|
||||
|
||||
#### [23.7.3.5.4.2](#aligned.members) Members [[mdspan.accessor.aligned.members]](mdspan.accessor.aligned.members)
|
||||
|
||||
[ð](#lib:aligned_accessor,constructor)
|
||||
|
||||
`template<class OtherElementType, size_t OtherByteAlignment>
|
||||
constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
|
||||
`
|
||||
|
||||
[1](#aligned.members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24545)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#aligned.members-1.1)
|
||||
|
||||
is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#aligned.members-1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#aligned.members-1.2)
|
||||
|
||||
OtherByteAlignment >= byte_alignment is true[.](#aligned.members-1.2.sentence-1)
|
||||
|
||||
[2](#aligned.members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24555)
|
||||
|
||||
*Effects*: None[.](#aligned.members-2.sentence-1)
|
||||
|
||||
[ð](#lib:aligned_accessor,constructor_)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept;
|
||||
`
|
||||
|
||||
[3](#aligned.members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24567)
|
||||
|
||||
*Constraints*: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#aligned.members-3.sentence-1)
|
||||
|
||||
[4](#aligned.members-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24572)
|
||||
|
||||
*Effects*: None[.](#aligned.members-4.sentence-1)
|
||||
|
||||
[ð](#lib:access,aligned_accessor)
|
||||
|
||||
`constexpr reference access(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#aligned.members-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24583)
|
||||
|
||||
*Preconditions*: [0, i + 1) is an accessible range for p and *this[.](#aligned.members-5.sentence-1)
|
||||
|
||||
[6](#aligned.members-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24587)
|
||||
|
||||
*Effects*: Equivalent to: return assume_aligned<byte_alignment>(p)[i];
|
||||
|
||||
[ð](#lib:operator_default_accessor,aligned_accessor)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr operator default_accessor<OtherElementType>() const noexcept;
|
||||
`
|
||||
|
||||
[7](#aligned.members-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24599)
|
||||
|
||||
*Constraints*: is_convertible_v<element_type(*)[], OtherElementType(*)[]> is true[.](#aligned.members-7.sentence-1)
|
||||
|
||||
[8](#aligned.members-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24604)
|
||||
|
||||
*Effects*: Equivalent to: return {};
|
||||
|
||||
[ð](#lib:offset,aligned_accessor)
|
||||
|
||||
`constexpr typename offset_policy::data_handle_type
|
||||
offset(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[9](#aligned.members-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24616)
|
||||
|
||||
*Preconditions*: [0, i + 1) is an accessible range for p and *this[.](#aligned.members-9.sentence-1)
|
||||
|
||||
[10](#aligned.members-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24620)
|
||||
|
||||
*Effects*: Equivalent to: return assume_aligned<byte_alignment>(p) + i;
|
||||
191
cppdraft/mdspan/accessor/aligned.md
Normal file
191
cppdraft/mdspan/accessor/aligned.md
Normal file
@@ -0,0 +1,191 @@
|
||||
[mdspan.accessor.aligned]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.aligned)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.aligned)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#aligned)
|
||||
|
||||
#### 23.7.3.5.4 Class template aligned_accessor [mdspan.accessor.aligned]
|
||||
|
||||
#### [23.7.3.5.4.1](#overview) Overview [[mdspan.accessor.aligned.overview]](mdspan.accessor.aligned.overview)
|
||||
|
||||
namespace std {template<class ElementType, size_t ByteAlignment>struct [aligned_accessor](#lib:aligned_accessor "23.7.3.5.4.1 Overview [mdspan.accessor.aligned.overview]") {using offset_policy = default_accessor<ElementType>; using element_type = ElementType; using reference = ElementType&; using data_handle_type = ElementType*; static constexpr size_t byte_alignment = ByteAlignment; constexpr aligned_accessor() noexcept = default; template<class OtherElementType, size_t OtherByteAlignment>constexpr aligned_accessor( aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept; template<class OtherElementType>constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept; template<class OtherElementType>constexpr operator default_accessor<OtherElementType>() const noexcept; constexpr reference access(data_handle_type p, size_t i) const noexcept; constexpr typename offset_policy::data_handle_type offset( data_handle_type p, size_t i) const noexcept; };}
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24469)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(1.1)](#overview-1.1)
|
||||
|
||||
byte_alignment is a power of two, and
|
||||
|
||||
- [(1.2)](#overview-1.2)
|
||||
|
||||
byte_alignment >= alignof(ElementType) is true[.](#overview-1.sentence-1)
|
||||
|
||||
[2](#overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24476)
|
||||
|
||||
aligned_accessor meets the accessor policy requirements[.](#overview-2.sentence-1)
|
||||
|
||||
[3](#overview-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24479)
|
||||
|
||||
ElementType is required to be a complete object type
|
||||
that is neither an abstract class type nor an array type[.](#overview-3.sentence-1)
|
||||
|
||||
[4](#overview-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24483)
|
||||
|
||||
Each specialization of aligned_accessor is
|
||||
a trivially copyable type that models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#overview-4.sentence-1)
|
||||
|
||||
[5](#overview-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24487)
|
||||
|
||||
[0, n) is an accessible range
|
||||
for an object p of type data_handle_type and
|
||||
an object of type aligned_accessor if and only if
|
||||
|
||||
- [(5.1)](#overview-5.1)
|
||||
|
||||
[p, p + n) is a valid range, and,
|
||||
|
||||
- [(5.2)](#overview-5.2)
|
||||
|
||||
if n is greater than zero,
|
||||
then is_sufficiently_aligned<byte_alignment>(p) is true[.](#overview-5.sentence-1)
|
||||
|
||||
[6](#overview-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24499)
|
||||
|
||||
[*Example [1](#overview-example-1)*:
|
||||
|
||||
The following function compute uses is_sufficiently_aligned to check
|
||||
whether a given mdspan with default_accessor has
|
||||
a data handle with sufficient alignment
|
||||
to be used with aligned_accessor<float, 4 * sizeof(float)>[.](#overview-6.sentence-1)
|
||||
|
||||
If so, the function dispatches to
|
||||
a function compute_using_fourfold_overalignment that requires fourfold over-alignment of arrays,
|
||||
but can therefore use hardware-specific instructions,
|
||||
such as four-wide SIMD (Single Instruction Multiple Data) instructions[.](#overview-6.sentence-2)
|
||||
|
||||
Otherwise, compute dispatches to a
|
||||
possibly less optimized function compute_without_requiring_overalignment that has no over-alignment requirement[.](#overview-6.sentence-3)
|
||||
|
||||
void compute_using_fourfold_overalignment( std::mdspan<float, std::dims<1>, std::layout_right,
|
||||
std::aligned_accessor<float, 4 * alignof(float)>> x);
|
||||
|
||||
void compute_without_requiring_overalignment( std::mdspan<float, std::dims<1>, std::layout_right> x);
|
||||
|
||||
void compute(std::mdspan<float, std::dims<1>> x) {constexpr auto byte_alignment = 4 * sizeof(float); auto accessor = std::aligned_accessor<float, byte_alignment>{}; auto x_handle = x.data_handle(); if (std::is_sufficiently_aligned<byte_alignment>(x_handle)) { compute_using_fourfold_overalignment(std::mdspan{x_handle, x.mapping(), accessor}); } else { compute_without_requiring_overalignment(x); }} â *end example*]
|
||||
|
||||
#### [23.7.3.5.4.2](#members) Members [[mdspan.accessor.aligned.members]](mdspan.accessor.aligned.members)
|
||||
|
||||
[ð](#lib:aligned_accessor,constructor)
|
||||
|
||||
`template<class OtherElementType, size_t OtherByteAlignment>
|
||||
constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
|
||||
`
|
||||
|
||||
[1](#members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24545)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#members-1.1)
|
||||
|
||||
is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#members-1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#members-1.2)
|
||||
|
||||
OtherByteAlignment >= byte_alignment is true[.](#members-1.2.sentence-1)
|
||||
|
||||
[2](#members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24555)
|
||||
|
||||
*Effects*: None[.](#members-2.sentence-1)
|
||||
|
||||
[ð](#lib:aligned_accessor,constructor_)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept;
|
||||
`
|
||||
|
||||
[3](#members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24567)
|
||||
|
||||
*Constraints*: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#members-3.sentence-1)
|
||||
|
||||
[4](#members-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24572)
|
||||
|
||||
*Effects*: None[.](#members-4.sentence-1)
|
||||
|
||||
[ð](#lib:access,aligned_accessor)
|
||||
|
||||
`constexpr reference access(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#members-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24583)
|
||||
|
||||
*Preconditions*: [0, i + 1) is an accessible range for p and *this[.](#members-5.sentence-1)
|
||||
|
||||
[6](#members-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24587)
|
||||
|
||||
*Effects*: Equivalent to: return assume_aligned<byte_alignment>(p)[i];
|
||||
|
||||
[ð](#lib:operator_default_accessor,aligned_accessor)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr operator default_accessor<OtherElementType>() const noexcept;
|
||||
`
|
||||
|
||||
[7](#members-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24599)
|
||||
|
||||
*Constraints*: is_convertible_v<element_type(*)[], OtherElementType(*)[]> is true[.](#members-7.sentence-1)
|
||||
|
||||
[8](#members-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24604)
|
||||
|
||||
*Effects*: Equivalent to: return {};
|
||||
|
||||
[ð](#lib:offset,aligned_accessor)
|
||||
|
||||
`constexpr typename offset_policy::data_handle_type
|
||||
offset(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[9](#members-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24616)
|
||||
|
||||
*Preconditions*: [0, i + 1) is an accessible range for p and *this[.](#members-9.sentence-1)
|
||||
|
||||
[10](#members-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24620)
|
||||
|
||||
*Effects*: Equivalent to: return assume_aligned<byte_alignment>(p) + i;
|
||||
110
cppdraft/mdspan/accessor/aligned/members.md
Normal file
110
cppdraft/mdspan/accessor/aligned/members.md
Normal file
@@ -0,0 +1,110 @@
|
||||
[mdspan.accessor.aligned.members]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.aligned.members)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.aligned.members)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#aligned.members)
|
||||
|
||||
#### 23.7.3.5.4 Class template aligned_accessor [[mdspan.accessor.aligned]](mdspan.accessor.aligned#members)
|
||||
|
||||
#### 23.7.3.5.4.2 Members [mdspan.accessor.aligned.members]
|
||||
|
||||
[ð](#lib:aligned_accessor,constructor)
|
||||
|
||||
`template<class OtherElementType, size_t OtherByteAlignment>
|
||||
constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24545)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
OtherByteAlignment >= byte_alignment is true[.](#1.2.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24555)
|
||||
|
||||
*Effects*: None[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:aligned_accessor,constructor_)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24567)
|
||||
|
||||
*Constraints*: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24572)
|
||||
|
||||
*Effects*: None[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:access,aligned_accessor)
|
||||
|
||||
`constexpr reference access(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24583)
|
||||
|
||||
*Preconditions*: [0, i + 1) is an accessible range for p and *this[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24587)
|
||||
|
||||
*Effects*: Equivalent to: return assume_aligned<byte_alignment>(p)[i];
|
||||
|
||||
[ð](#lib:operator_default_accessor,aligned_accessor)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr operator default_accessor<OtherElementType>() const noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24599)
|
||||
|
||||
*Constraints*: is_convertible_v<element_type(*)[], OtherElementType(*)[]> is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24604)
|
||||
|
||||
*Effects*: Equivalent to: return {};
|
||||
|
||||
[ð](#lib:offset,aligned_accessor)
|
||||
|
||||
`constexpr typename offset_policy::data_handle_type
|
||||
offset(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24616)
|
||||
|
||||
*Preconditions*: [0, i + 1) is an accessible range for p and *this[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24620)
|
||||
|
||||
*Effects*: Equivalent to: return assume_aligned<byte_alignment>(p) + i;
|
||||
92
cppdraft/mdspan/accessor/aligned/overview.md
Normal file
92
cppdraft/mdspan/accessor/aligned/overview.md
Normal file
@@ -0,0 +1,92 @@
|
||||
[mdspan.accessor.aligned.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.aligned.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.aligned.overview)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#aligned.overview)
|
||||
|
||||
#### 23.7.3.5.4 Class template aligned_accessor [[mdspan.accessor.aligned]](mdspan.accessor.aligned#overview)
|
||||
|
||||
#### 23.7.3.5.4.1 Overview [mdspan.accessor.aligned.overview]
|
||||
|
||||
namespace std {template<class ElementType, size_t ByteAlignment>struct [aligned_accessor](#lib:aligned_accessor "23.7.3.5.4.1 Overview [mdspan.accessor.aligned.overview]") {using offset_policy = default_accessor<ElementType>; using element_type = ElementType; using reference = ElementType&; using data_handle_type = ElementType*; static constexpr size_t byte_alignment = ByteAlignment; constexpr aligned_accessor() noexcept = default; template<class OtherElementType, size_t OtherByteAlignment>constexpr aligned_accessor( aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept; template<class OtherElementType>constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept; template<class OtherElementType>constexpr operator default_accessor<OtherElementType>() const noexcept; constexpr reference access(data_handle_type p, size_t i) const noexcept; constexpr typename offset_policy::data_handle_type offset( data_handle_type p, size_t i) const noexcept; };}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24469)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
byte_alignment is a power of two, and
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
byte_alignment >= alignof(ElementType) is true[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24476)
|
||||
|
||||
aligned_accessor meets the accessor policy requirements[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24479)
|
||||
|
||||
ElementType is required to be a complete object type
|
||||
that is neither an abstract class type nor an array type[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24483)
|
||||
|
||||
Each specialization of aligned_accessor is
|
||||
a trivially copyable type that models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24487)
|
||||
|
||||
[0, n) is an accessible range
|
||||
for an object p of type data_handle_type and
|
||||
an object of type aligned_accessor if and only if
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
[p, p + n) is a valid range, and,
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
if n is greater than zero,
|
||||
then is_sufficiently_aligned<byte_alignment>(p) is true[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24499)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
The following function compute uses is_sufficiently_aligned to check
|
||||
whether a given mdspan with default_accessor has
|
||||
a data handle with sufficient alignment
|
||||
to be used with aligned_accessor<float, 4 * sizeof(float)>[.](#6.sentence-1)
|
||||
|
||||
If so, the function dispatches to
|
||||
a function compute_using_fourfold_overalignment that requires fourfold over-alignment of arrays,
|
||||
but can therefore use hardware-specific instructions,
|
||||
such as four-wide SIMD (Single Instruction Multiple Data) instructions[.](#6.sentence-2)
|
||||
|
||||
Otherwise, compute dispatches to a
|
||||
possibly less optimized function compute_without_requiring_overalignment that has no over-alignment requirement[.](#6.sentence-3)
|
||||
|
||||
void compute_using_fourfold_overalignment( std::mdspan<float, std::dims<1>, std::layout_right,
|
||||
std::aligned_accessor<float, 4 * alignof(float)>> x);
|
||||
|
||||
void compute_without_requiring_overalignment( std::mdspan<float, std::dims<1>, std::layout_right> x);
|
||||
|
||||
void compute(std::mdspan<float, std::dims<1>> x) {constexpr auto byte_alignment = 4 * sizeof(float); auto accessor = std::aligned_accessor<float, byte_alignment>{}; auto x_handle = x.data_handle(); if (std::is_sufficiently_aligned<byte_alignment>(x_handle)) { compute_using_fourfold_overalignment(std::mdspan{x_handle, x.mapping(), accessor}); } else { compute_without_requiring_overalignment(x); }} â *end example*]
|
||||
79
cppdraft/mdspan/accessor/default.md
Normal file
79
cppdraft/mdspan/accessor/default.md
Normal file
@@ -0,0 +1,79 @@
|
||||
[mdspan.accessor.default]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.default)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.default)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#default)
|
||||
|
||||
#### 23.7.3.5.3 Class template default_accessor [mdspan.accessor.default]
|
||||
|
||||
#### [23.7.3.5.3.1](#overview) Overview [[mdspan.accessor.default.overview]](mdspan.accessor.default.overview)
|
||||
|
||||
namespace std {template<class ElementType>struct default_accessor {using offset_policy = default_accessor; using element_type = ElementType; using reference = ElementType&; using data_handle_type = ElementType*; constexpr default_accessor() noexcept = default; template<class OtherElementType>constexpr default_accessor(default_accessor<OtherElementType>) noexcept; constexpr reference access(data_handle_type p, size_t i) const noexcept; constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; };}
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24382)
|
||||
|
||||
default_accessor meets the accessor policy requirements[.](#overview-1.sentence-1)
|
||||
|
||||
[2](#overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24385)
|
||||
|
||||
ElementType is required to be a complete object type
|
||||
that is neither an abstract class type nor an array type[.](#overview-2.sentence-1)
|
||||
|
||||
[3](#overview-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24389)
|
||||
|
||||
Each specialization of default_accessor is
|
||||
a trivially copyable type that models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#overview-3.sentence-1)
|
||||
|
||||
[4](#overview-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24393)
|
||||
|
||||
[0,n) is an accessible range for
|
||||
an object p of type data_handle_type and
|
||||
an object of type default_accessor if and only if [p, p + n) is a valid range[.](#overview-4.sentence-1)
|
||||
|
||||
#### [23.7.3.5.3.2](#members) Members [[mdspan.accessor.default.members]](mdspan.accessor.default.members)
|
||||
|
||||
[ð](#lib:default_accessor,constructor)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
|
||||
`
|
||||
|
||||
[1](#members-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24408)
|
||||
|
||||
*Constraints*: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#members-1.sentence-1)
|
||||
|
||||
[ð](#lib:access,default_accessor)
|
||||
|
||||
`constexpr reference access(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#members-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24420)
|
||||
|
||||
*Effects*: Equivalent to: return p[i];
|
||||
|
||||
[ð](#lib:offset,default_accessor)
|
||||
|
||||
`constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[3](#members-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24431)
|
||||
|
||||
*Effects*: Equivalent to: return p + i;
|
||||
47
cppdraft/mdspan/accessor/default/members.md
Normal file
47
cppdraft/mdspan/accessor/default/members.md
Normal file
@@ -0,0 +1,47 @@
|
||||
[mdspan.accessor.default.members]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.default.members)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.default.members)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#default.members)
|
||||
|
||||
#### 23.7.3.5.3 Class template default_accessor [[mdspan.accessor.default]](mdspan.accessor.default#members)
|
||||
|
||||
#### 23.7.3.5.3.2 Members [mdspan.accessor.default.members]
|
||||
|
||||
[ð](#lib:default_accessor,constructor)
|
||||
|
||||
`template<class OtherElementType>
|
||||
constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24408)
|
||||
|
||||
*Constraints*: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:access,default_accessor)
|
||||
|
||||
`constexpr reference access(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24420)
|
||||
|
||||
*Effects*: Equivalent to: return p[i];
|
||||
|
||||
[ð](#lib:offset,default_accessor)
|
||||
|
||||
`constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24431)
|
||||
|
||||
*Effects*: Equivalent to: return p + i;
|
||||
43
cppdraft/mdspan/accessor/default/overview.md
Normal file
43
cppdraft/mdspan/accessor/default/overview.md
Normal file
@@ -0,0 +1,43 @@
|
||||
[mdspan.accessor.default.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.default.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.default.overview)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#default.overview)
|
||||
|
||||
#### 23.7.3.5.3 Class template default_accessor [[mdspan.accessor.default]](mdspan.accessor.default#overview)
|
||||
|
||||
#### 23.7.3.5.3.1 Overview [mdspan.accessor.default.overview]
|
||||
|
||||
namespace std {template<class ElementType>struct default_accessor {using offset_policy = default_accessor; using element_type = ElementType; using reference = ElementType&; using data_handle_type = ElementType*; constexpr default_accessor() noexcept = default; template<class OtherElementType>constexpr default_accessor(default_accessor<OtherElementType>) noexcept; constexpr reference access(data_handle_type p, size_t i) const noexcept; constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept; };}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24382)
|
||||
|
||||
default_accessor meets the accessor policy requirements[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24385)
|
||||
|
||||
ElementType is required to be a complete object type
|
||||
that is neither an abstract class type nor an array type[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24389)
|
||||
|
||||
Each specialization of default_accessor is
|
||||
a trivially copyable type that models [semiregular](concepts.object#concept:semiregular "18.6 Object concepts [concepts.object]")[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24393)
|
||||
|
||||
[0,n) is an accessible range for
|
||||
an object p of type data_handle_type and
|
||||
an object of type default_accessor if and only if [p, p + n) is a valid range[.](#4.sentence-1)
|
||||
53
cppdraft/mdspan/accessor/general.md
Normal file
53
cppdraft/mdspan/accessor/general.md
Normal file
@@ -0,0 +1,53 @@
|
||||
[mdspan.accessor.general]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.general)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.general)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#general)
|
||||
|
||||
#### 23.7.3.5.1 General [mdspan.accessor.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24204)
|
||||
|
||||
An [*accessor policy*](#def:accessor_policy "23.7.3.5.1 General [mdspan.accessor.general]") defines types and operations by which
|
||||
a reference to a single object is created
|
||||
from an abstract data handle to a number of such objects and an index[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24209)
|
||||
|
||||
A range of indices [0,N) is an [*accessible range*](#def:range,accessible "23.7.3.5.1 General [mdspan.accessor.general]") of
|
||||
a given data handle and an accessor
|
||||
if, for each i in the range,
|
||||
the accessor policy's access function produces a valid reference to an object[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24215)
|
||||
|
||||
In [[mdspan.accessor.reqmts]](mdspan.accessor.reqmts "23.7.3.5.2 Requirements"),
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
A denotes an accessor policy[.](#3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
a denotes a value of type A or const A[.](#3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
p denotes a value of type A::data_handle_type or const A::data_handle_type[.](#3.3.sentence-1)
|
||||
[*Note [1](#note-1)*:
|
||||
The type A::data_handle_type need not be dereferenceable[.](#3.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
n, i, and j each denote values of type size_t[.](#3.4.sentence-1)
|
||||
173
cppdraft/mdspan/accessor/reqmts.md
Normal file
173
cppdraft/mdspan/accessor/reqmts.md
Normal file
@@ -0,0 +1,173 @@
|
||||
[mdspan.accessor.reqmts]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.accessor.reqmts)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.accessor.reqmts)
|
||||
|
||||
#### 23.7.3.5 Accessor policy [[mdspan.accessor]](mdspan.accessor#reqmts)
|
||||
|
||||
#### 23.7.3.5.2 Requirements [mdspan.accessor.reqmts]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24234)
|
||||
|
||||
A type A meets the accessor policy requirements if
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
A models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]"),
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
is_nothrow_move_constructible_v<A> is true,
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
is_nothrow_move_assignable_v<A> is true,
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
is_nothrow_swappable_v<A> is true, and
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
the following types and expressions
|
||||
are well-formed and have the specified semantics[.](#1.sentence-1)
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`typename A::element_type
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24255)
|
||||
|
||||
*Result*: A complete object type that is not an abstract class type[.](#2.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`typename A::data_handle_type
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24265)
|
||||
|
||||
*Result*: A type that models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]"), and
|
||||
for which is_nothrow_move_constructible_v<A::data_handle_type> is true,is_nothrow_move_assignable_v<A::data_handle_type> is true, andis_nothrow_swappable_v<A::data_handle_type> is true[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
The type of data_handle_type need not be element_type*[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`typename A::reference
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24281)
|
||||
|
||||
*Result*: A type that models[common_reference_with](concept.commonref#concept:common_reference_with "18.4.5 Concept common_reference_with [concept.commonref]")<A::reference&&, A::element_type&>[.](#4.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
The type of reference need not be element_type&[.](#4.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:4)
|
||||
|
||||
`typename A::offset_policy
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24295)
|
||||
|
||||
*Result*: A type OP such that:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
OP meets the accessor policy requirements,
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<OP, const A&> is modeled, and
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
is_same_v<typename OP::element_type, typename A::element_type> is true[.](#5.sentence-1)
|
||||
|
||||
[ð](#itemdecl:5)
|
||||
|
||||
`a.access(p, i)
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24313)
|
||||
|
||||
*Result*: A::reference
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24317)
|
||||
|
||||
*Remarks*: The expression is equality preserving[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24321)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
Concrete accessor policies can impose preconditions for their access function[.](#8.sentence-1)
|
||||
|
||||
However, they might not[.](#8.sentence-2)
|
||||
|
||||
For example, an accessor wherep is span<A::element_type, dynamic_extent> andaccess(p, i) returns p[i % p.size()] does not need to impose a precondition on i[.](#8.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:6)
|
||||
|
||||
`a.offset(p, i)
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24337)
|
||||
|
||||
*Result*: A::offset_policy::data_handle_type
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24341)
|
||||
|
||||
*Returns*: q such that for b being A::offset_policy(a), and
|
||||
any integer n for which [0, n) is
|
||||
an accessible range of p and a:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
[0,nâi) is an accessible range of q and b; and
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
b.access(q, j) provides access to
|
||||
the same element as a.access(p, i + j),
|
||||
for every j in the range [0,nâi)[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24355)
|
||||
|
||||
*Remarks*: The expression is equality-preserving[.](#11.sentence-1)
|
||||
454
cppdraft/mdspan/extents.md
Normal file
454
cppdraft/mdspan/extents.md
Normal file
@@ -0,0 +1,454 @@
|
||||
[mdspan.extents]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents)
|
||||
|
||||
#### 23.7.3.3 Class template extents [mdspan.extents]
|
||||
|
||||
#### [23.7.3.3.1](#overview) Overview [[mdspan.extents.overview]](mdspan.extents.overview)
|
||||
|
||||
The class template extents represents
|
||||
a multidimensional index space of rank equal to sizeof...(Extents)[.](#overview-sentence-1)
|
||||
|
||||
In [[views]](views "23.7 Views"),extents is used synonymously with multidimensional index space[.](#overview-sentence-2)
|
||||
|
||||
namespace std {template<class IndexType, size_t... Extents>class [extents](#lib:extents "23.7.3.3.1 Overview [mdspan.extents.overview]") {public:using index_type = IndexType; using size_type = make_unsigned_t<index_type>; using rank_type = size_t; // [[mdspan.extents.obs]](#obs "23.7.3.3.4 Observers of the multidimensional index space"), 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]](#cons "23.7.3.3.3 Constructors"), 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]](#cmp "23.7.3.3.5 Comparison operators"), comparison operatorstemplate<class OtherIndexType, size_t... OtherExtents>friend constexpr bool operator==(const extents&, const extents<OtherIndexType, OtherExtents...>&) noexcept; // [[mdspan.extents.expo]](#expo "23.7.3.3.2 Exposition-only helpers"), exposition-only helpersconstexpr 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*;}
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21152)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(1.1)](#overview-1.1)
|
||||
|
||||
IndexType is a signed or unsigned integer type, and
|
||||
|
||||
- [(1.2)](#overview-1.2)
|
||||
|
||||
each element of Extents is either equal to dynamic_extent, or
|
||||
is representable as a value of type IndexType[.](#overview-1.sentence-1)
|
||||
|
||||
[2](#overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21162)
|
||||
|
||||
Each specialization of extents models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") and
|
||||
is trivially copyable[.](#overview-2.sentence-1)
|
||||
|
||||
[3](#overview-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21166)
|
||||
|
||||
Let Er be the rth element of Extents[.](#overview-3.sentence-1)
|
||||
|
||||
Er is a [*dynamic extent*](#def:extent,dynamic "23.7.3.3.1 Overview [mdspan.extents.overview]") if it is equal to dynamic_extent,
|
||||
otherwise Er is a [*static extent*](#def:extent,static "23.7.3.3.1 Overview [mdspan.extents.overview]")[.](#overview-3.sentence-2)
|
||||
|
||||
Let Dr be the value of *dynamic-extents*[*dynamic-index*(r)] if Er is a dynamic extent,
|
||||
otherwise Er[.](#overview-3.sentence-3)
|
||||
|
||||
[4](#overview-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21174)
|
||||
|
||||
The rth interval of the multidimensional index space
|
||||
represented by an extents object is [0,Dr)[.](#overview-4.sentence-1)
|
||||
|
||||
#### [23.7.3.3.2](#expo) Exposition-only helpers [[mdspan.extents.expo]](mdspan.extents.expo)
|
||||
|
||||
[ð](#expo-itemdecl:1)
|
||||
|
||||
`static constexpr rank_type dynamic-index(rank_type i) noexcept;
|
||||
`
|
||||
|
||||
[1](#expo-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21185)
|
||||
|
||||
*Preconditions*: i <= rank() is true[.](#expo-1.sentence-1)
|
||||
|
||||
[2](#expo-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21189)
|
||||
|
||||
*Returns*: The number of Er with r<i for which Er is a dynamic extent[.](#expo-2.sentence-1)
|
||||
|
||||
[ð](#expo-itemdecl:2)
|
||||
|
||||
`static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
|
||||
`
|
||||
|
||||
[3](#expo-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21199)
|
||||
|
||||
*Preconditions*: i < rank_dynamic() is true[.](#expo-3.sentence-1)
|
||||
|
||||
[4](#expo-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21203)
|
||||
|
||||
*Returns*: The minimum value of r such that *dynamic-index*(r + 1) == i + 1 is true[.](#expo-4.sentence-1)
|
||||
|
||||
[ð](#expo-itemdecl:3)
|
||||
|
||||
`constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#expo-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21214)
|
||||
|
||||
*Preconditions*: i <= rank() is true[.](#expo-5.sentence-1)
|
||||
|
||||
[6](#expo-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21218)
|
||||
|
||||
*Returns*: If i > 0 is true,
|
||||
the product of extent(k) for all k in the range [0, i),
|
||||
otherwise 1[.](#expo-6.sentence-1)
|
||||
|
||||
[ð](#expo-itemdecl:4)
|
||||
|
||||
`constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[7](#expo-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21230)
|
||||
|
||||
*Preconditions*: i < rank() is true[.](#expo-7.sentence-1)
|
||||
|
||||
[8](#expo-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21234)
|
||||
|
||||
*Returns*: If i + 1 < rank() is true,
|
||||
the product of extent(k) for all k in the range [i + 1, rank()),
|
||||
otherwise 1[.](#expo-8.sentence-1)
|
||||
|
||||
[ð](#expo-itemdecl:5)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
static constexpr auto index-cast(OtherIndexType&& i) noexcept;
|
||||
`
|
||||
|
||||
[9](#expo-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21248)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(9.1)](#expo-9.1)
|
||||
|
||||
If OtherIndexType is an integral type other than bool,
|
||||
then equivalent to return i;,
|
||||
|
||||
- [(9.2)](#expo-9.2)
|
||||
|
||||
otherwise, equivalent to return static_cast<index_type>(i);[.](#expo-9.sentence-1)
|
||||
|
||||
[*Note [1](#expo-note-1)*:
|
||||
|
||||
This function will always return an integral type other than bool[.](#expo-9.sentence-2)
|
||||
|
||||
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[.](#expo-9.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.3.3](#cons) Constructors [[mdspan.extents.cons]](mdspan.extents.cons)
|
||||
|
||||
[ð](#lib:extents,constructor)
|
||||
|
||||
`template<class OtherIndexType, size_t... OtherExtents>
|
||||
constexpr explicit(see below)
|
||||
extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;
|
||||
`
|
||||
|
||||
[1](#cons-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21276)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#cons-1.1)
|
||||
|
||||
sizeof...(OtherExtents) == rank() is true[.](#cons-1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#cons-1.2)
|
||||
|
||||
((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents ==
|
||||
Extents) && ...) is true[.](#cons-1.2.sentence-1)
|
||||
|
||||
[2](#cons-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21285)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(2.1)](#cons-2.1)
|
||||
|
||||
other.extent(r) equals Er for each r for which Er is a static extent, and
|
||||
|
||||
- [(2.2)](#cons-2.2)
|
||||
|
||||
either
|
||||
* [(2.2.1)](#cons-2.2.1)
|
||||
|
||||
sizeof...(OtherExtents) is zero, or
|
||||
|
||||
* [(2.2.2)](#cons-2.2.2)
|
||||
|
||||
other.extent(r) is representable as
|
||||
a value of type index_type for every rank index r of other[.](#cons-2.sentence-1)
|
||||
|
||||
[3](#cons-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21302)
|
||||
|
||||
*Postconditions*: *this == other is true[.](#cons-3.sentence-1)
|
||||
|
||||
[4](#cons-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21306)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:(((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||(numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
|
||||
|
||||
[ð](#lib:extents,constructor_)
|
||||
|
||||
`template<class... OtherIndexTypes>
|
||||
constexpr explicit extents(OtherIndexTypes... exts) noexcept;
|
||||
`
|
||||
|
||||
[5](#cons-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21322)
|
||||
|
||||
Let N be sizeof...(OtherIndexTypes),
|
||||
and let exts_arr bearray<index_type, N>{static_cast<
|
||||
index_type>(std::move(exts))...}[.](#cons-5.sentence-1)
|
||||
|
||||
[6](#cons-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21327)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#cons-6.1)
|
||||
|
||||
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
|
||||
|
||||
- [(6.2)](#cons-6.2)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
|
||||
|
||||
- [(6.3)](#cons-6.3)
|
||||
|
||||
N == rank_dynamic() || N == rank() is true[.](#cons-6.sentence-1)
|
||||
[*Note [1](#cons-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[.](#cons-6.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[7](#cons-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21343)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(7.1)](#cons-7.1)
|
||||
|
||||
If N != rank_dynamic() is true,exts_arr[r] equals Er for each r for which Er is a static extent, and
|
||||
|
||||
- [(7.2)](#cons-7.2)
|
||||
|
||||
either
|
||||
* [(7.2.1)](#cons-7.2.1)
|
||||
|
||||
sizeof...(exts) == 0 is true, or
|
||||
|
||||
* [(7.2.2)](#cons-7.2.2)
|
||||
|
||||
each element of exts is representable
|
||||
as a nonnegative value of type index_type[.](#cons-7.sentence-1)
|
||||
|
||||
[8](#cons-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21361)
|
||||
|
||||
*Postconditions*: *this == extents(exts_arr) is true[.](#cons-8.sentence-1)
|
||||
|
||||
[ð](#lib:extents,constructor__)
|
||||
|
||||
`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](#cons-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21377)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(9.1)](#cons-9.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true,
|
||||
|
||||
- [(9.2)](#cons-9.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
|
||||
|
||||
- [(9.3)](#cons-9.3)
|
||||
|
||||
N == rank_dynamic() || N == rank() is true[.](#cons-9.sentence-1)
|
||||
|
||||
[10](#cons-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21388)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(10.1)](#cons-10.1)
|
||||
|
||||
If N != rank_dynamic() is true,exts[r] equals Er for each r for which Er is a static extent, and
|
||||
|
||||
- [(10.2)](#cons-10.2)
|
||||
|
||||
either
|
||||
* [(10.2.1)](#cons-10.2.1)
|
||||
|
||||
N is zero, or
|
||||
|
||||
* [(10.2.2)](#cons-10.2.2)
|
||||
|
||||
exts[r] is representable
|
||||
as a nonnegative value of type index_type for every rank index r[.](#cons-10.sentence-1)
|
||||
|
||||
[11](#cons-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21405)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(11.1)](#cons-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])[.](#cons-11.1.sentence-1)
|
||||
|
||||
- [(11.2)](#cons-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)])[.](#cons-11.2.sentence-1)
|
||||
|
||||
[ð](#lib:extents,constructor___)
|
||||
|
||||
`template<class... Integrals>
|
||||
explicit extents(Integrals...) -> see below;
|
||||
`
|
||||
|
||||
[12](#cons-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21427)
|
||||
|
||||
*Constraints*: (is_convertible_v<Integrals, size_t> && ...) is true[.](#cons-12.sentence-1)
|
||||
|
||||
[13](#cons-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21431)
|
||||
|
||||
*Remarks*: The deduced type is extents<size_t, [*maybe-static-ext*](span.syn#concept:maybe-static-ext "23.7.2.1 Header <span> synopsis [span.syn]")<Integrals>...>[.](#cons-13.sentence-1)
|
||||
|
||||
#### [23.7.3.3.4](#obs) Observers of the multidimensional index space [[mdspan.extents.obs]](mdspan.extents.obs)
|
||||
|
||||
[ð](#lib:static_extent,extents)
|
||||
|
||||
`static constexpr size_t static_extent(rank_type i) noexcept;
|
||||
`
|
||||
|
||||
[1](#obs-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21444)
|
||||
|
||||
*Preconditions*: i < rank() is true[.](#obs-1.sentence-1)
|
||||
|
||||
[2](#obs-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21448)
|
||||
|
||||
*Returns*: Ei[.](#obs-2.sentence-1)
|
||||
|
||||
[ð](#lib:extent,extents)
|
||||
|
||||
`constexpr index_type extent(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[3](#obs-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21459)
|
||||
|
||||
*Preconditions*: i < rank() is true[.](#obs-3.sentence-1)
|
||||
|
||||
[4](#obs-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21463)
|
||||
|
||||
*Returns*: Di[.](#obs-4.sentence-1)
|
||||
|
||||
#### [23.7.3.3.5](#cmp) Comparison operators [[mdspan.extents.cmp]](mdspan.extents.cmp)
|
||||
|
||||
[ð](#lib:operator==,extents)
|
||||
|
||||
`template<class OtherIndexType, size_t... OtherExtents>
|
||||
friend constexpr bool operator==(const extents& lhs,
|
||||
const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
|
||||
`
|
||||
|
||||
[1](#cmp-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21478)
|
||||
|
||||
*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[.](#cmp-1.sentence-1)
|
||||
|
||||
#### [23.7.3.3.6](#dextents) Alias template dextents [[mdspan.extents.dextents]](mdspan.extents.dextents)
|
||||
|
||||
[ð](#lib:dextents)
|
||||
|
||||
`template<class IndexType, size_t Rank>
|
||||
using dextents = see below;
|
||||
`
|
||||
|
||||
[1](#dextents-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21495)
|
||||
|
||||
*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[.](#dextents-1.sentence-1)
|
||||
|
||||
#### [23.7.3.3.7](#dims) Alias template dims [[mdspan.extents.dims]](mdspan.extents.dims)
|
||||
|
||||
[ð](#lib:dims)
|
||||
|
||||
`template<size_t Rank, class IndexType = size_t>
|
||||
using dims = see below;
|
||||
`
|
||||
|
||||
[1](#dims-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21511)
|
||||
|
||||
*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[.](#dims-1.sentence-1)
|
||||
26
cppdraft/mdspan/extents/cmp.md
Normal file
26
cppdraft/mdspan/extents/cmp.md
Normal file
@@ -0,0 +1,26 @@
|
||||
[mdspan.extents.cmp]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.cmp)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.cmp)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#cmp)
|
||||
|
||||
#### 23.7.3.3.5 Comparison operators [mdspan.extents.cmp]
|
||||
|
||||
[ð](#lib:operator==,extents)
|
||||
|
||||
`template<class OtherIndexType, size_t... OtherExtents>
|
||||
friend constexpr bool operator==(const extents& lhs,
|
||||
const extents<OtherIndexType, OtherExtents...>& rhs) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21478)
|
||||
|
||||
*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[.](#1.sentence-1)
|
||||
217
cppdraft/mdspan/extents/cons.md
Normal file
217
cppdraft/mdspan/extents/cons.md
Normal file
@@ -0,0 +1,217 @@
|
||||
[mdspan.extents.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.cons)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#cons)
|
||||
|
||||
#### 23.7.3.3.3 Constructors [mdspan.extents.cons]
|
||||
|
||||
[ð](#lib:extents,constructor)
|
||||
|
||||
`template<class OtherIndexType, size_t... OtherExtents>
|
||||
constexpr explicit(see below)
|
||||
extents(const extents<OtherIndexType, OtherExtents...>& other) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21276)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
sizeof...(OtherExtents) == rank() is true[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
((OtherExtents == dynamic_extent || Extents == dynamic_extent || OtherExtents ==
|
||||
Extents) && ...) is true[.](#1.2.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21285)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
other.extent(r) equals Er for each r for which Er is a static extent, and
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
either
|
||||
* [(2.2.1)](#2.2.1)
|
||||
|
||||
sizeof...(OtherExtents) is zero, or
|
||||
|
||||
* [(2.2.2)](#2.2.2)
|
||||
|
||||
other.extent(r) is representable as
|
||||
a value of type index_type for every rank index r of other[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21302)
|
||||
|
||||
*Postconditions*: *this == other is true[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21306)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:(((Extents != dynamic_extent) && (OtherExtents == dynamic_extent)) || ... ) ||(numeric_limits<index_type>::max() < numeric_limits<OtherIndexType>::max())
|
||||
|
||||
[ð](#lib:extents,constructor_)
|
||||
|
||||
`template<class... OtherIndexTypes>
|
||||
constexpr explicit extents(OtherIndexTypes... exts) noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21322)
|
||||
|
||||
Let N be sizeof...(OtherIndexTypes),
|
||||
and let exts_arr bearray<index_type, N>{static_cast<
|
||||
index_type>(std::move(exts))...}[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21327)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
N == rank_dynamic() || N == rank() is true[.](#6.sentence-1)
|
||||
[*Note [1](#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[.](#6.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21343)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
If N != rank_dynamic() is true,exts_arr[r] equals Er for each r for which Er is a static extent, and
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
either
|
||||
* [(7.2.1)](#7.2.1)
|
||||
|
||||
sizeof...(exts) == 0 is true, or
|
||||
|
||||
* [(7.2.2)](#7.2.2)
|
||||
|
||||
each element of exts is representable
|
||||
as a nonnegative value of type index_type[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21361)
|
||||
|
||||
*Postconditions*: *this == extents(exts_arr) is true[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:extents,constructor__)
|
||||
|
||||
`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](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21377)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true,
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true, and
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
N == rank_dynamic() || N == rank() is true[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21388)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
If N != rank_dynamic() is true,exts[r] equals Er for each r for which Er is a static extent, and
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
either
|
||||
* [(10.2.1)](#10.2.1)
|
||||
|
||||
N is zero, or
|
||||
|
||||
* [(10.2.2)](#10.2.2)
|
||||
|
||||
exts[r] is representable
|
||||
as a nonnegative value of type index_type for every rank index r[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21405)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(11.1)](#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.1.sentence-1)
|
||||
|
||||
- [(11.2)](#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)])[.](#11.2.sentence-1)
|
||||
|
||||
[ð](#lib:extents,constructor___)
|
||||
|
||||
`template<class... Integrals>
|
||||
explicit extents(Integrals...) -> see below;
|
||||
`
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21427)
|
||||
|
||||
*Constraints*: (is_convertible_v<Integrals, size_t> && ...) is true[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21431)
|
||||
|
||||
*Remarks*: The deduced type is extents<size_t, [*maybe-static-ext*](span.syn#concept:maybe-static-ext "23.7.2.1 Header <span> synopsis [span.syn]")<Integrals>...>[.](#13.sentence-1)
|
||||
23
cppdraft/mdspan/extents/dextents.md
Normal file
23
cppdraft/mdspan/extents/dextents.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[mdspan.extents.dextents]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.dextents)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.dextents)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#dextents)
|
||||
|
||||
#### 23.7.3.3.6 Alias template dextents [mdspan.extents.dextents]
|
||||
|
||||
[ð](#lib:dextents)
|
||||
|
||||
`template<class IndexType, size_t Rank>
|
||||
using dextents = see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21495)
|
||||
|
||||
*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[.](#1.sentence-1)
|
||||
23
cppdraft/mdspan/extents/dims.md
Normal file
23
cppdraft/mdspan/extents/dims.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[mdspan.extents.dims]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.dims)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.dims)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#dims)
|
||||
|
||||
#### 23.7.3.3.7 Alias template dims [mdspan.extents.dims]
|
||||
|
||||
[ð](#lib:dims)
|
||||
|
||||
`template<size_t Rank, class IndexType = size_t>
|
||||
using dims = see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21511)
|
||||
|
||||
*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[.](#1.sentence-1)
|
||||
115
cppdraft/mdspan/extents/expo.md
Normal file
115
cppdraft/mdspan/extents/expo.md
Normal file
@@ -0,0 +1,115 @@
|
||||
[mdspan.extents.expo]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.expo)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.expo)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#expo)
|
||||
|
||||
#### 23.7.3.3.2 Exposition-only helpers [mdspan.extents.expo]
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`static constexpr rank_type dynamic-index(rank_type i) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21185)
|
||||
|
||||
*Preconditions*: i <= rank() is true[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21189)
|
||||
|
||||
*Returns*: The number of Er with r<i for which Er is a dynamic extent[.](#2.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`static constexpr rank_type dynamic-index-inv(rank_type i) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21199)
|
||||
|
||||
*Preconditions*: i < rank_dynamic() is true[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21203)
|
||||
|
||||
*Returns*: The minimum value of r such that *dynamic-index*(r + 1) == i + 1 is true[.](#4.sentence-1)
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`constexpr size_t fwd-prod-of-extents(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21214)
|
||||
|
||||
*Preconditions*: i <= rank() is true[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21218)
|
||||
|
||||
*Returns*: If i > 0 is true,
|
||||
the product of extent(k) for all k in the range [0, i),
|
||||
otherwise 1[.](#6.sentence-1)
|
||||
|
||||
[ð](#itemdecl:4)
|
||||
|
||||
`constexpr size_t rev-prod-of-extents(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21230)
|
||||
|
||||
*Preconditions*: i < rank() is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21234)
|
||||
|
||||
*Returns*: If i + 1 < rank() is true,
|
||||
the product of extent(k) for all k in the range [i + 1, rank()),
|
||||
otherwise 1[.](#8.sentence-1)
|
||||
|
||||
[ð](#itemdecl:5)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
static constexpr auto index-cast(OtherIndexType&& i) noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21248)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
If OtherIndexType is an integral type other than bool,
|
||||
then equivalent to return i;,
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
otherwise, equivalent to return static_cast<index_type>(i);[.](#9.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This function will always return an integral type other than bool[.](#9.sentence-2)
|
||||
|
||||
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[.](#9.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
45
cppdraft/mdspan/extents/obs.md
Normal file
45
cppdraft/mdspan/extents/obs.md
Normal file
@@ -0,0 +1,45 @@
|
||||
[mdspan.extents.obs]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.obs)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.obs)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#obs)
|
||||
|
||||
#### 23.7.3.3.4 Observers of the multidimensional index space [mdspan.extents.obs]
|
||||
|
||||
[ð](#lib:static_extent,extents)
|
||||
|
||||
`static constexpr size_t static_extent(rank_type i) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21444)
|
||||
|
||||
*Preconditions*: i < rank() is true[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21448)
|
||||
|
||||
*Returns*: Ei[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:extent,extents)
|
||||
|
||||
`constexpr index_type extent(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21459)
|
||||
|
||||
*Preconditions*: i < rank() is true[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21463)
|
||||
|
||||
*Returns*: Di[.](#4.sentence-1)
|
||||
59
cppdraft/mdspan/extents/overview.md
Normal file
59
cppdraft/mdspan/extents/overview.md
Normal file
@@ -0,0 +1,59 @@
|
||||
[mdspan.extents.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.extents.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.extents.overview)
|
||||
|
||||
#### 23.7.3.3 Class template extents [[mdspan.extents]](mdspan.extents#overview)
|
||||
|
||||
#### 23.7.3.3.1 Overview [mdspan.extents.overview]
|
||||
|
||||
The class template extents represents
|
||||
a multidimensional index space of rank equal to sizeof...(Extents)[.](#sentence-1)
|
||||
|
||||
In [[views]](views "23.7 Views"),extents is used synonymously with multidimensional index space[.](#sentence-2)
|
||||
|
||||
namespace std {template<class IndexType, size_t... Extents>class [extents](#lib:extents "23.7.3.3.1 Overview [mdspan.extents.overview]") {public:using index_type = IndexType; using size_type = make_unsigned_t<index_type>; using rank_type = size_t; // [[mdspan.extents.obs]](mdspan.extents.obs "23.7.3.3.4 Observers of the multidimensional index space"), 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]](mdspan.extents.cons "23.7.3.3.3 Constructors"), 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]](mdspan.extents.cmp "23.7.3.3.5 Comparison operators"), comparison operatorstemplate<class OtherIndexType, size_t... OtherExtents>friend constexpr bool operator==(const extents&, const extents<OtherIndexType, OtherExtents...>&) noexcept; // [[mdspan.extents.expo]](mdspan.extents.expo "23.7.3.3.2 Exposition-only helpers"), exposition-only helpersconstexpr 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*;}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21152)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
IndexType is a signed or unsigned integer type, and
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
each element of Extents is either equal to dynamic_extent, or
|
||||
is representable as a value of type IndexType[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21162)
|
||||
|
||||
Each specialization of extents models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") and
|
||||
is trivially copyable[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21166)
|
||||
|
||||
Let Er be the rth element of Extents[.](#3.sentence-1)
|
||||
|
||||
Er is a [*dynamic extent*](#def:extent,dynamic "23.7.3.3.1 Overview [mdspan.extents.overview]") if it is equal to dynamic_extent,
|
||||
otherwise Er is a [*static extent*](#def:extent,static "23.7.3.3.1 Overview [mdspan.extents.overview]")[.](#3.sentence-2)
|
||||
|
||||
Let Dr be the value of *dynamic-extents*[*dynamic-index*(r)] if Er is a dynamic extent,
|
||||
otherwise Er[.](#3.sentence-3)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21174)
|
||||
|
||||
The rth interval of the multidimensional index space
|
||||
represented by an extents object is [0,Dr)[.](#4.sentence-1)
|
||||
2693
cppdraft/mdspan/layout.md
Normal file
2693
cppdraft/mdspan/layout.md
Normal file
File diff suppressed because it is too large
Load Diff
78
cppdraft/mdspan/layout/general.md
Normal file
78
cppdraft/mdspan/layout/general.md
Normal file
@@ -0,0 +1,78 @@
|
||||
[mdspan.layout.general]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.general)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.general)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#general)
|
||||
|
||||
#### 23.7.3.4.1 General [mdspan.layout.general]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21522)
|
||||
|
||||
In [[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2 Requirements") and [[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"):
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
M denotes a layout mapping class[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
m denotes a (possibly const) value of type M[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
i and j are packs of (possibly const) integers
|
||||
that are multidimensional indices in m.extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#1.3.sentence-1)
|
||||
[*Note [1](#note-1)*:
|
||||
The type of each element of the packs can be a different integer type[.](#1.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
r is a (possibly const) rank index of typename M::extents_type[.](#1.4.sentence-1)
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
dr is a pack of (possibly const) integers
|
||||
for which sizeof...(dr) == M::extents_type::rank() is true,
|
||||
the rth element is equal to 1, and
|
||||
all other elements are equal to 0[.](#1.5.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21549)
|
||||
|
||||
In [[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2 Requirements") through [[mdspan.layout.stride]](mdspan.layout.stride "23.7.3.4.7 Class template layout_stride::mapping"):
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
Let *is-mapping-of* be the exposition-only variable template defined as follows:template<class Layout, class Mapping>constexpr bool *is-mapping-of* = // *exposition only* is_same_v<typename Layout::template mapping<typename Mapping::extents_type>, Mapping>;
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
Let *is-layout-left-padded-mapping-of* be
|
||||
the exposition-only variable template defined as follows:template<class Mapping>constexpr bool *is-layout-left-padded-mapping-of* = *see below*; // *exposition only* where *is-layout-left-padded-mapping-of*<Mapping> is true if and only if Mapping denotes
|
||||
a specialization of layout_left_padded<S>::mapping for some value S of type size_t.
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
Let *is-layout-right-padded-mapping-of* be
|
||||
the exposition-only variable template defined as follows:template<class Mapping>constexpr bool *is-layout-right-padded-mapping-of* = *see below*; // *exposition only* where *is-layout-right-padded-mapping-of*<Mapping> is true if and only if Mapping denotes
|
||||
a specialization of layout_right_padded<S>::mapping for some value S of type size_t.
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
For nonnegative integers x and y,
|
||||
let LEAST-MULTIPLE-AT-LEAST(x,y) denote
|
||||
* [(2.4.1)](#2.4.1)
|
||||
|
||||
y if x is zero,
|
||||
|
||||
* [(2.4.2)](#2.4.2)
|
||||
|
||||
otherwise, the least multiple of x that is greater than or equal to y.
|
||||
317
cppdraft/mdspan/layout/left.md
Normal file
317
cppdraft/mdspan/layout/left.md
Normal file
@@ -0,0 +1,317 @@
|
||||
[mdspan.layout.left]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.left)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left)
|
||||
|
||||
#### 23.7.3.4.5 Class template layout_left::mapping [mdspan.layout.left]
|
||||
|
||||
#### [23.7.3.4.5.1](#overview) Overview [[mdspan.layout.left.overview]](mdspan.layout.left.overview)
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21916)
|
||||
|
||||
layout_left provides a layout mapping
|
||||
where the leftmost extent has stride 1, and
|
||||
strides increase left-to-right as the product of extents[.](#overview-1.sentence-1)
|
||||
|
||||
namespace std {template<class Extents>class layout_left::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_left; // [[mdspan.layout.left.cons]](#cons "23.7.3.4.5.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_right::mapping<OtherExtents>&) noexcept; template<class LayoutLeftPaddedMapping>constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
|
||||
extents_type>) mapping(const LayoutLeftPaddedMapping&) noexcept; template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&); constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.left.obs]](#obs "23.7.3.4.5.3 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr 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; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend 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#L21990)
|
||||
|
||||
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#L21994)
|
||||
|
||||
layout_left::mapping<E> 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#L21998)
|
||||
|
||||
*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.5.2](#cons) Constructors [[mdspan.layout.left.cons]](mdspan.layout.left.cons)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& e) noexcept;
|
||||
`
|
||||
|
||||
[1](#cons-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22012)
|
||||
|
||||
*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#L22017)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with e[.](#cons-2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor_)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[3](#cons-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22030)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-3.sentence-1)
|
||||
|
||||
[4](#cons-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22034)
|
||||
|
||||
*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#L22039)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#cons-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22052)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#cons-6.1)
|
||||
|
||||
extents_type::rank() <= 1 is true, and
|
||||
|
||||
- [(6.2)](#cons-6.2)
|
||||
|
||||
is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
|
||||
|
||||
[7](#cons-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22061)
|
||||
|
||||
*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#L22066)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-8.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor___)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
|
||||
extents_type>)
|
||||
mapping(const LayoutLeftPaddedMapping&) noexcept;
|
||||
`
|
||||
|
||||
[9](#cons-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22080)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(9.1)](#cons-9.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#cons-9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#cons-9.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
|
||||
is true[.](#cons-9.2.sentence-1)
|
||||
|
||||
[10](#cons-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22089)
|
||||
|
||||
*Mandates*: If
|
||||
|
||||
- [(10.1)](#cons-10.1)
|
||||
|
||||
Extents::rank() is greater than one,
|
||||
|
||||
- [(10.2)](#cons-10.2)
|
||||
|
||||
Extents::static_extent(0) does not equal dynamic_extent, and
|
||||
|
||||
- [(10.3)](#cons-10.3)
|
||||
|
||||
LayoutLeftPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
|
||||
|
||||
then Extents::static_extent(0) equalsLayoutLeftPaddedMapping::*static-padding-stride*[.](#cons-10.sentence-1)
|
||||
|
||||
[11](#cons-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22104)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#cons-11.1)
|
||||
|
||||
If extents_type::rank() > 1 is true,
|
||||
then other.stride(1) equals other.extents(0)[.](#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#L22115)
|
||||
|
||||
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#cons-12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor____)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(extents_type::rank() > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[13](#cons-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22128)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-13.sentence-1)
|
||||
|
||||
[14](#cons-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22132)
|
||||
|
||||
*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().*fwd-prod-of-extents*(r), and
|
||||
|
||||
- [(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.sentence-1)
|
||||
|
||||
[15](#cons-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22145)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-15.sentence-1)
|
||||
|
||||
#### [23.7.3.4.5.3](#obs) Observers [[mdspan.layout.left.obs]](mdspan.layout.left.obs)
|
||||
|
||||
[ð](#lib:required_span_size,layout_left::mapping)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[1](#obs-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22158)
|
||||
|
||||
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#obs-1.sentence-1)
|
||||
|
||||
[ð](#lib:operator(),layout_left::mapping)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr index_type operator()(Indices... i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#obs-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22170)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(2.1)](#obs-2.1)
|
||||
|
||||
sizeof...(Indices) == extents_type::rank() is true,
|
||||
|
||||
- [(2.2)](#obs-2.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true, and
|
||||
|
||||
- [(2.3)](#obs-2.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-2.sentence-1)
|
||||
|
||||
[3](#obs-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22181)
|
||||
|
||||
*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#L22186)
|
||||
|
||||
*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#obs-4.sentence-1)
|
||||
|
||||
Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
|
||||
|
||||
[ð](#lib:stride,layout_left::mapping)
|
||||
|
||||
`constexpr index_type stride(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#obs-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22205)
|
||||
|
||||
*Constraints*: extents_type::rank() > 0 is true[.](#obs-5.sentence-1)
|
||||
|
||||
[6](#obs-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22209)
|
||||
|
||||
*Preconditions*: i < extents_type::rank() is true[.](#obs-6.sentence-1)
|
||||
|
||||
[7](#obs-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22213)
|
||||
|
||||
*Returns*: extents().*fwd-prod-of-extents*(i)[.](#obs-7.sentence-1)
|
||||
|
||||
[ð](#lib:operator==,layout_left::mapping)
|
||||
|
||||
`template<class OtherExtents>
|
||||
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
|
||||
`
|
||||
|
||||
[8](#obs-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22225)
|
||||
|
||||
*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#L22229)
|
||||
|
||||
*Effects*: Equivalent to: return x.extents() == y.extents();
|
||||
190
cppdraft/mdspan/layout/left/cons.md
Normal file
190
cppdraft/mdspan/layout/left/cons.md
Normal file
@@ -0,0 +1,190 @@
|
||||
[mdspan.layout.left.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.left.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left.cons)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left.cons)
|
||||
|
||||
#### 23.7.3.4.5 Class template layout_left::mapping [[mdspan.layout.left]](mdspan.layout.left#cons)
|
||||
|
||||
#### 23.7.3.4.5.2 Constructors [mdspan.layout.left.cons]
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& e) noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22012)
|
||||
|
||||
*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"))[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22017)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with e[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor_)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22030)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22034)
|
||||
|
||||
*Preconditions*: other.required_span_size() is representable as
|
||||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22039)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_right::mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22052)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
extents_type::rank() <= 1 is true, and
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22061)
|
||||
|
||||
*Preconditions*: other.required_span_size() is representable as
|
||||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22066)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor___)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
|
||||
extents_type>)
|
||||
mapping(const LayoutLeftPaddedMapping&) noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22080)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
|
||||
is true[.](#9.2.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22089)
|
||||
|
||||
*Mandates*: If
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
Extents::rank() is greater than one,
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
Extents::static_extent(0) does not equal dynamic_extent, and
|
||||
|
||||
- [(10.3)](#10.3)
|
||||
|
||||
LayoutLeftPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
|
||||
|
||||
then Extents::static_extent(0) equalsLayoutLeftPaddedMapping::*static-padding-stride*[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22104)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
If extents_type::rank() > 1 is true,
|
||||
then other.stride(1) equals other.extents(0)[.](#11.1.sentence-1)
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#11.2.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22115)
|
||||
|
||||
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left::mapping,constructor____)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(extents_type::rank() > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22128)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22132)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(14.1)](#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().*fwd-prod-of-extents*(r), and
|
||||
|
||||
- [(14.2)](#14.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22145)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#15.sentence-1)
|
||||
104
cppdraft/mdspan/layout/left/obs.md
Normal file
104
cppdraft/mdspan/layout/left/obs.md
Normal file
@@ -0,0 +1,104 @@
|
||||
[mdspan.layout.left.obs]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.left.obs)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left.obs)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left.obs)
|
||||
|
||||
#### 23.7.3.4.5 Class template layout_left::mapping [[mdspan.layout.left]](mdspan.layout.left#obs)
|
||||
|
||||
#### 23.7.3.4.5.3 Observers [mdspan.layout.left.obs]
|
||||
|
||||
[ð](#lib:required_span_size,layout_left::mapping)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22158)
|
||||
|
||||
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:operator(),layout_left::mapping)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr index_type operator()(Indices... i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22170)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
sizeof...(Indices) == extents_type::rank() is true,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true, and
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22181)
|
||||
|
||||
*Preconditions*: extents_type::*index-cast*(i) is
|
||||
a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22186)
|
||||
|
||||
*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#4.sentence-1)
|
||||
|
||||
Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
|
||||
|
||||
[ð](#lib:stride,layout_left::mapping)
|
||||
|
||||
`constexpr index_type stride(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22205)
|
||||
|
||||
*Constraints*: extents_type::rank() > 0 is true[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22209)
|
||||
|
||||
*Preconditions*: i < extents_type::rank() is true[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22213)
|
||||
|
||||
*Returns*: extents().*fwd-prod-of-extents*(i)[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:operator==,layout_left::mapping)
|
||||
|
||||
`template<class OtherExtents>
|
||||
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22225)
|
||||
|
||||
*Constraints*: extents_type::rank() == OtherExtents::rank() is true[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22229)
|
||||
|
||||
*Effects*: Equivalent to: return x.extents() == y.extents();
|
||||
45
cppdraft/mdspan/layout/left/overview.md
Normal file
45
cppdraft/mdspan/layout/left/overview.md
Normal file
@@ -0,0 +1,45 @@
|
||||
[mdspan.layout.left.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.left.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.left.overview)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#left.overview)
|
||||
|
||||
#### 23.7.3.4.5 Class template layout_left::mapping [[mdspan.layout.left]](mdspan.layout.left#overview)
|
||||
|
||||
#### 23.7.3.4.5.1 Overview [mdspan.layout.left.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21916)
|
||||
|
||||
layout_left provides a layout mapping
|
||||
where the leftmost extent has stride 1, and
|
||||
strides increase left-to-right as the product of extents[.](#1.sentence-1)
|
||||
|
||||
namespace std {template<class Extents>class layout_left::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_left; // [[mdspan.layout.left.cons]](mdspan.layout.left.cons "23.7.3.4.5.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_right::mapping<OtherExtents>&) noexcept; template<class LayoutLeftPaddedMapping>constexpr explicit(!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type,
|
||||
extents_type>) mapping(const LayoutLeftPaddedMapping&) noexcept; template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&); constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.left.obs]](mdspan.layout.left.obs "23.7.3.4.5.3 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr 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; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21990)
|
||||
|
||||
If Extents is not a specialization of extents,
|
||||
then the program is ill-formed[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21994)
|
||||
|
||||
layout_left::mapping<E> is a trivially copyable type
|
||||
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21998)
|
||||
|
||||
*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[.](#4.sentence-1)
|
||||
648
cppdraft/mdspan/layout/leftpad.md
Normal file
648
cppdraft/mdspan/layout/leftpad.md
Normal file
@@ -0,0 +1,648 @@
|
||||
[mdspan.layout.leftpad]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.leftpad)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad)
|
||||
|
||||
#### 23.7.3.4.8 Class template layout_left_padded::mapping [mdspan.layout.leftpad]
|
||||
|
||||
#### [23.7.3.4.8.1](#overview) Overview [[mdspan.layout.leftpad.overview]](mdspan.layout.leftpad.overview)
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22947)
|
||||
|
||||
layout_left_padded provides a layout mapping
|
||||
that behaves like layout_left::mapping,
|
||||
except that the padding stride stride(1) can be greater than or equal to extent(0)[.](#overview-1.sentence-1)
|
||||
|
||||
namespace std {template<size_t PaddingValue>template<class Extents>class layout_left_padded<PaddingValue>::mapping {public:static constexpr size_t padding_value = PaddingValue; 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_left_padded<PaddingValue>; private:static constexpr size_t *rank_* = extents_type::rank(); // *exposition only*static constexpr size_t *first-static-extent* = // *exposition only* extents_type::static_extent(0); // [[mdspan.layout.leftpad.expo]](#expo "23.7.3.4.8.2 Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.leftpad.cons]](#cons "23.7.3.4.8.3 Constructors"), constructorsconstexpr mapping() noexcept : mapping(extents_type{}) {}constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&); template<class OtherIndexType>constexpr mapping(const extents_type&, OtherIndexType); template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_left::mapping<OtherExtents>&); template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&); template<class LayoutLeftPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutLeftPaddedMapping&); template<class LayoutRightPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutRightPaddedMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.leftpad.obs]](#obs "23.7.3.4.8.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr array<index_type, rank_> strides() const noexcept; constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept; static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class LayoutLeftPaddedMapping>friend constexpr bool operator==(const mapping&, const LayoutLeftPaddedMapping&) noexcept; private:// [[mdspan.layout.leftpad.expo]](#expo "23.7.3.4.8.2 Exposition-only members"), exposition-only members index_type *stride-1* = *static-padding-stride*; // *exposition only* extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend 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#L23035)
|
||||
|
||||
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#L23039)
|
||||
|
||||
layout_left_padded::mapping<E> 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#L23043)
|
||||
|
||||
Throughout [mdspan.layout.leftpad],
|
||||
let P_rank be the following
|
||||
size *rank_* parameter pack of size_t values:
|
||||
|
||||
- [(4.1)](#overview-4.1)
|
||||
|
||||
the empty parameter pack, if *rank_* equals zero;
|
||||
|
||||
- [(4.2)](#overview-4.2)
|
||||
|
||||
otherwise, 0zu, if *rank_* equals one;
|
||||
|
||||
- [(4.3)](#overview-4.3)
|
||||
|
||||
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#overview-4.sentence-1)
|
||||
|
||||
[5](#overview-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23056)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(5.1)](#overview-5.1)
|
||||
|
||||
If rank_dynamic() == 0 is true,
|
||||
then the size of the multidimensional index space Extents() is representable as a value of type index_type[.](#overview-5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#overview-5.2)
|
||||
|
||||
padding_value is representable as a value of type index_type[.](#overview-5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#overview-5.3)
|
||||
|
||||
If
|
||||
* [(5.3.1)](#overview-5.3.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.3.2)](#overview-5.3.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.3.3)](#overview-5.3.3)
|
||||
|
||||
*first-static-extent* does not equal dynamic_extent,
|
||||
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*) is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#overview-5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#overview-5.4)
|
||||
|
||||
If
|
||||
* [(5.4.1)](#overview-5.4.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.4.2)](#overview-5.4.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.4.3)](#overview-5.4.3)
|
||||
|
||||
extents_type::static_extent(k) does not equal dynamic_extent for all k in the range [0, extents_type::rank()),
|
||||
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.static_extent(0)) and
|
||||
all values ext.static_extent(k) with k in the range of [1, *rank_*)
|
||||
is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#overview-5.4.sentence-1)
|
||||
|
||||
#### [23.7.3.4.8.2](#expo) Exposition-only members [[mdspan.layout.leftpad.expo]](mdspan.layout.leftpad.expo)
|
||||
|
||||
[ð](#expo-itemdecl:1)
|
||||
|
||||
`static constexpr size_t static-padding-stride = see below;
|
||||
`
|
||||
|
||||
[1](#expo-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23104)
|
||||
|
||||
The value is
|
||||
|
||||
- [(1.1)](#expo-1.1)
|
||||
|
||||
0, if *rank_* equals zero or one;
|
||||
|
||||
- [(1.2)](#expo-1.2)
|
||||
|
||||
otherwise, dynamic_extent,
|
||||
if padding_value or *first-static-extent* equalsdynamic_extent;
|
||||
|
||||
- [(1.3)](#expo-1.3)
|
||||
|
||||
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*)[.](#expo-1.sentence-1)
|
||||
|
||||
[ð](#expo-itemdecl:2)
|
||||
|
||||
`index_type stride-1 = static-padding-stride;
|
||||
`
|
||||
|
||||
[2](#expo-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23124)
|
||||
|
||||
*Recommended practice*: Implementations should not store this value
|
||||
if *static-padding-stride* is not dynamic_extent[.](#expo-2.sentence-1)
|
||||
|
||||
[*Note [1](#expo-note-1)*:
|
||||
|
||||
Using extents<index_type, *static-padding-stride*> instead ofindex_type as the type of *stride-1* would achieve this[.](#expo-2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.4.8.3](#cons) Constructors [[mdspan.layout.leftpad.cons]](mdspan.layout.leftpad.cons)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& ext);
|
||||
`
|
||||
|
||||
[1](#cons-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23142)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(1.1)](#cons-1.1)
|
||||
|
||||
The size of the multidimensional index space ext is representable as
|
||||
a value of type index_type[.](#cons-1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#cons-1.2)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0)) is representable as a value of type *index_type*[.](#cons-1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#cons-1.3)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0)) and
|
||||
all values ext.extent(k) with k in the range of [1, *rank_*)
|
||||
is representable as a value of type index_type[.](#cons-1.3.sentence-1)
|
||||
|
||||
[2](#cons-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23163)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(2.1)](#cons-2.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with ext; and
|
||||
|
||||
- [(2.2)](#cons-2.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1*
|
||||
* [(2.2.1)](#cons-2.2.1)
|
||||
|
||||
with ext.extent(0) if padding_value is dynamic_extent,
|
||||
|
||||
* [(2.2.2)](#cons-2.2.2)
|
||||
|
||||
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0))[.](#cons-2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor_)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& ext, OtherIndexType pad);
|
||||
`
|
||||
|
||||
[3](#cons-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23188)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#cons-3.1)
|
||||
|
||||
is_convertible_v<OtherIndexType, index_type> is true[.](#cons-3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#cons-3.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#cons-3.2.sentence-1)
|
||||
|
||||
[4](#cons-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23197)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(4.1)](#cons-4.1)
|
||||
|
||||
pad is representable as a value of type index_type[.](#cons-4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#cons-4.2)
|
||||
|
||||
extents_type::index-cast(pad) is greater than zero[.](#cons-4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#cons-4.3)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0)) is representable as a value of type index_type.
|
||||
|
||||
- [(4.4)](#cons-4.4)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0)) and
|
||||
all values ext.extent(k) with k in the range of [1, *rank_*)
|
||||
is representable as a value of type index_type[.](#cons-4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#cons-4.5)
|
||||
|
||||
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#cons-4.5.sentence-1)
|
||||
|
||||
[5](#cons-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23220)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with ext, and
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1* with*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0))[.](#cons-5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_left::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[6](#cons-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23236)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
|
||||
|
||||
[7](#cons-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23240)
|
||||
|
||||
*Mandates*: If OtherExtents::rank() is greater than 1, then(*static-padding-stride* == dynamic_extent) ||(OtherExtents::static_extent(0) == dynamic_extent) ||(*static-padding-stride* == OtherExtents::static_extent(0)) is true[.](#cons-7.sentence-1)
|
||||
|
||||
[8](#cons-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23250)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(8.1)](#cons-8.1)
|
||||
|
||||
If extents_type::rank() > 1 is true andpadding_value == dynamic_extent is false,
|
||||
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(0))) and
|
||||
|
||||
- [(8.2)](#cons-8.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-8.sentence-1)
|
||||
|
||||
[9](#cons-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23267)
|
||||
|
||||
*Effects*: Equivalent to mapping(other.extents())[.](#cons-9.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor___)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(rank_ > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[10](#cons-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23280)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-10.sentence-1)
|
||||
|
||||
[11](#cons-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23284)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#cons-11.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(0)))
|
||||
|
||||
- [(11.2)](#cons-11.2)
|
||||
|
||||
If *rank_* is greater than 0,
|
||||
then other.stride(0) equals 1[.](#cons-11.2.sentence-1)
|
||||
|
||||
- [(11.3)](#cons-11.3)
|
||||
|
||||
If *rank_* is greater than 2,
|
||||
then for all r in the range [2, *rank_*),other.stride(r) equals(other.extents().*fwd-prod-of-extents*(r) / other.extents().extent(0)) * other.stride(1)
|
||||
|
||||
- [(11.4)](#cons-11.4)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type *index_type*[.](#cons-11.4.sentence-1)
|
||||
|
||||
[12](#cons-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23310)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(12.1)](#cons-12.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents() and
|
||||
|
||||
- [(12.2)](#cons-12.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1* withother.stride(1)[.](#cons-12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor____)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutLeftPaddedMapping& other);
|
||||
`
|
||||
|
||||
[13](#cons-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23330)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(13.1)](#cons-13.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#cons-13.1.sentence-1)
|
||||
|
||||
- [(13.2)](#cons-13.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
|
||||
is true[.](#cons-13.2.sentence-1)
|
||||
|
||||
[14](#cons-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23341)
|
||||
|
||||
*Mandates*: If *rank_* is greater than 1,
|
||||
thenpadding_value == dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutLeftPaddedMapping::padding_value is true[.](#cons-14.sentence-1)
|
||||
|
||||
[15](#cons-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23352)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(15.1)](#cons-15.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extent(0)))
|
||||
|
||||
- [(15.2)](#cons-15.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-15.sentence-1)
|
||||
|
||||
[16](#cons-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23368)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(16.1)](#cons-16.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents() and
|
||||
|
||||
- [(16.2)](#cons-16.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1* with other.stride(1)[.](#cons-16.sentence-1)
|
||||
|
||||
[17](#cons-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23378)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:rank_> 1 &&(padding_value != dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor_____)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutRightPaddedMapping& other) noexcept;
|
||||
`
|
||||
|
||||
[18](#cons-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23396)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(18.1)](#cons-18.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true or
|
||||
*is-mapping-of*<layout_right, LayoutRightPaddedMapping> is true[.](#cons-18.1.sentence-1)
|
||||
|
||||
- [(18.2)](#cons-18.2)
|
||||
|
||||
*rank_* equals zero or one[.](#cons-18.2.sentence-1)
|
||||
|
||||
- [(18.3)](#cons-18.3)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
|
||||
type> is true[.](#cons-18.3.sentence-1)
|
||||
|
||||
[19](#cons-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23411)
|
||||
|
||||
*Preconditions*: other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-19.sentence-1)
|
||||
|
||||
[20](#cons-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23416)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-20.sentence-1)
|
||||
|
||||
[21](#cons-21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23420)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<typename LayoutRightPaddedMapping::extents_type, extents_type>
|
||||
|
||||
[*Note [1](#cons-note-1)*:
|
||||
|
||||
Neither the input mapping nor the mapping to be constructed
|
||||
uses the padding stride in the rank-0 or rank-1 case,
|
||||
so the padding stride does not affect
|
||||
either the constraints or the preconditions[.](#cons-21.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.4.8.4](#obs) Observers [[mdspan.layout.leftpad.obs]](mdspan.layout.leftpad.obs)
|
||||
|
||||
[ð](#obs-itemdecl:1)
|
||||
|
||||
`constexpr array<index_type, rank_> strides() const noexcept;
|
||||
`
|
||||
|
||||
[1](#obs-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23442)
|
||||
|
||||
*Returns*: array<index_type, *rank_*>({stride(P_rank)...})[.](#obs-1.sentence-1)
|
||||
|
||||
[ð](#obs-itemdecl:2)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[2](#obs-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23452)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(2.1)](#obs-2.1)
|
||||
|
||||
0 if the multidimensional index space *extents_* is empty,
|
||||
|
||||
- [(2.2)](#obs-2.2)
|
||||
|
||||
otherwise, *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#obs-2.sentence-1)
|
||||
|
||||
[ð](#obs-itemdecl:3)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr size_t operator()(Indices... idxs) const noexcept;
|
||||
`
|
||||
|
||||
[3](#obs-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23468)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#obs-3.1)
|
||||
|
||||
sizeof...(Indices) == *rank_* is true[.](#obs-3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#obs-3.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true[.](#obs-3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#obs-3.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-3.3.sentence-1)
|
||||
|
||||
[4](#obs-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23479)
|
||||
|
||||
*Preconditions*: extents_type::*index-cast*(idxs) is
|
||||
a multidimensional index in extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#obs-4.sentence-1)
|
||||
|
||||
[5](#obs-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23484)
|
||||
|
||||
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#obs-5.sentence-1)
|
||||
|
||||
[ð](#obs-itemdecl:4)
|
||||
|
||||
`static constexpr bool is_always_exhaustive() noexcept;
|
||||
`
|
||||
|
||||
[6](#obs-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23494)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(6.1)](#obs-6.1)
|
||||
|
||||
If *rank_* equals zero or one, then true;
|
||||
|
||||
- [(6.2)](#obs-6.2)
|
||||
|
||||
otherwise, if
|
||||
neither *static-padding-stride* nor *first-static-extent* equal dynamic_extent,
|
||||
then *static-padding-stride* == *first-static-extent*;
|
||||
|
||||
- [(6.3)](#obs-6.3)
|
||||
|
||||
otherwise, false[.](#obs-6.sentence-1)
|
||||
|
||||
[ð](#obs-itemdecl:5)
|
||||
|
||||
`constexpr bool is_exhaustive() const noexcept;
|
||||
`
|
||||
|
||||
[7](#obs-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23514)
|
||||
|
||||
*Returns*: true if *rank_* equals zero or one;
|
||||
otherwise, extents_.extent(0) == stride(1)[.](#obs-7.sentence-1)
|
||||
|
||||
[ð](#obs-itemdecl:6)
|
||||
|
||||
`constexpr index_type stride(rank_type r) const noexcept;
|
||||
`
|
||||
|
||||
[8](#obs-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23525)
|
||||
|
||||
*Preconditions*: r is smaller than *rank_*[.](#obs-8.sentence-1)
|
||||
|
||||
[9](#obs-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23529)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(9.1)](#obs-9.1)
|
||||
|
||||
If r equals zero: 1;
|
||||
|
||||
- [(9.2)](#obs-9.2)
|
||||
|
||||
otherwise, if r equals one: *stride-1*;
|
||||
|
||||
- [(9.3)](#obs-9.3)
|
||||
|
||||
otherwise, the product of *stride-1* and
|
||||
all values extents_.extent(k) with k in the range [1, r)[.](#obs-9.sentence-1)
|
||||
|
||||
[ð](#obs-itemdecl:7)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept;
|
||||
`
|
||||
|
||||
[10](#obs-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23548)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(10.1)](#obs-10.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#obs-10.1.sentence-1)
|
||||
|
||||
- [(10.2)](#obs-10.2)
|
||||
|
||||
LayoutLeftPaddedMapping::extents_type::rank() == rank_ is true[.](#obs-10.2.sentence-1)
|
||||
|
||||
[11](#obs-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23558)
|
||||
|
||||
*Returns*: true if x.extents() == y.extents() is true and*rank_* < 2 || x.stride(1) == y.
|
||||
stride(1) is true[.](#obs-11.sentence-1)
|
||||
|
||||
Otherwise, false[.](#obs-11.sentence-2)
|
||||
340
cppdraft/mdspan/layout/leftpad/cons.md
Normal file
340
cppdraft/mdspan/layout/leftpad/cons.md
Normal file
@@ -0,0 +1,340 @@
|
||||
[mdspan.layout.leftpad.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.leftpad.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.cons)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.cons)
|
||||
|
||||
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#cons)
|
||||
|
||||
#### 23.7.3.4.8.3 Constructors [mdspan.layout.leftpad.cons]
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& ext);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23142)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
The size of the multidimensional index space ext is representable as
|
||||
a value of type index_type[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0)) is representable as a value of type *index_type*[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0)) and
|
||||
all values ext.extent(k) with k in the range of [1, *rank_*)
|
||||
is representable as a value of type index_type[.](#1.3.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23163)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with ext; and
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1*
|
||||
* [(2.2.1)](#2.2.1)
|
||||
|
||||
with ext.extent(0) if padding_value is dynamic_extent,
|
||||
|
||||
* [(2.2.2)](#2.2.2)
|
||||
|
||||
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(0))[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor_)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& ext, OtherIndexType pad);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23188)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
is_convertible_v<OtherIndexType, index_type> is true[.](#3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#3.2.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23197)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
pad is representable as a value of type index_type[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
extents_type::index-cast(pad) is greater than zero[.](#4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0)) is representable as a value of type index_type.
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0)) and
|
||||
all values ext.extent(k) with k in the range of [1, *rank_*)
|
||||
is representable as a value of type index_type[.](#4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#4.5)
|
||||
|
||||
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#4.5.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23220)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with ext, and
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1* with*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(0))[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_left::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23236)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23240)
|
||||
|
||||
*Mandates*: If OtherExtents::rank() is greater than 1, then(*static-padding-stride* == dynamic_extent) ||(OtherExtents::static_extent(0) == dynamic_extent) ||(*static-padding-stride* == OtherExtents::static_extent(0)) is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23250)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(8.1)](#8.1)
|
||||
|
||||
If extents_type::rank() > 1 is true andpadding_value == dynamic_extent is false,
|
||||
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(0))) and
|
||||
|
||||
- [(8.2)](#8.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23267)
|
||||
|
||||
*Effects*: Equivalent to mapping(other.extents())[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor___)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(rank_ > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23280)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23284)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(0)))
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
If *rank_* is greater than 0,
|
||||
then other.stride(0) equals 1[.](#11.2.sentence-1)
|
||||
|
||||
- [(11.3)](#11.3)
|
||||
|
||||
If *rank_* is greater than 2,
|
||||
then for all r in the range [2, *rank_*),other.stride(r) equals(other.extents().*fwd-prod-of-extents*(r) / other.extents().extent(0)) * other.stride(1)
|
||||
|
||||
- [(11.4)](#11.4)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type *index_type*[.](#11.4.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23310)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(12.1)](#12.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents() and
|
||||
|
||||
- [(12.2)](#12.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1* withother.stride(1)[.](#12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor____)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutLeftPaddedMapping& other);
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23330)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(13.1)](#13.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#13.1.sentence-1)
|
||||
|
||||
- [(13.2)](#13.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
|
||||
is true[.](#13.2.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23341)
|
||||
|
||||
*Mandates*: If *rank_* is greater than 1,
|
||||
thenpadding_value == dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutLeftPaddedMapping::padding_value is true[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23352)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(15.1)](#15.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(1) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extent(0)))
|
||||
|
||||
- [(15.2)](#15.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23368)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(16.1)](#16.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents() and
|
||||
|
||||
- [(16.2)](#16.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-1* with other.stride(1)[.](#16.sentence-1)
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23378)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:rank_> 1 &&(padding_value != dynamic_extent || LayoutLeftPaddedMapping::padding_value == dynamic_extent)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,constructor_____)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutRightPaddedMapping& other) noexcept;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23396)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(18.1)](#18.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true or
|
||||
*is-mapping-of*<layout_right, LayoutRightPaddedMapping> is true[.](#18.1.sentence-1)
|
||||
|
||||
- [(18.2)](#18.2)
|
||||
|
||||
*rank_* equals zero or one[.](#18.2.sentence-1)
|
||||
|
||||
- [(18.3)](#18.3)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
|
||||
type> is true[.](#18.3.sentence-1)
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23411)
|
||||
|
||||
*Preconditions*: other.required_span_size() is representable as
|
||||
a value of type index_type[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23416)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#20.sentence-1)
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23420)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<typename LayoutRightPaddedMapping::extents_type, extents_type>
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Neither the input mapping nor the mapping to be constructed
|
||||
uses the padding stride in the rank-0 or rank-1 case,
|
||||
so the padding stride does not affect
|
||||
either the constraints or the preconditions[.](#21.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
55
cppdraft/mdspan/layout/leftpad/expo.md
Normal file
55
cppdraft/mdspan/layout/leftpad/expo.md
Normal file
@@ -0,0 +1,55 @@
|
||||
[mdspan.layout.leftpad.expo]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.leftpad.expo)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.expo)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.expo)
|
||||
|
||||
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#expo)
|
||||
|
||||
#### 23.7.3.4.8.2 Exposition-only members [mdspan.layout.leftpad.expo]
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`static constexpr size_t static-padding-stride = see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23104)
|
||||
|
||||
The value is
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
0, if *rank_* equals zero or one;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise, dynamic_extent,
|
||||
if padding_value or *first-static-extent* equalsdynamic_extent;
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*)[.](#1.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`index_type stride-1 = static-padding-stride;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23124)
|
||||
|
||||
*Recommended practice*: Implementations should not store this value
|
||||
if *static-padding-stride* is not dynamic_extent[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Using extents<index_type, *static-padding-stride*> instead ofindex_type as the type of *stride-1* would achieve this[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
176
cppdraft/mdspan/layout/leftpad/obs.md
Normal file
176
cppdraft/mdspan/layout/leftpad/obs.md
Normal file
@@ -0,0 +1,176 @@
|
||||
[mdspan.layout.leftpad.obs]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.leftpad.obs)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.obs)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.obs)
|
||||
|
||||
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#obs)
|
||||
|
||||
#### 23.7.3.4.8.4 Observers [mdspan.layout.leftpad.obs]
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`constexpr array<index_type, rank_> strides() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23442)
|
||||
|
||||
*Returns*: array<index_type, *rank_*>({stride(P_rank)...})[.](#1.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23452)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
0 if the multidimensional index space *extents_* is empty,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
otherwise, *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#2.sentence-1)
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr size_t operator()(Indices... idxs) const noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23468)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
sizeof...(Indices) == *rank_* is true[.](#3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true[.](#3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#3.3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23479)
|
||||
|
||||
*Preconditions*: extents_type::*index-cast*(idxs) is
|
||||
a multidimensional index in extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23484)
|
||||
|
||||
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#5.sentence-1)
|
||||
|
||||
[ð](#itemdecl:4)
|
||||
|
||||
`static constexpr bool is_always_exhaustive() noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23494)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
If *rank_* equals zero or one, then true;
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
otherwise, if
|
||||
neither *static-padding-stride* nor *first-static-extent* equal dynamic_extent,
|
||||
then *static-padding-stride* == *first-static-extent*;
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
otherwise, false[.](#6.sentence-1)
|
||||
|
||||
[ð](#itemdecl:5)
|
||||
|
||||
`constexpr bool is_exhaustive() const noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23514)
|
||||
|
||||
*Returns*: true if *rank_* equals zero or one;
|
||||
otherwise, extents_.extent(0) == stride(1)[.](#7.sentence-1)
|
||||
|
||||
[ð](#itemdecl:6)
|
||||
|
||||
`constexpr index_type stride(rank_type r) const noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23525)
|
||||
|
||||
*Preconditions*: r is smaller than *rank_*[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23529)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
If r equals zero: 1;
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
otherwise, if r equals one: *stride-1*;
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
otherwise, the product of *stride-1* and
|
||||
all values extents_.extent(k) with k in the range [1, r)[.](#9.sentence-1)
|
||||
|
||||
[ð](#itemdecl:7)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
friend constexpr bool operator==(const mapping& x, const LayoutLeftPaddedMapping& y) noexcept;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23548)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true[.](#10.1.sentence-1)
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
LayoutLeftPaddedMapping::extents_type::rank() == rank_ is true[.](#10.2.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23558)
|
||||
|
||||
*Returns*: true if x.extents() == y.extents() is true and*rank_* < 2 || x.stride(1) == y.
|
||||
stride(1) is true[.](#11.sentence-1)
|
||||
|
||||
Otherwise, false[.](#11.sentence-2)
|
||||
110
cppdraft/mdspan/layout/leftpad/overview.md
Normal file
110
cppdraft/mdspan/layout/leftpad/overview.md
Normal file
@@ -0,0 +1,110 @@
|
||||
[mdspan.layout.leftpad.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.leftpad.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.leftpad.overview)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#leftpad.overview)
|
||||
|
||||
#### 23.7.3.4.8 Class template layout_left_padded::mapping [[mdspan.layout.leftpad]](mdspan.layout.leftpad#overview)
|
||||
|
||||
#### 23.7.3.4.8.1 Overview [mdspan.layout.leftpad.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22947)
|
||||
|
||||
layout_left_padded provides a layout mapping
|
||||
that behaves like layout_left::mapping,
|
||||
except that the padding stride stride(1) can be greater than or equal to extent(0)[.](#1.sentence-1)
|
||||
|
||||
namespace std {template<size_t PaddingValue>template<class Extents>class layout_left_padded<PaddingValue>::mapping {public:static constexpr size_t padding_value = PaddingValue; 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_left_padded<PaddingValue>; private:static constexpr size_t *rank_* = extents_type::rank(); // *exposition only*static constexpr size_t *first-static-extent* = // *exposition only* extents_type::static_extent(0); // [[mdspan.layout.leftpad.expo]](mdspan.layout.leftpad.expo "23.7.3.4.8.2 Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.leftpad.cons]](mdspan.layout.leftpad.cons "23.7.3.4.8.3 Constructors"), constructorsconstexpr mapping() noexcept : mapping(extents_type{}) {}constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&); template<class OtherIndexType>constexpr mapping(const extents_type&, OtherIndexType); template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_left::mapping<OtherExtents>&); template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&); template<class LayoutLeftPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutLeftPaddedMapping&); template<class LayoutRightPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutRightPaddedMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.leftpad.obs]](mdspan.layout.leftpad.obs "23.7.3.4.8.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr array<index_type, rank_> strides() const noexcept; constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept; static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class LayoutLeftPaddedMapping>friend constexpr bool operator==(const mapping&, const LayoutLeftPaddedMapping&) noexcept; private:// [[mdspan.layout.leftpad.expo]](mdspan.layout.leftpad.expo "23.7.3.4.8.2 Exposition-only members"), exposition-only members index_type *stride-1* = *static-padding-stride*; // *exposition only* extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23035)
|
||||
|
||||
If Extents is not a specialization of extents,
|
||||
then the program is ill-formed[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23039)
|
||||
|
||||
layout_left_padded::mapping<E> is a trivially copyable type
|
||||
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23043)
|
||||
|
||||
Throughout [[mdspan.layout.leftpad]](mdspan.layout.leftpad "23.7.3.4.8 Class template layout_left_padded::mapping"),
|
||||
let P_rank be the following
|
||||
size *rank_* parameter pack of size_t values:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
the empty parameter pack, if *rank_* equals zero;
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
otherwise, 0zu, if *rank_* equals one;
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23056)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
If rank_dynamic() == 0 is true,
|
||||
then the size of the multidimensional index space Extents() is representable as a value of type index_type[.](#5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
padding_value is representable as a value of type index_type[.](#5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
If
|
||||
* [(5.3.1)](#5.3.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.3.2)](#5.3.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.3.3)](#5.3.3)
|
||||
|
||||
*first-static-extent* does not equal dynamic_extent,
|
||||
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, *first-static-extent*) is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
If
|
||||
* [(5.4.1)](#5.4.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.4.2)](#5.4.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.4.3)](#5.4.3)
|
||||
|
||||
extents_type::static_extent(k) does not equal dynamic_extent for all k in the range [0, extents_type::rank()),
|
||||
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.static_extent(0)) and
|
||||
all values ext.static_extent(k) with k in the range of [1, *rank_*)
|
||||
is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#5.4.sentence-1)
|
||||
23
cppdraft/mdspan/layout/policy/overview.md
Normal file
23
cppdraft/mdspan/layout/policy/overview.md
Normal file
@@ -0,0 +1,23 @@
|
||||
[mdspan.layout.policy.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.policy.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.policy.overview)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#policy.overview)
|
||||
|
||||
#### 23.7.3.4.4 Layout mapping policies [mdspan.layout.policy.overview]
|
||||
|
||||
namespace std {struct layout_left {template<class Extents>class mapping; }; struct layout_right {template<class Extents>class mapping; }; struct layout_stride {template<class Extents>class mapping; }; template<size_t PaddingValue>struct layout_left_padded {template<class Extents> class mapping; }; template<size_t PaddingValue>struct layout_right_padded {template<class Extents> class mapping; };}
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21903)
|
||||
|
||||
Each of layout_left, layout_right, and layout_stride,
|
||||
as well as each specialization oflayout_left_padded and layout_right_padded,
|
||||
meets the layout mapping policy requirements and is a trivially copyable type[.](#1.sentence-1)
|
||||
|
||||
Furthermore,is_trivially_default_constructible_v<T> is true for any such type T[.](#1.sentence-2)
|
||||
21
cppdraft/mdspan/layout/policy/reqmts.md
Normal file
21
cppdraft/mdspan/layout/policy/reqmts.md
Normal file
@@ -0,0 +1,21 @@
|
||||
[mdspan.layout.policy.reqmts]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.policy.reqmts)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.policy.reqmts)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#policy.reqmts)
|
||||
|
||||
#### 23.7.3.4.3 Layout mapping policy requirements [mdspan.layout.policy.reqmts]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21866)
|
||||
|
||||
A type MP meets the [*layout mapping policy*](#def:layout_mapping_policy "23.7.3.4.3 Layout mapping policy requirements [mdspan.layout.policy.reqmts]") requirements
|
||||
if for a type E that is a specialization of extents,MP::mapping<E> is valid and denotes a type X that meets the layout mapping requirements ([[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2 Requirements")), and
|
||||
for which the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") X::layout_type is valid and
|
||||
denotes the type MP and
|
||||
the [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") X::extents_type denotes E[.](#1.sentence-1)
|
||||
352
cppdraft/mdspan/layout/reqmts.md
Normal file
352
cppdraft/mdspan/layout/reqmts.md
Normal file
@@ -0,0 +1,352 @@
|
||||
[mdspan.layout.reqmts]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.reqmts)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.reqmts)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#reqmts)
|
||||
|
||||
#### 23.7.3.4.2 Requirements [mdspan.layout.reqmts]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21594)
|
||||
|
||||
A type M meets the [*layout mapping*](#def:layout_mapping "23.7.3.4.2 Requirements [mdspan.layout.reqmts]") requirements if
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
M models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]") and [equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]"),
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
is_nothrow_move_constructible_v<M> is true,
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
is_nothrow_move_assignable_v<M> is true,
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
is_nothrow_swappable_v<M> is true, and
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
the following types and expressions are well-formed and
|
||||
have the specified semantics.
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`typename M::extents_type
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21616)
|
||||
|
||||
*Result*: A type that is a specialization of extents[.](#2.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`typename M::index_type
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21626)
|
||||
|
||||
*Result*: typename M::extents_type::index_type[.](#3.sentence-1)
|
||||
|
||||
[ð](#itemdecl:3)
|
||||
|
||||
`typename M::rank_type
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21636)
|
||||
|
||||
*Result*: typename M::extents_type::rank_type[.](#4.sentence-1)
|
||||
|
||||
[ð](#itemdecl:4)
|
||||
|
||||
`typename M::layout_type
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21646)
|
||||
|
||||
*Result*: A type MP that meets
|
||||
the layout mapping policy requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements")) and
|
||||
for which *is-mapping-of*<MP, M> is true[.](#5.sentence-1)
|
||||
|
||||
[ð](#itemdecl:5)
|
||||
|
||||
`m.extents()
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21658)
|
||||
|
||||
*Result*: const typename M::extents_type&
|
||||
|
||||
[ð](#itemdecl:6)
|
||||
|
||||
`m(i...)
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21668)
|
||||
|
||||
*Result*: typename M::index_type
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21672)
|
||||
|
||||
*Returns*: A nonnegative integer
|
||||
less than numeric_limits<typename M::index_type>::max() and
|
||||
less than or equal to numeric_limits<size_t>::max()[.](#8.sentence-1)
|
||||
|
||||
[ð](#itemdecl:7)
|
||||
|
||||
`m(i...) == m(static_cast<typename M::index_type>(i)...)
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21684)
|
||||
|
||||
*Result*: bool
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21688)
|
||||
|
||||
*Returns*: true
|
||||
|
||||
[ð](#itemdecl:8)
|
||||
|
||||
`m.required_span_size()
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21698)
|
||||
|
||||
*Result*: typename M::index_type
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21702)
|
||||
|
||||
*Returns*: If the size of the multidimensional index space m.extents() is 0,
|
||||
then 0,
|
||||
else 1 plus the maximum value of m(i...) for all i[.](#12.sentence-1)
|
||||
|
||||
[ð](#itemdecl:9)
|
||||
|
||||
`m.is_unique()
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21714)
|
||||
|
||||
*Result*: bool
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21718)
|
||||
|
||||
*Returns*: true only if
|
||||
for every i and j where (i != j || ...) is true,m(i...) != m(j...) is true[.](#14.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
A mapping can return false even if the condition is met[.](#14.sentence-2)
|
||||
|
||||
For certain layouts, it is possibly not feasible to determine efficiently
|
||||
whether the layout is unique[.](#14.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:10)
|
||||
|
||||
`m.is_exhaustive()
|
||||
`
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21735)
|
||||
|
||||
*Result*: bool
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21739)
|
||||
|
||||
*Returns*: true only if
|
||||
for all k in the range [0, m.required_span_size()) there exists an i such that m(i...) equals k[.](#16.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
A mapping can return false even if the condition is met[.](#16.sentence-2)
|
||||
|
||||
For certain layouts, it is possibly not feasible to determine efficiently
|
||||
whether the layout is exhaustive[.](#16.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:11)
|
||||
|
||||
`m.is_strided()
|
||||
`
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21756)
|
||||
|
||||
*Result*: bool
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21760)
|
||||
|
||||
*Returns*: true only if
|
||||
for every rank index r of m.extents() there exists an integer sr such that,
|
||||
for all i where (i+dr) is
|
||||
a multidimensional index in m.extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview")),m((i + dr)...) - m(i...) equals sr[.](#18.sentence-1)
|
||||
|
||||
[*Note [3](#note-3)*:
|
||||
|
||||
This implies that for a strided layoutm(i0,â¦,ik)=m(0,â¦,0)+i0Ãs0+â¯+ikÃsk[.](#18.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[*Note [4](#note-4)*:
|
||||
|
||||
A mapping can return false even if the condition is met[.](#18.sentence-3)
|
||||
|
||||
For certain layouts, it is possibly not feasible to determine efficiently
|
||||
whether the layout is strided[.](#18.sentence-4)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:12)
|
||||
|
||||
`m.stride(r)
|
||||
`
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21784)
|
||||
|
||||
*Preconditions*: m.is_strided() is true[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21788)
|
||||
|
||||
*Result*: typename M::index_type
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21792)
|
||||
|
||||
*Returns*: sr as defined in m.is_strided() above[.](#21.sentence-1)
|
||||
|
||||
[22](#22)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21796)
|
||||
|
||||
[*Note [5](#note-5)*:
|
||||
|
||||
It is not required for m.stride(r) to be well-formed
|
||||
if m.extents().rank() is zero,
|
||||
even if m.is_always_strided() is true[.](#22.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:13)
|
||||
|
||||
`M::is_always_unique()
|
||||
`
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21809)
|
||||
|
||||
*Result*: A constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type bool[.](#23.sentence-1)
|
||||
|
||||
[24](#24)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21813)
|
||||
|
||||
*Returns*: true only if m.is_unique() is true for all possible objects m of type M[.](#24.sentence-1)
|
||||
|
||||
[*Note [6](#note-6)*:
|
||||
|
||||
A mapping can return false even if the above condition is met[.](#24.sentence-2)
|
||||
|
||||
For certain layout mappings, it is possibly not feasible to determine
|
||||
whether every instance is unique[.](#24.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:14)
|
||||
|
||||
`M::is_always_exhaustive()
|
||||
`
|
||||
|
||||
[25](#25)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21829)
|
||||
|
||||
*Result*: A constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type bool[.](#25.sentence-1)
|
||||
|
||||
[26](#26)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21833)
|
||||
|
||||
*Returns*: true only if m.is_exhaustive() is true for all possible objects m of type M[.](#26.sentence-1)
|
||||
|
||||
[*Note [7](#note-7)*:
|
||||
|
||||
A mapping can return false even if the above condition is met[.](#26.sentence-2)
|
||||
|
||||
For certain layout mappings, it is possibly not feasible to determine
|
||||
whether every instance is exhaustive[.](#26.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[ð](#itemdecl:15)
|
||||
|
||||
`M::is_always_strided()
|
||||
`
|
||||
|
||||
[27](#27)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21849)
|
||||
|
||||
*Result*: A constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type bool[.](#27.sentence-1)
|
||||
|
||||
[28](#28)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21853)
|
||||
|
||||
*Returns*: true only if m.is_strided() is true for all possible objects m of type M[.](#28.sentence-1)
|
||||
|
||||
[*Note [8](#note-8)*:
|
||||
|
||||
A mapping can return false even if the above condition is met[.](#28.sentence-2)
|
||||
|
||||
For certain layout mappings, it is possibly not feasible to determine
|
||||
whether every instance is strided[.](#28.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
319
cppdraft/mdspan/layout/right.md
Normal file
319
cppdraft/mdspan/layout/right.md
Normal file
@@ -0,0 +1,319 @@
|
||||
[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 {template<class Extents>class 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; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_left::mapping<OtherExtents>&) noexcept; template<class LayoutRightPaddedMapping>constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
|
||||
extents_type>) mapping(const LayoutRightPaddedMapping&) noexcept; template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&) 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; template<class... Indices>constexpr 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; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend 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<E> 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<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[3](#cons-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22352)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> 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<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_left::mapping<OtherExtents>& 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<extents_type, OtherExtents> 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<class LayoutRightPaddedMapping>
|
||||
constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
|
||||
extents_type>)
|
||||
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*<LayoutRightPaddedMapping> is true[.](#cons-9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#cons-9.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
|
||||
type> 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<class OtherExtents>
|
||||
constexpr explicit(extents_type::rank() > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[13](#cons-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22454)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> 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<class... Indices>
|
||||
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<Indices, index_type> && ...) is true, and
|
||||
|
||||
- [(2.3)](#obs-2.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) 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_for<Indices...>, index_sequence<P...>> is true[.](#obs-4.sentence-1)
|
||||
|
||||
Equivalent to:return ((static_cast<index_type>(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<class OtherExtents>
|
||||
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& 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();
|
||||
192
cppdraft/mdspan/layout/right/cons.md
Normal file
192
cppdraft/mdspan/layout/right/cons.md
Normal file
@@ -0,0 +1,192 @@
|
||||
[mdspan.layout.right.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.right.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right.cons)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right.cons)
|
||||
|
||||
#### 23.7.3.4.6 Class template layout_right::mapping [[mdspan.layout.right]](mdspan.layout.right#cons)
|
||||
|
||||
#### 23.7.3.4.6.2 Constructors [mdspan.layout.right.cons]
|
||||
|
||||
[ð](#lib:layout_right::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& e) noexcept;
|
||||
`
|
||||
|
||||
[1](#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"))[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22339)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with e[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right::mapping,constructor_)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22352)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#3.sentence-1)
|
||||
|
||||
[4](#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"))[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22361)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_left::mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22374)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
extents_type::rank() <= 1 is true, and
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
|
||||
|
||||
[7](#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"))[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22388)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#8.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right::mapping,constructor___)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
|
||||
extents_type>)
|
||||
mapping(const LayoutRightPaddedMapping&) noexcept;
|
||||
`
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22402)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#9.1.sentence-1)
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
|
||||
type> is true[.](#9.2.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22413)
|
||||
|
||||
*Mandates*: If
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
Extents::rank() is greater than one,
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
Extents::static_extent(Extents::rank() - 1) does not equal dynamic_extent, and
|
||||
|
||||
- [(10.3)](#10.3)
|
||||
|
||||
LayoutRightPaddedMapping::*static-padding-stride* does not equal dynamic_extent,
|
||||
|
||||
then Extents::static_extent(Extents::rank() - 1) equalsLayoutRightPaddedMapping::*static-padding-stride*[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22429)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
If extents_type::rank() > 1 is true,
|
||||
then other.stride(extents_type::rank() - 2)
|
||||
equalsother.extents().extent(extents_type::rank() - 1)[.](#11.1.sentence-1)
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#11.2.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22441)
|
||||
|
||||
*Effects*: Direct-non-list-initializes extents_ with other.extents()[.](#12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right::mapping,constructor____)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(extents_type::rank() > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other) noexcept;
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22454)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22458)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(14.1)](#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)[.](#14.1.sentence-1)
|
||||
|
||||
- [(14.2)](#14.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#14.2.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22471)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#15.sentence-1)
|
||||
104
cppdraft/mdspan/layout/right/obs.md
Normal file
104
cppdraft/mdspan/layout/right/obs.md
Normal file
@@ -0,0 +1,104 @@
|
||||
[mdspan.layout.right.obs]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.right.obs)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right.obs)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right.obs)
|
||||
|
||||
#### 23.7.3.4.6 Class template layout_right::mapping [[mdspan.layout.right]](mdspan.layout.right#obs)
|
||||
|
||||
#### 23.7.3.4.6.3 Observers [mdspan.layout.right.obs]
|
||||
|
||||
[ð](#lib:required_span_size,layout_right::mapping)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22484)
|
||||
|
||||
*Returns*: extents().*fwd-prod-of-extents*(extents_type::rank())[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:operator(),layout_right::mapping)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr index_type operator()(Indices... i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22496)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
sizeof...(Indices) == extents_type::rank() is true,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true, and
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) istrue[.](#2.sentence-1)
|
||||
|
||||
[3](#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"))[.](#3.sentence-1)
|
||||
|
||||
[4](#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_for<Indices...>, index_sequence<P...>> is true[.](#4.sentence-1)
|
||||
|
||||
Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
|
||||
|
||||
[ð](#lib:stride,layout_right::mapping)
|
||||
|
||||
`constexpr index_type stride(rank_type i) const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22531)
|
||||
|
||||
*Constraints*: extents_type::rank() > 0 is true[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22535)
|
||||
|
||||
*Preconditions*: i < extents_type::rank() is true[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22539)
|
||||
|
||||
*Returns*: extents().*rev-prod-of-extents*(i)[.](#7.sentence-1)
|
||||
|
||||
[ð](#lib:operator==,layout_right::mapping)
|
||||
|
||||
`template<class OtherExtents>
|
||||
friend constexpr bool operator==(const mapping& x, const mapping<OtherExtents>& y) noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22551)
|
||||
|
||||
*Constraints*: extents_type::rank() == OtherExtents::rank() is true[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22555)
|
||||
|
||||
*Effects*: Equivalent to: return x.extents() == y.extents();
|
||||
45
cppdraft/mdspan/layout/right/overview.md
Normal file
45
cppdraft/mdspan/layout/right/overview.md
Normal file
@@ -0,0 +1,45 @@
|
||||
[mdspan.layout.right.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.right.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.right.overview)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#right.overview)
|
||||
|
||||
#### 23.7.3.4.6 Class template layout_right::mapping [[mdspan.layout.right]](mdspan.layout.right#overview)
|
||||
|
||||
#### 23.7.3.4.6.1 Overview [mdspan.layout.right.overview]
|
||||
|
||||
[1](#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[.](#1.sentence-1)
|
||||
|
||||
namespace std {template<class Extents>class 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]](mdspan.layout.right.cons "23.7.3.4.6.2 Constructors"), constructorsconstexpr mapping() noexcept = default; constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const mapping<OtherExtents>&) noexcept; template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_left::mapping<OtherExtents>&) noexcept; template<class LayoutRightPaddedMapping>constexpr explicit(!is_convertible_v<typename LayoutRightPaddedMapping::extents_type,
|
||||
extents_type>) mapping(const LayoutRightPaddedMapping&) noexcept; template<class OtherExtents>constexpr explicit(extents_type::rank() > 0) mapping(const layout_stride::mapping<OtherExtents>&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.right.obs]](mdspan.layout.right.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; template<class... Indices>constexpr 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; template<class OtherExtents>friend constexpr bool operator==(const mapping&, const mapping<OtherExtents>&) noexcept; private: extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}
|
||||
|
||||
[2](#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[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22316)
|
||||
|
||||
layout_right::mapping<E> is a trivially copyable type
|
||||
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#3.sentence-1)
|
||||
|
||||
[4](#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[.](#4.sentence-1)
|
||||
638
cppdraft/mdspan/layout/rightpad.md
Normal file
638
cppdraft/mdspan/layout/rightpad.md
Normal file
@@ -0,0 +1,638 @@
|
||||
[mdspan.layout.rightpad]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.rightpad)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad)
|
||||
|
||||
#### 23.7.3.4.9 Class template layout_right_padded::mapping [mdspan.layout.rightpad]
|
||||
|
||||
#### [23.7.3.4.9.1](#overview) Overview [[mdspan.layout.rightpad.overview]](mdspan.layout.rightpad.overview)
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23569)
|
||||
|
||||
layout_right_padded provides a layout mapping
|
||||
that behaves like layout_right::mapping,
|
||||
except that the padding stride stride(extents_type::rank() - 2) can be greater than or equal toextents_type::extent(extents_type::rank() - 1)[.](#overview-1.sentence-1)
|
||||
|
||||
namespace std {template<size_t PaddingValue>template<class Extents>class layout_right_padded<PaddingValue>::mapping {public:static constexpr size_t padding_value = PaddingValue; 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_padded<PaddingValue>; private:static constexpr size_t *rank_* = extents_type::rank(); // *exposition only*static constexpr size_t *last-static-extent* = // *exposition only* extents_type::static_extent(*rank_* - 1); // [[mdspan.layout.rightpad.expo]](#expo "23.7.3.4.9.2 Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.rightpad.cons]](#cons "23.7.3.4.9.3 Constructors"), constructorsconstexpr mapping() noexcept : mapping(extents_type{}) {}constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&); template<class OtherIndexType>constexpr mapping(const extents_type&, OtherIndexType); template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_right::mapping<OtherExtents>&); template<class OtherExtents>constexpr explicit(rank_ > 0) mapping(const layout_stride::mapping<OtherExtents>&); template<class LayoutRightPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutRightPaddedMapping&); template<class LayoutLeftPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutLeftPaddedMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.rightpad.obs]](#obs "23.7.3.4.9.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return extents_; }constexpr array<index_type, rank_> strides() const noexcept; constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept; static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class LayoutRightPaddedMapping>friend constexpr bool operator==(const mapping&, const LayoutRightPaddedMapping&) noexcept; private:// [[mdspan.layout.rightpad.expo]](#expo "23.7.3.4.9.2 Exposition-only members"), exposition-only members index_type *stride-rm2* = *static-padding-stride*; // *exposition only* extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend 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#L23661)
|
||||
|
||||
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#L23665)
|
||||
|
||||
layout_right_padded::mapping<E> 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#L23669)
|
||||
|
||||
Throughout [mdspan.layout.rightpad],
|
||||
let P_rank be the following
|
||||
size *rank_* parameter pack of size_t values:
|
||||
|
||||
- [(4.1)](#overview-4.1)
|
||||
|
||||
the empty parameter pack, if *rank_* equals zero;
|
||||
|
||||
- [(4.2)](#overview-4.2)
|
||||
|
||||
otherwise, 0zu, if *rank_* equals one;
|
||||
|
||||
- [(4.3)](#overview-4.3)
|
||||
|
||||
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#overview-4.sentence-1)
|
||||
|
||||
[5](#overview-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23682)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(5.1)](#overview-5.1)
|
||||
|
||||
If rank_dynamic() == 0 is true,
|
||||
then the size of the multidimensional index space Extents() is representable as a value of type index_type[.](#overview-5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#overview-5.2)
|
||||
|
||||
padding_value is representable as a value of type index_type[.](#overview-5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#overview-5.3)
|
||||
|
||||
If
|
||||
* [(5.3.1)](#overview-5.3.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.3.2)](#overview-5.3.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.3.3)](#overview-5.3.3)
|
||||
|
||||
*last-static-extent* does not equal dynamic_extent,
|
||||
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*) is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#overview-5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#overview-5.4)
|
||||
|
||||
If
|
||||
* [(5.4.1)](#overview-5.4.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.4.2)](#overview-5.4.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.4.3)](#overview-5.4.3)
|
||||
|
||||
extents_type::static_extent(k) does not equal dynamic_extent for all k in the range [0, *rank_*),
|
||||
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.static_extent(*rank_* - 1)) and
|
||||
all values ext.static_extent(k) with k in the range of [0, *rank_* - 1)
|
||||
is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#overview-5.4.sentence-1)
|
||||
|
||||
#### [23.7.3.4.9.2](#expo) Exposition-only members [[mdspan.layout.rightpad.expo]](mdspan.layout.rightpad.expo)
|
||||
|
||||
[ð](#expo-itemdecl:1)
|
||||
|
||||
`static constexpr size_t static-padding-stride = see below;
|
||||
`
|
||||
|
||||
[1](#expo-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23730)
|
||||
|
||||
The value is
|
||||
|
||||
- [(1.1)](#expo-1.1)
|
||||
|
||||
0, if *rank_* equals zero or one;
|
||||
|
||||
- [(1.2)](#expo-1.2)
|
||||
|
||||
otherwise, dynamic_extent,
|
||||
if padding_value or *last-static-extent* equalsdynamic_extent;
|
||||
|
||||
- [(1.3)](#expo-1.3)
|
||||
|
||||
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*)[.](#expo-1.sentence-1)
|
||||
|
||||
[ð](#expo-itemdecl:2)
|
||||
|
||||
`index_type stride-rm2 = static-padding-stride;
|
||||
`
|
||||
|
||||
[2](#expo-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23750)
|
||||
|
||||
*Recommended practice*: Implementations should not store this value
|
||||
if *static-padding-stride* is not dynamic_extent[.](#expo-2.sentence-1)
|
||||
|
||||
[*Note [1](#expo-note-1)*:
|
||||
|
||||
Using extents<index_type, *static-padding-stride*> instead of index_type as the type of *stride-rm2* would achieve this[.](#expo-2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.4.9.3](#cons) Constructors [[mdspan.layout.rightpad.cons]](mdspan.layout.rightpad.cons)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& ext);
|
||||
`
|
||||
|
||||
[1](#cons-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23769)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(1.1)](#cons-1.1)
|
||||
|
||||
The size of the multidimensional index space ext is representable as a value of type index_type[.](#cons-1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#cons-1.2)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1)) is representable as a value of type *index_type*[.](#cons-1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#cons-1.3)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1)) and
|
||||
all values ext.extent(k) with k in the range of [0, *rank_* - 1)
|
||||
is representable as a value of type index_type[.](#cons-1.3.sentence-1)
|
||||
|
||||
[2](#cons-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23790)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(2.1)](#cons-2.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with ext; and
|
||||
|
||||
- [(2.2)](#cons-2.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2*
|
||||
* [(2.2.1)](#cons-2.2.1)
|
||||
|
||||
with ext.extent(*rank_* - 1) if padding_value is dynamic_extent,
|
||||
|
||||
* [(2.2.2)](#cons-2.2.2)
|
||||
|
||||
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1))[.](#cons-2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor_)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& ext, OtherIndexType pad);
|
||||
`
|
||||
|
||||
[3](#cons-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23816)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#cons-3.1)
|
||||
|
||||
is_convertible_v<OtherIndexType, index_type> is true[.](#cons-3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#cons-3.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#cons-3.2.sentence-1)
|
||||
|
||||
[4](#cons-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23825)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(4.1)](#cons-4.1)
|
||||
|
||||
pad is representable as a value of type index_type[.](#cons-4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#cons-4.2)
|
||||
|
||||
extents_type::*index-cast*(pad) is greater than zero[.](#cons-4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#cons-4.3)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1)) is representable as a value of type index_type[.](#cons-4.3.sentence-1)
|
||||
|
||||
- [(4.4)](#cons-4.4)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1)) and
|
||||
all values ext.extent(k) with k in the range of [0, *rank_* - 1)
|
||||
is representable as a value of type index_type[.](#cons-4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#cons-4.5)
|
||||
|
||||
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#cons-4.5.sentence-1)
|
||||
|
||||
[5](#cons-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23848)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with ext, and
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2* with*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1))[.](#cons-5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_right::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[6](#cons-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23864)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-6.sentence-1)
|
||||
|
||||
[7](#cons-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23868)
|
||||
|
||||
*Mandates*: If OtherExtents::rank() is greater than 1, then(*static-padding-stride* == dynamic_extent) ||(OtherExtents::static_extent(*rank_* - 1) == dynamic_extent) ||(*static-padding-stride* == OtherExtents::static_extent(*rank_* - 1)) is true[.](#cons-7.sentence-1)
|
||||
|
||||
[8](#cons-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23878)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(8.1)](#cons-8.1)
|
||||
|
||||
If *rank_* > 1 is true andpadding_value == dynamic_extent is false, thenother.stride(
|
||||
*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(rank_ - 1))) and
|
||||
|
||||
- [(8.2)](#cons-8.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-8.sentence-1)
|
||||
|
||||
[9](#cons-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23895)
|
||||
|
||||
*Effects*: Equivalent to mapping(other.extents())[.](#cons-9.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor___)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(rank_ > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[10](#cons-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23908)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#cons-10.sentence-1)
|
||||
|
||||
[11](#cons-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23912)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#cons-11.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(*rank_* - 1)))
|
||||
|
||||
- [(11.2)](#cons-11.2)
|
||||
|
||||
If *rank_* is greater than 0,
|
||||
then other.stride(*rank_* - 1) equals 1[.](#cons-11.2.sentence-1)
|
||||
|
||||
- [(11.3)](#cons-11.3)
|
||||
|
||||
If *rank_* is greater than 2,
|
||||
then for all r in the range [0, *rank_* - 2),other.stride(r) equals(other.extents().*rev-prod-of-extents*(r) / other.extents().extent(*rank_* - 1)) * other.stride(*rank_* - 2)
|
||||
|
||||
- [(11.4)](#cons-11.4)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-11.4.sentence-1)
|
||||
|
||||
[12](#cons-12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23939)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(12.1)](#cons-12.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents(); and
|
||||
|
||||
- [(12.2)](#cons-12.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2* with other.stride(*rank_* - 2)[.](#cons-12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor____)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutRightPaddedMapping& other);
|
||||
`
|
||||
|
||||
[13](#cons-13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23959)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(13.1)](#cons-13.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#cons-13.1.sentence-1)
|
||||
|
||||
- [(13.2)](#cons-13.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
|
||||
type> is true[.](#cons-13.2.sentence-1)
|
||||
|
||||
[14](#cons-14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23970)
|
||||
|
||||
*Mandates*: If *rank_* is greater than 1, thenpadding_value == dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutRightPaddedMapping::padding_value is true[.](#cons-14.sentence-1)
|
||||
|
||||
[15](#cons-15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23980)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(15.1)](#cons-15.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extent(*rank_* - 1)))
|
||||
|
||||
- [(15.2)](#cons-15.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-15.sentence-1)
|
||||
|
||||
[16](#cons-16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23996)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(16.1)](#cons-16.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents(); and
|
||||
|
||||
- [(16.2)](#cons-16.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2* with other.stride(rank_ - 2)[.](#cons-16.sentence-1)
|
||||
|
||||
[17](#cons-17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24007)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:*rank_* > 1 &&(padding_value != dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor_____)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutLeftPaddedMapping& other) noexcept;
|
||||
`
|
||||
|
||||
[18](#cons-18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24025)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(18.1)](#cons-18.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true or
|
||||
*is-mapping-of*<layout_left, LayoutLeftPaddedMapping> is true[.](#cons-18.1.sentence-1)
|
||||
|
||||
- [(18.2)](#cons-18.2)
|
||||
|
||||
*rank_* equals zero or one[.](#cons-18.2.sentence-1)
|
||||
|
||||
- [(18.3)](#cons-18.3)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
|
||||
is true[.](#cons-18.3.sentence-1)
|
||||
|
||||
[19](#cons-19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24040)
|
||||
|
||||
*Preconditions*: other.required_span_size() is representable as
|
||||
a value of type index_type[.](#cons-19.sentence-1)
|
||||
|
||||
[20](#cons-20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24045)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#cons-20.sentence-1)
|
||||
|
||||
[21](#cons-21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24049)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type, extents_type>
|
||||
|
||||
[*Note [1](#cons-note-1)*:
|
||||
|
||||
Neither the input mapping nor the mapping to be constructed
|
||||
uses the padding stride in the rank-0 or rank-1 case,
|
||||
so the padding stride affects neither the constraints nor the preconditions[.](#cons-21.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.4.9.4](#obs) Observers [[mdspan.layout.rightpad.obs]](mdspan.layout.rightpad.obs)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,strides)
|
||||
|
||||
`constexpr array<index_type, rank_> strides() const noexcept;
|
||||
`
|
||||
|
||||
[1](#obs-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24070)
|
||||
|
||||
*Returns*: array<index_type, *rank_*>(stride(P_rank)...)[.](#obs-1.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,required_span_size)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[2](#obs-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24081)
|
||||
|
||||
*Returns*: 0 if the multidimensional index space *extents_* is empty,
|
||||
otherwise *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#obs-2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,operator())
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr size_t operator()(Indices... idxs) const noexcept;
|
||||
`
|
||||
|
||||
[3](#obs-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24094)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#obs-3.1)
|
||||
|
||||
sizeof...(Indices) == *rank_* is true[.](#obs-3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#obs-3.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true[.](#obs-3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#obs-3.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-3.3.sentence-1)
|
||||
|
||||
[4](#obs-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24105)
|
||||
|
||||
*Preconditions*: extents_type::*index-cast*(idxs) is
|
||||
a multidimensional index in extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#obs-4.sentence-1)
|
||||
|
||||
[5](#obs-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24110)
|
||||
|
||||
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#obs-5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,is_always_exhaustive)
|
||||
|
||||
`static constexpr bool is_always_exhaustive() noexcept;
|
||||
`
|
||||
|
||||
[6](#obs-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24121)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(6.1)](#obs-6.1)
|
||||
|
||||
If *rank_* equals zero or one, then true;
|
||||
|
||||
- [(6.2)](#obs-6.2)
|
||||
|
||||
otherwise,
|
||||
if neither *static-padding-stride* nor *last-static-extent* equal dynamic_extent,
|
||||
then *static-padding-stride* == *last-static-extent*;
|
||||
|
||||
- [(6.3)](#obs-6.3)
|
||||
|
||||
otherwise, false[.](#obs-6.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,is_exhaustive)
|
||||
|
||||
`constexpr bool is_exhaustive() const noexcept;
|
||||
`
|
||||
|
||||
[7](#obs-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24142)
|
||||
|
||||
*Returns*: true if *rank_* equals zero or one;
|
||||
otherwise,*extents_*.extent(*rank_* - 1) == stride(*rank_* - 2)
|
||||
|
||||
[ð](#obs-itemdecl:6)
|
||||
|
||||
`constexpr index_type stride(rank_type r) const noexcept;
|
||||
`
|
||||
|
||||
[8](#obs-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24156)
|
||||
|
||||
*Preconditions*: r is smaller than *rank_*[.](#obs-8.sentence-1)
|
||||
|
||||
[9](#obs-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24160)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(9.1)](#obs-9.1)
|
||||
|
||||
If r equals *rank_* - 1: 1;
|
||||
|
||||
- [(9.2)](#obs-9.2)
|
||||
|
||||
otherwise, if r equals *rank_* - 2: *stride-rm2*;
|
||||
|
||||
- [(9.3)](#obs-9.3)
|
||||
|
||||
otherwise,
|
||||
the product of *stride-rm2* and
|
||||
all values extents_.extent(k) with k in the range of [r + 1, *rank_* - 1)[.](#obs-9.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,operator==)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept;
|
||||
`
|
||||
|
||||
[10](#obs-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24182)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(10.1)](#obs-10.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#obs-10.1.sentence-1)
|
||||
|
||||
- [(10.2)](#obs-10.2)
|
||||
|
||||
LayoutRightPaddedMapping::extents_type::rank() == *rank_* is true[.](#obs-10.2.sentence-1)
|
||||
|
||||
[11](#obs-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24193)
|
||||
|
||||
*Returns*: true if x.extents() == y.extents() is true and*rank_* < 2 || x.stride(*rank_* - 2) == y.stride(*rank_* - 2) is true[.](#obs-11.sentence-1)
|
||||
|
||||
Otherwise, false[.](#obs-11.sentence-2)
|
||||
337
cppdraft/mdspan/layout/rightpad/cons.md
Normal file
337
cppdraft/mdspan/layout/rightpad/cons.md
Normal file
@@ -0,0 +1,337 @@
|
||||
[mdspan.layout.rightpad.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.rightpad.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.cons)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.cons)
|
||||
|
||||
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#cons)
|
||||
|
||||
#### 23.7.3.4.9.3 Constructors [mdspan.layout.rightpad.cons]
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor)
|
||||
|
||||
`constexpr mapping(const extents_type& ext);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23769)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
The size of the multidimensional index space ext is representable as a value of type index_type[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1)) is representable as a value of type *index_type*[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
If *rank_* is greater than one andpadding_value does not equal dynamic_extent,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1)) and
|
||||
all values ext.extent(k) with k in the range of [0, *rank_* - 1)
|
||||
is representable as a value of type index_type[.](#1.3.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23790)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with ext; and
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2*
|
||||
* [(2.2.1)](#2.2.1)
|
||||
|
||||
with ext.extent(*rank_* - 1) if padding_value is dynamic_extent,
|
||||
|
||||
* [(2.2.2)](#2.2.2)
|
||||
|
||||
otherwise with*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.extent(*rank_* - 1))[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor_)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& ext, OtherIndexType pad);
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23816)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
is_convertible_v<OtherIndexType, index_type> is true[.](#3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, OtherIndexType> is true[.](#3.2.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23825)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
pad is representable as a value of type index_type[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
extents_type::*index-cast*(pad) is greater than zero[.](#4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1)) is representable as a value of type index_type[.](#4.3.sentence-1)
|
||||
|
||||
- [(4.4)](#4.4)
|
||||
|
||||
If *rank_* is greater than one,
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1)) and
|
||||
all values ext.extent(k) with k in the range of [0, *rank_* - 1)
|
||||
is representable as a value of type index_type[.](#4.4.sentence-1)
|
||||
|
||||
- [(4.5)](#4.5)
|
||||
|
||||
If padding_value is not equal to dynamic_extent,padding_value equals extents_type::*index-cast*(pad)[.](#4.5.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23848)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with ext, and
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2* with*LEAST-MULTIPLE-AT-LEAST*(pad, ext.extent(*rank_* - 1))[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor__)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(!is_convertible_v<OtherExtents, extents_type>)
|
||||
mapping(const layout_right::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23864)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23868)
|
||||
|
||||
*Mandates*: If OtherExtents::rank() is greater than 1, then(*static-padding-stride* == dynamic_extent) ||(OtherExtents::static_extent(*rank_* - 1) == dynamic_extent) ||(*static-padding-stride* == OtherExtents::static_extent(*rank_* - 1)) is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23878)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(8.1)](#8.1)
|
||||
|
||||
If *rank_* > 1 is true andpadding_value == dynamic_extent is false, thenother.stride(
|
||||
*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(rank_ - 1))) and
|
||||
|
||||
- [(8.2)](#8.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23895)
|
||||
|
||||
*Effects*: Equivalent to mapping(other.extents())[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor___)
|
||||
|
||||
`template<class OtherExtents>
|
||||
constexpr explicit(rank_ > 0)
|
||||
mapping(const layout_stride::mapping<OtherExtents>& other);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23908)
|
||||
|
||||
*Constraints*: is_constructible_v<extents_type, OtherExtents> is true[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23912)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extents().extent(*rank_* - 1)))
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
If *rank_* is greater than 0,
|
||||
then other.stride(*rank_* - 1) equals 1[.](#11.2.sentence-1)
|
||||
|
||||
- [(11.3)](#11.3)
|
||||
|
||||
If *rank_* is greater than 2,
|
||||
then for all r in the range [0, *rank_* - 2),other.stride(r) equals(other.extents().*rev-prod-of-extents*(r) / other.extents().extent(*rank_* - 1)) * other.stride(*rank_* - 2)
|
||||
|
||||
- [(11.4)](#11.4)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#11.4.sentence-1)
|
||||
|
||||
[12](#12)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23939)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(12.1)](#12.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents(); and
|
||||
|
||||
- [(12.2)](#12.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2* with other.stride(*rank_* - 2)[.](#12.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor____)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutRightPaddedMapping& other);
|
||||
`
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23959)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(13.1)](#13.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#13.1.sentence-1)
|
||||
|
||||
- [(13.2)](#13.2)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutRightPaddedMapping::extents_-
|
||||
type> is true[.](#13.2.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23970)
|
||||
|
||||
*Mandates*: If *rank_* is greater than 1, thenpadding_value == dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent || padding_value == LayoutRightPaddedMapping::padding_value is true[.](#14.sentence-1)
|
||||
|
||||
[15](#15)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23980)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(15.1)](#15.1)
|
||||
|
||||
If *rank_* is greater than 1 andpadding_value does not equal dynamic_extent,
|
||||
then other.stride(*rank_* - 2) equals*LEAST-MULTIPLE-AT-LEAST*(padding_value,
|
||||
extents_type::*index-cast*(other.extent(*rank_* - 1)))
|
||||
|
||||
- [(15.2)](#15.2)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23996)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(16.1)](#16.1)
|
||||
|
||||
Direct-non-list-initializes *extents_* with other.extents(); and
|
||||
|
||||
- [(16.2)](#16.2)
|
||||
|
||||
if *rank_* is greater than one,
|
||||
direct-non-list-initializes *stride-rm2* with other.stride(rank_ - 2)[.](#16.sentence-1)
|
||||
|
||||
[17](#17)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24007)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:*rank_* > 1 &&(padding_value != dynamic_extent || LayoutRightPaddedMapping::padding_value == dynamic_extent)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,constructor_____)
|
||||
|
||||
`template<class LayoutLeftPaddedMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const LayoutLeftPaddedMapping& other) noexcept;
|
||||
`
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24025)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(18.1)](#18.1)
|
||||
|
||||
*is-layout-left-padded-mapping-of*<LayoutLeftPaddedMapping> is true or
|
||||
*is-mapping-of*<layout_left, LayoutLeftPaddedMapping> is true[.](#18.1.sentence-1)
|
||||
|
||||
- [(18.2)](#18.2)
|
||||
|
||||
*rank_* equals zero or one[.](#18.2.sentence-1)
|
||||
|
||||
- [(18.3)](#18.3)
|
||||
|
||||
is_constructible_v<extents_type, typename LayoutLeftPaddedMapping::extents_type>
|
||||
is true[.](#18.3.sentence-1)
|
||||
|
||||
[19](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24040)
|
||||
|
||||
*Preconditions*: other.required_span_size() is representable as
|
||||
a value of type index_type[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24045)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents()[.](#20.sentence-1)
|
||||
|
||||
[21](#21)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24049)
|
||||
|
||||
*Remarks*: The expression inside explicit is equivalent to:!is_convertible_v<typename LayoutLeftPaddedMapping::extents_type, extents_type>
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Neither the input mapping nor the mapping to be constructed
|
||||
uses the padding stride in the rank-0 or rank-1 case,
|
||||
so the padding stride affects neither the constraints nor the preconditions[.](#21.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
55
cppdraft/mdspan/layout/rightpad/expo.md
Normal file
55
cppdraft/mdspan/layout/rightpad/expo.md
Normal file
@@ -0,0 +1,55 @@
|
||||
[mdspan.layout.rightpad.expo]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.rightpad.expo)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.expo)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.expo)
|
||||
|
||||
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#expo)
|
||||
|
||||
#### 23.7.3.4.9.2 Exposition-only members [mdspan.layout.rightpad.expo]
|
||||
|
||||
[ð](#itemdecl:1)
|
||||
|
||||
`static constexpr size_t static-padding-stride = see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23730)
|
||||
|
||||
The value is
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
0, if *rank_* equals zero or one;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise, dynamic_extent,
|
||||
if padding_value or *last-static-extent* equalsdynamic_extent;
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise, the size_t value which is*LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*)[.](#1.sentence-1)
|
||||
|
||||
[ð](#itemdecl:2)
|
||||
|
||||
`index_type stride-rm2 = static-padding-stride;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23750)
|
||||
|
||||
*Recommended practice*: Implementations should not store this value
|
||||
if *static-padding-stride* is not dynamic_extent[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
Using extents<index_type, *static-padding-stride*> instead of index_type as the type of *stride-rm2* would achieve this[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
169
cppdraft/mdspan/layout/rightpad/obs.md
Normal file
169
cppdraft/mdspan/layout/rightpad/obs.md
Normal file
@@ -0,0 +1,169 @@
|
||||
[mdspan.layout.rightpad.obs]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.rightpad.obs)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.obs)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.obs)
|
||||
|
||||
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#obs)
|
||||
|
||||
#### 23.7.3.4.9.4 Observers [mdspan.layout.rightpad.obs]
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,strides)
|
||||
|
||||
`constexpr array<index_type, rank_> strides() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24070)
|
||||
|
||||
*Returns*: array<index_type, *rank_*>(stride(P_rank)...)[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,required_span_size)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24081)
|
||||
|
||||
*Returns*: 0 if the multidimensional index space *extents_* is empty,
|
||||
otherwise *this(((*extents_*(P_rank) - index_type(1))...)) + 1[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,operator())
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr size_t operator()(Indices... idxs) const noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24094)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
sizeof...(Indices) == *rank_* is true[.](#3.1.sentence-1)
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true[.](#3.2.sentence-1)
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#3.3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24105)
|
||||
|
||||
*Preconditions*: extents_type::*index-cast*(idxs) is
|
||||
a multidimensional index in extents() ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24110)
|
||||
|
||||
*Returns*: ((static_cast<index_type>(idxs) * stride(P_rank)) + ... + 0)[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,is_always_exhaustive)
|
||||
|
||||
`static constexpr bool is_always_exhaustive() noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24121)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
If *rank_* equals zero or one, then true;
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
otherwise,
|
||||
if neither *static-padding-stride* nor *last-static-extent* equal dynamic_extent,
|
||||
then *static-padding-stride* == *last-static-extent*;
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
otherwise, false[.](#6.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,is_exhaustive)
|
||||
|
||||
`constexpr bool is_exhaustive() const noexcept;
|
||||
`
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24142)
|
||||
|
||||
*Returns*: true if *rank_* equals zero or one;
|
||||
otherwise,*extents_*.extent(*rank_* - 1) == stride(*rank_* - 2)
|
||||
|
||||
[ð](#itemdecl:6)
|
||||
|
||||
`constexpr index_type stride(rank_type r) const noexcept;
|
||||
`
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24156)
|
||||
|
||||
*Preconditions*: r is smaller than *rank_*[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24160)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
If r equals *rank_* - 1: 1;
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
otherwise, if r equals *rank_* - 2: *stride-rm2*;
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
otherwise,
|
||||
the product of *stride-rm2* and
|
||||
all values extents_.extent(k) with k in the range of [r + 1, *rank_* - 1)[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,operator==)
|
||||
|
||||
`template<class LayoutRightPaddedMapping>
|
||||
friend constexpr bool operator==(const mapping& x, const LayoutRightPaddedMapping& y) noexcept;
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24182)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
*is-layout-right-padded-mapping-of*<LayoutRightPaddedMapping> is true[.](#10.1.sentence-1)
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
LayoutRightPaddedMapping::extents_type::rank() == *rank_* is true[.](#10.2.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24193)
|
||||
|
||||
*Returns*: true if x.extents() == y.extents() is true and*rank_* < 2 || x.stride(*rank_* - 2) == y.stride(*rank_* - 2) is true[.](#11.sentence-1)
|
||||
|
||||
Otherwise, false[.](#11.sentence-2)
|
||||
110
cppdraft/mdspan/layout/rightpad/overview.md
Normal file
110
cppdraft/mdspan/layout/rightpad/overview.md
Normal file
@@ -0,0 +1,110 @@
|
||||
[mdspan.layout.rightpad.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.rightpad.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.rightpad.overview)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#rightpad.overview)
|
||||
|
||||
#### 23.7.3.4.9 Class template layout_right_padded::mapping [[mdspan.layout.rightpad]](mdspan.layout.rightpad#overview)
|
||||
|
||||
#### 23.7.3.4.9.1 Overview [mdspan.layout.rightpad.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23569)
|
||||
|
||||
layout_right_padded provides a layout mapping
|
||||
that behaves like layout_right::mapping,
|
||||
except that the padding stride stride(extents_type::rank() - 2) can be greater than or equal toextents_type::extent(extents_type::rank() - 1)[.](#1.sentence-1)
|
||||
|
||||
namespace std {template<size_t PaddingValue>template<class Extents>class layout_right_padded<PaddingValue>::mapping {public:static constexpr size_t padding_value = PaddingValue; 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_padded<PaddingValue>; private:static constexpr size_t *rank_* = extents_type::rank(); // *exposition only*static constexpr size_t *last-static-extent* = // *exposition only* extents_type::static_extent(*rank_* - 1); // [[mdspan.layout.rightpad.expo]](mdspan.layout.rightpad.expo "23.7.3.4.9.2 Exposition-only members"), exposition-only membersstatic constexpr size_t *static-padding-stride* = *see below*; // *exposition only*public:// [[mdspan.layout.rightpad.cons]](mdspan.layout.rightpad.cons "23.7.3.4.9.3 Constructors"), constructorsconstexpr mapping() noexcept : mapping(extents_type{}) {}constexpr mapping(const mapping&) noexcept = default; constexpr mapping(const extents_type&); template<class OtherIndexType>constexpr mapping(const extents_type&, OtherIndexType); template<class OtherExtents>constexpr explicit(!is_convertible_v<OtherExtents, extents_type>) mapping(const layout_right::mapping<OtherExtents>&); template<class OtherExtents>constexpr explicit(rank_ > 0) mapping(const layout_stride::mapping<OtherExtents>&); template<class LayoutRightPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutRightPaddedMapping&); template<class LayoutLeftPaddedMapping>constexpr explicit(*see below*) mapping(const LayoutLeftPaddedMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.rightpad.obs]](mdspan.layout.rightpad.obs "23.7.3.4.9.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return extents_; }constexpr array<index_type, rank_> strides() const noexcept; constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept; static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type) const noexcept; template<class LayoutRightPaddedMapping>friend constexpr bool operator==(const mapping&, const LayoutRightPaddedMapping&) noexcept; private:// [[mdspan.layout.rightpad.expo]](mdspan.layout.rightpad.expo "23.7.3.4.9.2 Exposition-only members"), exposition-only members index_type *stride-rm2* = *static-padding-stride*; // *exposition only* extents_type *extents_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23661)
|
||||
|
||||
If Extents is not a specialization of extents,
|
||||
then the program is ill-formed[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23665)
|
||||
|
||||
layout_right_padded::mapping<E> is a trivially copyable type
|
||||
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23669)
|
||||
|
||||
Throughout [[mdspan.layout.rightpad]](mdspan.layout.rightpad "23.7.3.4.9 Class template layout_right_padded::mapping"),
|
||||
let P_rank be the following
|
||||
size *rank_* parameter pack of size_t values:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
the empty parameter pack, if *rank_* equals zero;
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
otherwise, 0zu, if *rank_* equals one;
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
otherwise, the parameter pack 0zu, 1zu, …, *rank_*- 1[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L23682)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
If rank_dynamic() == 0 is true,
|
||||
then the size of the multidimensional index space Extents() is representable as a value of type index_type[.](#5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
padding_value is representable as a value of type index_type[.](#5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
If
|
||||
* [(5.3.1)](#5.3.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.3.2)](#5.3.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.3.3)](#5.3.3)
|
||||
|
||||
*last-static-extent* does not equal dynamic_extent,
|
||||
|
||||
then *LEAST-MULTIPLE-AT-LEAST*(padding_value, *last-static-extent*) is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#5.3.sentence-1)
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
If
|
||||
* [(5.4.1)](#5.4.1)
|
||||
|
||||
*rank_* is greater than one,
|
||||
|
||||
* [(5.4.2)](#5.4.2)
|
||||
|
||||
padding_value does not equal dynamic_extent, and
|
||||
|
||||
* [(5.4.3)](#5.4.3)
|
||||
|
||||
extents_type::static_extent(k) does not equal dynamic_extent for all k in the range [0, *rank_*),
|
||||
|
||||
then the product of*LEAST-MULTIPLE-AT-LEAST*(padding_value, ext.static_extent(*rank_* - 1)) and
|
||||
all values ext.static_extent(k) with k in the range of [0, *rank_* - 1)
|
||||
is representable as a value of type size_t, and
|
||||
is representable as a value of type index_type[.](#5.4.sentence-1)
|
||||
369
cppdraft/mdspan/layout/stride.md
Normal file
369
cppdraft/mdspan/layout/stride.md
Normal file
@@ -0,0 +1,369 @@
|
||||
[mdspan.layout.stride]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.stride)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride)
|
||||
|
||||
#### 23.7.3.4.7 Class template layout_stride::mapping [mdspan.layout.stride]
|
||||
|
||||
#### [23.7.3.4.7.1](#overview) Overview [[mdspan.layout.stride.overview]](mdspan.layout.stride.overview)
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22564)
|
||||
|
||||
layout_stride provides a layout mapping
|
||||
where the strides are user-defined[.](#overview-1.sentence-1)
|
||||
|
||||
namespace std {template<class Extents>class layout_stride::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_stride; private:static constexpr rank_type *rank_* = extents_type::rank(); // *exposition only*public:// [[mdspan.layout.stride.cons]](#cons "23.7.3.4.7.3 Constructors"), constructorsconstexpr mapping() noexcept; constexpr mapping(const mapping&) noexcept = default; template<class OtherIndexType>constexpr mapping(const extents_type&, span<OtherIndexType, *rank_*>) noexcept; template<class OtherIndexType>constexpr mapping(const extents_type&, const array<OtherIndexType, *rank_*>&) noexcept; template<class StridedLayoutMapping>constexpr explicit(*see below*) mapping(const StridedLayoutMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.stride.obs]](#obs "23.7.3.4.7.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr array<index_type, *rank_*> strides() const noexcept { return *strides_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept { return false; }static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type i) const noexcept { return *strides_*[i]; }template<class OtherMapping>friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; private: extents_type *extents_*{}; // *exposition only* array<index_type, *rank_*> *strides_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend 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#L22636)
|
||||
|
||||
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#L22640)
|
||||
|
||||
layout_stride::mapping<E> 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#L22644)
|
||||
|
||||
*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.7.2](#expo) Exposition-only helpers [[mdspan.layout.stride.expo]](mdspan.layout.stride.expo)
|
||||
|
||||
[1](#expo-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22652)
|
||||
|
||||
Let *REQUIRED-SPAN-SIZE*(e, strides) be:
|
||||
|
||||
- [(1.1)](#expo-1.1)
|
||||
|
||||
1, if e.rank() == 0 is true,
|
||||
|
||||
- [(1.2)](#expo-1.2)
|
||||
|
||||
otherwise 0, if the size of the multidimensional index space e is 0,
|
||||
|
||||
- [(1.3)](#expo-1.3)
|
||||
|
||||
otherwise 1 plus the sum of products of(e.extent(r) - 1) andextents_type::*index-cast*(strides[r]) for all r in the range [0, e.rank())[.](#expo-1.sentence-1)
|
||||
|
||||
[2](#expo-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22668)
|
||||
|
||||
Let *OFFSET*(m) be:
|
||||
|
||||
- [(2.1)](#expo-2.1)
|
||||
|
||||
m(), if e.rank() == 0 is true,
|
||||
|
||||
- [(2.2)](#expo-2.2)
|
||||
|
||||
otherwise 0, if the size of the multidimensional index space e is 0,
|
||||
|
||||
- [(2.3)](#expo-2.3)
|
||||
|
||||
otherwise m(z...) for a pack of integers z that is a multidimensional index in m.extents() and
|
||||
each element of z equals 0[.](#expo-2.sentence-1)
|
||||
|
||||
[3](#expo-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22681)
|
||||
|
||||
Let *is-extents* be the exposition-only variable template
|
||||
defined as follows:template<class T>constexpr bool *is-extents* = false; // *exposition only*template<class IndexType, size_t... Args>constexpr bool *is-extents*<extents<IndexType, Args...>> = true; // *exposition only*
|
||||
|
||||
[4](#expo-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22691)
|
||||
|
||||
Let [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]") be the exposition-only concept
|
||||
defined as follows:template<class M>concept [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]") = requires { // *exposition only*requires *is-extents*<typename M::extents_type>; { M::is_always_strided() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { M::is_always_exhaustive() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { M::is_always_unique() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>;
|
||||
bool_constant<M::is_always_strided()>::value;
|
||||
bool_constant<M::is_always_exhaustive()>::value;
|
||||
bool_constant<M::is_always_unique()>::value;};
|
||||
|
||||
[*Note [1](#expo-note-1)*:
|
||||
|
||||
This concept checks that the functionsM::is_always_strided(),M::is_always_exhaustive(), andM::is_always_unique() exist,
|
||||
are constant expressions, and
|
||||
have a return type of bool[.](#expo-4.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.4.7.3](#cons) Constructors [[mdspan.layout.stride.cons]](mdspan.layout.stride.cons)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,constructor)
|
||||
|
||||
`constexpr mapping() noexcept;
|
||||
`
|
||||
|
||||
[1](#cons-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22723)
|
||||
|
||||
*Preconditions*: layout_right::mapping<extents_type>().required_span_size() 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#L22728)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with extents_type(), and
|
||||
for all d in the range [0, *rank_*),
|
||||
direct-non-list-initializes *strides_*[d] withlayout_right::mapping<extents_type>().stride(d)[.](#cons-2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,constructor_)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
|
||||
template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
|
||||
`
|
||||
|
||||
[3](#cons-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22745)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#cons-3.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true, and
|
||||
|
||||
- [(3.2)](#cons-3.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#cons-3.sentence-1)
|
||||
|
||||
[4](#cons-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22754)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(4.1)](#cons-4.1)
|
||||
|
||||
The result of converting s[i] to index_type is greater than 0 for all i in the range [0, *rank_*)[.](#cons-4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#cons-4.2)
|
||||
|
||||
*REQUIRED-SPAN-SIZE*(e, s) is representable
|
||||
as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#cons-4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#cons-4.3)
|
||||
|
||||
If *rank_* is greater than 0,
|
||||
then there exists a permutation P of the integers
|
||||
in the range [0, *rank_*),
|
||||
such that s[pi] >= s[piâ1] * e.extent(piâ1) is true for all i in the range [1, *rank_*),
|
||||
where pi is the ith element of P[.](#cons-4.3.sentence-1)
|
||||
[*Note [1](#cons-note-1)*:
|
||||
For layout_stride,
|
||||
this condition is necessary and sufficient
|
||||
for is_unique() to be true[.](#cons-4.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[5](#cons-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22778)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with e, and
|
||||
for all d in the range [0, *rank_*),
|
||||
direct-non-list-initializes strides_[d] with as_const(s[d])[.](#cons-5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,constructor__)
|
||||
|
||||
`template<class StridedLayoutMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const StridedLayoutMapping& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#cons-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22793)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#cons-6.1)
|
||||
|
||||
[*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]")<StridedLayoutMapping> is satisfied[.](#cons-6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#cons-6.2)
|
||||
|
||||
is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type> is
|
||||
true[.](#cons-6.2.sentence-2)
|
||||
|
||||
- [(6.3)](#cons-6.3)
|
||||
|
||||
StridedLayoutMapping::is_always_unique() is true[.](#cons-6.3.sentence-1)
|
||||
|
||||
- [(6.4)](#cons-6.4)
|
||||
|
||||
StridedLayoutMapping::is_always_strided() is true[.](#cons-6.4.sentence-1)
|
||||
|
||||
[7](#cons-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22806)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(7.1)](#cons-7.1)
|
||||
|
||||
StridedLayoutMapping meets the layout mapping requirements ([[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2 Requirements")),
|
||||
|
||||
- [(7.2)](#cons-7.2)
|
||||
|
||||
other.stride(r) > 0 is true for every rank index r of extents(),
|
||||
|
||||
- [(7.3)](#cons-7.3)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")), and
|
||||
|
||||
- [(7.4)](#cons-7.4)
|
||||
|
||||
*OFFSET*(other) == 0 is true[.](#cons-7.sentence-1)
|
||||
|
||||
[8](#cons-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22821)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents(), and
|
||||
for all d in the range [0, *rank_*),
|
||||
direct-non-list-initializes *strides_*[d] with other.stride(d)[.](#cons-8.sentence-1)
|
||||
|
||||
[9](#cons-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22828)
|
||||
|
||||
Remarks: The expression inside explicit is equivalent to:!(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&(*is-mapping-of*<layout_left, StridedLayoutMapping> ||*is-mapping-of*<layout_right, StridedLayoutMapping> ||*is-layout-left-padded-mapping-of*<StridedLayoutMapping> ||*is-layout-right-padded-mapping-of*<StridedLayoutMapping> ||*is-mapping-of*<layout_stride, StridedLayoutMapping>))
|
||||
|
||||
#### [23.7.3.4.7.4](#obs) Observers [[mdspan.layout.stride.obs]](mdspan.layout.stride.obs)
|
||||
|
||||
[ð](#lib:required_span_size,layout_stride::mapping)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[1](#obs-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22848)
|
||||
|
||||
*Returns*: *REQUIRED-SPAN-SIZE*(extents(), *strides_*)[.](#obs-1.sentence-1)
|
||||
|
||||
[ð](#lib:operator(),layout_stride::mapping)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr index_type operator()(Indices... i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#obs-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22860)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(2.1)](#obs-2.1)
|
||||
|
||||
sizeof...(Indices) == *rank_* is true,
|
||||
|
||||
- [(2.2)](#obs-2.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true, and
|
||||
|
||||
- [(2.3)](#obs-2.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#obs-2.sentence-1)
|
||||
|
||||
[3](#obs-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22871)
|
||||
|
||||
*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#L22876)
|
||||
|
||||
*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#obs-4.sentence-1)
|
||||
|
||||
Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
|
||||
|
||||
[ð](#lib:is_exhaustive,layout_stride::mapping)
|
||||
|
||||
`constexpr bool is_exhaustive() const noexcept;
|
||||
`
|
||||
|
||||
[5](#obs-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22895)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(5.1)](#obs-5.1)
|
||||
|
||||
true if *rank_* is 0[.](#obs-5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#obs-5.2)
|
||||
|
||||
Otherwise, true if there is
|
||||
a permutation P of the integers in the range [0, *rank_*) such that stride(p0) equals 1, andstride(pi) equals stride(piâ1) * extents().extent(piâ1) for i in the range [1, *rank_*),
|
||||
where pi is the ith element of P[.](#obs-5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#obs-5.3)
|
||||
|
||||
Otherwise, false[.](#obs-5.3.sentence-1)
|
||||
|
||||
[ð](#lib:operator==,layout_stride::mapping)
|
||||
|
||||
`template<class OtherMapping>
|
||||
friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
|
||||
`
|
||||
|
||||
[6](#obs-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22919)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#obs-6.1)
|
||||
|
||||
[*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]")<OtherMapping> is satisfied[.](#obs-6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#obs-6.2)
|
||||
|
||||
*rank_* == OtherMapping::extents_type::rank() is true[.](#obs-6.2.sentence-1)
|
||||
|
||||
- [(6.3)](#obs-6.3)
|
||||
|
||||
OtherMapping::is_always_strided() is true[.](#obs-6.3.sentence-1)
|
||||
|
||||
[7](#obs-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22930)
|
||||
|
||||
*Preconditions*: OtherMapping meets the layout mapping requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"))[.](#obs-7.sentence-1)
|
||||
|
||||
[8](#obs-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22934)
|
||||
|
||||
*Returns*: true if x.extents() == y.extents() is true,*OFFSET*(y) == 0 is true, and
|
||||
each of x.stride(r) == y.stride(r) is true for r in the range [0, x.extents().rank())[.](#obs-8.sentence-1)
|
||||
|
||||
Otherwise, false[.](#obs-8.sentence-2)
|
||||
157
cppdraft/mdspan/layout/stride/cons.md
Normal file
157
cppdraft/mdspan/layout/stride/cons.md
Normal file
@@ -0,0 +1,157 @@
|
||||
[mdspan.layout.stride.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.stride.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.cons)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.cons)
|
||||
|
||||
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#cons)
|
||||
|
||||
#### 23.7.3.4.7.3 Constructors [mdspan.layout.stride.cons]
|
||||
|
||||
[ð](#lib:layout_stride::mapping,constructor)
|
||||
|
||||
`constexpr mapping() noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22723)
|
||||
|
||||
*Preconditions*: layout_right::mapping<extents_type>().required_span_size() is representable as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22728)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with extents_type(), and
|
||||
for all d in the range [0, *rank_*),
|
||||
direct-non-list-initializes *strides_*[d] withlayout_right::mapping<extents_type>().stride(d)[.](#2.sentence-1)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,constructor_)
|
||||
|
||||
`template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& e, span<OtherIndexType, rank_> s) noexcept;
|
||||
template<class OtherIndexType>
|
||||
constexpr mapping(const extents_type& e, const array<OtherIndexType, rank_>& s) noexcept;
|
||||
`
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22745)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true, and
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22754)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
The result of converting s[i] to index_type is greater than 0 for all i in the range [0, *rank_*)[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
*REQUIRED-SPAN-SIZE*(e, s) is representable
|
||||
as a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types"))[.](#4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
If *rank_* is greater than 0,
|
||||
then there exists a permutation P of the integers
|
||||
in the range [0, *rank_*),
|
||||
such that s[pi] >= s[piâ1] * e.extent(piâ1) is true for all i in the range [1, *rank_*),
|
||||
where pi is the ith element of P[.](#4.3.sentence-1)
|
||||
[*Note [1](#note-1)*:
|
||||
For layout_stride,
|
||||
this condition is necessary and sufficient
|
||||
for is_unique() to be true[.](#4.3.sentence-2)
|
||||
â *end note*]
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22778)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with e, and
|
||||
for all d in the range [0, *rank_*),
|
||||
direct-non-list-initializes strides_[d] with as_const(s[d])[.](#5.sentence-1)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,constructor__)
|
||||
|
||||
`template<class StridedLayoutMapping>
|
||||
constexpr explicit(see below)
|
||||
mapping(const StridedLayoutMapping& other) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22793)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
[*layout-mapping-alike*](mdspan.layout.stride.expo#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]")<StridedLayoutMapping> is satisfied[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
is_constructible_v<extents_type, typename StridedLayoutMapping::extents_type> is
|
||||
true[.](#6.2.sentence-2)
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
StridedLayoutMapping::is_always_unique() is true[.](#6.3.sentence-1)
|
||||
|
||||
- [(6.4)](#6.4)
|
||||
|
||||
StridedLayoutMapping::is_always_strided() is true[.](#6.4.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22806)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
StridedLayoutMapping meets the layout mapping requirements ([[mdspan.layout.reqmts]](mdspan.layout.reqmts "23.7.3.4.2 Requirements")),
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
other.stride(r) > 0 is true for every rank index r of extents(),
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
other.required_span_size() is representable as
|
||||
a value of type index_type ([[basic.fundamental]](basic.fundamental "6.9.2 Fundamental types")), and
|
||||
|
||||
- [(7.4)](#7.4)
|
||||
|
||||
*OFFSET*(other) == 0 is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22821)
|
||||
|
||||
*Effects*: Direct-non-list-initializes *extents_* with other.extents(), and
|
||||
for all d in the range [0, *rank_*),
|
||||
direct-non-list-initializes *strides_*[d] with other.stride(d)[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22828)
|
||||
|
||||
Remarks: The expression inside explicit is equivalent to:!(is_convertible_v<typename StridedLayoutMapping::extents_type, extents_type> &&(*is-mapping-of*<layout_left, StridedLayoutMapping> ||*is-mapping-of*<layout_right, StridedLayoutMapping> ||*is-layout-left-padded-mapping-of*<StridedLayoutMapping> ||*is-layout-right-padded-mapping-of*<StridedLayoutMapping> ||*is-mapping-of*<layout_stride, StridedLayoutMapping>))
|
||||
75
cppdraft/mdspan/layout/stride/expo.md
Normal file
75
cppdraft/mdspan/layout/stride/expo.md
Normal file
@@ -0,0 +1,75 @@
|
||||
[mdspan.layout.stride.expo]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.stride.expo)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.expo)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.expo)
|
||||
|
||||
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#expo)
|
||||
|
||||
#### 23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22652)
|
||||
|
||||
Let *REQUIRED-SPAN-SIZE*(e, strides) be:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
1, if e.rank() == 0 is true,
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise 0, if the size of the multidimensional index space e is 0,
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise 1 plus the sum of products of(e.extent(r) - 1) andextents_type::*index-cast*(strides[r]) for all r in the range [0, e.rank())[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22668)
|
||||
|
||||
Let *OFFSET*(m) be:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
m(), if e.rank() == 0 is true,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
otherwise 0, if the size of the multidimensional index space e is 0,
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
otherwise m(z...) for a pack of integers z that is a multidimensional index in m.extents() and
|
||||
each element of z equals 0[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22681)
|
||||
|
||||
Let *is-extents* be the exposition-only variable template
|
||||
defined as follows:template<class T>constexpr bool *is-extents* = false; // *exposition only*template<class IndexType, size_t... Args>constexpr bool *is-extents*<extents<IndexType, Args...>> = true; // *exposition only*
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22691)
|
||||
|
||||
Let [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]") be the exposition-only concept
|
||||
defined as follows:template<class M>concept [*layout-mapping-alike*](#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]") = requires { // *exposition only*requires *is-extents*<typename M::extents_type>; { M::is_always_strided() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { M::is_always_exhaustive() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { M::is_always_unique() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>;
|
||||
bool_constant<M::is_always_strided()>::value;
|
||||
bool_constant<M::is_always_exhaustive()>::value;
|
||||
bool_constant<M::is_always_unique()>::value;};
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This concept checks that the functionsM::is_always_strided(),M::is_always_exhaustive(), andM::is_always_unique() exist,
|
||||
are constant expressions, and
|
||||
have a return type of bool[.](#4.sentence-1)
|
||||
|
||||
â *end note*]
|
||||
127
cppdraft/mdspan/layout/stride/obs.md
Normal file
127
cppdraft/mdspan/layout/stride/obs.md
Normal file
@@ -0,0 +1,127 @@
|
||||
[mdspan.layout.stride.obs]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.stride.obs)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.obs)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.obs)
|
||||
|
||||
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#obs)
|
||||
|
||||
#### 23.7.3.4.7.4 Observers [mdspan.layout.stride.obs]
|
||||
|
||||
[ð](#lib:required_span_size,layout_stride::mapping)
|
||||
|
||||
`constexpr index_type required_span_size() const noexcept;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22848)
|
||||
|
||||
*Returns*: *REQUIRED-SPAN-SIZE*(extents(), *strides_*)[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:operator(),layout_stride::mapping)
|
||||
|
||||
`template<class... Indices>
|
||||
constexpr index_type operator()(Indices... i) const noexcept;
|
||||
`
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22860)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
sizeof...(Indices) == *rank_* is true,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
(is_convertible_v<Indices, index_type> && ...) is true, and
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, Indices> && ...) is true[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22871)
|
||||
|
||||
*Preconditions*: extents_type::*index-cast*(i) is
|
||||
a multidimensional index in *extents_* ([[mdspan.overview]](mdspan.overview "23.7.3.1 Overview"))[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22876)
|
||||
|
||||
*Effects*: Let P be a parameter pack such thatis_same_v<index_sequence_for<Indices...>, index_sequence<P...>> is true[.](#4.sentence-1)
|
||||
|
||||
Equivalent to:return ((static_cast<index_type>(i) * stride(P)) + ... + 0);
|
||||
|
||||
[ð](#lib:is_exhaustive,layout_stride::mapping)
|
||||
|
||||
`constexpr bool is_exhaustive() const noexcept;
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22895)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
true if *rank_* is 0[.](#5.1.sentence-1)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
Otherwise, true if there is
|
||||
a permutation P of the integers in the range [0, *rank_*) such that stride(p0) equals 1, andstride(pi) equals stride(piâ1) * extents().extent(piâ1) for i in the range [1, *rank_*),
|
||||
where pi is the ith element of P[.](#5.2.sentence-1)
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
Otherwise, false[.](#5.3.sentence-1)
|
||||
|
||||
[ð](#lib:operator==,layout_stride::mapping)
|
||||
|
||||
`template<class OtherMapping>
|
||||
friend constexpr bool operator==(const mapping& x, const OtherMapping& y) noexcept;
|
||||
`
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22919)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
[*layout-mapping-alike*](mdspan.layout.stride.expo#concept:layout-mapping-alike "23.7.3.4.7.2 Exposition-only helpers [mdspan.layout.stride.expo]")<OtherMapping> is satisfied[.](#6.1.sentence-1)
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
*rank_* == OtherMapping::extents_type::rank() is true[.](#6.2.sentence-1)
|
||||
|
||||
- [(6.3)](#6.3)
|
||||
|
||||
OtherMapping::is_always_strided() is true[.](#6.3.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22930)
|
||||
|
||||
*Preconditions*: OtherMapping meets the layout mapping requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"))[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22934)
|
||||
|
||||
*Returns*: true if x.extents() == y.extents() is true,*OFFSET*(y) == 0 is true, and
|
||||
each of x.stride(r) == y.stride(r) is true for r in the range [0, x.extents().rank())[.](#8.sentence-1)
|
||||
|
||||
Otherwise, false[.](#8.sentence-2)
|
||||
43
cppdraft/mdspan/layout/stride/overview.md
Normal file
43
cppdraft/mdspan/layout/stride/overview.md
Normal file
@@ -0,0 +1,43 @@
|
||||
[mdspan.layout.stride.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.layout.stride.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.layout.stride.overview)
|
||||
|
||||
#### 23.7.3.4 Layout mapping [[mdspan.layout]](mdspan.layout#stride.overview)
|
||||
|
||||
#### 23.7.3.4.7 Class template layout_stride::mapping [[mdspan.layout.stride]](mdspan.layout.stride#overview)
|
||||
|
||||
#### 23.7.3.4.7.1 Overview [mdspan.layout.stride.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22564)
|
||||
|
||||
layout_stride provides a layout mapping
|
||||
where the strides are user-defined[.](#1.sentence-1)
|
||||
|
||||
namespace std {template<class Extents>class layout_stride::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_stride; private:static constexpr rank_type *rank_* = extents_type::rank(); // *exposition only*public:// [[mdspan.layout.stride.cons]](mdspan.layout.stride.cons "23.7.3.4.7.3 Constructors"), constructorsconstexpr mapping() noexcept; constexpr mapping(const mapping&) noexcept = default; template<class OtherIndexType>constexpr mapping(const extents_type&, span<OtherIndexType, *rank_*>) noexcept; template<class OtherIndexType>constexpr mapping(const extents_type&, const array<OtherIndexType, *rank_*>&) noexcept; template<class StridedLayoutMapping>constexpr explicit(*see below*) mapping(const StridedLayoutMapping&) noexcept; constexpr mapping& operator=(const mapping&) noexcept = default; // [[mdspan.layout.stride.obs]](mdspan.layout.stride.obs "23.7.3.4.7.4 Observers"), observersconstexpr const extents_type& extents() const noexcept { return *extents_*; }constexpr array<index_type, *rank_*> strides() const noexcept { return *strides_*; }constexpr index_type required_span_size() const noexcept; template<class... Indices>constexpr index_type operator()(Indices...) const noexcept; static constexpr bool is_always_unique() noexcept { return true; }static constexpr bool is_always_exhaustive() noexcept { return false; }static constexpr bool is_always_strided() noexcept { return true; }static constexpr bool is_unique() noexcept { return true; }constexpr bool is_exhaustive() const noexcept; static constexpr bool is_strided() noexcept { return true; }constexpr index_type stride(rank_type i) const noexcept { return *strides_*[i]; }template<class OtherMapping>friend constexpr bool operator==(const mapping&, const OtherMapping&) noexcept; private: extents_type *extents_*{}; // *exposition only* array<index_type, *rank_*> *strides_*{}; // *exposition only*// [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping"), submdspan mapping specializationtemplate<class... SliceSpecifiers>constexpr auto *submdspan-mapping-impl*(SliceSpecifiers...) const // *exposition only*-> *see below*; template<class... SliceSpecifiers>friend constexpr auto submdspan_mapping(const mapping& src, SliceSpecifiers... slices) {return src.*submdspan-mapping-impl*(slices...); }};}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22636)
|
||||
|
||||
If Extents is not a specialization of extents,
|
||||
then the program is ill-formed[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22640)
|
||||
|
||||
layout_stride::mapping<E> is a trivially copyable type
|
||||
that models [regular](concepts.object#concept:regular "18.6 Object concepts [concepts.object]") for each E[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L22644)
|
||||
|
||||
*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[.](#4.sentence-1)
|
||||
621
cppdraft/mdspan/mdspan.md
Normal file
621
cppdraft/mdspan/mdspan.md
Normal file
@@ -0,0 +1,621 @@
|
||||
[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.2 Constructors"), 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.3 Members"), 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.1 Header <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.3 Layout mapping policy requirements")), andAccessorPolicy shall meet
|
||||
the accessor policy requirements ([[mdspan.accessor.reqmts]](mdspan.accessor.reqmts "23.7.3.5.2 Requirements"))[.](#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.6 Object 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.2 Fundamental 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_*);
|
||||
361
cppdraft/mdspan/mdspan/cons.md
Normal file
361
cppdraft/mdspan/mdspan/cons.md
Normal file
@@ -0,0 +1,361 @@
|
||||
[mdspan.mdspan.cons]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.mdspan.cons)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.mdspan.cons)
|
||||
|
||||
#### 23.7.3.6 Class template mdspan [[mdspan.mdspan]](mdspan.mdspan#cons)
|
||||
|
||||
#### 23.7.3.6.2 Constructors [mdspan.mdspan.cons]
|
||||
|
||||
[ð](#lib:mdspan,constructor)
|
||||
|
||||
`constexpr mdspan();
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24815)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
rank_dynamic() > 0 is true[.](#1.1.sentence-1)
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
is_default_constructible_v<data_handle_type> is true[.](#1.2.sentence-1)
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
is_default_constructible_v<mapping_type> is true[.](#1.3.sentence-1)
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
is_default_constructible_v<accessor_type> is true[.](#1.4.sentence-1)
|
||||
|
||||
[2](#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[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24835)
|
||||
|
||||
*Effects*: Value-initializes *ptr_*, *map_*, and *acc_*[.](#3.sentence-1)
|
||||
|
||||
[ð](#lib:mdspan,constructor_)
|
||||
|
||||
`template<class... OtherIndexTypes>
|
||||
constexpr explicit mdspan(data_handle_type p, OtherIndexTypes... exts);
|
||||
`
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24847)
|
||||
|
||||
Let N be sizeof...(OtherIndexTypes)[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24850)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
(is_nothrow_constructible<index_type, OtherIndexTypes> && ...) is true,
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
N == rank() || N == rank_dynamic() is true,
|
||||
|
||||
- [(5.4)](#5.4)
|
||||
|
||||
is_constructible_v<mapping_type, extents_type> is true, and
|
||||
|
||||
- [(5.5)](#5.5)
|
||||
|
||||
is_default_constructible_v<accessor_type> is true[.](#5.sentence-1)
|
||||
|
||||
[6](#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[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24872)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
Direct-non-list-initializes *ptr_* with std::move(p),
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
direct-non-list-initializes *map_* withextents_type(static_cast<index_type>(std::move(exts))...), and
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
value-initializes *acc_*[.](#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](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24896)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(8.1)](#8.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true,
|
||||
|
||||
- [(8.2)](#8.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true,
|
||||
|
||||
- [(8.3)](#8.3)
|
||||
|
||||
N == rank() || N == rank_dynamic() is true,
|
||||
|
||||
- [(8.4)](#8.4)
|
||||
|
||||
is_constructible_v<mapping_type, extents_type> is true, and
|
||||
|
||||
- [(8.5)](#8.5)
|
||||
|
||||
is_default_constructible_v<accessor_type> is true[.](#8.sentence-1)
|
||||
|
||||
[9](#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[.](#9.sentence-1)
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24918)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(10.1)](#10.1)
|
||||
|
||||
Direct-non-list-initializes *ptr_* with std::move(p),
|
||||
|
||||
- [(10.2)](#10.2)
|
||||
|
||||
direct-non-list-initializes *map_* with extents_type(exts), and
|
||||
|
||||
- [(10.3)](#10.3)
|
||||
|
||||
value-initializes *acc_*[.](#10.sentence-1)
|
||||
|
||||
[ð](#lib:mdspan,constructor___)
|
||||
|
||||
`constexpr mdspan(data_handle_type p, const extents_type& ext);
|
||||
`
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24936)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
is_constructible_v<mapping_type, const extents_type&> is true, and
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
is_default_constructible_v<accessor_type> is true[.](#11.sentence-1)
|
||||
|
||||
[12](#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[.](#12.sentence-1)
|
||||
|
||||
[13](#13)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24952)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(13.1)](#13.1)
|
||||
|
||||
Direct-non-list-initializes *ptr_* with std::move(p),
|
||||
|
||||
- [(13.2)](#13.2)
|
||||
|
||||
direct-non-list-initializes *map_* with ext, and
|
||||
|
||||
- [(13.3)](#13.3)
|
||||
|
||||
value-initializes *acc_*[.](#13.sentence-1)
|
||||
|
||||
[ð](#lib:mdspan,constructor____)
|
||||
|
||||
`constexpr mdspan(data_handle_type p, const mapping_type& m);
|
||||
`
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24970)
|
||||
|
||||
*Constraints*: is_default_constructible_v<accessor_type> is true[.](#14.sentence-1)
|
||||
|
||||
[15](#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[.](#15.sentence-1)
|
||||
|
||||
[16](#16)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24980)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(16.1)](#16.1)
|
||||
|
||||
Direct-non-list-initializes *ptr_* with std::move(p),
|
||||
|
||||
- [(16.2)](#16.2)
|
||||
|
||||
direct-non-list-initializes *map_* with m, and
|
||||
|
||||
- [(16.3)](#16.3)
|
||||
|
||||
value-initializes *acc_*[.](#16.sentence-1)
|
||||
|
||||
[ð](#lib:mdspan,constructor_____)
|
||||
|
||||
`constexpr mdspan(data_handle_type p, const mapping_type& m, const accessor_type& a);
|
||||
`
|
||||
|
||||
[17](#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[.](#17.sentence-1)
|
||||
|
||||
[18](#18)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25003)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(18.1)](#18.1)
|
||||
|
||||
Direct-non-list-initializes *ptr_* with std::move(p),
|
||||
|
||||
- [(18.2)](#18.2)
|
||||
|
||||
direct-non-list-initializes *map_* with m, and
|
||||
|
||||
- [(18.3)](#18.3)
|
||||
|
||||
direct-non-list-initializes *acc_* with a[.](#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](#19)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25025)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(19.1)](#19.1)
|
||||
|
||||
is_constructible_v<mapping_type, const OtherLayoutPolicy::template mapping<Oth-
|
||||
erExtents>&> is true, and
|
||||
|
||||
- [(19.2)](#19.2)
|
||||
|
||||
is_constructible_v<accessor_type, const OtherAccessor&> is true[.](#19.sentence-1)
|
||||
|
||||
[20](#20)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25035)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(20.1)](#20.1)
|
||||
|
||||
is_constructible_v<data_handle_type, const OtherAccessor::data_handle_type&> is
|
||||
true, and
|
||||
|
||||
- [(20.2)](#20.2)
|
||||
|
||||
is_constructible_v<extents_type, OtherExtents> is true[.](#20.sentence-1)
|
||||
|
||||
[21](#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[.](#21.sentence-1)
|
||||
|
||||
[22](#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[.](#22.sentence-1)
|
||||
|
||||
[23](#23)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25057)
|
||||
|
||||
*Effects*:
|
||||
|
||||
- [(23.1)](#23.1)
|
||||
|
||||
Direct-non-list-initializes *ptr_* with other.*ptr_*,
|
||||
|
||||
- [(23.2)](#23.2)
|
||||
|
||||
direct-non-list-initializes *map_* with other.*map_*, and
|
||||
|
||||
- [(23.3)](#23.3)
|
||||
|
||||
direct-non-list-initializes *acc_* with other.*acc_*[.](#23.sentence-1)
|
||||
|
||||
[24](#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>
|
||||
203
cppdraft/mdspan/mdspan/members.md
Normal file
203
cppdraft/mdspan/mdspan/members.md
Normal file
@@ -0,0 +1,203 @@
|
||||
[mdspan.mdspan.members]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.mdspan.members)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.mdspan.members)
|
||||
|
||||
#### 23.7.3.6 Class template mdspan [[mdspan.mdspan]](mdspan.mdspan#members)
|
||||
|
||||
#### 23.7.3.6.3 Members [mdspan.mdspan.members]
|
||||
|
||||
[ð](#lib:operator%5b%5d,mdspan)
|
||||
|
||||
`template<class... OtherIndexTypes>
|
||||
constexpr reference operator[](OtherIndexTypes... indices) const;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25086)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
sizeof...(OtherIndexTypes) == rank() is true[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25097)
|
||||
|
||||
Let I be extents_type::*index-cast*(std::move(indices))[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25100)
|
||||
|
||||
*Hardened preconditions*: I is a multidimensional index in extents()[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This implies that*map_*(I) < *map_*.required_span_size() is true[.](#3.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[4](#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](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25126)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true, and
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#5.sentence-1)
|
||||
|
||||
[6](#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[.](#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](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25155)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
(is_convertible_v<OtherIndexTypes, index_type> && ...) is true,
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
(is_nothrow_constructible_v<index_type, OtherIndexTypes> && ...) is true, and
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
sizeof...(OtherIndexTypes) == rank() is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25166)
|
||||
|
||||
Let I be extents_type::*index-cast*(std::move(indices))[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25169)
|
||||
|
||||
*Returns*: (*this)[I...][.](#9.sentence-1)
|
||||
|
||||
[10](#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()[.](#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](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25187)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
is_convertible_v<const OtherIndexType&, index_type> is true, and
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
is_nothrow_constructible_v<index_type, const OtherIndexType&> is true[.](#11.sentence-1)
|
||||
|
||||
[12](#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[.](#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](#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.2 Fundamental types"))[.](#13.sentence-1)
|
||||
|
||||
[14](#14)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25220)
|
||||
|
||||
*Returns*: extents().*fwd-prod-of-extents*(rank())[.](#14.sentence-1)
|
||||
|
||||
[ð](#lib:empty,mdspan)
|
||||
|
||||
`constexpr bool empty() const noexcept;
|
||||
`
|
||||
|
||||
[15](#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[.](#15.sentence-1)
|
||||
|
||||
[ð](#lib:swap,mdspan)
|
||||
|
||||
`friend constexpr void swap(mdspan& x, mdspan& y) noexcept;
|
||||
`
|
||||
|
||||
[16](#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_*);
|
||||
75
cppdraft/mdspan/mdspan/overview.md
Normal file
75
cppdraft/mdspan/mdspan/overview.md
Normal file
@@ -0,0 +1,75 @@
|
||||
[mdspan.mdspan.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.mdspan.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.mdspan.overview)
|
||||
|
||||
#### 23.7.3.6 Class template mdspan [[mdspan.mdspan]](mdspan.mdspan#overview)
|
||||
|
||||
#### 23.7.3.6.1 Overview [mdspan.mdspan.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24629)
|
||||
|
||||
mdspan is a view of a multidimensional array of elements[.](#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]](mdspan.mdspan.cons "23.7.3.6.2 Constructors"), 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]](mdspan.mdspan.members "23.7.3.6.3 Members"), 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.1 Header <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](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24772)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
ElementType is a complete object type
|
||||
that is neither an abstract class type nor an array type,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
Extents is a specialization of extents, and
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
is_same_v<ElementType, typename AccessorPolicy::element_type> is true[.](#2.sentence-1)
|
||||
|
||||
[3](#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.3 Layout mapping policy requirements")), andAccessorPolicy shall meet
|
||||
the accessor policy requirements ([[mdspan.accessor.reqmts]](mdspan.accessor.reqmts "23.7.3.5.2 Requirements"))[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L24791)
|
||||
|
||||
Each specialization MDS of mdspan models [copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]") and
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
is_nothrow_move_constructible_v<MDS> is true,
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
is_nothrow_move_assignable_v<MDS> is true, and
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
is_nothrow_swappable_v<MDS> is true[.](#4.sentence-1)
|
||||
|
||||
[5](#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[.](#5.sentence-1)
|
||||
49
cppdraft/mdspan/overview.md
Normal file
49
cppdraft/mdspan/overview.md
Normal file
@@ -0,0 +1,49 @@
|
||||
[mdspan.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.overview)
|
||||
|
||||
#### 23.7.3.1 Overview [mdspan.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20993)
|
||||
|
||||
A [*multidimensional index space*](#def:index_space,multidimensional "23.7.3.1 Overview [mdspan.overview]") is
|
||||
a Cartesian product of integer intervals[.](#1.sentence-1)
|
||||
|
||||
Each interval can be represented by a half-open range [Li,Ui),
|
||||
where Li and Ui are the lower and upper bounds of
|
||||
the ith dimension[.](#1.sentence-2)
|
||||
|
||||
The [*rank*](#def:rank "23.7.3.1 Overview [mdspan.overview]") of a multidimensional index space is
|
||||
the number of intervals it represents[.](#1.sentence-3)
|
||||
|
||||
The [*size of a multidimensional index space*](#def:size_of_a_multidimensional_index_space "23.7.3.1 Overview [mdspan.overview]") is
|
||||
the product of UiâLi for each dimension i if its rank is greater than 0, and 1 otherwise[.](#1.sentence-4)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21005)
|
||||
|
||||
An integer r is a [*rank index*](#def:rank_index "23.7.3.1 Overview [mdspan.overview]") of an index space S if r is in the range [0,rank of S)[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L21009)
|
||||
|
||||
A pack of integers idx is
|
||||
a [*multidimensional index*](#def:index,multidimensional "23.7.3.1 Overview [mdspan.overview]") in a multidimensional index space S (or representation thereof) if both of the following are true:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
sizeof...(idx) is equal to the rank of S, and
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
for every rank index i of S,
|
||||
the ith value of idx is an integer
|
||||
in the interval [Li,Ui) of S[.](#3.sentence-1)
|
||||
964
cppdraft/mdspan/sub.md
Normal file
964
cppdraft/mdspan/sub.md
Normal file
@@ -0,0 +1,964 @@
|
||||
[mdspan.sub]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub)
|
||||
|
||||
#### 23.7.3.7 submdspan [mdspan.sub]
|
||||
|
||||
#### [23.7.3.7.1](#overview) Overview [[mdspan.sub.overview]](mdspan.sub.overview)
|
||||
|
||||
[1](#overview-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25258)
|
||||
|
||||
The submdspan facilities create a new mdspan viewing a subset of elements of an existing input mdspan[.](#overview-1.sentence-1)
|
||||
|
||||
The subset viewed by the created mdspan is determined by
|
||||
the SliceSpecifier arguments[.](#overview-1.sentence-2)
|
||||
|
||||
[2](#overview-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25264)
|
||||
|
||||
For each function defined in [mdspan.sub] that
|
||||
takes a parameter pack named slices as an argument:
|
||||
|
||||
- [(2.1)](#overview-2.1)
|
||||
|
||||
let index_type be
|
||||
* [(2.1.1)](#overview-2.1.1)
|
||||
|
||||
M::index_type if the function is a member of a class M,
|
||||
|
||||
* [(2.1.2)](#overview-2.1.2)
|
||||
|
||||
otherwise, remove_reference_t<decltype(src)>::index_type if the function has a parameter named src,
|
||||
|
||||
* [(2.1.3)](#overview-2.1.3)
|
||||
|
||||
otherwise,
|
||||
the same type as the function's template argument IndexType;
|
||||
|
||||
- [(2.2)](#overview-2.2)
|
||||
|
||||
let rank be the number of elements in slices;
|
||||
|
||||
- [(2.3)](#overview-2.3)
|
||||
|
||||
let sk be the kth element of slices;
|
||||
|
||||
- [(2.4)](#overview-2.4)
|
||||
|
||||
let Sk be the type of sk; and
|
||||
|
||||
- [(2.5)](#overview-2.5)
|
||||
|
||||
let *map-rank* be an array<size_t, rank> such that
|
||||
for each k in the range [0, rank),*map-rank*[k] equals:
|
||||
* [(2.5.1)](#overview-2.5.1)
|
||||
|
||||
dynamic_extent if Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
* [(2.5.2)](#overview-2.5.2)
|
||||
|
||||
otherwise,
|
||||
the number of types Sj with j<k that
|
||||
do not model [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>[.](#overview-2.sentence-1)
|
||||
|
||||
#### [23.7.3.7.2](#strided.slice) strided_slice [[mdspan.sub.strided.slice]](mdspan.sub.strided.slice)
|
||||
|
||||
[1](#strided.slice-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25300)
|
||||
|
||||
strided_slice represents a set ofextent regularly spaced integer indices[.](#strided.slice-1.sentence-1)
|
||||
|
||||
The indices start at offset, and
|
||||
increase by increments of stride[.](#strided.slice-1.sentence-2)
|
||||
|
||||
[ð](#lib:strided_slice)
|
||||
|
||||
namespace std {template<class OffsetType, class ExtentType, class StrideType>struct strided_slice {using offset_type = OffsetType; using extent_type = ExtentType; using stride_type = StrideType; [[no_unique_address]] offset_type offset{}; [[no_unique_address]] extent_type extent{}; [[no_unique_address]] stride_type stride{}; };}
|
||||
|
||||
[2](#strided.slice-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25322)
|
||||
|
||||
strided_slice has the data members and special members specified above[.](#strided.slice-2.sentence-1)
|
||||
|
||||
It has no base classes or members other than those specified[.](#strided.slice-2.sentence-2)
|
||||
|
||||
[3](#strided.slice-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25326)
|
||||
|
||||
*Mandates*: OffsetType, ExtentType, and StrideType are signed or unsigned integer types, or
|
||||
model [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]")[.](#strided.slice-3.sentence-1)
|
||||
|
||||
[*Note [1](#strided.slice-note-1)*:
|
||||
|
||||
strided_slice{.offset = 1, .extent = 10, .stride = 3} indicates the indices 1, 4, 7, and 10[.](#strided.slice-3.sentence-2)
|
||||
|
||||
Indices are selected from the half-open interval [1, 1 + 10)[.](#strided.slice-3.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
|
||||
#### [23.7.3.7.3](#map.result) submdspan_mapping_result [[mdspan.sub.map.result]](mdspan.sub.map.result)
|
||||
|
||||
[1](#map.result-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25339)
|
||||
|
||||
Specializations of submdspan_mapping_result are returned by overloads of submdspan_mapping[.](#map.result-1.sentence-1)
|
||||
|
||||
[ð](#lib:submdspan_mapping_result)
|
||||
|
||||
namespace std {template<class LayoutMapping>struct submdspan_mapping_result {[[no_unique_address]] LayoutMapping mapping = LayoutMapping();
|
||||
size_t offset{}; };}
|
||||
|
||||
[2](#map.result-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25354)
|
||||
|
||||
submdspan_mapping_result has
|
||||
the data members and special members specified above[.](#map.result-2.sentence-1)
|
||||
|
||||
It has no base classes or members other than those specified[.](#map.result-2.sentence-2)
|
||||
|
||||
[3](#map.result-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25359)
|
||||
|
||||
LayoutMapping shall meet
|
||||
the layout mapping requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"))[.](#map.result-3.sentence-1)
|
||||
|
||||
#### [23.7.3.7.4](#helpers) Exposition-only helpers [[mdspan.sub.helpers]](mdspan.sub.helpers)
|
||||
|
||||
[ð](#lib:de-ice)
|
||||
|
||||
`template<class T>
|
||||
constexpr T de-ice(T val) { return val; }
|
||||
template<[integral-constant-like](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]") T>
|
||||
constexpr auto de-ice(T) { return T::value; }
|
||||
|
||||
template<class IndexType, size_t k, class... SliceSpecifiers>
|
||||
constexpr IndexType first_(SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[1](#helpers-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25378)
|
||||
|
||||
*Mandates*: IndexType is a signed or unsigned integer type[.](#helpers-1.sentence-1)
|
||||
|
||||
[2](#helpers-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25383)
|
||||
|
||||
Let Ïk denote the following value:
|
||||
|
||||
- [(2.1)](#helpers-2.1)
|
||||
|
||||
sk if Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<IndexType>;
|
||||
|
||||
- [(2.2)](#helpers-2.2)
|
||||
|
||||
otherwise,get<0>(sk) if Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<IndexType>;
|
||||
|
||||
- [(2.3)](#helpers-2.3)
|
||||
|
||||
otherwise,*de-ice*(sk.offset) if Sk is a specialization of strided_slice;
|
||||
|
||||
- [(2.4)](#helpers-2.4)
|
||||
|
||||
otherwise,0[.](#helpers-2.sentence-1)
|
||||
|
||||
[3](#helpers-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25401)
|
||||
|
||||
*Preconditions*: Ïk is representable as a value of type IndexType[.](#helpers-3.sentence-1)
|
||||
|
||||
[4](#helpers-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25405)
|
||||
|
||||
*Returns*: extents<IndexType>::*index-cast*(Ïk)[.](#helpers-4.sentence-1)
|
||||
|
||||
[ð](#lib:last_)
|
||||
|
||||
`template<size_t k, class Extents, class... SliceSpecifiers>
|
||||
constexpr auto last_(const Extents& src, SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[5](#helpers-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25417)
|
||||
|
||||
*Mandates*: Extents is a specialization of extents[.](#helpers-5.sentence-1)
|
||||
|
||||
[6](#helpers-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25421)
|
||||
|
||||
Let index_type be typename Extents::index_type[.](#helpers-6.sentence-1)
|
||||
|
||||
[7](#helpers-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25425)
|
||||
|
||||
Let λk denote the following value:
|
||||
|
||||
- [(7.1)](#helpers-7.1)
|
||||
|
||||
*de-ice*(sk) + 1 if Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>; otherwise
|
||||
|
||||
- [(7.2)](#helpers-7.2)
|
||||
|
||||
get<1>(sk) if Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>; otherwise
|
||||
|
||||
- [(7.3)](#helpers-7.3)
|
||||
|
||||
*de-ice*(sk.offset) +*de-ice*(sk.extent) if Sk is a specialization of strided_slice; otherwise
|
||||
|
||||
- [(7.4)](#helpers-7.4)
|
||||
|
||||
src.extent(k)[.](#helpers-7.sentence-1)
|
||||
|
||||
[8](#helpers-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25443)
|
||||
|
||||
*Preconditions*: λk is representable as a value of type index_type[.](#helpers-8.sentence-1)
|
||||
|
||||
[9](#helpers-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25447)
|
||||
|
||||
*Returns*: Extents::*index-cast*(λk)[.](#helpers-9.sentence-1)
|
||||
|
||||
[ð](#lib:src-indices)
|
||||
|
||||
`template<class IndexType, size_t N, class... SliceSpecifiers>
|
||||
constexpr array<IndexType, sizeof...(SliceSpecifiers)>
|
||||
src-indices(const array<IndexType, N>& indices, SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[10](#helpers-10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25460)
|
||||
|
||||
*Mandates*: IndexType is a signed or unsigned integer type[.](#helpers-10.sentence-1)
|
||||
|
||||
[11](#helpers-11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25464)
|
||||
|
||||
*Returns*: An array<IndexType, sizeof...(SliceSpecifiers)> src_idx such that
|
||||
for each k in the range [0, sizeof...(SliceSpecifiers)),src_idx[k] equals
|
||||
|
||||
- [(11.1)](#helpers-11.1)
|
||||
|
||||
*first_*<IndexType, k>(slices...) for each k where *map-rank*[k] equalsdynamic_extent,
|
||||
|
||||
- [(11.2)](#helpers-11.2)
|
||||
|
||||
otherwise,*first_*<IndexType, k>(slices...) +indices[*map-rank*[k]].
|
||||
|
||||
#### [23.7.3.7.5](#extents) submdspan_extents function [[mdspan.sub.extents]](mdspan.sub.extents)
|
||||
|
||||
[ð](#lib:submdspan_extents)
|
||||
|
||||
`template<class IndexType, size_t... Extents, class... SliceSpecifiers>
|
||||
constexpr auto submdspan_extents(const extents<IndexType, Extents...>& src,
|
||||
SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[1](#extents-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25496)
|
||||
|
||||
*Constraints*: sizeof...(slices) equals sizeof...(Extents)[.](#extents-1.sentence-1)
|
||||
|
||||
[2](#extents-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25500)
|
||||
|
||||
*Mandates*: For each rank index k of src.extents(),
|
||||
exactly one of the following is true:
|
||||
|
||||
- [(2.1)](#extents-2.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<IndexType>,
|
||||
|
||||
- [(2.2)](#extents-2.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<IndexType>,
|
||||
|
||||
- [(2.3)](#extents-2.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
- [(2.4)](#extents-2.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#extents-2.sentence-1)
|
||||
|
||||
[3](#extents-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25511)
|
||||
|
||||
*Preconditions*: For each rank index k of src.extents(),
|
||||
all of the following are true:
|
||||
|
||||
- [(3.1)](#extents-3.1)
|
||||
|
||||
if Sk is a specialization of strided_slice
|
||||
* [(3.1.1)](#extents-3.1.1)
|
||||
|
||||
sk.extent=0, or
|
||||
|
||||
* [(3.1.2)](#extents-3.1.2)
|
||||
|
||||
sk.stride>0
|
||||
|
||||
- [(3.2)](#extents-3.2)
|
||||
|
||||
0 ⤠*first_*<IndexType, k>(slices...) ⤠*last_*<k>(src, slices...) ⤠src.extent(k)
|
||||
|
||||
[4](#extents-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25528)
|
||||
|
||||
Let SubExtents be a specialization of extents such that:
|
||||
|
||||
- [(4.1)](#extents-4.1)
|
||||
|
||||
SubExtents::rank() equals the number of k such thatSk does not model [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<IndexType>; and
|
||||
|
||||
- [(4.2)](#extents-4.2)
|
||||
|
||||
for each rank index k of Extents such that*map-rank*[k] != dynamic_extent is true,SubExtents::static_extent(*map-rank*[k]) equals:
|
||||
* [(4.2.1)](#extents-4.2.1)
|
||||
|
||||
Extents::static_extent(k) if is_convertible_v<Sk, full_extent_t> is true;
|
||||
otherwise
|
||||
|
||||
* [(4.2.2)](#extents-4.2.2)
|
||||
|
||||
*de-ice*(tuple_element_t<1, Sk>()) -*de-ice*(tuple_element_t<0, Sk>()) if Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<IndexType>, and
|
||||
both tuple_element_t<0, Sk> and tuple_element_t<1, Sk> model [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]"); otherwise
|
||||
|
||||
* [(4.2.3)](#extents-4.2.3)
|
||||
|
||||
0,
|
||||
if Sk is a specialization of strided_slice, whose extent_type models *integral-constant-like*,
|
||||
for which extent_type() equals zero; otherwise
|
||||
|
||||
* [(4.2.4)](#extents-4.2.4)
|
||||
|
||||
1 + (*de-ice*(Sk::extent_type()) - 1) /*de-ice*(Sk::stride_type()),
|
||||
if Sk is a specialization of strided_slice whose extent_type and stride_type model *integral-constant-like*;
|
||||
|
||||
* [(4.2.5)](#extents-4.2.5)
|
||||
|
||||
otherwise, dynamic_extent[.](#extents-4.sentence-1)
|
||||
|
||||
[5](#extents-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25573)
|
||||
|
||||
*Returns*: A value ext of type SubExtents such that
|
||||
for each k for which *map-rank*[k] != dynamic_extent is true,ext.extent(*map-rank*[k]) equals:
|
||||
|
||||
- [(5.1)](#extents-5.1)
|
||||
|
||||
sk.extent == 0 ? 0 : 1 + (*de-ice*(sk.extent) - 1) / *de-ice*(sk.stride) if Sk is a specialization of strided_slice,
|
||||
|
||||
- [(5.2)](#extents-5.2)
|
||||
|
||||
otherwise,*last_*<k>(src, slices...) - *first_*<IndexType, k>(slices...)[.](#extents-5.sentence-1)
|
||||
|
||||
#### [23.7.3.7.6](#map) Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map)
|
||||
|
||||
#### [23.7.3.7.6.1](#map.common) Common [[mdspan.sub.map.common]](mdspan.sub.map.common)
|
||||
|
||||
[1](#map.common-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25594)
|
||||
|
||||
The following elements apply to all functions in [[mdspan.sub.map]](#map "23.7.3.7.6 Specializations of submdspan_mapping")[.](#map.common-1.sentence-1)
|
||||
|
||||
[2](#map.common-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25597)
|
||||
|
||||
*Constraints*: sizeof...(slices) equals extents_type::rank()[.](#map.common-2.sentence-1)
|
||||
|
||||
[3](#map.common-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25601)
|
||||
|
||||
*Mandates*: For each rank index k of extents(),
|
||||
exactly one of the following is true:
|
||||
|
||||
- [(3.1)](#map.common-3.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
- [(3.2)](#map.common-3.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>,
|
||||
|
||||
- [(3.3)](#map.common-3.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
- [(3.4)](#map.common-3.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#map.common-3.sentence-1)
|
||||
|
||||
[4](#map.common-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25616)
|
||||
|
||||
*Preconditions*: For each rank index k of extents(),
|
||||
all of the following are true:
|
||||
|
||||
- [(4.1)](#map.common-4.1)
|
||||
|
||||
if Sk is a specialization of strided_slice,sk.extent is equal to zero orsk.stride is greater than zero; and
|
||||
|
||||
- [(4.2)](#map.common-4.2)
|
||||
|
||||
0 ⤠*first_*<index_type, k>(slices...)
|
||||
0 ⤠*last_*<k>(extents(), slices...)
|
||||
0 ⤠extents().extent(k)
|
||||
|
||||
[5](#map.common-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25631)
|
||||
|
||||
Let sub_ext be
|
||||
the result of submdspan_extents(extents(), slices...) and
|
||||
let SubExtents be decltype(sub_ext)[.](#map.common-5.sentence-1)
|
||||
|
||||
[6](#map.common-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25636)
|
||||
|
||||
Let sub_strides be
|
||||
an array<SubExtents::index_type, SubExtents::rank()> such that for each rank index k of extents() for which *map-rank*[k] is not dynamic_extent,sub_strides[*map-rank*[k]] equals:
|
||||
|
||||
- [(6.1)](#map.common-6.1)
|
||||
|
||||
stride(k) * *de-ice*(sk.stride) if Sk is a specialization of strided_slice andsk.stride < sk.extent is true;
|
||||
|
||||
- [(6.2)](#map.common-6.2)
|
||||
|
||||
otherwise, stride(k)[.](#map.common-6.sentence-1)
|
||||
|
||||
[7](#map.common-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25651)
|
||||
|
||||
Let P be a parameter pack
|
||||
such that is_same_v<make_index_sequence<rank()>, index_sequence<P...>> is true[.](#map.common-7.sentence-1)
|
||||
|
||||
[8](#map.common-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25656)
|
||||
|
||||
If *first_*<index_type, k>(slices...) equals extents().extent(k) for any rank index k of extents(), then
|
||||
let offset be a value of type size_t equal to(*this).required_span_size()[.](#map.common-8.sentence-1)
|
||||
|
||||
Otherwise,
|
||||
let offset be a value of type size_t equal to(*this)(*first_*<index_type, P>(slices...)...)[.](#map.common-8.sentence-2)
|
||||
|
||||
[9](#map.common-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25666)
|
||||
|
||||
Given a layout mapping type M, a type S is a[*unit-stride slice for M*](#def:slice,unit-stride "23.7.3.7.6.1 Common [mdspan.sub.map.common]") if
|
||||
|
||||
- [(9.1)](#map.common-9.1)
|
||||
|
||||
S is a specialization of strided_slice where S::stride_type models [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]") and S::stride_type::value equals 1,
|
||||
|
||||
- [(9.2)](#map.common-9.2)
|
||||
|
||||
S models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<M::index_type>, or
|
||||
|
||||
- [(9.3)](#map.common-9.3)
|
||||
|
||||
is_convertible_v<S, full_extent_t> is true[.](#map.common-9.sentence-1)
|
||||
|
||||
#### [23.7.3.7.6.2](#map.left) layout_left specialization of submdspan_mapping [[mdspan.sub.map.left]](mdspan.sub.map.left)
|
||||
|
||||
[ð](#lib:layout_left::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_left::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#map.left-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25688)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#map.left-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#map.left-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if SubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#map.left-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#map.left-1.3.1)
|
||||
|
||||
for each k in the range [0, SubExtents::rank() - 1)), is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.3.2)](#map.left-1.3.2)
|
||||
|
||||
for k equal to SubExtents::rank() - 1, Sk is a unit-stride slice for mapping;
|
||||
|
||||
[*Note [1](#map.left-note-1)*:
|
||||
If the above conditions are true,
|
||||
all Sk with k larger than SubExtents::rank() - 1 are convertible to index_type[.](#map.left-1.3.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#map.left-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
|
||||
offset} if for a value u for which u+1 is
|
||||
the smallest value p larger than zero
|
||||
for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#map.left-1.4.1)
|
||||
|
||||
S0 is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#map.left-1.4.2)
|
||||
|
||||
for each k in the range [u + 1, u + SubExtents::rank() - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#map.left-1.4.3)
|
||||
|
||||
for k equal to u + SubExtents::rank() - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#map.left-1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if static_extent(k) is dynamic_extent for any k in the range [0, u + 1),
|
||||
|
||||
* [(1.4.5)](#map.left-1.4.5)
|
||||
|
||||
otherwise, the product of all valuesstatic_extent(k) for k in the range [0, u + 1);
|
||||
|
||||
- [(1.5)](#map.left-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.3](#map.right) layout_right specialization of submdspan_mapping [[mdspan.sub.map.right]](mdspan.sub.map.right)
|
||||
|
||||
[ð](#lib:layout_right::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_right::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#map.right-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25764)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#map.right-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#map.right-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if SubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#map.right-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#map.right-1.3.1)
|
||||
|
||||
for each k in the range [*rank_* - SubExtents::rank() + 1, *rank_*), is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.3.2)](#map.right-1.3.2)
|
||||
|
||||
for k equal to *_rank* - SubExtents::rank(), Sk is a unit-stride slice for mapping;
|
||||
|
||||
[*Note [1](#map.right-note-1)*:
|
||||
If the above conditions are true,
|
||||
all Sk with k<_rank - SubExtents::rank() are convertible to index_type[.](#map.right-1.3.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#map.right-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
|
||||
stride(*rank_* - u - 2)), offset} if for a value u for which rank_âuâ2 is
|
||||
the largest value p smaller than *rank_* - 1 for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#map.right-1.4.1)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#map.right-1.4.2)
|
||||
|
||||
for each k in the range
|
||||
[*rank_* - SubExtents::rank() - u + 1, *rank_* - u - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#map.right-1.4.3)
|
||||
|
||||
for k equal to *rank_* - SubExtents::rank() - u,
|
||||
Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#map.right-1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if static_extent(k) is dynamic_extent for any k in the range [*rank_* - u - 1, *rank_*),
|
||||
|
||||
* [(1.4.5)](#map.right-1.4.5)
|
||||
|
||||
otherwise, the product of all valuesstatic_extent(k) for k in the range [*rank_* - u - 1, *rank_*);
|
||||
|
||||
- [(1.5)](#map.right-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.4](#map.stride) layout_stride specialization of submdspan_mapping [[mdspan.sub.map.stride]](mdspan.sub.map.stride)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_stride::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#map.stride-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25843)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#map.stride-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#map.stride-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.5](#map.leftpad) layout_left_padded specialization of submdspan_mapping [[mdspan.sub.map.leftpad]](mdspan.sub.map.leftpad)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_left_padded::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#map.leftpad-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25868)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#map.leftpad-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#map.leftpad-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if *rank_* == 1 is true orSubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#map.leftpad-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#map.leftpad-1.3.1)
|
||||
|
||||
SubExtents::rank() == 1 is true and
|
||||
|
||||
* [(1.3.2)](#map.leftpad-1.3.2)
|
||||
|
||||
S0 is a unit-stride slice for mapping;
|
||||
|
||||
- [(1.4)](#map.leftpad-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
|
||||
offset} if for a value u for which u + 1 is the smallest value p larger than zero
|
||||
for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#map.leftpad-1.4.1)
|
||||
|
||||
S0 is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#map.leftpad-1.4.2)
|
||||
|
||||
for each k in the range [u + 1, u + SubExtents::rank() - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#map.leftpad-1.4.3)
|
||||
|
||||
for k equal to u + SubExtents::rank() - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
where S_static is:
|
||||
* [(1.4.4)](#map.leftpad-1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if *static-padding-stride* is dynamic_extent orstatic_extent(k) is dynamic_extent for any k in the range [1, u + 1),
|
||||
|
||||
* [(1.4.5)](#map.leftpad-1.4.5)
|
||||
|
||||
otherwise, the product of *static-padding-stride* and
|
||||
all values static_extent(k) for k in the range [1, u + 1);
|
||||
|
||||
- [(1.5)](#map.leftpad-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.6](#map.rightpad) layout_right_padded specialization of submdspan_mapping [[mdspan.sub.map.rightpad]](mdspan.sub.map.rightpad)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_right_padded::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#map.rightpad-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25939)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#map.rightpad-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if *rank_* == 0 is true;
|
||||
|
||||
- [(1.2)](#map.rightpad-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if *rank_* == 1 is true orSubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#map.rightpad-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#map.rightpad-1.3.1)
|
||||
|
||||
SubExtents::rank() == 1 is true and
|
||||
|
||||
* [(1.3.2)](#map.rightpad-1.3.2)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
- [(1.4)](#map.rightpad-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
|
||||
stride(*rank_* - u - 2)), offset} if for a value u for which *rank_* - u - 2 is the largest value p smaller than *rank_* - 1 for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#map.rightpad-1.4.1)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#map.rightpad-1.4.2)
|
||||
|
||||
for each k in the range
|
||||
[*rank_* - SubExtents::rank() - u + 1, *rank_* - u - 1)),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#map.rightpad-1.4.3)
|
||||
|
||||
for k equal to *rank_* - SubExtents::rank() - u,
|
||||
Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#map.rightpad-1.4.4)
|
||||
|
||||
dynamic_extent if *static-padding-stride* is dynamic_extent or
|
||||
for any k in the range [*rank_* - u - 1, *rank_* - 1)static_extent(k) is dynamic_extent,
|
||||
|
||||
* [(1.4.5)](#map.rightpad-1.4.5)
|
||||
|
||||
otherwise, the product of *static-padding-stride* and
|
||||
all values static_extent(k) with k in the range [*rank_* - u - 1, *rank_* - 1);
|
||||
|
||||
- [(1.5)](#map.rightpad-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.7](#sub) submdspan function template [[mdspan.sub.sub]](mdspan.sub.sub)
|
||||
|
||||
[ð](#lib:submdspan)
|
||||
|
||||
`template<class ElementType, class Extents, class LayoutPolicy,
|
||||
class AccessorPolicy, class... SliceSpecifiers>
|
||||
constexpr auto submdspan(
|
||||
const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src,
|
||||
SliceSpecifiers... slices) -> see below;
|
||||
`
|
||||
|
||||
[1](#sub-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26016)
|
||||
|
||||
Let index_type be typename Extents::index_type[.](#sub-1.sentence-1)
|
||||
|
||||
[2](#sub-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26019)
|
||||
|
||||
Let sub_map_offset be the result ofsubmdspan_mapping(src.mapping(), slices...)[.](#sub-2.sentence-1)
|
||||
|
||||
[*Note [1](#sub-note-1)*:
|
||||
|
||||
This invocation of submdspan_mapping selects a function call via overload resolution
|
||||
on a candidate set that includes the lookup set
|
||||
found by argument-dependent lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))[.](#sub-2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#sub-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26029)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#sub-3.1)
|
||||
|
||||
sizeof...(slices) equals Extents::rank(), and
|
||||
|
||||
- [(3.2)](#sub-3.2)
|
||||
|
||||
the expression submdspan_mapping(src.mapping(), slices...) is well-formed when treated as an unevaluated operand[.](#sub-3.sentence-1)
|
||||
|
||||
[4](#sub-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26039)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(4.1)](#sub-4.1)
|
||||
|
||||
decltype(submdspan_mapping(src.mapping(), slices...)) is a specialization of submdspan_mapping_result[.](#sub-4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#sub-4.2)
|
||||
|
||||
is_same_v<remove_cvref_t<decltype(sub_map_offset.mapping.extents())>,decltype(submdspan_extents(src.mapping(), slices...))> is true[.](#sub-4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#sub-4.3)
|
||||
|
||||
For each rank index k of src.extents(),
|
||||
exactly one of the following is true:
|
||||
* [(4.3.1)](#sub-4.3.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
* [(4.3.2)](#sub-4.3.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>,
|
||||
|
||||
* [(4.3.3)](#sub-4.3.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
* [(4.3.4)](#sub-4.3.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#sub-4.3.sentence-1)
|
||||
|
||||
[5](#sub-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26062)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(5.1)](#sub-5.1)
|
||||
|
||||
For each rank index k of src.extents(),
|
||||
all of the following are true:
|
||||
* [(5.1.1)](#sub-5.1.1)
|
||||
|
||||
if Sk is a specialization of strided_slice
|
||||
+
|
||||
[(5.1.1.1)](#sub-5.1.1.1)
|
||||
sk.extent=0, or
|
||||
|
||||
+
|
||||
[(5.1.1.2)](#sub-5.1.1.2)
|
||||
sk.stride>0
|
||||
|
||||
* [(5.1.2)](#sub-5.1.2)
|
||||
|
||||
0 ⤠*first_*<index_type, k>(slices...) ⤠*last_*<k>(src.extents(), slices...) ⤠src.extent(k)
|
||||
|
||||
- [(5.2)](#sub-5.2)
|
||||
|
||||
sub_map_offset.mapping.extents() == submdspan_extents(src.mapping(), slices...) is true; and
|
||||
|
||||
- [(5.3)](#sub-5.3)
|
||||
|
||||
for each integer pack I which is a multidimensional index
|
||||
in sub_map_offset.mapping.extents(),sub_map_offset.mapping(I...) + sub_map_offset.offset == src.mapping()(*src-indices*(array{I...}, slices...)) is true[.](#sub-5.sentence-1)
|
||||
|
||||
[*Note [2](#sub-note-2)*:
|
||||
|
||||
These conditions ensure that the mapping returned by submdspan_mapping matches the algorithmically expected index-mapping given the slice specifiers[.](#sub-5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#sub-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26100)
|
||||
|
||||
*Effects*: Equivalent to:auto sub_map_result = submdspan_mapping(src.mapping(), slices...);return mdspan(src.accessor().offset(src.data_handle(), sub_map_result.offset),
|
||||
sub_map_result.mapping, typename AccessorPolicy::offset_policy(src.accessor()));
|
||||
|
||||
[7](#sub-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26111)
|
||||
|
||||
[*Example [1](#sub-example-1)*:
|
||||
|
||||
Given a rank-3 mdspan grid3d representing a three-dimensional grid
|
||||
of regularly spaced points in a rectangular prism,
|
||||
the function zero_surface sets all elements on
|
||||
the surface of the 3-dimensional shape to zero[.](#sub-7.sentence-1)
|
||||
|
||||
It does so by reusing a function zero_2d that takes a rank-2 mdspan[.](#sub-7.sentence-2)
|
||||
|
||||
// zero out all elements in an mdspantemplate<class T, class E, class L, class A>void zero_2d(mdspan<T, E, L, A> a) {static_assert(a.rank() == 2); for (int i = 0; i < a.extent(0); i++)for (int j = 0; j < a.extent(1); j++) a[i, j] = 0;}// zero out just the surfacetemplate<class T, class E, class L, class A>void zero_surface(mdspan<T, E, L, A> grid3d) {static_assert(grid3d.rank() == 3);
|
||||
zero_2d(submdspan(grid3d, 0, full_extent, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, 0, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, full_extent, 0));
|
||||
zero_2d(submdspan(grid3d, grid3d.extent(0) - 1, full_extent, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, grid3d.extent(1) - 1, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, full_extent, grid3d.extent(2) - 1));} â *end example*]
|
||||
122
cppdraft/mdspan/sub/extents.md
Normal file
122
cppdraft/mdspan/sub/extents.md
Normal file
@@ -0,0 +1,122 @@
|
||||
[mdspan.sub.extents]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.extents)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.extents)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#extents)
|
||||
|
||||
#### 23.7.3.7.5 submdspan_extents function [mdspan.sub.extents]
|
||||
|
||||
[ð](#lib:submdspan_extents)
|
||||
|
||||
`template<class IndexType, size_t... Extents, class... SliceSpecifiers>
|
||||
constexpr auto submdspan_extents(const extents<IndexType, Extents...>& src,
|
||||
SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25496)
|
||||
|
||||
*Constraints*: sizeof...(slices) equals sizeof...(Extents)[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25500)
|
||||
|
||||
*Mandates*: For each rank index k of src.extents(),
|
||||
exactly one of the following is true:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<IndexType>,
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<IndexType>,
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25511)
|
||||
|
||||
*Preconditions*: For each rank index k of src.extents(),
|
||||
all of the following are true:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
if Sk is a specialization of strided_slice
|
||||
* [(3.1.1)](#3.1.1)
|
||||
|
||||
sk.extent=0, or
|
||||
|
||||
* [(3.1.2)](#3.1.2)
|
||||
|
||||
sk.stride>0
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
0 ⤠*first_*<IndexType, k>(slices...) ⤠*last_*<k>(src, slices...) ⤠src.extent(k)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25528)
|
||||
|
||||
Let SubExtents be a specialization of extents such that:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
SubExtents::rank() equals the number of k such thatSk does not model [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<IndexType>; and
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
for each rank index k of Extents such that*map-rank*[k] != dynamic_extent is true,SubExtents::static_extent(*map-rank*[k]) equals:
|
||||
* [(4.2.1)](#4.2.1)
|
||||
|
||||
Extents::static_extent(k) if is_convertible_v<Sk, full_extent_t> is true;
|
||||
otherwise
|
||||
|
||||
* [(4.2.2)](#4.2.2)
|
||||
|
||||
*de-ice*(tuple_element_t<1, Sk>()) -*de-ice*(tuple_element_t<0, Sk>()) if Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<IndexType>, and
|
||||
both tuple_element_t<0, Sk> and tuple_element_t<1, Sk> model [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]"); otherwise
|
||||
|
||||
* [(4.2.3)](#4.2.3)
|
||||
|
||||
0,
|
||||
if Sk is a specialization of strided_slice, whose extent_type models *integral-constant-like*,
|
||||
for which extent_type() equals zero; otherwise
|
||||
|
||||
* [(4.2.4)](#4.2.4)
|
||||
|
||||
1 + (*de-ice*(Sk::extent_type()) - 1) /*de-ice*(Sk::stride_type()),
|
||||
if Sk is a specialization of strided_slice whose extent_type and stride_type model *integral-constant-like*;
|
||||
|
||||
* [(4.2.5)](#4.2.5)
|
||||
|
||||
otherwise, dynamic_extent[.](#4.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25573)
|
||||
|
||||
*Returns*: A value ext of type SubExtents such that
|
||||
for each k for which *map-rank*[k] != dynamic_extent is true,ext.extent(*map-rank*[k]) equals:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
sk.extent == 0 ? 0 : 1 + (*de-ice*(sk.extent) - 1) / *de-ice*(sk.stride) if Sk is a specialization of strided_slice,
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
otherwise,*last_*<k>(src, slices...) - *first_*<IndexType, k>(slices...)[.](#5.sentence-1)
|
||||
142
cppdraft/mdspan/sub/helpers.md
Normal file
142
cppdraft/mdspan/sub/helpers.md
Normal file
@@ -0,0 +1,142 @@
|
||||
[mdspan.sub.helpers]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.helpers)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.helpers)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#helpers)
|
||||
|
||||
#### 23.7.3.7.4 Exposition-only helpers [mdspan.sub.helpers]
|
||||
|
||||
[ð](#lib:de-ice)
|
||||
|
||||
`template<class T>
|
||||
constexpr T de-ice(T val) { return val; }
|
||||
template<[integral-constant-like](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]") T>
|
||||
constexpr auto de-ice(T) { return T::value; }
|
||||
|
||||
template<class IndexType, size_t k, class... SliceSpecifiers>
|
||||
constexpr IndexType first_(SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25378)
|
||||
|
||||
*Mandates*: IndexType is a signed or unsigned integer type[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25383)
|
||||
|
||||
Let Ïk denote the following value:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
sk if Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<IndexType>;
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
otherwise,get<0>(sk) if Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<IndexType>;
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
otherwise,*de-ice*(sk.offset) if Sk is a specialization of strided_slice;
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
otherwise,0[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25401)
|
||||
|
||||
*Preconditions*: Ïk is representable as a value of type IndexType[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25405)
|
||||
|
||||
*Returns*: extents<IndexType>::*index-cast*(Ïk)[.](#4.sentence-1)
|
||||
|
||||
[ð](#lib:last_)
|
||||
|
||||
`template<size_t k, class Extents, class... SliceSpecifiers>
|
||||
constexpr auto last_(const Extents& src, SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25417)
|
||||
|
||||
*Mandates*: Extents is a specialization of extents[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25421)
|
||||
|
||||
Let index_type be typename Extents::index_type[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25425)
|
||||
|
||||
Let λk denote the following value:
|
||||
|
||||
- [(7.1)](#7.1)
|
||||
|
||||
*de-ice*(sk) + 1 if Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>; otherwise
|
||||
|
||||
- [(7.2)](#7.2)
|
||||
|
||||
get<1>(sk) if Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>; otherwise
|
||||
|
||||
- [(7.3)](#7.3)
|
||||
|
||||
*de-ice*(sk.offset) +*de-ice*(sk.extent) if Sk is a specialization of strided_slice; otherwise
|
||||
|
||||
- [(7.4)](#7.4)
|
||||
|
||||
src.extent(k)[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25443)
|
||||
|
||||
*Preconditions*: λk is representable as a value of type index_type[.](#8.sentence-1)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25447)
|
||||
|
||||
*Returns*: Extents::*index-cast*(λk)[.](#9.sentence-1)
|
||||
|
||||
[ð](#lib:src-indices)
|
||||
|
||||
`template<class IndexType, size_t N, class... SliceSpecifiers>
|
||||
constexpr array<IndexType, sizeof...(SliceSpecifiers)>
|
||||
src-indices(const array<IndexType, N>& indices, SliceSpecifiers... slices);
|
||||
`
|
||||
|
||||
[10](#10)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25460)
|
||||
|
||||
*Mandates*: IndexType is a signed or unsigned integer type[.](#10.sentence-1)
|
||||
|
||||
[11](#11)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25464)
|
||||
|
||||
*Returns*: An array<IndexType, sizeof...(SliceSpecifiers)> src_idx such that
|
||||
for each k in the range [0, sizeof...(SliceSpecifiers)),src_idx[k] equals
|
||||
|
||||
- [(11.1)](#11.1)
|
||||
|
||||
*first_*<IndexType, k>(slices...) for each k where *map-rank*[k] equalsdynamic_extent,
|
||||
|
||||
- [(11.2)](#11.2)
|
||||
|
||||
otherwise,*first_*<IndexType, k>(slices...) +indices[*map-rank*[k]].
|
||||
444
cppdraft/mdspan/sub/map.md
Normal file
444
cppdraft/mdspan/sub/map.md
Normal file
@@ -0,0 +1,444 @@
|
||||
[mdspan.sub.map]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [mdspan.sub.map]
|
||||
|
||||
#### [23.7.3.7.6.1](#common) Common [[mdspan.sub.map.common]](mdspan.sub.map.common)
|
||||
|
||||
[1](#common-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25594)
|
||||
|
||||
The following elements apply to all functions in [mdspan.sub.map][.](#common-1.sentence-1)
|
||||
|
||||
[2](#common-2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25597)
|
||||
|
||||
*Constraints*: sizeof...(slices) equals extents_type::rank()[.](#common-2.sentence-1)
|
||||
|
||||
[3](#common-3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25601)
|
||||
|
||||
*Mandates*: For each rank index k of extents(),
|
||||
exactly one of the following is true:
|
||||
|
||||
- [(3.1)](#common-3.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
- [(3.2)](#common-3.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>,
|
||||
|
||||
- [(3.3)](#common-3.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
- [(3.4)](#common-3.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#common-3.sentence-1)
|
||||
|
||||
[4](#common-4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25616)
|
||||
|
||||
*Preconditions*: For each rank index k of extents(),
|
||||
all of the following are true:
|
||||
|
||||
- [(4.1)](#common-4.1)
|
||||
|
||||
if Sk is a specialization of strided_slice,sk.extent is equal to zero orsk.stride is greater than zero; and
|
||||
|
||||
- [(4.2)](#common-4.2)
|
||||
|
||||
0 ⤠*first_*<index_type, k>(slices...)
|
||||
0 ⤠*last_*<k>(extents(), slices...)
|
||||
0 ⤠extents().extent(k)
|
||||
|
||||
[5](#common-5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25631)
|
||||
|
||||
Let sub_ext be
|
||||
the result of submdspan_extents(extents(), slices...) and
|
||||
let SubExtents be decltype(sub_ext)[.](#common-5.sentence-1)
|
||||
|
||||
[6](#common-6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25636)
|
||||
|
||||
Let sub_strides be
|
||||
an array<SubExtents::index_type, SubExtents::rank()> such that for each rank index k of extents() for which *map-rank*[k] is not dynamic_extent,sub_strides[*map-rank*[k]] equals:
|
||||
|
||||
- [(6.1)](#common-6.1)
|
||||
|
||||
stride(k) * *de-ice*(sk.stride) if Sk is a specialization of strided_slice andsk.stride < sk.extent is true;
|
||||
|
||||
- [(6.2)](#common-6.2)
|
||||
|
||||
otherwise, stride(k)[.](#common-6.sentence-1)
|
||||
|
||||
[7](#common-7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25651)
|
||||
|
||||
Let P be a parameter pack
|
||||
such that is_same_v<make_index_sequence<rank()>, index_sequence<P...>> is true[.](#common-7.sentence-1)
|
||||
|
||||
[8](#common-8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25656)
|
||||
|
||||
If *first_*<index_type, k>(slices...) equals extents().extent(k) for any rank index k of extents(), then
|
||||
let offset be a value of type size_t equal to(*this).required_span_size()[.](#common-8.sentence-1)
|
||||
|
||||
Otherwise,
|
||||
let offset be a value of type size_t equal to(*this)(*first_*<index_type, P>(slices...)...)[.](#common-8.sentence-2)
|
||||
|
||||
[9](#common-9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25666)
|
||||
|
||||
Given a layout mapping type M, a type S is a[*unit-stride slice for M*](#def:slice,unit-stride "23.7.3.7.6.1 Common [mdspan.sub.map.common]") if
|
||||
|
||||
- [(9.1)](#common-9.1)
|
||||
|
||||
S is a specialization of strided_slice where S::stride_type models [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]") and S::stride_type::value equals 1,
|
||||
|
||||
- [(9.2)](#common-9.2)
|
||||
|
||||
S models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<M::index_type>, or
|
||||
|
||||
- [(9.3)](#common-9.3)
|
||||
|
||||
is_convertible_v<S, full_extent_t> is true[.](#common-9.sentence-1)
|
||||
|
||||
#### [23.7.3.7.6.2](#left) layout_left specialization of submdspan_mapping [[mdspan.sub.map.left]](mdspan.sub.map.left)
|
||||
|
||||
[ð](#lib:layout_left::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_left::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#left-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25688)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#left-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#left-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if SubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#left-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#left-1.3.1)
|
||||
|
||||
for each k in the range [0, SubExtents::rank() - 1)), is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.3.2)](#left-1.3.2)
|
||||
|
||||
for k equal to SubExtents::rank() - 1, Sk is a unit-stride slice for mapping;
|
||||
|
||||
[*Note [1](#left-note-1)*:
|
||||
If the above conditions are true,
|
||||
all Sk with k larger than SubExtents::rank() - 1 are convertible to index_type[.](#left-1.3.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#left-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
|
||||
offset} if for a value u for which u+1 is
|
||||
the smallest value p larger than zero
|
||||
for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#left-1.4.1)
|
||||
|
||||
S0 is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#left-1.4.2)
|
||||
|
||||
for each k in the range [u + 1, u + SubExtents::rank() - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#left-1.4.3)
|
||||
|
||||
for k equal to u + SubExtents::rank() - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#left-1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if static_extent(k) is dynamic_extent for any k in the range [0, u + 1),
|
||||
|
||||
* [(1.4.5)](#left-1.4.5)
|
||||
|
||||
otherwise, the product of all valuesstatic_extent(k) for k in the range [0, u + 1);
|
||||
|
||||
- [(1.5)](#left-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.3](#right) layout_right specialization of submdspan_mapping [[mdspan.sub.map.right]](mdspan.sub.map.right)
|
||||
|
||||
[ð](#lib:layout_right::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_right::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#right-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25764)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#right-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#right-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if SubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#right-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#right-1.3.1)
|
||||
|
||||
for each k in the range [*rank_* - SubExtents::rank() + 1, *rank_*), is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.3.2)](#right-1.3.2)
|
||||
|
||||
for k equal to *_rank* - SubExtents::rank(), Sk is a unit-stride slice for mapping;
|
||||
|
||||
[*Note [1](#right-note-1)*:
|
||||
If the above conditions are true,
|
||||
all Sk with k<_rank - SubExtents::rank() are convertible to index_type[.](#right-1.3.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#right-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
|
||||
stride(*rank_* - u - 2)), offset} if for a value u for which rank_âuâ2 is
|
||||
the largest value p smaller than *rank_* - 1 for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#right-1.4.1)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#right-1.4.2)
|
||||
|
||||
for each k in the range
|
||||
[*rank_* - SubExtents::rank() - u + 1, *rank_* - u - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#right-1.4.3)
|
||||
|
||||
for k equal to *rank_* - SubExtents::rank() - u,
|
||||
Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#right-1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if static_extent(k) is dynamic_extent for any k in the range [*rank_* - u - 1, *rank_*),
|
||||
|
||||
* [(1.4.5)](#right-1.4.5)
|
||||
|
||||
otherwise, the product of all valuesstatic_extent(k) for k in the range [*rank_* - u - 1, *rank_*);
|
||||
|
||||
- [(1.5)](#right-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.4](#stride) layout_stride specialization of submdspan_mapping [[mdspan.sub.map.stride]](mdspan.sub.map.stride)
|
||||
|
||||
[ð](#lib:layout_stride::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_stride::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#stride-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25843)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#stride-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#stride-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.5](#leftpad) layout_left_padded specialization of submdspan_mapping [[mdspan.sub.map.leftpad]](mdspan.sub.map.leftpad)
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_left_padded::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#leftpad-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25868)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#leftpad-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#leftpad-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if *rank_* == 1 is true orSubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#leftpad-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#leftpad-1.3.1)
|
||||
|
||||
SubExtents::rank() == 1 is true and
|
||||
|
||||
* [(1.3.2)](#leftpad-1.3.2)
|
||||
|
||||
S0 is a unit-stride slice for mapping;
|
||||
|
||||
- [(1.4)](#leftpad-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
|
||||
offset} if for a value u for which u + 1 is the smallest value p larger than zero
|
||||
for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#leftpad-1.4.1)
|
||||
|
||||
S0 is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#leftpad-1.4.2)
|
||||
|
||||
for each k in the range [u + 1, u + SubExtents::rank() - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#leftpad-1.4.3)
|
||||
|
||||
for k equal to u + SubExtents::rank() - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
where S_static is:
|
||||
* [(1.4.4)](#leftpad-1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if *static-padding-stride* is dynamic_extent orstatic_extent(k) is dynamic_extent for any k in the range [1, u + 1),
|
||||
|
||||
* [(1.4.5)](#leftpad-1.4.5)
|
||||
|
||||
otherwise, the product of *static-padding-stride* and
|
||||
all values static_extent(k) for k in the range [1, u + 1);
|
||||
|
||||
- [(1.5)](#leftpad-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
|
||||
#### [23.7.3.7.6.6](#rightpad) layout_right_padded specialization of submdspan_mapping [[mdspan.sub.map.rightpad]](mdspan.sub.map.rightpad)
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_right_padded::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#rightpad-1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25939)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#rightpad-1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if *rank_* == 0 is true;
|
||||
|
||||
- [(1.2)](#rightpad-1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if *rank_* == 1 is true orSubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#rightpad-1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#rightpad-1.3.1)
|
||||
|
||||
SubExtents::rank() == 1 is true and
|
||||
|
||||
* [(1.3.2)](#rightpad-1.3.2)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
- [(1.4)](#rightpad-1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
|
||||
stride(*rank_* - u - 2)), offset} if for a value u for which *rank_* - u - 2 is the largest value p smaller than *rank_* - 1 for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#rightpad-1.4.1)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#rightpad-1.4.2)
|
||||
|
||||
for each k in the range
|
||||
[*rank_* - SubExtents::rank() - u + 1, *rank_* - u - 1)),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#rightpad-1.4.3)
|
||||
|
||||
for k equal to *rank_* - SubExtents::rank() - u,
|
||||
Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#rightpad-1.4.4)
|
||||
|
||||
dynamic_extent if *static-padding-stride* is dynamic_extent or
|
||||
for any k in the range [*rank_* - u - 1, *rank_* - 1)static_extent(k) is dynamic_extent,
|
||||
|
||||
* [(1.4.5)](#rightpad-1.4.5)
|
||||
|
||||
otherwise, the product of *static-padding-stride* and
|
||||
all values static_extent(k) with k in the range [*rank_* - u - 1, *rank_* - 1);
|
||||
|
||||
- [(1.5)](#rightpad-1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
123
cppdraft/mdspan/sub/map/common.md
Normal file
123
cppdraft/mdspan/sub/map/common.md
Normal file
@@ -0,0 +1,123 @@
|
||||
[mdspan.sub.map.common]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.common)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.common)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.common)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map#common)
|
||||
|
||||
#### 23.7.3.7.6.1 Common [mdspan.sub.map.common]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25594)
|
||||
|
||||
The following elements apply to all functions in [[mdspan.sub.map]](mdspan.sub.map "23.7.3.7.6 Specializations of submdspan_mapping")[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25597)
|
||||
|
||||
*Constraints*: sizeof...(slices) equals extents_type::rank()[.](#2.sentence-1)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25601)
|
||||
|
||||
*Mandates*: For each rank index k of extents(),
|
||||
exactly one of the following is true:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>,
|
||||
|
||||
- [(3.3)](#3.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
- [(3.4)](#3.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25616)
|
||||
|
||||
*Preconditions*: For each rank index k of extents(),
|
||||
all of the following are true:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
if Sk is a specialization of strided_slice,sk.extent is equal to zero orsk.stride is greater than zero; and
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
0 ⤠*first_*<index_type, k>(slices...)
|
||||
0 ⤠*last_*<k>(extents(), slices...)
|
||||
0 ⤠extents().extent(k)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25631)
|
||||
|
||||
Let sub_ext be
|
||||
the result of submdspan_extents(extents(), slices...) and
|
||||
let SubExtents be decltype(sub_ext)[.](#5.sentence-1)
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25636)
|
||||
|
||||
Let sub_strides be
|
||||
an array<SubExtents::index_type, SubExtents::rank()> such that for each rank index k of extents() for which *map-rank*[k] is not dynamic_extent,sub_strides[*map-rank*[k]] equals:
|
||||
|
||||
- [(6.1)](#6.1)
|
||||
|
||||
stride(k) * *de-ice*(sk.stride) if Sk is a specialization of strided_slice andsk.stride < sk.extent is true;
|
||||
|
||||
- [(6.2)](#6.2)
|
||||
|
||||
otherwise, stride(k)[.](#6.sentence-1)
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25651)
|
||||
|
||||
Let P be a parameter pack
|
||||
such that is_same_v<make_index_sequence<rank()>, index_sequence<P...>> is true[.](#7.sentence-1)
|
||||
|
||||
[8](#8)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25656)
|
||||
|
||||
If *first_*<index_type, k>(slices...) equals extents().extent(k) for any rank index k of extents(), then
|
||||
let offset be a value of type size_t equal to(*this).required_span_size()[.](#8.sentence-1)
|
||||
|
||||
Otherwise,
|
||||
let offset be a value of type size_t equal to(*this)(*first_*<index_type, P>(slices...)...)[.](#8.sentence-2)
|
||||
|
||||
[9](#9)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25666)
|
||||
|
||||
Given a layout mapping type M, a type S is a[*unit-stride slice for M*](#def:slice,unit-stride "23.7.3.7.6.1 Common [mdspan.sub.map.common]") if
|
||||
|
||||
- [(9.1)](#9.1)
|
||||
|
||||
S is a specialization of strided_slice where S::stride_type models [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]") and S::stride_type::value equals 1,
|
||||
|
||||
- [(9.2)](#9.2)
|
||||
|
||||
S models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<M::index_type>, or
|
||||
|
||||
- [(9.3)](#9.3)
|
||||
|
||||
is_convertible_v<S, full_extent_t> is true[.](#9.sentence-1)
|
||||
87
cppdraft/mdspan/sub/map/left.md
Normal file
87
cppdraft/mdspan/sub/map/left.md
Normal file
@@ -0,0 +1,87 @@
|
||||
[mdspan.sub.map.left]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.left)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.left)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.left)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map#left)
|
||||
|
||||
#### 23.7.3.7.6.2 layout_left specialization of submdspan_mapping [mdspan.sub.map.left]
|
||||
|
||||
[ð](#lib:layout_left::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_left::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25688)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if SubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#1.3.1)
|
||||
|
||||
for each k in the range [0, SubExtents::rank() - 1)), is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.3.2)](#1.3.2)
|
||||
|
||||
for k equal to SubExtents::rank() - 1, Sk is a unit-stride slice for mapping;
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
If the above conditions are true,
|
||||
all Sk with k larger than SubExtents::rank() - 1 are convertible to index_type[.](#1.3.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
|
||||
offset} if for a value u for which u+1 is
|
||||
the smallest value p larger than zero
|
||||
for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#1.4.1)
|
||||
|
||||
S0 is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#1.4.2)
|
||||
|
||||
for each k in the range [u + 1, u + SubExtents::rank() - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#1.4.3)
|
||||
|
||||
for k equal to u + SubExtents::rank() - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if static_extent(k) is dynamic_extent for any k in the range [0, u + 1),
|
||||
|
||||
* [(1.4.5)](#1.4.5)
|
||||
|
||||
otherwise, the product of all valuesstatic_extent(k) for k in the range [0, u + 1);
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
82
cppdraft/mdspan/sub/map/leftpad.md
Normal file
82
cppdraft/mdspan/sub/map/leftpad.md
Normal file
@@ -0,0 +1,82 @@
|
||||
[mdspan.sub.map.leftpad]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.leftpad)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.leftpad)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.leftpad)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map#leftpad)
|
||||
|
||||
#### 23.7.3.7.6.5 layout_left_padded specialization of submdspan_mapping [mdspan.sub.map.leftpad]
|
||||
|
||||
[ð](#lib:layout_left_padded::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_left_padded::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25868)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if *rank_* == 1 is true orSubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#1.3.1)
|
||||
|
||||
SubExtents::rank() == 1 is true and
|
||||
|
||||
* [(1.3.2)](#1.3.2)
|
||||
|
||||
S0 is a unit-stride slice for mapping;
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left_padded<S_static>::mapping(sub_ext, stride(u + 1)),
|
||||
offset} if for a value u for which u + 1 is the smallest value p larger than zero
|
||||
for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#1.4.1)
|
||||
|
||||
S0 is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#1.4.2)
|
||||
|
||||
for each k in the range [u + 1, u + SubExtents::rank() - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#1.4.3)
|
||||
|
||||
for k equal to u + SubExtents::rank() - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
where S_static is:
|
||||
* [(1.4.4)](#1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if *static-padding-stride* is dynamic_extent orstatic_extent(k) is dynamic_extent for any k in the range [1, u + 1),
|
||||
|
||||
* [(1.4.5)](#1.4.5)
|
||||
|
||||
otherwise, the product of *static-padding-stride* and
|
||||
all values static_extent(k) for k in the range [1, u + 1);
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
38
cppdraft/mdspan/sub/map/result.md
Normal file
38
cppdraft/mdspan/sub/map/result.md
Normal file
@@ -0,0 +1,38 @@
|
||||
[mdspan.sub.map.result]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.result)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.result)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.result)
|
||||
|
||||
#### 23.7.3.7.3 submdspan_mapping_result [mdspan.sub.map.result]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25339)
|
||||
|
||||
Specializations of submdspan_mapping_result are returned by overloads of submdspan_mapping[.](#1.sentence-1)
|
||||
|
||||
[ð](#lib:submdspan_mapping_result)
|
||||
|
||||
namespace std {template<class LayoutMapping>struct submdspan_mapping_result {[[no_unique_address]] LayoutMapping mapping = LayoutMapping();
|
||||
size_t offset{}; };}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25354)
|
||||
|
||||
submdspan_mapping_result has
|
||||
the data members and special members specified above[.](#2.sentence-1)
|
||||
|
||||
It has no base classes or members other than those specified[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25359)
|
||||
|
||||
LayoutMapping shall meet
|
||||
the layout mapping requirements ([[mdspan.layout.policy.reqmts]](mdspan.layout.policy.reqmts "23.7.3.4.3 Layout mapping policy requirements"))[.](#3.sentence-1)
|
||||
88
cppdraft/mdspan/sub/map/right.md
Normal file
88
cppdraft/mdspan/sub/map/right.md
Normal file
@@ -0,0 +1,88 @@
|
||||
[mdspan.sub.map.right]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.right)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.right)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.right)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map#right)
|
||||
|
||||
#### 23.7.3.7.6.3 layout_right specialization of submdspan_mapping [mdspan.sub.map.right]
|
||||
|
||||
[ð](#lib:layout_right::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_right::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25764)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if SubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_left::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#1.3.1)
|
||||
|
||||
for each k in the range [*rank_* - SubExtents::rank() + 1, *rank_*), is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.3.2)](#1.3.2)
|
||||
|
||||
for k equal to *_rank* - SubExtents::rank(), Sk is a unit-stride slice for mapping;
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
If the above conditions are true,
|
||||
all Sk with k<_rank - SubExtents::rank() are convertible to index_type[.](#1.3.sentence-1)
|
||||
â *end note*]
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
|
||||
stride(*rank_* - u - 2)), offset} if for a value u for which rank_âuâ2 is
|
||||
the largest value p smaller than *rank_* - 1 for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#1.4.1)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#1.4.2)
|
||||
|
||||
for each k in the range
|
||||
[*rank_* - SubExtents::rank() - u + 1, *rank_* - u - 1),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#1.4.3)
|
||||
|
||||
for k equal to *rank_* - SubExtents::rank() - u,
|
||||
Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#1.4.4)
|
||||
|
||||
dynamic_extent,
|
||||
if static_extent(k) is dynamic_extent for any k in the range [*rank_* - u - 1, *rank_*),
|
||||
|
||||
* [(1.4.5)](#1.4.5)
|
||||
|
||||
otherwise, the product of all valuesstatic_extent(k) for k in the range [*rank_* - u - 1, *rank_*);
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
83
cppdraft/mdspan/sub/map/rightpad.md
Normal file
83
cppdraft/mdspan/sub/map/rightpad.md
Normal file
@@ -0,0 +1,83 @@
|
||||
[mdspan.sub.map.rightpad]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.rightpad)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.rightpad)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.rightpad)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map#rightpad)
|
||||
|
||||
#### 23.7.3.7.6.6 layout_right_padded specialization of submdspan_mapping [mdspan.sub.map.rightpad]
|
||||
|
||||
[ð](#lib:layout_right_padded::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_right_padded::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25939)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if *rank_* == 0 is true;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if *rank_* == 1 is true orSubExtents::rank() == 0 is true;
|
||||
|
||||
- [(1.3)](#1.3)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right::mapping(sub_ext), offset},
|
||||
if
|
||||
* [(1.3.1)](#1.3.1)
|
||||
|
||||
SubExtents::rank() == 1 is true and
|
||||
|
||||
* [(1.3.2)](#1.3.2)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping;
|
||||
|
||||
- [(1.4)](#1.4)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_right_padded<S_static>::mapping(sub_ext,
|
||||
stride(*rank_* - u - 2)), offset} if for a value u for which *rank_* - u - 2 is the largest value p smaller than *rank_* - 1 for which Sp is a unit-stride slice for mapping,
|
||||
the following conditions are met:
|
||||
* [(1.4.1)](#1.4.1)
|
||||
|
||||
for k equal to *rank_* - 1,Sk is a unit-stride slice for mapping; and
|
||||
|
||||
* [(1.4.2)](#1.4.2)
|
||||
|
||||
for each k in the range
|
||||
[*rank_* - SubExtents::rank() - u + 1, *rank_* - u - 1)),is_convertible_v<Sk, full_extent_t> is true; and
|
||||
|
||||
* [(1.4.3)](#1.4.3)
|
||||
|
||||
for k equal to *rank_* - SubExtents::rank() - u,
|
||||
Sk is a unit-stride slice for mapping;
|
||||
|
||||
and where S_static is:
|
||||
* [(1.4.4)](#1.4.4)
|
||||
|
||||
dynamic_extent if *static-padding-stride* is dynamic_extent or
|
||||
for any k in the range [*rank_* - u - 1, *rank_* - 1)static_extent(k) is dynamic_extent,
|
||||
|
||||
* [(1.4.5)](#1.4.5)
|
||||
|
||||
otherwise, the product of *static-padding-stride* and
|
||||
all values static_extent(k) with k in the range [*rank_* - u - 1, *rank_* - 1);
|
||||
|
||||
- [(1.5)](#1.5)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
36
cppdraft/mdspan/sub/map/stride.md
Normal file
36
cppdraft/mdspan/sub/map/stride.md
Normal file
@@ -0,0 +1,36 @@
|
||||
[mdspan.sub.map.stride]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.map.stride)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.map.stride)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#map.stride)
|
||||
|
||||
#### 23.7.3.7.6 Specializations of submdspan_mapping [[mdspan.sub.map]](mdspan.sub.map#stride)
|
||||
|
||||
#### 23.7.3.7.6.4 layout_stride specialization of submdspan_mapping [mdspan.sub.map.stride]
|
||||
|
||||
[ð](#lib:layout_stride::mapping,submdspan-mapping-impl)
|
||||
|
||||
`template<class Extents>
|
||||
template<class... SliceSpecifiers>
|
||||
constexpr auto layout_stride::mapping<Extents>::submdspan-mapping-impl(
|
||||
SliceSpecifiers... slices) const -> see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25843)
|
||||
|
||||
*Returns*:
|
||||
|
||||
- [(1.1)](#1.1)
|
||||
|
||||
submdspan_mapping_result{*this, 0},
|
||||
if Extents::rank() == 0 is true;
|
||||
|
||||
- [(1.2)](#1.2)
|
||||
|
||||
otherwise,submdspan_mapping_result{layout_stride::mapping(sub_ext, sub_strides), offset}
|
||||
69
cppdraft/mdspan/sub/overview.md
Normal file
69
cppdraft/mdspan/sub/overview.md
Normal file
@@ -0,0 +1,69 @@
|
||||
[mdspan.sub.overview]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.overview)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.overview)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#overview)
|
||||
|
||||
#### 23.7.3.7.1 Overview [mdspan.sub.overview]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25258)
|
||||
|
||||
The submdspan facilities create a new mdspan viewing a subset of elements of an existing input mdspan[.](#1.sentence-1)
|
||||
|
||||
The subset viewed by the created mdspan is determined by
|
||||
the SliceSpecifier arguments[.](#1.sentence-2)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25264)
|
||||
|
||||
For each function defined in [[mdspan.sub]](mdspan.sub "23.7.3.7 submdspan") that
|
||||
takes a parameter pack named slices as an argument:
|
||||
|
||||
- [(2.1)](#2.1)
|
||||
|
||||
let index_type be
|
||||
* [(2.1.1)](#2.1.1)
|
||||
|
||||
M::index_type if the function is a member of a class M,
|
||||
|
||||
* [(2.1.2)](#2.1.2)
|
||||
|
||||
otherwise, remove_reference_t<decltype(src)>::index_type if the function has a parameter named src,
|
||||
|
||||
* [(2.1.3)](#2.1.3)
|
||||
|
||||
otherwise,
|
||||
the same type as the function's template argument IndexType;
|
||||
|
||||
- [(2.2)](#2.2)
|
||||
|
||||
let rank be the number of elements in slices;
|
||||
|
||||
- [(2.3)](#2.3)
|
||||
|
||||
let sk be the kth element of slices;
|
||||
|
||||
- [(2.4)](#2.4)
|
||||
|
||||
let Sk be the type of sk; and
|
||||
|
||||
- [(2.5)](#2.5)
|
||||
|
||||
let *map-rank* be an array<size_t, rank> such that
|
||||
for each k in the range [0, rank),*map-rank*[k] equals:
|
||||
* [(2.5.1)](#2.5.1)
|
||||
|
||||
dynamic_extent if Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
* [(2.5.2)](#2.5.2)
|
||||
|
||||
otherwise,
|
||||
the number of types Sj with j<k that
|
||||
do not model [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>[.](#2.sentence-1)
|
||||
47
cppdraft/mdspan/sub/strided/slice.md
Normal file
47
cppdraft/mdspan/sub/strided/slice.md
Normal file
@@ -0,0 +1,47 @@
|
||||
[mdspan.sub.strided.slice]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.strided.slice)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.strided.slice)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#strided.slice)
|
||||
|
||||
#### 23.7.3.7.2 strided_slice [mdspan.sub.strided.slice]
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25300)
|
||||
|
||||
strided_slice represents a set ofextent regularly spaced integer indices[.](#1.sentence-1)
|
||||
|
||||
The indices start at offset, and
|
||||
increase by increments of stride[.](#1.sentence-2)
|
||||
|
||||
[ð](#lib:strided_slice)
|
||||
|
||||
namespace std {template<class OffsetType, class ExtentType, class StrideType>struct strided_slice {using offset_type = OffsetType; using extent_type = ExtentType; using stride_type = StrideType; [[no_unique_address]] offset_type offset{}; [[no_unique_address]] extent_type extent{}; [[no_unique_address]] stride_type stride{}; };}
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25322)
|
||||
|
||||
strided_slice has the data members and special members specified above[.](#2.sentence-1)
|
||||
|
||||
It has no base classes or members other than those specified[.](#2.sentence-2)
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L25326)
|
||||
|
||||
*Mandates*: OffsetType, ExtentType, and StrideType are signed or unsigned integer types, or
|
||||
model [*integral-constant-like*](span.syn#concept:integral-constant-like "23.7.2.1 Header <span> synopsis [span.syn]")[.](#3.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
strided_slice{.offset = 1, .extent = 10, .stride = 3} indicates the indices 1, 4, 7, and 10[.](#3.sentence-2)
|
||||
|
||||
Indices are selected from the half-open interval [1, 1 + 10)[.](#3.sentence-3)
|
||||
|
||||
â *end note*]
|
||||
156
cppdraft/mdspan/sub/sub.md
Normal file
156
cppdraft/mdspan/sub/sub.md
Normal file
@@ -0,0 +1,156 @@
|
||||
[mdspan.sub.sub]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.sub.sub)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.sub.sub)
|
||||
|
||||
#### 23.7.3.7 submdspan [[mdspan.sub]](mdspan.sub#sub)
|
||||
|
||||
#### 23.7.3.7.7 submdspan function template [mdspan.sub.sub]
|
||||
|
||||
[ð](#lib:submdspan)
|
||||
|
||||
`template<class ElementType, class Extents, class LayoutPolicy,
|
||||
class AccessorPolicy, class... SliceSpecifiers>
|
||||
constexpr auto submdspan(
|
||||
const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src,
|
||||
SliceSpecifiers... slices) -> see below;
|
||||
`
|
||||
|
||||
[1](#1)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26016)
|
||||
|
||||
Let index_type be typename Extents::index_type[.](#1.sentence-1)
|
||||
|
||||
[2](#2)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26019)
|
||||
|
||||
Let sub_map_offset be the result ofsubmdspan_mapping(src.mapping(), slices...)[.](#2.sentence-1)
|
||||
|
||||
[*Note [1](#note-1)*:
|
||||
|
||||
This invocation of submdspan_mapping selects a function call via overload resolution
|
||||
on a candidate set that includes the lookup set
|
||||
found by argument-dependent lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))[.](#2.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[3](#3)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26029)
|
||||
|
||||
*Constraints*:
|
||||
|
||||
- [(3.1)](#3.1)
|
||||
|
||||
sizeof...(slices) equals Extents::rank(), and
|
||||
|
||||
- [(3.2)](#3.2)
|
||||
|
||||
the expression submdspan_mapping(src.mapping(), slices...) is well-formed when treated as an unevaluated operand[.](#3.sentence-1)
|
||||
|
||||
[4](#4)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26039)
|
||||
|
||||
*Mandates*:
|
||||
|
||||
- [(4.1)](#4.1)
|
||||
|
||||
decltype(submdspan_mapping(src.mapping(), slices...)) is a specialization of submdspan_mapping_result[.](#4.1.sentence-1)
|
||||
|
||||
- [(4.2)](#4.2)
|
||||
|
||||
is_same_v<remove_cvref_t<decltype(sub_map_offset.mapping.extents())>,decltype(submdspan_extents(src.mapping(), slices...))> is true[.](#4.2.sentence-1)
|
||||
|
||||
- [(4.3)](#4.3)
|
||||
|
||||
For each rank index k of src.extents(),
|
||||
exactly one of the following is true:
|
||||
* [(4.3.1)](#4.3.1)
|
||||
|
||||
Sk models [convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<index_type>,
|
||||
|
||||
* [(4.3.2)](#4.3.2)
|
||||
|
||||
Sk models [*index-pair-like*](mdspan.syn#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]")<index_type>,
|
||||
|
||||
* [(4.3.3)](#4.3.3)
|
||||
|
||||
is_convertible_v<Sk, full_extent_t> is true, or
|
||||
|
||||
* [(4.3.4)](#4.3.4)
|
||||
|
||||
Sk is a specialization of strided_slice[.](#4.3.sentence-1)
|
||||
|
||||
[5](#5)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26062)
|
||||
|
||||
*Preconditions*:
|
||||
|
||||
- [(5.1)](#5.1)
|
||||
|
||||
For each rank index k of src.extents(),
|
||||
all of the following are true:
|
||||
* [(5.1.1)](#5.1.1)
|
||||
|
||||
if Sk is a specialization of strided_slice
|
||||
+
|
||||
[(5.1.1.1)](#5.1.1.1)
|
||||
sk.extent=0, or
|
||||
|
||||
+
|
||||
[(5.1.1.2)](#5.1.1.2)
|
||||
sk.stride>0
|
||||
|
||||
* [(5.1.2)](#5.1.2)
|
||||
|
||||
0 ⤠*first_*<index_type, k>(slices...) ⤠*last_*<k>(src.extents(), slices...) ⤠src.extent(k)
|
||||
|
||||
- [(5.2)](#5.2)
|
||||
|
||||
sub_map_offset.mapping.extents() == submdspan_extents(src.mapping(), slices...) is true; and
|
||||
|
||||
- [(5.3)](#5.3)
|
||||
|
||||
for each integer pack I which is a multidimensional index
|
||||
in sub_map_offset.mapping.extents(),sub_map_offset.mapping(I...) + sub_map_offset.offset == src.mapping()(*src-indices*(array{I...}, slices...)) is true[.](#5.sentence-1)
|
||||
|
||||
[*Note [2](#note-2)*:
|
||||
|
||||
These conditions ensure that the mapping returned by submdspan_mapping matches the algorithmically expected index-mapping given the slice specifiers[.](#5.sentence-2)
|
||||
|
||||
â *end note*]
|
||||
|
||||
[6](#6)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26100)
|
||||
|
||||
*Effects*: Equivalent to:auto sub_map_result = submdspan_mapping(src.mapping(), slices...);return mdspan(src.accessor().offset(src.data_handle(), sub_map_result.offset),
|
||||
sub_map_result.mapping, typename AccessorPolicy::offset_policy(src.accessor()));
|
||||
|
||||
[7](#7)
|
||||
|
||||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L26111)
|
||||
|
||||
[*Example [1](#example-1)*:
|
||||
|
||||
Given a rank-3 mdspan grid3d representing a three-dimensional grid
|
||||
of regularly spaced points in a rectangular prism,
|
||||
the function zero_surface sets all elements on
|
||||
the surface of the 3-dimensional shape to zero[.](#7.sentence-1)
|
||||
|
||||
It does so by reusing a function zero_2d that takes a rank-2 mdspan[.](#7.sentence-2)
|
||||
|
||||
// zero out all elements in an mdspantemplate<class T, class E, class L, class A>void zero_2d(mdspan<T, E, L, A> a) {static_assert(a.rank() == 2); for (int i = 0; i < a.extent(0); i++)for (int j = 0; j < a.extent(1); j++) a[i, j] = 0;}// zero out just the surfacetemplate<class T, class E, class L, class A>void zero_surface(mdspan<T, E, L, A> grid3d) {static_assert(grid3d.rank() == 3);
|
||||
zero_2d(submdspan(grid3d, 0, full_extent, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, 0, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, full_extent, 0));
|
||||
zero_2d(submdspan(grid3d, grid3d.extent(0) - 1, full_extent, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, grid3d.extent(1) - 1, full_extent));
|
||||
zero_2d(submdspan(grid3d, full_extent, full_extent, grid3d.extent(2) - 1));} â *end example*]
|
||||
14
cppdraft/mdspan/syn.md
Normal file
14
cppdraft/mdspan/syn.md
Normal file
@@ -0,0 +1,14 @@
|
||||
[mdspan.syn]
|
||||
|
||||
# 23 Containers library [[containers]](./#containers)
|
||||
|
||||
## 23.7 Views [[views]](views#mdspan.syn)
|
||||
|
||||
### 23.7.3 Multidimensional access [[views.multidim]](views.multidim#mdspan.syn)
|
||||
|
||||
#### 23.7.3.2 Header <mdspan> synopsis [mdspan.syn]
|
||||
|
||||
[ð](#header:%3cmdspan%3e)
|
||||
|
||||
// mostly freestandingnamespace std {// [[mdspan.extents]](mdspan.extents "23.7.3.3 Class template extents"), class template extentstemplate<class IndexType, size_t... Extents>class extents; // [[mdspan.extents.dextents]](mdspan.extents.dextents "23.7.3.3.6 Alias template dextents"), alias template dextentstemplate<class IndexType, size_t Rank>using dextents = *see below*; // [[mdspan.extents.dims]](mdspan.extents.dims "23.7.3.3.7 Alias template dims"), alias template dimstemplate<size_t Rank, class IndexType = size_t>using dims = *see below*; // [[mdspan.layout]](mdspan.layout "23.7.3.4 Layout mapping"), layout mappingstruct layout_left; struct layout_right; struct layout_stride; template<size_t PaddingValue = dynamic_extent>struct layout_left_padded; template<size_t PaddingValue = dynamic_extent>struct layout_right_padded; // [[mdspan.accessor.default]](mdspan.accessor.default "23.7.3.5.3 Class template default_accessor"), class template default_accessortemplate<class ElementType>class default_accessor; // [[mdspan.accessor.aligned]](mdspan.accessor.aligned "23.7.3.5.4 Class template aligned_accessor"), class template aligned_accessortemplate<class ElementType, size_t ByteAlignment>class aligned_accessor; // [[mdspan.mdspan]](mdspan.mdspan "23.7.3.6 Class template mdspan"), class template mdspantemplate<class ElementType, class Extents, class LayoutPolicy = layout_right, class AccessorPolicy = default_accessor<ElementType>>class mdspan; // partially freestanding// [[mdspan.sub]](mdspan.sub "23.7.3.7 submdspan"), submdspan creationtemplate<class OffsetType, class LengthType, class StrideType>struct strided_slice; template<class LayoutMapping>struct submdspan_mapping_result; struct full_extent_t { explicit full_extent_t() = default; }; inline constexpr full_extent_t full_extent{}; template<class IndexType, size_t... Extents, class... SliceSpecifiers>constexpr auto submdspan_extents(const extents<IndexType, Extents...>&, SliceSpecifiers...); // [[mdspan.sub.sub]](mdspan.sub.sub "23.7.3.7.7 submdspan function template"), submdspan function templatetemplate<class ElementType, class Extents, class LayoutPolicy, class AccessorPolicy, class... SliceSpecifiers>constexpr auto submdspan(const mdspan<ElementType, Extents, LayoutPolicy, AccessorPolicy>& src,
|
||||
SliceSpecifiers... slices) -> *see below*; template<class T, class IndexType>concept [*index-pair-like*](#concept:index-pair-like "23.7.3.2 Header <mdspan> synopsis [mdspan.syn]") = // *exposition only*[*pair-like*](tuple.syn#concept:pair-like "22.4.2 Header <tuple> synopsis [tuple.syn]")<T> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<tuple_element_t<0, T>, IndexType> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_to [concept.convertible]")<tuple_element_t<1, T>, IndexType>;}
|
||||
Reference in New Issue
Block a user