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

470 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

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

[mdspan.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.1General[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.1General[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.2Requirements"),
- [(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.6Object 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.6Object 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.5Concept 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.11Concept 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.6Object 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.1Overview[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.6Object 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;