65 static_assert(std::is_object_v<Element>);
66 static_assert(!std::is_abstract_v<Element>);
67 static_assert(!std::is_array_v<Element>);
68 static_assert(std::is_same_v<Element, typename AccessorPolicy::element_type>);
77 using mapping_type =
typename layout_type::template mapping<extents_type>;
82 using reference =
typename accessor_type::reference;
86 static_assert(std::is_nothrow_move_constructible_v<mapping_type>);
87 static_assert(std::is_nothrow_move_assignable_v<mapping_type>);
88 static_assert(std::is_nothrow_swappable_v<mapping_type>);
91 static_assert(std::is_nothrow_move_constructible_v<accessor_type>);
92 static_assert(std::is_nothrow_move_assignable_v<accessor_type>);
93 static_assert(std::is_nothrow_swappable_v<accessor_type>);
101 std::enable_if_t<(E::rank_dynamic() > 0),
int> = 0,
102 std::enable_if_t<std::is_default_constructible_v<D>,
int> = 0,
103 std::enable_if_t<std::is_default_constructible_v<M>,
int> = 0,
104 std::enable_if_t<std::is_default_constructible_v<A>,
int> = 0>
112 template <
class... IndexTypes,
114 std::enable_if_t<(
sizeof...(IndexTypes) == E::rank() ||
sizeof...(IndexTypes) == E::rank_dynamic()),
int> = 0,
115 std::enable_if_t<(... && std::is_convertible_v<IndexTypes, index_type>),
int> = 0,
116 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type, IndexTypes>),
int> = 0,
117 std::enable_if_t<std::is_constructible_v<M, E>,
int> = 0,
118 std::enable_if_t<std::is_default_constructible_v<A>,
int> = 0>
124 template <
class IndexType, std::size_t N,
125 std::enable_if_t<std::is_convertible_v<const IndexType&, index_type>,
int> = 0,
126 std::enable_if_t<std::is_nothrow_constructible_v<index_type,const IndexType&>,
int> = 0,
127 std::enable_if_t<(N == extents_type::rank_dynamic() || N == extents_type::rank()),
int> = 0>
128 #
if __cpp_conditional_explicit >= 201806L
129 explicit(N != extents_type::rank_dynamic())
136 template <
class IndexType, std::size_t N,
137 std::enable_if_t<std::is_convertible_v<IndexType, index_type>,
int> = 0,
138 std::enable_if_t<(N == extents_type::rank_dynamic() || N == extents_type::rank()),
int> = 0>
139 #
if __cpp_conditional_explicit >= 201806L
140 explicit(N != extents_type::rank_dynamic())
148 std::enable_if_t<std::is_constructible_v<M, const extents_type&>,
int> = 0>
155 std::enable_if_t<std::is_default_constructible_v<A>,
int> = 0>
162 : data_handle_(
std::move(p))
169 template <
class OtherElementType,
class OtherExtends,
class OtherLayoutPolicy,
class OtherAccessor,
170 std::enable_if_t<std::is_constructible_v<mapping_type, const typename OtherElementType::template mapping<OtherExtends>&>,
int> = 0,
171 std::enable_if_t<std::is_constructible_v<accessor_type, const OtherAccessor&>,
int> = 0>
172 #if __cpp_conditional_explicit >= 201806L
173 explicit(!std::is_convertible_v<const typename OtherElementType::template mapping<OtherExtends>&,
mapping_type>
174 || !std::is_convertible_v<const OtherAccessor&, accessor_type>)
191 template <
class... Indices,
192 std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()),
int> = 0,
193 std::enable_if_t<(... && std::is_convertible_v<Indices, index_type>),
int> = 0,
194 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,Indices>),
int> = 0>
195 constexpr reference operator() (Indices... indices)
const
197 return accessor_.access(data_handle_, mapping_(
index_type(std::move(indices))...));
200#if __cpp_multidimensional_subscript >= 202110L
203 template <
class... Indices,
204 std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()),
int> = 0,
205 std::enable_if_t<(... && std::is_convertible_v<Indices, index_type>),
int> = 0,
206 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,Indices>),
int> = 0>
207 constexpr reference operator[] (Indices... indices)
const
209 return accessor_.access(data_handle_, mapping_(
index_type(std::move(indices))...));
217 std::enable_if_t<std::is_convertible_v<Index,index_type>,
int> = 0,
218 std::enable_if_t<(E::rank() == 1),
int> = 0>
221 return accessor_.access(data_handle_, mapping_(
index_type(std::move(index))));
227 template <
class Index,
228 std::enable_if_t<std::is_convertible_v<const Index&, index_type>,
int> = 0,
229 std::enable_if_t<std::is_nothrow_constructible_v<index_type, const Index&>,
int> = 0>
233 return accessor_.access(data_handle_, mapping_(
index_type(indices[ii])...)); },
234 std::make_index_sequence<extents_type::rank()>{});
238 template <
class Index,
239 std::enable_if_t<std::is_convertible_v<const Index&, index_type>,
int> = 0,
240 std::enable_if_t<std::is_nothrow_constructible_v<index_type, const Index&>,
int> = 0>
243 return std::apply([&](
auto... ii) ->
reference {
244 return accessor_.access(data_handle_, mapping_(
index_type(ii)...)); }, indices);
266 static constexpr rank_type rank () noexcept {
return extents_type::rank(); }
287 [[nodiscard]]
constexpr bool empty () const noexcept {
return size() == 0; }
302 constexpr bool is_unique ()
const {
return mapping_.is_unique(); }
313 constexpr bool is_strided ()
const {
return mapping_.is_strided(); }
323 swap(x.data_handle_, y.data_handle_);
324 swap(x.mapping_, y.mapping_);
325 swap(x.accessor_, y.accessor_);