tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
mdspan.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2019 Tobias Hienzsch
3
4#ifndef TETL_MDSPAN_MDSPAN_HPP
5#define TETL_MDSPAN_MDSPAN_HPP
6
7#include <etl/_config/all.hpp>
8
9#include <etl/_array/array.hpp>
10#include <etl/_contracts/check.hpp>
11#include <etl/_mdspan/default_accessor.hpp>
12#include <etl/_mdspan/layout_left.hpp>
13#include <etl/_mdspan/layout_right.hpp>
14#include <etl/_span/span.hpp>
15#include <etl/_type_traits/bool_constant.hpp>
16#include <etl/_type_traits/extent.hpp>
17#include <etl/_type_traits/is_array.hpp>
18#include <etl/_type_traits/is_constructible.hpp>
19#include <etl/_type_traits/is_convertible.hpp>
20#include <etl/_type_traits/is_default_constructible.hpp>
21#include <etl/_type_traits/is_nothrow_constructible.hpp>
22#include <etl/_type_traits/is_object.hpp>
23#include <etl/_type_traits/is_pointer.hpp>
24#include <etl/_type_traits/rank.hpp>
25#include <etl/_type_traits/remove_all_extents.hpp>
26#include <etl/_type_traits/remove_cv.hpp>
27#include <etl/_type_traits/remove_pointer.hpp>
28#include <etl/_type_traits/remove_reference.hpp>
29#include <etl/_utility/index_sequence.hpp>
30#include <etl/_utility/move.hpp>
31
32namespace etl {
33
34/// \ingroup mdspan
35template <
36 typename ElementType,
37 typename Extents,
38 typename LayoutPolicy = layout_right,
39 typename AccessorPolicy = default_accessor<ElementType>
40>
41struct mdspan {
42 using extents_type = Extents;
43 using layout_type = LayoutPolicy;
44 using accessor_type = AccessorPolicy;
45 using mapping_type = typename layout_type::template mapping<extents_type>;
46 using element_type = ElementType;
47 using value_type = remove_cv_t<element_type>;
48 using index_type = typename extents_type::index_type;
49 using size_type = typename extents_type::size_type;
50 using rank_type = typename extents_type::rank_type;
51 using data_handle_type = typename accessor_type::data_handle_type;
52 using reference = typename accessor_type::reference;
53
54 [[nodiscard]] static constexpr auto rank() noexcept -> rank_type
55 {
56 return extents_type::rank();
57 }
58
59 [[nodiscard]] static constexpr auto rank_dynamic() noexcept -> rank_type
60 {
61 return extents_type::rank_dynamic();
62 }
63
64 [[nodiscard]] static constexpr auto static_extent(rank_type r) noexcept -> size_t
65 {
66 return Extents::static_extent(r);
67 }
68
69 [[nodiscard]] constexpr auto extent(rank_type r) const noexcept -> index_type
70 {
71 return extents().extent(r);
72 }
73
74 // Constructor (1)
75 constexpr mdspan()
76 requires((rank_dynamic() > 0)
77 and is_default_constructible_v<data_handle_type>
78 and is_default_constructible_v<mapping_type>
79 and is_default_constructible_v<accessor_type>)
80 : _ptr()
81 , _map()
82 , _acc()
83 {
84 }
85
86 // Constructor (2)
87 template <typename... OtherIndexTypes>
88 requires((is_convertible_v<OtherIndexTypes, index_type> and ...)
89 and (is_nothrow_constructible_v<index_type, OtherIndexTypes> and ...)
90 and ((sizeof...(OtherIndexTypes) == rank()) or (sizeof...(OtherIndexTypes) == rank_dynamic()))
91 and is_constructible_v<mapping_type, extents_type>
92 and is_default_constructible_v<accessor_type>)
93 explicit constexpr mdspan(data_handle_type ptr, OtherIndexTypes... exts)
94 : _ptr(etl::move(ptr))
95 , _map(extents_type(static_cast<index_type>(etl::move(exts))...))
96 {
97 }
98
99 // Constructor (3)
100 template <typename OtherIndexType, size_t N>
101 requires(is_convertible_v<OtherIndexType const&, index_type>
102 and is_nothrow_constructible_v<index_type, OtherIndexType const&>
103 and (N == rank() or N == rank_dynamic())
104 and is_constructible_v<mapping_type, extents_type>
105 and is_default_constructible_v<accessor_type>)
106 explicit(N != rank_dynamic()) constexpr mdspan(data_handle_type p, span<OtherIndexType, N> exts)
107 : _ptr(etl::move(p))
108 , _map(extents_type(exts))
109 , _acc()
110 {
111 }
112
113 // Constructor (4)
114 template <typename OtherIndexType, size_t N>
115 requires(is_convertible_v<OtherIndexType const&, index_type>
116 and is_nothrow_constructible_v<index_type, OtherIndexType const&>
117 and (N == rank() or N == rank_dynamic())
118 and is_constructible_v<mapping_type, extents_type>
119 and is_default_constructible_v<accessor_type>)
120 explicit(N != rank_dynamic()) constexpr mdspan(data_handle_type p, array<OtherIndexType, N> const& exts)
121 : _ptr(etl::move(p))
122 , _map(extents_type(exts))
123 , _acc()
124 {
125 }
126
127 // Constructor (5)
128 constexpr mdspan(data_handle_type ptr, extents_type const& ext)
129 requires(is_constructible_v<mapping_type, mapping_type const&> and is_default_constructible_v<accessor_type>)
130 : _ptr(etl::move(ptr))
131 , _map(ext)
132 {
133 }
134
135 // Constructor (6)
136 constexpr mdspan(data_handle_type ptr, mapping_type const& m)
137 requires(is_default_constructible_v<accessor_type>)
138 : _ptr(etl::move(ptr))
139 , _map(m)
140 {
141 }
142
143 // Constructor (7)
144 constexpr mdspan(data_handle_type ptr, mapping_type const& m, accessor_type const& a)
145 : _ptr(etl::move(ptr))
146 , _map(m)
147 , _acc(a)
148 {
149 }
150
151 template <typename OtherElement, typename OtherExtents, typename OtherLayout, typename OtherAccessor>
152 requires(is_constructible_v<mapping_type, typename OtherLayout::template mapping<OtherExtents> const&>
153 and is_constructible_v<accessor_type, OtherAccessor const&>)
154 explicit(
155 not is_convertible_v<typename OtherLayout::template mapping<OtherExtents> const&, mapping_type>
157 ) constexpr mdspan(mdspan<OtherElement, OtherExtents, OtherLayout, OtherAccessor> const& other)
158 : _ptr(other.data_handle())
159 , _map(other.mapping())
160 , _acc(other.accessor())
161 {
162 static_assert(is_constructible_v<extents_type, OtherExtents>);
163 static_assert(is_constructible_v<data_handle_type, typename OtherAccessor::data_handle_type const&>);
164 }
165
166 constexpr mdspan(mdspan const& rhs) = default;
167 constexpr mdspan(mdspan&& rhs) = default; // NOLINT(performance-noexcept-move-constructor)
168
169 template <typename... OtherIndexTypes>
170 requires(
171 (is_convertible_v<OtherIndexTypes, index_type> and ...)
172 and (is_nothrow_constructible_v<index_type, OtherIndexTypes> and ...)
173 and sizeof...(OtherIndexTypes) == rank()
174 )
175 [[nodiscard]] constexpr auto operator()(OtherIndexTypes... indices) const -> reference
176 {
177 auto const idx = static_cast<etl::size_t>(_map(extents_type::index_cast(etl::move(indices))...));
178 return _acc.access(_ptr, idx);
179 }
180
181#if defined(__cpp_multidimensional_subscript)
182 template <typename... OtherIndexTypes>
183 requires(
184 (is_convertible_v<OtherIndexTypes, index_type> and ...)
185 and (is_nothrow_constructible_v<index_type, OtherIndexTypes> and ...)
186 and sizeof...(OtherIndexTypes) == rank()
187 )
188 [[nodiscard]] constexpr auto operator[](OtherIndexTypes... indices) const -> reference
189 {
190 return (*this)(etl::move(indices)...);
191 }
192#endif
193
194 template <typename OtherIndexType>
195 requires(
196 is_convertible_v<OtherIndexType const&, index_type>
197 and is_nothrow_constructible_v<index_type, OtherIndexType const&>
198 )
199 [[nodiscard]] constexpr auto operator[](span<OtherIndexType, rank()> indices) const -> reference
200 {
201 return [&]<size_t... Is>(index_sequence<Is...> /*seq*/) -> reference {
202 return (*this)(indices[Is]...);
203 }(make_index_sequence<rank()>{});
204 }
205
206 template <typename OtherIndexType>
207 requires(
208 is_convertible_v<OtherIndexType const&, index_type>
209 and is_nothrow_constructible_v<index_type, OtherIndexType const&>
210 )
211 [[nodiscard]] constexpr auto operator[](array<OtherIndexType, rank()> const& indices) const -> reference
212 {
213 return (*this)[etl::span{indices}];
214 }
215
216 [[nodiscard]] constexpr auto data_handle() const noexcept -> data_handle_type const&
217 {
218 return _ptr;
219 }
220 [[nodiscard]] constexpr auto mapping() const noexcept -> mapping_type const&
221 {
222 return _map;
223 }
224 [[nodiscard]] constexpr auto accessor() const noexcept -> accessor_type const&
225 {
226 return _acc;
227 }
228
229 [[nodiscard]] constexpr auto extents() const noexcept -> extents_type const&
230 {
231 return _map.extents();
232 }
233 [[nodiscard]] constexpr auto stride(rank_type r) const -> index_type
234 {
235 return _map.stride(r);
236 }
237 [[nodiscard]] constexpr auto empty() const noexcept -> bool
238 {
239 return size() == size_type{};
240 }
241 [[nodiscard]] constexpr auto size() const noexcept -> size_type
242 {
243 return static_cast<size_type>(extents().fwd_prod_of_extents(rank()));
244 }
245
246 [[nodiscard]] constexpr auto is_unique() const -> bool
247 {
248 return _map.is_unique();
249 }
250 [[nodiscard]] constexpr auto is_exhaustive() const -> bool
251 {
252 return _map.is_exhaustive();
253 }
254 [[nodiscard]] constexpr auto is_strided() const -> bool
255 {
256 return _map.is_strided();
257 }
258
259 [[nodiscard]] static constexpr auto is_always_unique() -> bool
260 {
261 return mapping_type::is_always_unique();
262 }
263 [[nodiscard]] static constexpr auto is_always_exhaustive() -> bool
264 {
265 return mapping_type::is_always_exhaustive();
266 }
267 [[nodiscard]] static constexpr auto is_always_strided() -> bool
268 {
269 return mapping_type::is_always_strided();
270 }
271
272private:
273 TETL_NO_UNIQUE_ADDRESS data_handle_type _ptr; // NOLINT(modernize-use-default-member-init)
274 TETL_NO_UNIQUE_ADDRESS mapping_type _map; // NOLINT(modernize-use-default-member-init)
275 TETL_NO_UNIQUE_ADDRESS accessor_type _acc; // NOLINT(modernize-use-default-member-init)
276};
277
278template <typename CArray>
279 requires(is_array_v<CArray> and rank_v<CArray> == 1)
280mdspan(CArray&) -> mdspan<remove_all_extents_t<CArray>, extents<size_t, extent_v<CArray, 0>>>;
281
282template <typename Pointer>
283 requires(is_pointer_v<remove_reference_t<Pointer>>)
284mdspan(Pointer&&) -> mdspan<remove_pointer_t<remove_reference_t<Pointer>>, extents<size_t>>;
285
286template <typename ElementType, typename... Integrals>
287 requires((is_convertible_v<Integrals, size_t> and ...) and sizeof...(Integrals) > 0)
288explicit mdspan(ElementType*, Integrals...) -> mdspan<ElementType, dextents<size_t, sizeof...(Integrals)>>;
289
290template <typename ElementType, typename IndexType, size_t... ExtentsPack>
291mdspan(ElementType*, extents<IndexType, ExtentsPack...> const&)
292 -> mdspan<ElementType, extents<IndexType, ExtentsPack...>>;
293
294template <typename ElementType, typename MappingType>
295mdspan(ElementType*, MappingType const&)
296 -> mdspan<ElementType, typename MappingType::extents_type, typename MappingType::layout_type>;
297
298template <typename MappingType, typename AccessorType>
299mdspan(typename AccessorType::data_handle_type const&, MappingType const&, AccessorType const&) -> mdspan<
300 typename AccessorType::element_type,
301 typename MappingType::extents_type,
302 typename MappingType::layout_type,
303 AccessorType
304>;
305
306template <typename ElementType, typename Extents, typename LayoutPolicy, typename Container>
307struct mdarray;
308
309template <class ElementType, class Extents, class Layout, class Container>
310mdspan(mdarray<ElementType, Extents, Layout, Container>) -> mdspan<
311 typename decltype(declval<mdarray<ElementType, Extents, Layout, Container>>().to_mdspan())::element_type,
312 typename decltype(declval<mdarray<ElementType, Extents, Layout, Container>>().to_mdspan())::extens_type,
313 typename decltype(declval<mdarray<ElementType, Extents, Layout, Container>>().to_mdspan())::layout_type,
314 typename decltype(declval<mdarray<ElementType, Extents, Layout, Container>>().to_mdspan())::accessor_type
315>;
316
317template <typename T>
318struct is_mdspan : false_type { };
319
320template <typename T, typename Extents, typename Layout, typename Accessor>
321struct is_mdspan<mdspan<T, Extents, Layout, Accessor>> : true_type { };
322
323template <typename T>
324inline constexpr auto is_mdspan_v = is_mdspan<T>::value;
325
326} // namespace etl
327
328#endif // TETL_MDSPAN_MDSPAN_HPP
Definition adjacent_find.hpp:9
mdspan(typename AccessorType::data_handle_type const &, MappingType const &, AccessorType const &) -> mdspan< typename AccessorType::element_type, typename MappingType::extents_type, typename MappingType::layout_type, AccessorType >
mdspan(mdarray< ElementType, Extents, Layout, Container >) -> mdspan< typename decltype(declval< mdarray< ElementType, Extents, Layout, Container > >().to_mdspan())::element_type, typename decltype(declval< mdarray< ElementType, Extents, Layout, Container > >().to_mdspan())::extens_type, typename decltype(declval< mdarray< ElementType, Extents, Layout, Container > >().to_mdspan())::layout_type, typename decltype(declval< mdarray< ElementType, Extents, Layout, Container > >().to_mdspan())::accessor_type >
mdspan(ElementType *, Integrals...) -> mdspan< ElementType, dextents< size_t, sizeof...(Integrals)> >
constexpr auto is_mdspan_v
Definition mdspan.hpp:324
mdspan(Pointer &&) -> mdspan< remove_pointer_t< remove_reference_t< Pointer > >, extents< size_t > >
mdspan(ElementType *, MappingType const &) -> mdspan< ElementType, typename MappingType::extents_type, typename MappingType::layout_type >
mdspan(CArray &) -> mdspan< remove_all_extents_t< CArray >, extents< size_t, extent_v< CArray, 0 > > >
mdspan(ElementType *, extents< IndexType, ExtentsPack... > const &) -> mdspan< ElementType, extents< IndexType, ExtentsPack... > >
A container that encapsulates fixed size arrays.
Definition array.hpp:49
Definition default_accessor.hpp:13
Definition extents.hpp:23
Definition mdspan.hpp:318
Definition layout.hpp:14
Definition mdarray.hpp:26
Definition mdspan.hpp:41
static constexpr auto is_always_unique() -> bool
Definition mdspan.hpp:259
constexpr mdspan(data_handle_type ptr, mapping_type const &m)
Definition mdspan.hpp:136
static constexpr auto rank() noexcept -> rank_type
Definition mdspan.hpp:54
constexpr auto accessor() const noexcept -> accessor_type const &
Definition mdspan.hpp:224
constexpr mdspan(data_handle_type ptr, extents_type const &ext)
Definition mdspan.hpp:128
constexpr auto stride(rank_type r) const -> index_type
Definition mdspan.hpp:233
constexpr auto operator[](span< OtherIndexType, rank()> indices) const -> reference
Definition mdspan.hpp:199
OtherAccessor const & other
Definition mdspan.hpp:159
constexpr auto operator[](array< OtherIndexType, rank()> const &indices) const -> reference
Definition mdspan.hpp:211
constexpr mdspan(data_handle_type ptr, OtherIndexTypes... exts)
Definition mdspan.hpp:93
constexpr auto mapping() const noexcept -> mapping_type const &
Definition mdspan.hpp:220
constexpr mdspan(data_handle_type ptr, mapping_type const &m, accessor_type const &a)
Definition mdspan.hpp:144
explicit(N !=rank_dynamic()) const expr mdspan(data_handle_type p
constexpr auto extent(rank_type r) const noexcept -> index_type
Definition mdspan.hpp:69
span< OtherIndexType, N > exts
Definition mdspan.hpp:108
constexpr auto empty() const noexcept -> bool
Definition mdspan.hpp:237
constexpr auto data_handle() const noexcept -> data_handle_type const &
Definition mdspan.hpp:216
array< OtherIndexType, N > const & exts
Definition mdspan.hpp:122
explicit(not is_convertible_v< typename OtherLayout::template mapping< OtherExtents > const &, mapping_type > or not is_convertible_v< OtherAccessor const &, accessor_type >) const expr mdspan(mdspan< OtherElement
static constexpr auto rank_dynamic() noexcept -> rank_type
Definition mdspan.hpp:59
static constexpr auto is_always_exhaustive() -> bool
Definition mdspan.hpp:263
constexpr auto is_unique() const -> bool
Definition mdspan.hpp:246
constexpr auto operator()(OtherIndexTypes... indices) const -> reference
Definition mdspan.hpp:175
constexpr mdspan(mdspan &&rhs)=default
constexpr auto is_strided() const -> bool
Definition mdspan.hpp:254
constexpr auto is_exhaustive() const -> bool
Definition mdspan.hpp:250
static constexpr auto static_extent(rank_type r) noexcept -> size_t
Definition mdspan.hpp:64
constexpr auto extents() const noexcept -> extents_type const &
Definition mdspan.hpp:229
constexpr auto size() const noexcept -> size_type
Definition mdspan.hpp:241
static constexpr auto is_always_strided() -> bool
Definition mdspan.hpp:267
constexpr mdspan(mdspan const &rhs)=default