tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
mdarray.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2
3#ifndef TETL_ARRAY_MDARRAY_HPP
4#define TETL_ARRAY_MDARRAY_HPP
5
10#include <etl/_span/span.hpp>
19#include <etl/_utility/move.hpp>
20
21namespace etl {
22
24template <typename ElementType, typename Extents, typename LayoutPolicy, typename Container>
25struct mdarray {
26private:
27 template <typename C, typename... Args>
28 static constexpr auto array_or_constructible_from = is_etl_array<C> or is_constructible_v<C, Args...>;
29
30public:
31 using extents_type = Extents;
32 using layout_type = LayoutPolicy;
33 using container_type = Container;
34 using mapping_type = typename layout_type::template mapping<extents_type>;
35 using element_type = ElementType;
39 using index_type = typename Extents::index_type;
40 using size_type = typename Extents::size_type;
41 using rank_type = typename Extents::rank_type;
43 using reference = typename container_type::reference;
45 using const_reference = typename container_type::const_reference;
46
47 [[nodiscard]] static constexpr auto rank() noexcept -> rank_type { return Extents::rank(); }
48 [[nodiscard]] static constexpr auto rank_dynamic() noexcept -> rank_type { return Extents::rank_dynamic(); }
49 [[nodiscard]] static constexpr auto static_extent(rank_type r) noexcept -> size_t
50 {
51 return Extents::static_extent(r);
52 }
53 [[nodiscard]] constexpr auto extent(rank_type r) const noexcept -> index_type { return extents().extent(r); }
54
55 // [mdarray.ctors], mdarray constructors
56 constexpr mdarray()
57 requires(rank_dynamic() != 0)
58 = default;
59 constexpr mdarray(mdarray const& rhs) = default;
60 constexpr mdarray(mdarray&& rhs) = default;
61
62 template <typename... OtherIndexTypes>
63 requires(
67 and (is_constructible_v<mapping_type, extents_type>) and (array_or_constructible_from<Container, size_t>)
68 )
69 explicit constexpr mdarray(OtherIndexTypes... exts)
70 : mdarray(extents_type(static_cast<index_type>(etl::move(exts))...))
71 {
72 }
73
74 explicit constexpr mdarray(extents_type const& ext)
75 requires(is_constructible_v<mapping_type, extents_type const&> and array_or_constructible_from<Container, size_t>)
76 : mdarray(mapping_type(ext))
77 {
78 }
79
80 explicit constexpr mdarray(mapping_type const& m)
81 requires(array_or_constructible_from<Container, size_t>)
82 : _map(m)
83 , _ctr([&]() -> container_type {
84 if constexpr (is_constructible_v<Container, size_t>) {
85 return container_type(static_cast<size_t>(_map.required_span_size()));
86 } else {
87 return {};
88 }
89 }())
90 {
91 }
92
93 constexpr mdarray(extents_type const& ext, value_type const& val)
94 requires(is_constructible_v<mapping_type, extents_type const&> and array_or_constructible_from<Container, size_t, value_type>)
95 : mdarray(mapping_type(ext), val)
96 {
97 }
98
99 constexpr mdarray(mapping_type const& m, value_type const& val)
100 requires(array_or_constructible_from<Container, size_t, value_type>)
101 : _map(m)
102 , _ctr([&]() -> container_type {
103 if constexpr (is_constructible_v<Container, size_t, value_type>) {
104 return container_type(static_cast<size_t>(_map.required_span_size()), val);
105 } else {
106 return value_to_array<element_type, container_type().size()>(val);
107 }
108 }())
109 {
110 }
111
112 constexpr mdarray(extents_type const& ext, container_type const& c)
114 : mdarray(mapping_type(ext), c)
115 {
116 }
117
118 constexpr mdarray(mapping_type const& m, container_type const& c)
119 : _map(m)
120 , _ctr(c)
121 {
122 }
123
124 constexpr mdarray(extents_type const& ext, container_type&& c)
126 : mdarray(mapping_type(ext), etl::move(c))
127 {
128 }
129
130 constexpr mdarray(mapping_type const& m, container_type&& c)
131 : _map(m)
132 , _ctr(etl::move(c))
133 {
134 }
135
136 // template <typename OtherElementType, typename OtherExtents, typename OtherLayoutPolicy,
137 // typename OtherContainer> explicit(see below) constexpr mdarray(
138 // mdarray<OtherElementType, OtherExtents, OtherLayoutPolicy, OtherContainer> const& other);
139
140 // template <typename OtherElementType, typename OtherExtents, typename OtherLayoutPolicy,
141 // typename Accessor> explicit(see below) constexpr mdarray(
142 // mdspan<OtherElementType, OtherExtents, OtherLayoutPolicy, Accessor> const& other);
143
144 constexpr auto operator=(mdarray const& rhs) -> mdarray& = default;
145 constexpr auto operator=(mdarray&& rhs) -> mdarray& = default;
146
147#if defined(__cpp_multidimensional_subscript)
148 template <typename... OtherIndexTypes>
149 requires(
152 and (sizeof...(OtherIndexTypes) == rank())
153 )
154 [[nodiscard]] constexpr auto operator[](OtherIndexTypes... indices) -> reference
155 {
156 return (*this)(etl::move(indices)...);
157 }
158
159 template <typename... OtherIndexTypes>
160 requires(
163 and (sizeof...(OtherIndexTypes) == rank())
164 )
165 [[nodiscard]] constexpr auto operator[](OtherIndexTypes... indices) const -> const_reference
166 {
167 return (*this)(etl::move(indices)...);
168 }
169#endif
170
171 template <typename... OtherIndexTypes>
172 requires(
173 (is_convertible_v<OtherIndexTypes, index_type> and ...)
174 and (is_nothrow_constructible_v<index_type, OtherIndexTypes> and ...)
175 and (sizeof...(OtherIndexTypes) == rank())
176 )
177 [[nodiscard]] constexpr auto operator()(OtherIndexTypes... indices) -> reference
178 {
179 return _ctr[static_cast<size_t>(_map(static_cast<index_type>(etl::move(indices))...))];
180 }
181
182 template <typename... OtherIndexTypes>
183 requires(
186 and (sizeof...(OtherIndexTypes) == rank())
187 )
188 [[nodiscard]] constexpr auto operator()(OtherIndexTypes... indices) const -> const_reference
189 {
190 return _ctr[static_cast<size_t>(_map(static_cast<index_type>(etl::move(indices))...))];
191 }
192
193 template <typename OtherIndexType>
195 [[nodiscard]] constexpr auto operator[](span<OtherIndexType, rank()> indices) -> reference
196 {
197 return [&]<size_t... Is>(index_sequence<Is...> /*seq*/) -> decltype(auto) {
198 return (*this)(etl::as_const(indices[Is])...);
200 }
201
202 template <typename OtherIndexType>
204 [[nodiscard]] constexpr auto operator[](span<OtherIndexType, rank()> indices) const -> const_reference
205 {
206 return [&]<size_t... Is>(index_sequence<Is...> /*seq*/) -> decltype(auto) {
207 return (*this)(etl::as_const(indices[Is])...);
209 }
210
211 template <typename OtherIndexType>
213 [[nodiscard]] constexpr auto operator[](array<OtherIndexType, rank()> const& indices) -> reference
214 {
215 return operator[](span{indices});
216 }
217
218 template <typename OtherIndexType>
220 [[nodiscard]] constexpr auto operator[](array<OtherIndexType, rank()> const& indices) const -> const_reference
221 {
222 return operator[](span{indices});
223 }
224
225 [[nodiscard]] constexpr auto size() const -> size_type { return size_type(extents().fwd_prod_of_extents(rank())); }
226 [[nodiscard]] constexpr auto empty() const noexcept -> bool { return size() == 0; }
227
228 [[nodiscard]] constexpr auto extents() const -> extents_type const& { return _map.extents(); }
229 [[nodiscard]] constexpr auto mapping() const -> mapping_type const& { return _map; }
230 [[nodiscard]] constexpr auto stride(size_t r) const -> index_type { return _map.stride(r); }
231
232 [[nodiscard]] constexpr auto container_size() const { return _ctr.size(); }
233 [[nodiscard]] constexpr auto container_data() -> pointer { return to_address(_ctr.begin()); }
234 [[nodiscard]] constexpr auto container_data() const -> const_pointer { return to_address(_ctr.cbegin()); }
235 [[nodiscard]] constexpr auto extract_container() && -> container_type&& { return etl::move(_ctr); }
236
237 [[nodiscard]] constexpr auto is_unique() const -> bool { return _map.is_unique(); }
238 [[nodiscard]] constexpr auto is_exhaustive() const -> bool { return _map.is_exhaustive(); }
239 [[nodiscard]] constexpr auto is_strided() const -> bool { return _map.is_strided(); }
240
241 [[nodiscard]] static constexpr auto is_always_unique() -> bool { return mapping_type::is_always_unique(); }
242 [[nodiscard]] static constexpr auto is_always_exhaustive() -> bool { return mapping_type::is_always_exhaustive(); }
243 [[nodiscard]] static constexpr auto is_always_strided() -> bool { return mapping_type::is_always_strided(); }
244
245 template <typename OtherElement, typename OtherExtents, typename OtherLayout, typename OtherAccessor>
246 // requires is_assignable_v<mdspan<OtherElement, OtherExtents, OtherLayout, OtherAccessor>, mdspan_type>
248 {
249 return mdspan_type(container_data(), _map);
250 }
251
252 template <typename OtherElement, typename OtherExtents, typename OtherLayout, typename OtherAccessor>
253 // requires is_assignable_v<mdspan<OtherElement, OtherExtents, OtherLayout, OtherAccessor>, const_mdspan_type>
255 {
256 return const_mdspan_type(container_data(), _map);
257 }
258
259 template <typename OtherAccessor = default_accessor<element_type>>
260 // requires is_assignable_v<typename OtherAccessor::data_handle_type, pointer>
266
267 template <typename OtherAccessor = default_accessor<element_type const>>
268 // requires is_assignable_v<typename OtherAccessor::data_handle_type, const_pointer>
269 [[nodiscard]] constexpr auto to_mdspan(OtherAccessor const& a = default_accessor<element_type const>()) const
270 -> mdspan<element_type const, extents_type, layout_type, OtherAccessor>
271 {
273 }
274
275 friend constexpr void swap(mdarray& lhs, mdarray& rhs) noexcept
276 {
277 swap(lhs._map, rhs._map);
278 swap(lhs._ctr, rhs._ctr);
279 }
280
281private:
282 template <typename Value, size_t N>
283 [[nodiscard]] static constexpr auto value_to_array(Value const& t) -> array<Value, N>
284 {
285 constexpr auto value = []<typename V>(auto /*i*/, V&& v) -> decltype(auto) { return etl::forward<V&&>(v); };
286 return [&]<size_t... Indices>(index_sequence<Indices...>) {
287 return array<Value, N>{value(Indices, t)...};
288 }(make_index_sequence<N>());
289 }
290
291 mapping_type _map;
292 container_type _ctr;
293};
294
295} // namespace etl
296
297#endif // TETL_ARRAY_MDARRAY_HPP
constexpr auto move(InputIt first, InputIt last, OutputIt destination) -> OutputIt
Moves the elements in the range [first, last), to another range beginning at destination,...
Definition move.hpp:26
constexpr auto cbegin(C const &c) noexcept(noexcept(begin(c))) -> decltype(begin(c))
Definition begin.hpp:41
constexpr auto begin(C &c) -> decltype(c.begin())
Returns an iterator to the beginning of the given container c or array array. These templates rely on...
Definition begin.hpp:20
Definition adjacent_find.hpp:8
constexpr auto as_const(T &t) noexcept -> add_const_t< T > &
Forms lvalue reference to const type of t.
Definition as_const.hpp:12
constexpr bool is_constructible_v
Definition is_constructible.hpp:24
auto declval() noexcept -> add_rvalue_reference_t< T >
etl::make_integer_sequence< etl::size_t, Size > make_index_sequence
Definition index_sequence.hpp:15
etl::integer_sequence< etl::size_t, Ints... > index_sequence
Definition index_sequence.hpp:12
constexpr auto is_etl_array
Definition array.hpp:331
constexpr auto to_address(Ptr const &ptr) noexcept
Obtain the address represented by p without forming a reference to the object pointed to by p.
Definition to_address.hpp:18
constexpr bool is_nothrow_constructible_v
Definition is_nothrow_constructible.hpp:50
constexpr bool is_convertible_v
Definition is_convertible.hpp:46
constexpr auto forward(remove_reference_t< T > &param) noexcept -> T &&
Forwards lvalues as either lvalues or as rvalues, depending on T. When t is a forwarding reference (a...
Definition forward.hpp:18
TETL_BUILTIN_SIZET size_t
etl::size_t is the unsigned integer type of the result of the sizeof operator.
Definition size_t.hpp:14
A container that encapsulates fixed size arrays.
Definition array.hpp:48
Definition default_accessor.hpp:12
typename Extents::size_type size_type
Definition mdarray.hpp:40
constexpr auto to_mdspan(OtherAccessor const &a=default_accessor< element_type >()) -> mdspan< element_type, extents_type, layout_type, OtherAccessor >
Definition mdarray.hpp:261
static constexpr auto is_always_unique() -> bool
Definition mdarray.hpp:241
constexpr auto operator=(mdarray &&rhs) -> mdarray &=default
static constexpr auto rank() noexcept -> rank_type
Definition mdarray.hpp:47
constexpr auto mapping() const -> mapping_type const &
Definition mdarray.hpp:229
typename Extents::index_type index_type
Definition mdarray.hpp:39
constexpr auto operator[](span< OtherIndexType, rank()> indices) -> reference
Definition mdarray.hpp:195
constexpr mdarray(extents_type const &ext, container_type &&c)
Definition mdarray.hpp:124
Extents extents_type
Definition mdarray.hpp:31
constexpr mdarray(extents_type const &ext, container_type const &c)
Definition mdarray.hpp:112
constexpr auto extents() const -> extents_type const &
Definition mdarray.hpp:228
constexpr auto stride(size_t r) const -> index_type
Definition mdarray.hpp:230
constexpr auto container_data() -> pointer
Definition mdarray.hpp:233
friend constexpr void swap(mdarray &lhs, mdarray &rhs) noexcept
Definition mdarray.hpp:275
constexpr auto extract_container() &&-> container_type &&
Definition mdarray.hpp:235
constexpr mdarray(extents_type const &ext, value_type const &val)
Definition mdarray.hpp:93
constexpr mdarray(mapping_type const &m, container_type &&c)
Definition mdarray.hpp:130
decltype(etl::to_address(etl::declval< container_type >().begin())) pointer
Definition mdarray.hpp:42
typename container_type::const_reference const_reference
Definition mdarray.hpp:45
typename container_type::reference reference
Definition mdarray.hpp:43
constexpr auto size() const -> size_type
Definition mdarray.hpp:225
typename Extents::rank_type rank_type
Definition mdarray.hpp:41
constexpr mdarray(mapping_type const &m, value_type const &val)
Definition mdarray.hpp:99
mdspan< element_type, extents_type, layout_type > mdspan_type
Definition mdarray.hpp:36
constexpr auto operator=(mdarray const &rhs) -> mdarray &=default
LayoutPolicy layout_type
Definition mdarray.hpp:32
constexpr mdarray(mapping_type const &m, container_type const &c)
Definition mdarray.hpp:118
ElementType element_type
Definition mdarray.hpp:35
constexpr auto extent(rank_type r) const noexcept -> index_type
Definition mdarray.hpp:53
constexpr auto empty() const noexcept -> bool
Definition mdarray.hpp:226
Container container_type
Definition mdarray.hpp:33
static constexpr auto rank_dynamic() noexcept -> rank_type
Definition mdarray.hpp:48
static constexpr auto is_always_exhaustive() -> bool
Definition mdarray.hpp:242
constexpr auto is_unique() const -> bool
Definition mdarray.hpp:237
constexpr auto container_size() const
Definition mdarray.hpp:232
element_type value_type
Definition mdarray.hpp:38
constexpr mdarray(extents_type const &ext)
Definition mdarray.hpp:74
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:269
decltype(etl::to_address(etl::declval< container_type >().cbegin())) const_pointer
Definition mdarray.hpp:44
constexpr mdarray(mdarray const &rhs)=default
constexpr auto container_data() const -> const_pointer
Definition mdarray.hpp:234
constexpr auto is_strided() const -> bool
Definition mdarray.hpp:239
constexpr auto is_exhaustive() const -> bool
Definition mdarray.hpp:238
constexpr mdarray(mapping_type const &m)
Definition mdarray.hpp:80
static constexpr auto static_extent(rank_type r) noexcept -> size_t
Definition mdarray.hpp:49
constexpr mdarray(mdarray &&rhs)=default
typename layout_type::template mapping< extents_type > mapping_type
Definition mdarray.hpp:34
mdspan< element_type const, extents_type, layout_type > const_mdspan_type
Definition mdarray.hpp:37
static constexpr auto is_always_strided() -> bool
Definition mdarray.hpp:243
constexpr mdarray()=default
constexpr mdarray(OtherIndexTypes... exts)
Definition mdarray.hpp:69
Definition mdspan.hpp:38
If Type is an array type, provides the member constant value equal to the number of dimensions of the...
Definition rank.hpp:16
A non-owning view over a contiguous sequence of objects.
Definition span.hpp:83