dune-common 2.12-git
Loading...
Searching...
No Matches
mdarray.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_COMMON_STD_MDARRAY_HH
6#define DUNE_COMMON_STD_MDARRAY_HH
7
8#include <algorithm>
9#include <array>
10#include <memory>
11#include <stdexcept>
12#include <vector>
13#include <span>
14#include <tuple>
15#include <type_traits>
16#if __has_include(<version>)
17 #include <version>
18#endif
19
27
28namespace Dune::Std {
29
68template <class Element, class Extents, class LayoutPolicy = Std::layout_right,
69 class Container = std::vector<Element>>
71{
72 template <class,class,class,class> friend class mdarray;
73
74 static_assert(std::is_object_v<Element>);
75 static_assert(!std::is_abstract_v<Element>);
76 static_assert(!std::is_array_v<Element>);
77 static_assert(std::is_same_v<Element, typename Container::value_type>);
78
79public:
80 using element_type = Element;
81 using extents_type = Extents;
82 using layout_type = LayoutPolicy;
83 using container_type = Container;
84
86 using mapping_type = typename layout_type::template mapping<extents_type>;
87
88 using index_type = typename extents_type::index_type;
89 using size_type = typename extents_type::size_type;
90 using rank_type = typename extents_type::rank_type;
91
94
95 using pointer = decltype(std::to_address(std::declval<container_type>().begin()));
96 using reference = typename container_type::reference;
97 using const_pointer = decltype(std::to_address(std::declval<container_type>().cbegin()));
98 using const_reference = typename container_type::const_reference;
99
100 static_assert(std::is_constructible_v<mapping_type, extents_type>);
101
102private:
103 // helper function to construct the container
104 template <class C, class... Args>
105 static constexpr auto construct_container (Args&&... args)
106 -> decltype(Impl::ContainerConstructionTraits<C>::construct(std::forward<Args>(args)...))
107 {
108 return Impl::ContainerConstructionTraits<C>::construct(std::forward<Args>(args)...);
109 }
110
111public:
114
116 template <class E = extents_type, class C = container_type, class M = mapping_type,
117 std::enable_if_t<(E::rank_dynamic() != 0), int> = 0,
118 std::enable_if_t<std::is_default_constructible_v<C>, int> = 0,
119 std::enable_if_t<std::is_default_constructible_v<M>, int> = 0>
120 constexpr mdarray ()
121 : container_{}
122 , mapping_{}
123 {}
124
125
126 // -------------------------------------
127 // constructors from extents or mappings
128
129
131 template <class... IndexTypes,
132 std::enable_if_t<(... && std::is_convertible_v<IndexTypes,index_type>), int> = 0,
133 std::enable_if_t<std::is_constructible_v<extents_type,IndexTypes...>, int> = 0,
134 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,IndexTypes>), int> = 0>
135 explicit constexpr mdarray (IndexTypes... exts)
136 : mdarray(extents_type(index_type(std::move(exts))...))
137 {}
138
140 explicit constexpr mdarray (const extents_type& e)
142 {}
143
145 template <class C = container_type,
146 decltype(construct_container<C>(std::declval<std::size_t>()), bool{}) = true>
147 explicit constexpr mdarray (const mapping_type& m)
148 : container_(construct_container<C>(m.required_span_size()))
149 , mapping_(m)
150 {}
151
152
153 // ---------------------------------------
154 // constructors with a given initial value
155
157 constexpr mdarray (const extents_type& e, const value_type& v)
158 : mdarray(mapping_type(e), v)
159 {}
160
162 template <class C = container_type,
163 decltype(construct_container<C>(std::declval<std::size_t>(),std::declval<const value_type&>()), bool{}) = true>
164 constexpr mdarray (const mapping_type& m, const value_type& v)
165 : container_(construct_container<C>(m.required_span_size(), v))
166 , mapping_(m)
167 {}
168
169
170 // -----------------------------------
171 // constructors with a given container
172
174 template <class E = extents_type,
176 constexpr mdarray (const E& e, const container_type& c)
177 : container_(c)
178 , mapping_(e)
179 {}
180
182 template <class E = extents_type,
184 constexpr mdarray (const E& e, container_type&& c)
185 : container_(std::move(c))
186 , mapping_(e)
187 {}
188
190 constexpr mdarray (const mapping_type& m, const container_type& c)
191 : container_(c)
192 , mapping_(m)
193 {}
194
196 constexpr mdarray (const mapping_type& m, container_type&& c)
197 : container_(std::move(c))
198 , mapping_(m)
199 {}
200
201
202 // -----------------------
203 // converting constructors
204
206 template <class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class OtherContainer,
210 #if __cpp_conditional_explicit >= 201806L
211 explicit(
212 !std::is_convertible_v<const typename OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type> ||
213 !std::is_convertible_v<const OtherContainer&, container_type>)
214 #endif
219
221 template <class OtherElementType, class OtherExtents, class OtherLayoutPolicy, class Accessor,
225 decltype(construct_container<container_type>(std::declval<std::size_t>()), bool{}) = true>
226 #if __cpp_conditional_explicit >= 201806L
227 explicit(
228 !std::is_convertible_v<const typename OtherLayoutPolicy::template mapping<OtherExtents>&, mapping_type> ||
229 !std::is_convertible_v<typename Accessor::reference, value_type>)
230 #endif
232 : container_(construct_container<container_type>(other.size()))
233 , mapping_(other.mapping())
234 {
235 init_from_mdspan(other);
236 }
237
238
239 // ----------------------------
240 // constructors with allocators
241
243 template <class Alloc,
245 constexpr mdarray (const extents_type& e, const Alloc& a)
246 : mdarray(mapping_type(e), a)
247 {}
248
250 template <class Alloc,
252 constexpr mdarray (const mapping_type& m, const Alloc& a)
253 : container_(m.required_span_size(), a)
254 , mapping_(m)
255 {}
256
258 template <class Alloc>
259 constexpr mdarray (const extents_type& e, const value_type& v, const Alloc& a)
260 : mdarray(mapping_type(e), v, a)
261 {}
262
264 template <class Alloc,
266 constexpr mdarray (const mapping_type& m, const value_type& v, const Alloc& a)
267 : container_(m.required_span_size(), v, a)
268 , mapping_(m)
269 {}
270
272 template <class Alloc,
274 constexpr mdarray (const extents_type& e, const container_type& c, const Alloc& a)
275 : container_(c, a)
276 , mapping_(e)
277 {}
278
280 template <class Alloc,
282 constexpr mdarray (const extents_type& e, container_type&& c, const Alloc& a)
283 : container_(std::move(c), a)
284 , mapping_(e)
285 {}
286
288 template <class Alloc,
290 constexpr mdarray (const mapping_type& m, const container_type& c, const Alloc& a)
291 : container_(c, a)
292 , mapping_(m)
293 {}
294
296 template <class Alloc,
298 constexpr mdarray (const mapping_type& m, container_type&& c, const Alloc& a)
299 : container_(std::move(c), a)
300 , mapping_(m)
301 {}
302
304 template <class V, class E, class L, class C, class Alloc,
306 #if __cpp_conditional_explicit >= 201806L
307 explicit(
308 !std::is_convertible_v<const typename L::template mapping<E>&, mapping_type> ||
309 !std::is_convertible_v<const C&, container_type>)
310 #endif
311 constexpr mdarray (const mdarray<V,E,L,C>& other, const Alloc& a) noexcept
312 : container_(other.container_, a)
313 , mapping_(other.mapping_)
314 {}
315
317 template <class V, class E, class L, class A, class Alloc,
318 class C = container_type,
319 class Al = typename C::allocator_type,
321 #if __cpp_conditional_explicit >= 201806L
322 explicit(
323 !std::is_convertible_v<const typename L::template mapping<E>&, mapping_type> ||
324 !std::is_convertible_v<typename A::reference, value_type> ||
325 !std::is_convertible_v<Alloc, Al>)
326 #endif
327 constexpr mdarray (const mdspan<V,E,L,A>& other, const Alloc& a)
328 : container_(other.size(), a)
329 , mapping_(other.mapping_)
330 {
331 init_from_mdspan(other);
332 }
333
335
336private:
337
338 template <class V, class E, class L, class A, class... Indices>
339 void init_from_mdspan (const mdspan<V,E,L,A>& other, Indices... ii)
340 {
341 constexpr rank_type pos = sizeof...(Indices);
342 if constexpr(pos < rank()) {
343 for (typename E::index_type i = 0; i < other.extent(pos); ++i)
344 init_from_mdspan(other,ii...,i);
345 } else {
346 using I = std::array<typename E::index_type,E::rank()>;
347 container_[mapping_(index_type(ii)...)] = other[I{ii...}];
348 }
349 }
350
351public:
352
355
362 template <class... Indices,
363 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
364 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0>
365 constexpr reference operator() (Indices... indices)
366 {
367 return container_[mapping_(index_type(std::move(indices))...)];
368 }
369
374 template <class... Indices,
375 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
376 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0>
377 constexpr const_reference operator() (Indices... indices) const
378 {
379 return container_[mapping_(index_type(std::move(indices))...)];
380 }
381
382
383#if __cpp_multidimensional_subscript >= 202110L
384
386 template <class... Indices,
387 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
388 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0>
389 constexpr reference operator[] (Indices... indices)
390 {
391 return container_[mapping_(index_type(std::move(indices))...)];
392 }
393
395 template <class... Indices,
396 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
397 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0>
398 constexpr const_reference operator[] (Indices... indices) const
399 {
400 return container_[mapping_(index_type(std::move(indices))...)];
401 }
402
403#else
404
407 template <class Index, class E = extents_type,
409 std::enable_if_t<(E::rank() == 1), int> = 0>
410 constexpr reference operator[] (Index index)
411 {
412 return container_[mapping_(index_type(std::move(index)))];
413 }
414
417 template <class Index, class E = extents_type,
419 std::enable_if_t<(E::rank() == 1), int> = 0>
420 constexpr const_reference operator[] (Index index) const
421 {
422 return container_[mapping_(index_type(std::move(index)))];
423 }
424
425#endif
426
427
429 template <class Index,
431 constexpr reference operator[] (std::span<Index,extents_type::rank()> indices)
432 {
433 return unpackIntegerSequence([&](auto... ii) -> reference {
434 return container_[mapping_(index_type(indices[ii])...)]; },
435 std::make_index_sequence<extents_type::rank()>{});
436 }
437
439 template <class Index,
441 constexpr const_reference operator[] (std::span<Index,extents_type::rank()> indices) const
442 {
443 return unpackIntegerSequence([&](auto... ii) -> const_reference {
444 return container_[mapping_(index_type(indices[ii])...)]; },
445 std::make_index_sequence<extents_type::rank()>{});
446 }
447
449 template <class Index,
451 constexpr reference operator[] (const std::array<Index,extents_type::rank()>& indices)
452 {
453 return std::apply([&](auto... ii) -> reference {
454 return container_[mapping_(index_type(ii)...)]; }, indices);
455 }
456
458 template <class Index,
460 constexpr const_reference operator[] (const std::array<Index,extents_type::rank()>& indices) const
461 {
462 return std::apply([&](auto... ii) -> const_reference {
463 return container_[mapping_(index_type(ii)...)]; }, indices);
464 }
465
467 template <class... Indices,
468 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
469 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0,
470 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,Indices>), int> = 0>
471 constexpr reference at (Indices... indices)
472 {
473 if (!Impl::indexInIndexSpace(*this, indices...))
474 throw std::out_of_range("mdarray index out of range");
475 return container_[mapping_(index_type(std::move(indices))...)];
476 }
477
479 template <class... Indices,
480 std::enable_if_t<(sizeof...(Indices) == extents_type::rank()), int> = 0,
481 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>), int> = 0,
482 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,Indices>), int> = 0>
483 constexpr const_reference at (Indices... indices) const
484 {
485 if (!Impl::indexInIndexSpace(*this, indices...))
486 throw std::out_of_range("mdarray index out of range");
487 return container_[mapping_(index_type(std::move(indices))...)];
488 }
489
491 template <class Index,
494 constexpr reference at (std::span<Index,extents_type::rank()> indices)
495 {
496 if (!Impl::indexInIndexSpace(*this, indices))
497 throw std::out_of_range("mdarray index out of range");
498 return unpackIntegerSequence([&](auto... ii) -> reference {
499 return container_[mapping_(index_type(indices[ii])...)]; },
500 std::make_index_sequence<extents_type::rank()>{});
501 }
502
504 template <class Index,
507 constexpr const_reference at (std::span<Index,extents_type::rank()> indices) const
508 {
509 if (!Impl::indexInIndexSpace(*this, indices))
510 throw std::out_of_range("mdarray index out of range");
511 return unpackIntegerSequence([&](auto... ii) -> const_reference {
512 return container_[mapping_(index_type(indices[ii])...)]; },
513 std::make_index_sequence<extents_type::rank()>{});
514 }
515
517 template <class Index,
520 constexpr reference at (const std::array<Index,extents_type::rank()>& indices)
521 {
522 if (!Impl::indexInIndexSpace(*this, indices))
523 throw std::out_of_range("mdarray index out of range");
524 return std::apply([&](auto... ii) -> reference {
525 return container_[mapping_(index_type(ii)...)]; }, indices);
526 }
527
529 template <class Index,
532 constexpr const_reference at (const std::array<Index,extents_type::rank()>& indices) const
533 {
534 if (!Impl::indexInIndexSpace(*this, indices))
535 throw std::out_of_range("mdarray index out of range");
536 return std::apply([&](auto... ii) -> const_reference {
537 return container_[mapping_(index_type(ii)...)]; }, indices);
538 }
539
541
542
544 constexpr const extents_type& extents () const noexcept { return mapping_.extents(); }
545
547 constexpr const mapping_type& mapping () const noexcept { return mapping_; }
548
550 constexpr const container_type& container () const noexcept { return container_; }
551
558 constexpr container_type&& extract_container () && noexcept { return std::move(container_); }
559
560
563
565 static constexpr rank_type rank () noexcept { return extents_type::rank(); }
566
568 static constexpr rank_type rank_dynamic () noexcept { return extents_type::rank_dynamic(); }
569
571 static constexpr std::size_t static_extent (rank_type r) noexcept { return extents_type::static_extent(r); }
572
574 constexpr index_type extent (rank_type r) const noexcept { return extents().extent(r); }
575
577 constexpr size_type size () const noexcept
578 {
579 size_type s = 1;
580 for (rank_type r = 0; r < rank(); ++r)
581 s *= extent(r);
582 return s;
583 }
584
586 constexpr std::size_t container_size () const { return container_.size(); }
587
589 [[nodiscard]] constexpr bool empty () const noexcept { return size() == 0; }
590
592 constexpr index_type stride (rank_type r) const { return mapping().stride(r); };
593
595
596
597 static constexpr bool is_always_unique () noexcept { return mapping_type::is_always_unique(); }
598 static constexpr bool is_always_exhaustive () noexcept { return mapping_type::is_always_exhaustive(); }
599 static constexpr bool is_always_strided () noexcept { return mapping_type::is_always_strided(); }
600
601 constexpr bool is_unique () const noexcept { return mapping_.is_unique(); }
602 constexpr bool is_exhaustive () const noexcept { return mapping_.is_exhaustive(); }
603 constexpr bool is_strided () const noexcept { return mapping_.is_strided(); }
604
605
608
610 constexpr pointer container_data () noexcept { return std::to_address(container_.begin()); }
611
613 constexpr const_pointer container_data () const noexcept { return std::to_address(container_.begin()); }
614
616
617
618 friend constexpr void swap (mdarray& x, mdarray& y) noexcept
619 {
620 using std::swap;
621 swap(x.container_, y.container_);
622 swap(x.mapping_, y.mapping_);
623 }
624
625
628
629 friend constexpr bool operator== (const mdarray& lhs, const mdarray& rhs) noexcept
630 {
631 return lhs.mapping() == rhs.mapping() && lhs.container() == rhs.container();
632 }
633
635
638
640 template <class V, class E, class L, class A,
642 constexpr operator mdspan<V,E,L,A> ()
643 {
645 }
646
648 template <class V, class E, class L, class A,
650 constexpr operator mdspan<V,E,L,A> () const
651 {
653 }
654
656 template <class AccessorPolicy = Std::default_accessor<element_type>,
657 std::enable_if_t<
658 std::is_assignable_v<mdspan_type, mdspan<element_type,extents_type,layout_type,AccessorPolicy>>, int> = 0>
660 to_mdspan (const AccessorPolicy& a = AccessorPolicy{})
661 {
663 }
664
666 template <class AccessorPolicy = Std::default_accessor<const element_type>,
667 std::enable_if_t<
668 std::is_assignable_v<const_mdspan_type, mdspan<const element_type,extents_type,layout_type,AccessorPolicy>>, int> = 0>
669 constexpr mdspan<const element_type,extents_type,layout_type,AccessorPolicy>
670 to_mdspan (const AccessorPolicy& a = AccessorPolicy{}) const
671 {
673 }
674
675protected:
678};
679
683
684template <class IndexType, std::size_t... exts, class Container>
685mdarray (const Std::extents<IndexType, exts...>&, const Container&)
686 -> mdarray<typename Container::value_type, Std::extents<IndexType, exts...>, layout_right, Container>;
687
688template <class Mapping, class Container>
689mdarray (const Mapping&, const Container&)
691
692template <class IndexType, std::size_t... exts, class Container>
693mdarray (const Std::extents<IndexType, exts...>&, Container&&)
694 -> mdarray<typename Container::value_type, Std::extents<IndexType, exts...>, layout_right, Container>;
695
696template <class Mapping, class Container>
697mdarray (const Mapping&, Container&&)
699
700template <class Element, class Extents, class Layout, class Accessor>
702 -> mdarray<std::remove_cv_t<Element>, Extents, Layout>;
703
704template <class IndexType, std::size_t... exts, class Container, class Alloc>
705mdarray (const Std::extents<IndexType, exts...>&, const Container&, const Alloc&)
706 -> mdarray<typename Container::value_type, Std::extents<IndexType, exts...>, layout_right, Container>;
707
708template <class Mapping, class Container, class Alloc>
709mdarray (const Mapping&, const Container&, const Alloc&)
711
712template <class IndexType, std::size_t... exts, class Container, class Alloc>
713mdarray (const Std::extents<IndexType, exts...>&, Container&&, const Alloc&)
714 -> mdarray<typename Container::value_type, Std::extents<IndexType, exts...>, layout_right, Container>;
715
716template <class Mapping, class Container, class Alloc>
717mdarray (const Mapping&, Container&&, const Alloc&)
719
720template <class Element, class Extents, class Layout, class Accessor, class Alloc>
722 -> mdarray<std::remove_cv_t<Element>, Extents, Layout>;
723
725
729
730template <class Element, class Extents, class Layout, class Container>
732 typename decltype(std::declval<mdarray<Element, Extents, Layout, Container>>().to_mdspan())::element_type,
733 typename decltype(std::declval<mdarray<Element, Extents, Layout, Container>>().to_mdspan())::extents_type,
734 typename decltype(std::declval<mdarray<Element, Extents, Layout, Container>>().to_mdspan())::layout_type,
735 typename decltype(std::declval<mdarray<Element, Extents, Layout, Container>>().to_mdspan())::accessor_type>;
736
738
739} // end namespace Dune::Std
740
741#endif // DUNE_COMMON_STD_MDARRAY_HH
Utilities for reduction like operations on ranges.
#define DUNE_NO_UNIQUE_ADDRESS
Definition no_unique_address.hh:24
decltype(auto) constexpr unpackIntegerSequence(F &&f, std::integer_sequence< I, i... > sequence)
Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
Definition indices.hh:124
STL namespace.
Namespace for features backported from new C++ standards.
Definition algorithm.hh:19
Get the 'const' version of a reference to a mutable object.
Definition genericiterator.hh:87
Multidimensional index space with dynamic and static extents.
Definition extents.hh:55
A layout where the rightmost extent has stride 1, and strides increase right-to-left as the product o...
Definition fwd_layouts.hh:32
An owning multi-dimensional array analog of mdspan.
Definition mdarray.hh:71
mdspan< const element_type, extents_type, layout_type > const_mdspan_type
Definition mdarray.hh:93
constexpr mdarray(const mapping_type &m, const container_type &c, const Alloc &a)
Construct from layout mapping, container and allocator.
Definition mdarray.hh:290
typename container_type::const_reference const_reference
Definition mdarray.hh:98
constexpr mdarray(const mapping_type &m, container_type &&c)
Construct from layout mapping and the storage container.
Definition mdarray.hh:196
Container container_type
Definition mdarray.hh:83
Extents extents_type
Definition mdarray.hh:81
constexpr mdarray(const E &e, const container_type &c)
Construct from extents and the storage container.
Definition mdarray.hh:176
static constexpr bool is_always_exhaustive() noexcept
Definition mdarray.hh:598
constexpr mdspan< const element_type, extents_type, layout_type, AccessorPolicy > to_mdspan(const AccessorPolicy &a=AccessorPolicy{}) const
Conversion function to mdspan.
Definition mdarray.hh:670
constexpr index_type stride(rank_type r) const
The stride along the specified dimension.
Definition mdarray.hh:592
constexpr bool is_unique() const noexcept
Definition mdarray.hh:601
constexpr index_type extent(rank_type r) const noexcept
Number of elements in the r'th dimension of the tensor.
Definition mdarray.hh:574
constexpr mdarray(const extents_type &e, const Alloc &a)
Construct from the extents of the array and allocator.
Definition mdarray.hh:245
static constexpr std::size_t static_extent(rank_type r) noexcept
Number of elements in the r'th dimension of the tensor.
Definition mdarray.hh:571
constexpr mdarray(const mdspan< OtherElementType, OtherExtents, OtherLayoutPolicy, Accessor > &other)
Converting constructor from mdspan.
Definition mdarray.hh:231
constexpr const_reference at(const std::array< Index, extents_type::rank()> &indices) const
Access element with bounds checking.
Definition mdarray.hh:532
typename layout_type::template mapping< extents_type > mapping_type
Definition mdarray.hh:86
constexpr const_pointer container_data() const noexcept
Direct access to the underlying const data in the container.
Definition mdarray.hh:613
DUNE_NO_UNIQUE_ADDRESS mapping_type mapping_
Definition mdarray.hh:677
constexpr mdarray(const extents_type &e, const value_type &v)
Construct from extents and initial value.
Definition mdarray.hh:157
constexpr mdarray(const mapping_type &m, const Alloc &a)
Construct from the layout mapping of the array and allocator.
Definition mdarray.hh:252
constexpr pointer container_data() noexcept
Direct access to the underlying data in the container.
Definition mdarray.hh:610
constexpr bool is_exhaustive() const noexcept
Definition mdarray.hh:602
decltype(std::to_address(std::declval< container_type >().cbegin())) const_pointer
Definition mdarray.hh:97
constexpr reference operator[](Index index)
Access specified element at position [i0] For a rank one mdarray, the operator[i] is added to support...
Definition mdarray.hh:410
constexpr const extents_type & extents() const noexcept
Number of elements in all dimensions of the array,.
Definition mdarray.hh:544
constexpr bool is_strided() const noexcept
Definition mdarray.hh:603
constexpr reference at(std::span< Index, extents_type::rank()> indices)
Access element with bounds checking.
Definition mdarray.hh:494
constexpr mdarray(const mapping_type &m, const container_type &c)
Construct from layout mapping and the storage container.
Definition mdarray.hh:190
static constexpr bool is_always_unique() noexcept
Definition mdarray.hh:597
constexpr mdarray(const mapping_type &m, container_type &&c, const Alloc &a)
Construct from layout mapping, container and allocator.
Definition mdarray.hh:298
constexpr mdarray(const E &e, container_type &&c)
Construct from extents and the storage container.
Definition mdarray.hh:184
constexpr const container_type & container() const noexcept
The underlying storage container.
Definition mdarray.hh:550
constexpr std::size_t container_size() const
Size of the underlying container.
Definition mdarray.hh:586
typename extents_type::size_type size_type
Definition mdarray.hh:89
static constexpr rank_type rank() noexcept
Number of dimensions of the array.
Definition mdarray.hh:565
constexpr bool empty() const noexcept
Check whether the index space is empty.
Definition mdarray.hh:589
constexpr mdarray(const extents_type &e, container_type &&c, const Alloc &a)
Construct from extents, container and allocator.
Definition mdarray.hh:282
mdspan< element_type, extents_type, layout_type > mdspan_type
Definition mdarray.hh:92
constexpr size_type size() const noexcept
Size of the multi-dimensional index space.
Definition mdarray.hh:577
decltype(std::to_address(std::declval< container_type >().begin())) pointer
Definition mdarray.hh:95
friend constexpr bool operator==(const mdarray &lhs, const mdarray &rhs) noexcept
Definition mdarray.hh:629
friend constexpr void swap(mdarray &x, mdarray &y) noexcept
Definition mdarray.hh:618
constexpr const mapping_type & mapping() const noexcept
Index mapping of a layout policy.
Definition mdarray.hh:547
Element element_type
Definition mdarray.hh:80
constexpr mdarray(const mapping_type &m, const value_type &v, const Alloc &a)
Construct from layout mapping, initial value and allocator.
Definition mdarray.hh:266
constexpr mdarray(const extents_type &e, const value_type &v, const Alloc &a)
Construct from extents, initial value and allocator.
Definition mdarray.hh:259
typename container_type::reference reference
Definition mdarray.hh:96
constexpr mdspan< element_type, extents_type, layout_type, AccessorPolicy > to_mdspan(const AccessorPolicy &a=AccessorPolicy{})
Conversion function to mdspan.
Definition mdarray.hh:660
element_type value_type
Definition mdarray.hh:85
LayoutPolicy layout_type
Definition mdarray.hh:82
constexpr reference at(Indices... indices)
Access element with bounds checking.
Definition mdarray.hh:471
constexpr container_type && extract_container() &&noexcept
Move the container out of the mdarray.
Definition mdarray.hh:558
constexpr mdarray(const extents_type &e, const container_type &c, const Alloc &a)
Construct from extents, container and allocator.
Definition mdarray.hh:274
typename extents_type::rank_type rank_type
Definition mdarray.hh:90
constexpr reference at(const std::array< Index, extents_type::rank()> &indices)
Access element with bounds checking.
Definition mdarray.hh:520
static constexpr rank_type rank_dynamic() noexcept
Number of dimension with dynamic size.
Definition mdarray.hh:568
constexpr reference operator()(Indices... indices)
Access element at position (i0,i1,...)
Definition mdarray.hh:365
constexpr mdarray(const extents_type &e)
Construct from the extents of the array.
Definition mdarray.hh:140
container_type container_
Definition mdarray.hh:676
typename extents_type::index_type index_type
Definition mdarray.hh:88
constexpr mdarray(IndexTypes... exts)
Construct from the dynamic extents.
Definition mdarray.hh:135
constexpr const_reference at(std::span< Index, extents_type::rank()> indices) const
Access element with bounds checking.
Definition mdarray.hh:507
static constexpr bool is_always_strided() noexcept
Definition mdarray.hh:599
A multi-dimensional non-owning array view.
Definition mdspan.hh:67
constexpr index_type extent(rank_type r) const noexcept
Number of elements in the r'th dimension of the tensor.
Definition mdspan.hh:315
constexpr size_type size() const noexcept
The number of elements accessible by this multi-dimensional span.
Definition mdspan.hh:318
T apply(T... args)
T declval(T... args)
T is_convertible_v
T swap(T... args)
T to_address(T... args)