8#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MDSPAN_LAYOUT_STRIDE_HPP_
9#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_MDSPAN_LAYOUT_STRIDE_HPP_
14#include "arene/base/array/array.hpp"
15#include "arene/base/constraints/constraints.hpp"
16#include "arene/base/contracts/contract.hpp"
17#include "arene/base/mdspan/detail/all_valid_submdspan_slice_types_for.hpp"
18#include "arene/base/mdspan/detail/layout_common.hpp"
19#include "arene/base/mdspan/detail/strided_mapping_base.hpp"
20#include "arene/base/mdspan/detail/submdspan_offset.hpp"
21#include "arene/base/mdspan/detail/submdspan_sub_strides.hpp"
22#include "arene/base/mdspan/is_layout_mapping.hpp"
23#include "arene/base/mdspan/is_sliceable_mapping.hpp"
24#include "arene/base/mdspan/submdspan_extents.hpp"
25#include "arene/base/mdspan/submdspan_mapping_result.hpp"
26#include "arene/base/mdspan/submdspan_subextents_type.hpp"
27#include "arene/base/span/span.hpp"
28#include "arene/base/stdlib_choice/cstddef.hpp"
29#include "arene/base/stdlib_choice/enable_if.hpp"
30#include "arene/base/stdlib_choice/integer_sequence.hpp"
31#include "arene/base/stdlib_choice/integral_constant.hpp"
32#include "arene/base/stdlib_choice/is_constructible.hpp"
33#include "arene/base/stdlib_choice/is_convertible.hpp"
34#include "arene/base/stdlib_choice/is_same.hpp"
35#include "arene/base/stdlib_choice/move.hpp"
36#include "arene/base/stdlib_choice/numeric_limits.hpp"
37#include "arene/base/utility/safe_comparisons.hpp"
45namespace layout_detail {
51template <
typename IndexType>
52constexpr auto precondition_all_strides_positive(span<IndexType
const> strides)
noexcept ->
void {
53 for (
auto const& stride : strides) {
54 ARENE_PRECONDITION(stride > IndexType{});
66 typename OutputIndexType,
67 typename InputIndexType,
69 constraints<std::enable_if_t<Rank != 0UL>> =
nullptr>
70constexpr auto stride_cast(span<InputIndexType
const, Rank> strides)
noexcept -> array<OutputIndexType, Rank> {
71 precondition_all_strides_positive<InputIndexType>(strides);
73 array<OutputIndexType, Rank> converted{};
74 for (std::size_t dim{}; dim < Rank; ++dim) {
75 converted[dim] =
static_cast<OutputIndexType>(strides[dim]);
87 typename OutputIndexType,
88 typename InputIndexType,
90 constraints<std::enable_if_t<Rank == 0UL>> =
nullptr>
91constexpr auto stride_cast(span<InputIndexType
const, Rank>)
noexcept -> array<OutputIndexType, Rank> {
99template <
typename FromMapping,
typename ToMapping,
typename = constraints<>>
100class implicit_conversion_ok :
public std::false_type {};
106template <
typename FromMapping,
typename ToMapping>
107class implicit_conversion_ok<
110 constraints<
typename FromMapping::extents_type,
typename ToMapping::extents_type>>
111 :
public std::integral_constant<
113 std::is_convertible<
typename FromMapping::extents_type,
typename ToMapping::extents_type>::value &&
114 (std::is_same<layout_left::mapping<
typename FromMapping::extents_type>, FromMapping>::value ||
115 std::is_same<layout_right::mapping<
typename FromMapping::extents_type>, FromMapping>::value ||
116 std::is_same<layout_stride::mapping<
typename FromMapping::extents_type>, FromMapping>::value)> {};
123template <
typename Mapping, constraints<std::enable_if_t<Mapping::extents_type::rank() != 0U>> =
nullptr>
124constexpr auto extract_strides(Mapping
const& mapping)
noexcept
125 -> array<
typename Mapping::index_type, Mapping::extents_type::rank()> {
126 array<
typename Mapping::index_type, Mapping::extents_type::rank()> strides{};
127 for (
typename Mapping::rank_type dim{}; dim < Mapping::extents_type::rank(); ++dim) {
128 strides[dim] = mapping.stride(dim);
138template <
typename Mapping, constraints<std::enable_if_t<Mapping::extents_type::rank() == 0U>> =
nullptr>
139constexpr auto extract_strides(Mapping
const&)
noexcept -> array<
typename Mapping::index_type, 0U> {
149template <
typename Mapping,
typename Mapping::rank_type... Dims>
151get_offset_of_mapping_impl(Mapping
const& mapping, std::integer_sequence<
typename Mapping::rank_type, Dims...>)
noexcept
152 ->
typename Mapping::index_type {
154 if (mapping.required_span_size() ==
typename Mapping::index_type{}) {
159 return mapping((
static_cast<
void>(Dims),
typename Mapping::index_type{})...);
168template <
typename Mapping, constraints<std::enable_if_t<Mapping::extents_type::rank() != 0U>> =
nullptr>
169constexpr auto get_offset_of_mapping(Mapping
const& mapping)
noexcept ->
typename Mapping::index_type {
170 return get_offset_of_mapping_impl(
172 std::make_integer_sequence<
typename Mapping::rank_type, Mapping::extents_type::rank()>{}
180template <
typename Mapping, constraints<std::enable_if_t<Mapping::extents_type::rank() == 0U>> =
nullptr>
181constexpr auto get_offset_of_mapping(Mapping
const&)
noexcept ->
typename Mapping::index_type {
192template <
class Extents>
214 static constexpr auto passkey()
noexcept -> layout_detail::check_bypasser {
return layout_detail::check_bypasser{}; }
228 extents_type
const& exts,
229 array<index_type, extents_type::rank()>
const& strds,
359 return required_span_size() == layout_detail::extent_product(
this->extents()).value;
A mapping from a logical pack of indices into a single flat physical output index.
Definition layout_left.hpp:84
static constexpr auto is_always_exhaustive() noexcept -> bool
Return whether or not this mapping is always exhaustive, i.e. every element is reachable using some i...
Definition layout_left.hpp:234
constexpr mapping() noexcept
Construct a default left-strided mapping for the given extents.
Definition layout_left.hpp:99
constexpr auto is_exhaustive() const noexcept -> bool
Return whether or not this instance is exhaustive, i.e. every element is reachable using some indices...
Definition layout_stride.hpp:358
constexpr mapping(extents_type const &exts, array< index_type, extents_type::rank()> const &strds, layout_detail::check_bypasser) noexcept
Construct a mapping with the given strides, bypassing precondition checks.
Definition layout_stride.hpp:227
Definition array_exceptions_disabled.cpp:11
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10