#
An accessor policy 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.
2
#
A range of indices
A type A meets the accessor policy requirements if
  • A models copyable,
  • is_nothrow_move_constructible_v<A> is true,
  • is_nothrow_move_assignable_v<A> is true,
  • is_nothrow_swappable_v<A> is true, and
  • the following types and expressions are well-formed and have the specified semantics.
typename A::element_type
Result: A complete object type that is not an abstract class type.
typename A::data_handle_type
Result: A type that models copyable, 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, and is_nothrow_swappable_v<A​::​data_handle_type> is true.
[Note 1: 
The type of data_handle_type need not be element_type*.
— end note]
typename A::reference
Result: A type that models common_reference_with<A​::​reference&&, A​::​element_type&>.
[Note 2: 
The type of reference need not be element_type&.
— end note]
typename A::offset_policy
Result: A type OP such that:
  • OP meets the accessor policy requirements,
  • constructible_from<OP, const A&> is modeled, and
  • is_same_v<typename OP​::​element_type, typename A​::​element_type> is true.
a.access(p, i)
[Note 3: 
Concrete accessor policies can impose preconditions for their access function.
However, they might not.
For example, an accessor where p is span<A​::​element_type, dynamic_extent> and access(p, i) returns p[i % p.size()] does not need to impose a precondition on i.
— end note]
a.offset(p, i)
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:
  • b.access(q, j) provides access to the same element as a.access(p, i + j), for every j in the range
Remarks: The expression is equality-preserving.

23.7.3.5.3 Class template default_accessor [mdspan.accessor.default]

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; }; }
ElementType is required to be a complete object type that is neither an abstract class type nor an array type.
Each specialization of default_accessor is a trivially copyable type that models semiregular.
template<class OtherElementType> constexpr default_accessor(default_accessor<OtherElementType>) noexcept {}
Constraints: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true.
constexpr reference access(data_handle_type p, size_t i) const noexcept;
Effects: Equivalent to: return p[i];
constexpr data_handle_type offset(data_handle_type p, size_t i) const noexcept;
Effects: Equivalent to: return p + i;

23.7.3.5.4 Class template aligned_accessor [mdspan.accessor.aligned]

namespace std { template<class ElementType, size_t ByteAlignment> struct aligned_accessor { 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; }; }
ElementType is required to be a complete object type that is neither an abstract class type nor an array type.
Each specialization of aligned_accessor is a trivially copyable type that models semiregular.
[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
  • [p, p + n) is a valid range, and,
  • if n is greater than zero, then is_sufficiently_aligned<byte_alignment>(p) is true.
[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)>.
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.
Otherwise, compute dispatches to a possibly less optimized function compute_without_requiring_overalignment that has no over-alignment requirement.
void compute_using_fourfold_overalignment( mdspan<float, dims<1>, layout_right, aligned_accessor<float, 4 * alignof(float)> x); void compute_without_requiring_overalignment( mdspan<float, dims<1>, layout_right> x); void compute(mdspan<float, dims<1> x) { constexpr auto byte_alignment = 4 * sizeof(float); auto accessor = aligned_accessor<float, byte_alignment>{}; auto x_handle = x.data_handle(); if (is_sufficiently_aligned<byte_alignment>(x_handle)) { compute_using_fourfold_overalignment(mdspan{x_handle, x.mapping(), accessor}); } else { compute_without_requiring_overalignment(x); } } — end example]
template<class OtherElementType, size_t OtherByteAlignment> constexpr aligned_accessor(aligned_accessor<OtherElementType, OtherByteAlignment>) noexcept;
Constraints:
  • is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true.
  • OtherByteAlignment >= byte_alignment is true.
Effects: None.
template<class OtherElementType> constexpr explicit aligned_accessor(default_accessor<OtherElementType>) noexcept;
Constraints: is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true.
Effects: None.
constexpr reference access(data_handle_type p, size_t i) const noexcept;
Effects: Equivalent to: return assume_aligned<byte_alignment>(p)[i];
template<class OtherElementType> constexpr operator default_accessor<OtherElementType>() const noexcept;
Constraints: is_convertible_v<element_type(*)[], OtherElementType(*)[]> is true.
Effects: Equivalent to: return {};
constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const noexcept;
Effects: Equivalent to: return assume_aligned<byte_alignment>(p) + i;

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

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