17 #ifndef OPENKALMAN_TO_DIAGONAL_MDSPAN_POLICIES_HPP 18 #define OPENKALMAN_TO_DIAGONAL_MDSPAN_POLICIES_HPP 20 #include "patterns/patterns.hpp" 28 template<
typename NestedLayout,
typename NestedExtents>
31 template<
class Extents>
34 using extents_type = Extents;
35 using index_type =
typename extents_type::index_type;
36 using size_type =
typename extents_type::size_type;
37 using rank_type =
typename extents_type::rank_type;
42 using nested_extents_type = NestedExtents;
45 template<
typename...Is>
47 access_with_padded_indices(Is...is)
const 49 if constexpr (
sizeof...(Is) < nested_extents_type::rank())
50 return access_with_padded_indices(is..., 0_uz);
52 return nested_mapping_(is...);
58 mapping(
const nested_mapping_type& map,
const extents_type& e)
59 : nested_mapping_(map), extents_(e) {}
61 constexpr
const extents_type&
62 extents()
const noexcept {
return extents_; }
66 operator() ()
const requires (extents_type::rank() == 0)
68 template<
bool Enable = true, std::enable_if_t<Enable and (extents_type::rank() == 0),
int> = 0>
73 return access_with_padded_indices();
78 operator() (std::convertible_to<index_type>
auto i0)
const requires (extents_type::rank() == 1)
80 template<
typename IndexType0, std::enable_if_t<
81 std::is_convertible_v<IndexType0, index_type> and
82 (extents_type::rank() == 1),
int> = 0>
84 operator() (IndexType0 i0)
const 87 if (i0 == 0)
return access_with_padded_indices();
88 return nested_mapping_.required_span_size();
94 std::convertible_to<index_type>
auto i0,
95 std::convertible_to<index_type>
auto i1,
96 std::convertible_to<index_type>
auto...is)
const requires (2 +
sizeof...(is) == extents_type::rank())
98 template<
typename IndexType0,
typename IndexType1,
typename...IndexTypes, std::enable_if_t<
99 std::is_convertible_v<IndexType0, index_type> and
100 std::is_convertible_v<IndexType1, index_type> and
101 (... and std::is_convertible_v<IndexTypes, index_type>) and
102 (2 +
sizeof...(IndexTypes) == extents_type::rank()),
int> = 0>
104 operator() (IndexType0 i0, IndexType1 i1, IndexTypes...is)
const 107 if (i0 == i1)
return access_with_padded_indices(i1, is...);
108 return nested_mapping_.required_span_size();
112 required_span_size()
const noexcept
114 auto s = nested_mapping_.required_span_size();
115 return s == 0 ? 0 : s + 1;
118 static constexpr
bool 119 is_always_unique() noexcept
121 if constexpr (not nested_mapping_type::is_always_unique())
return false;
122 else if constexpr (extents_type::rank() == 0)
return true;
123 else if constexpr (extents_type::rank() == 1)
return extents_type::static_extent(0) == 1;
124 else return extents_type::static_extent(0) == 1 and extents_type::static_extent(1) == 1;
127 static constexpr
bool 128 is_always_exhaustive() noexcept {
return nested_mapping_type::is_always_exhaustive(); }
130 static constexpr
bool 131 is_always_strided() noexcept {
return false; }
136 if (not nested_mapping_type::is_unique())
return false;
137 if constexpr (extents_type::rank() == 0)
return true;
138 else if constexpr (extents_type::rank() == 1)
return extents_.extent(0) == 1;
139 else return extents_.extent(0) == 1 and extents_.extent(1) == 1;
143 is_exhaustive()
const {
return nested_mapping_type::is_exhaustive(); }
146 is_strided()
const {
return false; }
149 stride(std::size_t r)
const 155 template<
class OtherExtents>
156 friend constexpr
bool 164 nested_mapping_type nested_mapping_;
165 extents_type extents_;
176 template<
typename NestedAccessor>
180 using reference = element_type;
181 using data_handle_type = std::tuple<typename NestedAccessor::data_handle_type, std::size_t>;
184 static_assert(values::value<element_type>);
185 #ifdef __cpp_concepts 186 static_assert(requires {
static_cast<reference
>(std::declval<int>()); });
187 static_assert(requires {
static_cast<reference
>(std::declval<typename NestedAccessor::reference>()); });
199 #ifdef __cpp_concepts 200 template<stdex::convertible_to<NestedAccessor> OtherNestedAccessor> requires
201 (not std::is_same_v<NestedAccessor, OtherNestedAccessor>)
203 template<
typename OtherNestedAccessor, std::enable_if_t<
204 stdex::convertible_to<OtherNestedAccessor, NestedAccessor> and
205 (not std::is_same_v<NestedAccessor, OtherNestedAccessor>),
int> = 0>
208 : nested_accessor_ {other.element_} {}
210 #ifdef __cpp_concepts 211 template<stdex::convertible_to<NestedAccessor> OtherNestedAccessor> requires
212 (not std::is_same_v<NestedAccessor, OtherNestedAccessor>)
214 template<
typename OtherNestedAccessor, std::enable_if_t<
215 stdex::convertible_to<OtherNestedAccessor, NestedAccessor> and
216 (not std::is_same_v<NestedAccessor, OtherNestedAccessor>),
int> = 0>
219 : nested_accessor_ {std::move(other).element_} {}
222 access(data_handle_type p, std::size_t i)
const noexcept
224 if (i == std::get<1>(p))
return static_cast<reference
>(0);
225 return static_cast<reference
>(nested_accessor_.access(std::get<0>(std::move(p)), i));
228 constexpr data_handle_type
229 offset(data_handle_type p, std::size_t i)
const noexcept
231 if (i == 0)
return p;
232 return {std::get<0>(std::move(p)), std::get<1>(p) - i};
235 const NestedAccessor&
236 nested_accessor()
const noexcept {
return nested_accessor_; }
240 NestedAccessor nested_accessor_;
Definition: basics.hpp:41
typename value_type_of< T >::type value_type_of_t
Helper template for value_type_of.
Definition: value_type_of.hpp:52
Definition: to_diagonal_mdspan_policies.hpp:29
constexpr to_diagonal_accessor(NestedAccessor acc)
Definition: to_diagonal_mdspan_policies.hpp:195
decltype(auto) constexpr access(Arg &&arg, const Indices &indices)
Access a component of an indexible object at a given set of indices.
Definition: access.hpp:74
constexpr auto compare_pattern_collections(const A &a, const B &b)
Compare each element of two pattern_collection objects lexicographically.
Definition: compare_pattern_collections.hpp:137
Definition: to_diagonal_mdspan_policies.hpp:177
Definition: to_diagonal_mdspan_policies.hpp:32