4#ifndef TETL_ARRAY_MDARRAY_HPP
5#define TETL_ARRAY_MDARRAY_HPP
7#include <etl/_array/array.hpp>
8#include <etl/_iterator/size.hpp>
9#include <etl/_mdspan/mdspan.hpp>
10#include <etl/_memory/to_address.hpp>
11#include <etl/_span/span.hpp>
12#include <etl/_type_traits/declval.hpp>
13#include <etl/_type_traits/is_assignable.hpp>
14#include <etl/_type_traits/is_constructible.hpp>
15#include <etl/_type_traits/is_convertible.hpp>
16#include <etl/_type_traits/is_nothrow_constructible.hpp>
17#include <etl/_utility/as_const.hpp>
18#include <etl/_utility/forward.hpp>
19#include <etl/_utility/index_sequence.hpp>
20#include <etl/_utility/move.hpp>
25template <
typename ElementType,
typename Extents,
typename LayoutPolicy,
typename Container>
28 template <
typename C,
typename... Args>
29 static constexpr auto array_or_constructible_from = is_etl_array<C>
or is_constructible_v<C, Args...>;
32 using extents_type = Extents;
33 using layout_type = LayoutPolicy;
34 using container_type = Container;
35 using mapping_type =
typename layout_type::
template mapping<extents_type>;
36 using element_type = ElementType;
37 using mdspan_type =
mdspan<element_type, extents_type, layout_type>;
38 using const_mdspan_type =
mdspan<element_type
const, extents_type, layout_type>;
39 using value_type = element_type;
40 using index_type =
typename Extents::index_type;
41 using size_type =
typename Extents::size_type;
42 using rank_type =
typename Extents::rank_type;
43 using pointer =
decltype(
etl::to_address(
etl::declval<container_type>().begin()));
44 using reference =
typename container_type::reference;
45 using const_pointer =
decltype(
etl::to_address(
etl::declval<container_type>().cbegin()));
46 using const_reference =
typename container_type::const_reference;
50 return Extents::rank();
54 return Extents::rank_dynamic();
58 return Extents::static_extent(r);
72 template <
typename... OtherIndexTypes>
74 (is_convertible_v<OtherIndexTypes, index_type>
and ...)
75 and (is_nothrow_constructible_v<index_type, OtherIndexTypes>
and ...)
76 and (is_constructible_v<extents_type, OtherIndexTypes...>)
77 and (is_constructible_v<mapping_type, extents_type>)
78 and (array_or_constructible_from<Container, size_t>)
80 explicit constexpr mdarray(OtherIndexTypes... exts)
81 :
mdarray(extents_type(
static_cast<index_type>(
etl::move(exts))...))
85 explicit constexpr mdarray(extents_type
const& ext)
87 is_constructible_v<mapping_type, extents_type
const&>
and array_or_constructible_from<Container, size_t>
93 explicit constexpr mdarray(mapping_type
const& m)
94 requires(array_or_constructible_from<Container, size_t>)
96 , _ctr([&]() -> container_type {
97 if constexpr (is_constructible_v<Container, size_t>) {
98 return container_type(
static_cast<size_t>(_map.required_span_size()));
106 constexpr mdarray(extents_type
const& ext, value_type
const& val)
108 is_constructible_v<mapping_type, extents_type
const&>
109 and array_or_constructible_from<Container, size_t, value_type>
111 :
mdarray(mapping_type(ext), val)
115 constexpr mdarray(mapping_type
const& m, value_type
const& val)
116 requires(array_or_constructible_from<Container, size_t, value_type>)
118 , _ctr([&]() -> container_type {
119 if constexpr (is_constructible_v<Container, size_t, value_type>) {
120 return container_type(
static_cast<size_t>(_map.required_span_size()), val);
122 return value_to_array<element_type, container_type().size()>(val);
128 constexpr mdarray(extents_type
const& ext, container_type
const& c)
129 requires(is_constructible_v<mapping_type, extents_type
const&>)
130 :
mdarray(mapping_type(ext), c)
134 constexpr mdarray(mapping_type
const& m, container_type
const& c)
140 constexpr mdarray(extents_type
const& ext, container_type&& c)
141 requires(is_constructible_v<mapping_type, extents_type
const&>)
146 constexpr mdarray(mapping_type
const& m, container_type&& c)
163#if defined(__cpp_multidimensional_subscript)
164 template <
typename... OtherIndexTypes>
166 (is_convertible_v<OtherIndexTypes, index_type>
and ...)
167 and (is_nothrow_constructible_v<index_type, OtherIndexTypes>
and ...)
168 and (
sizeof...(OtherIndexTypes) ==
rank())
170 [[nodiscard]]
constexpr auto operator[](OtherIndexTypes... indices) -> reference
172 return (*
this)(
etl::move(indices)...);
175 template <
typename... OtherIndexTypes>
177 (is_convertible_v<OtherIndexTypes, index_type>
and ...)
178 and (is_nothrow_constructible_v<index_type, OtherIndexTypes>
and ...)
179 and (
sizeof...(OtherIndexTypes) ==
rank())
181 [[nodiscard]]
constexpr auto operator[](OtherIndexTypes... indices)
const -> const_reference
183 return (*
this)(
etl::move(indices)...);
187 template <
typename... OtherIndexTypes>
189 (is_convertible_v<OtherIndexTypes, index_type>
and ...)
190 and (is_nothrow_constructible_v<index_type, OtherIndexTypes>
and ...)
191 and (
sizeof...(OtherIndexTypes) ==
rank())
193 [[nodiscard]]
constexpr auto operator()(OtherIndexTypes... indices) -> reference
195 return _ctr[
static_cast<size_t>(_map(
static_cast<index_type>(
etl::move(indices))...))];
198 template <
typename... OtherIndexTypes>
200 (is_convertible_v<OtherIndexTypes, index_type>
and ...)
201 and (is_nothrow_constructible_v<index_type, OtherIndexTypes>
and ...)
202 and (
sizeof...(OtherIndexTypes) ==
rank())
204 [[nodiscard]]
constexpr auto operator()(OtherIndexTypes... indices)
const -> const_reference
206 return _ctr[
static_cast<size_t>(_map(
static_cast<index_type>(
etl::move(indices))...))];
209 template <
typename OtherIndexType>
211 is_convertible_v<OtherIndexType
const&, index_type>
212 and is_nothrow_constructible_v<index_type, OtherIndexType
const&>
214 [[nodiscard]]
constexpr auto operator[](span<OtherIndexType,
rank()> indices) -> reference
216 return [&]<size_t... Is>(index_sequence<Is...> ) ->
decltype(
auto) {
217 return (*
this)(
etl::as_const(indices[Is])...);
218 }(make_index_sequence<
rank()>());
221 template <
typename OtherIndexType>
223 is_convertible_v<OtherIndexType
const&, index_type>
224 and is_nothrow_constructible_v<index_type, OtherIndexType
const&>
226 [[nodiscard]]
constexpr auto operator[](span<OtherIndexType,
rank()> indices)
const -> const_reference
228 return [&]<size_t... Is>(index_sequence<Is...> ) ->
decltype(
auto) {
229 return (*
this)(
etl::as_const(indices[Is])...);
230 }(make_index_sequence<
rank()>());
233 template <
typename OtherIndexType>
235 is_convertible_v<OtherIndexType
const&, index_type>
236 and is_nothrow_constructible_v<index_type, OtherIndexType
const&>
240 return operator[](span{indices});
243 template <
typename OtherIndexType>
245 is_convertible_v<OtherIndexType
const&, index_type>
246 and is_nothrow_constructible_v<index_type, OtherIndexType
const&>
248 [[nodiscard]]
constexpr auto operator[](
array<OtherIndexType,
rank()>
const& indices)
const -> const_reference
250 return operator[](span{indices});
264 return _map.extents();
272 return _map.stride(r);
281 return to_address(_ctr.begin());
285 return to_address(_ctr.cbegin());
289 return etl::move(_ctr);
294 return _map.is_unique();
298 return _map.is_exhaustive();
302 return _map.is_strided();
307 return mapping_type::is_always_unique();
311 return mapping_type::is_always_exhaustive();
315 return mapping_type::is_always_strided();
318 template <
typename OtherElement,
typename OtherExtents,
typename OtherLayout,
typename OtherAccessor>
320 [[nodiscard]]
constexpr operator mdspan<OtherElement, OtherExtents, OtherLayout, OtherAccessor>()
322 return mdspan_type(container_data(), _map);
325 template <
typename OtherElement,
typename OtherExtents,
typename OtherLayout,
typename OtherAccessor>
327 [[nodiscard]]
constexpr operator mdspan<OtherElement, OtherExtents, OtherLayout, OtherAccessor>()
const
329 return const_mdspan_type(container_data(), _map);
335 ->
mdspan<element_type, extents_type, layout_type, OtherAccessor>
337 return mdspan<element_type, extents_type, layout_type, OtherAccessor>(container_data(), _map, a);
343 ->
mdspan<element_type
const, extents_type, layout_type, OtherAccessor>
345 return mdspan<element_type
const, extents_type, layout_type, OtherAccessor>(container_data(), _map, a);
350 swap(lhs._map, rhs._map);
351 swap(lhs._ctr, rhs._ctr);
355 template <
typename Value, size_t N>
356 [[nodiscard]]
static constexpr auto value_to_array(Value
const& t) ->
array<Value, N>
358 constexpr auto value = []<
typename V>(
auto , V&& v) ->
decltype(
auto) {
return etl::forward<V&&>(v); };
359 return [&]<size_t... Indices>(index_sequence<Indices...>) {
360 return array<Value, N>{value(Indices, t)...};
361 }(make_index_sequence<N>());
Definition adjacent_find.hpp:9
A container that encapsulates fixed size arrays.
Definition array.hpp:49
Definition default_accessor.hpp:13
Definition mdarray.hpp:26
constexpr auto to_mdspan(OtherAccessor const &a=default_accessor< element_type >()) -> mdspan< element_type, extents_type, layout_type, OtherAccessor >
Definition mdarray.hpp:334
static constexpr auto is_always_unique() -> bool
Definition mdarray.hpp:305
constexpr auto operator=(mdarray &&rhs) -> mdarray &=default
constexpr auto operator[](array< OtherIndexType, rank()> const &indices) const -> const_reference
Definition mdarray.hpp:248
static constexpr auto rank() noexcept -> rank_type
Definition mdarray.hpp:48
constexpr auto mapping() const -> mapping_type const &
Definition mdarray.hpp:266
constexpr mdarray(extents_type const &ext, container_type &&c)
Definition mdarray.hpp:140
constexpr mdarray(extents_type const &ext, container_type const &c)
Definition mdarray.hpp:128
constexpr auto extents() const -> extents_type const &
Definition mdarray.hpp:262
constexpr auto stride(size_t r) const -> index_type
Definition mdarray.hpp:270
constexpr auto container_data() -> pointer
Definition mdarray.hpp:279
friend constexpr void swap(mdarray &lhs, mdarray &rhs) noexcept
Definition mdarray.hpp:348
constexpr auto extract_container() &&-> container_type &&
Definition mdarray.hpp:287
constexpr mdarray(mapping_type const &m, container_type &&c)
Definition mdarray.hpp:146
constexpr auto size() const -> size_type
Definition mdarray.hpp:253
constexpr mdarray(mapping_type const &m, value_type const &val)
Definition mdarray.hpp:115
constexpr auto operator()(OtherIndexTypes... indices) const -> const_reference
Definition mdarray.hpp:204
constexpr auto operator[](span< OtherIndexType, rank()> indices) const -> const_reference
Definition mdarray.hpp:226
constexpr auto operator=(mdarray const &rhs) -> mdarray &=default
constexpr mdarray(extents_type const &ext)
Definition mdarray.hpp:85
constexpr mdarray(mapping_type const &m, container_type const &c)
Definition mdarray.hpp:134
constexpr auto operator()(OtherIndexTypes... indices) -> reference
Definition mdarray.hpp:193
constexpr auto extent(rank_type r) const noexcept -> index_type
Definition mdarray.hpp:60
constexpr auto empty() const noexcept -> bool
Definition mdarray.hpp:257
constexpr auto operator[](span< OtherIndexType, rank()> indices) -> reference
Definition mdarray.hpp:214
static constexpr auto rank_dynamic() noexcept -> rank_type
Definition mdarray.hpp:52
static constexpr auto is_always_exhaustive() -> bool
Definition mdarray.hpp:309
constexpr auto is_unique() const -> bool
Definition mdarray.hpp:292
constexpr auto container_size() const
Definition mdarray.hpp:275
constexpr auto to_mdspan(OtherAccessor const &a=default_accessor< element_type const >()) const -> mdspan< element_type const, extents_type, layout_type, OtherAccessor >
Definition mdarray.hpp:342
constexpr mdarray(mdarray const &rhs)=default
constexpr auto container_data() const -> const_pointer
Definition mdarray.hpp:283
constexpr auto is_strided() const -> bool
Definition mdarray.hpp:300
constexpr auto is_exhaustive() const -> bool
Definition mdarray.hpp:296
constexpr mdarray(mapping_type const &m)
Definition mdarray.hpp:93
constexpr mdarray(extents_type const &ext, value_type const &val)
Definition mdarray.hpp:106
static constexpr auto static_extent(rank_type r) noexcept -> size_t
Definition mdarray.hpp:56
constexpr auto operator[](array< OtherIndexType, rank()> const &indices) -> reference
Definition mdarray.hpp:238
constexpr mdarray(mdarray &&rhs)=default
constexpr operator mdspan< OtherElement, OtherExtents, OtherLayout, OtherAccessor >()
Definition mdarray.hpp:320
constexpr operator mdspan< OtherElement, OtherExtents, OtherLayout, OtherAccessor >() const
Definition mdarray.hpp:327
static constexpr auto is_always_strided() -> bool
Definition mdarray.hpp:313
constexpr mdarray(OtherIndexTypes... exts)
Definition mdarray.hpp:80