5#ifndef DUNE_COMMON_STD_MDARRAY_HH
6#define DUNE_COMMON_STD_MDARRAY_HH
14#if __has_include(<version>)
66template <
class Element,
class Extents,
class LayoutPolicy = Std::layout_right,
67 class Container = std::vector<Element>>
70 template <
class,
class,
class,
class>
friend class mdarray;
72 static_assert(std::is_object_v<Element>);
73 static_assert(!std::is_abstract_v<Element>);
74 static_assert(!std::is_array_v<Element>);
75 static_assert(std::is_same_v<Element, typename Container::value_type>);
84 using mapping_type =
typename layout_type::template mapping<extents_type>;
94 using reference =
typename container_type::reference;
98 static_assert(std::is_constructible_v<mapping_type, extents_type>);
102 template <
class C,
class... Args>
103 static constexpr auto construct_container (Args&&... args)
104 ->
decltype(Impl::ContainerConstructionTraits<C>::construct(std::forward<Args>(args)...))
106 return Impl::ContainerConstructionTraits<C>::construct(std::forward<Args>(args)...);
115 std::enable_if_t<(E::rank_dynamic() != 0),
int> = 0,
116 std::enable_if_t<std::is_default_constructible_v<C>,
int> = 0,
117 std::enable_if_t<std::is_default_constructible_v<M>,
int> = 0>
129 template <
class... IndexTypes,
130 std::enable_if_t<(... && std::is_convertible_v<IndexTypes,index_type>),
int> = 0,
131 std::enable_if_t<std::is_constructible_v<extents_type,IndexTypes...>,
int> = 0,
132 std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,IndexTypes>),
int> = 0>
133 explicit constexpr mdarray (IndexTypes... exts)
144 decltype(construct_container<C>(std::declval<std::size_t>()),
bool{}) =
true>
146 :
container_(construct_container<C>(m.required_span_size()))
161 decltype(construct_container<C>(std::declval<std::size_t>(),std::declval<const value_type&>()),
bool{}) =
true>
163 :
container_(construct_container<C>(m.required_span_size(), v))
173 std::enable_if_t<std::is_constructible_v<mapping_type,const E&>,
int> = 0>
181 std::enable_if_t<std::is_constructible_v<mapping_type,const E&>,
int> = 0>
204 template <
class OtherElementType,
class OtherExtents,
class OtherLayoutPolicy,
class OtherContainer,
205 std::enable_if_t<std::is_constructible_v<Container,const OtherContainer&>,
int> = 0,
206 std::enable_if_t<std::is_constructible_v<extents_type,OtherExtents>,
int> = 0,
207 std::enable_if_t<std::is_constructible_v<mapping_type,const typename OtherLayoutPolicy::template mapping<OtherExtents>&>,
int> = 0>
208 #if __cpp_conditional_explicit >= 201806L
210 !std::is_convertible_v<const typename OtherLayoutPolicy::template mapping<OtherExtents>&,
mapping_type> ||
211 !std::is_convertible_v<const OtherContainer&, container_type>)
219 template <
class OtherElementType,
class OtherExtents,
class OtherLayoutPolicy,
class Accessor,
220 std::enable_if_t<std::is_constructible_v<value_type,typename Accessor::reference>,
int> = 0,
221 std::enable_if_t<std::is_assignable_v<typename Accessor::reference, value_type>,
int> = 0,
222 std::enable_if_t<std::is_constructible_v<mapping_type, const typename OtherLayoutPolicy::template mapping<OtherExtents>&>,
int> = 0,
223 decltype(construct_container<container_type>(std::declval<std::size_t>()),
bool{}) =
true>
224 #
if __cpp_conditional_explicit >= 201806L
226 !std::is_convertible_v<
const typename OtherLayoutPolicy::template mapping<OtherExtents>&,
mapping_type> ||
227 !std::is_convertible_v<typename Accessor::reference, value_type>)
233 init_from_mdspan(other);
241 template <
class Alloc,
242 std::enable_if_t<std::is_constructible_v<container_type, std::size_t, Alloc>,
int> = 0>
248 template <
class Alloc,
249 std::enable_if_t<std::is_constructible_v<container_type, std::size_t, Alloc>,
int> = 0>
256 template <
class Alloc>
262 template <
class Alloc,
263 std::enable_if_t<std::is_constructible_v<container_type, std::size_t, value_type, Alloc>,
int> = 0>
270 template <
class Alloc,
271 std::enable_if_t<std::is_constructible_v<container_type, container_type, Alloc>,
int> = 0>
278 template <
class Alloc,
279 std::enable_if_t<std::is_constructible_v<container_type, container_type, Alloc>,
int> = 0>
286 template <
class Alloc,
287 std::enable_if_t<std::is_constructible_v<container_type, container_type, Alloc>,
int> = 0>
294 template <
class Alloc,
295 std::enable_if_t<std::is_constructible_v<container_type, container_type, Alloc>,
int> = 0>
302 template <
class V,
class E,
class L,
class C,
class Alloc,
303 std::enable_if_t<std::is_constructible_v<container_type, C, Alloc>,
int> = 0>
304 #if __cpp_conditional_explicit >= 201806L
306 !std::is_convertible_v<const typename L::template mapping<E>&,
mapping_type> ||
307 !std::is_convertible_v<const C&, container_type>)
315 template <
class V,
class E,
class L,
class A,
class Alloc,
317 class Al =
typename C::allocator_type,
318 std::enable_if_t<std::is_constructible_v<C, std::size_t, Alloc>,
int> = 0>
319 #if __cpp_conditional_explicit >= 201806L
321 !std::is_convertible_v<const typename L::template mapping<E>&,
mapping_type> ||
322 !std::is_convertible_v<typename A::reference, value_type> ||
323 !std::is_convertible_v<Alloc, Al>)
329 init_from_mdspan(other);
336 template <
class V,
class E,
class L,
class A,
class... Indices>
339 constexpr rank_type pos =
sizeof...(Indices);
340 if constexpr(pos <
rank()) {
341 for (
typename E::index_type i = 0; i < other.
extent(pos); ++i)
342 init_from_mdspan(other,ii...,i);
344 using I = std::array<
typename E::index_type,E::rank()>;
360 template <
class... Indices,
361 std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()),
int> = 0,
362 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>),
int> = 0>
372 template <
class... Indices,
373 std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()),
int> = 0,
374 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>),
int> = 0>
381#if __cpp_multidimensional_subscript >= 202110L
384 template <
class... Indices,
385 std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()),
int> = 0,
386 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>),
int> = 0>
393 template <
class... Indices,
394 std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()),
int> = 0,
395 std::enable_if_t<(... && std::is_convertible_v<Indices,index_type>),
int> = 0>
406 std::enable_if_t<std::is_convertible_v<Index,index_type>,
int> = 0,
407 std::enable_if_t<(E::rank() == 1),
int> = 0>
416 std::enable_if_t<std::is_convertible_v<Index,index_type>,
int> = 0,
417 std::enable_if_t<(E::rank() == 1),
int> = 0>
427 template <
class Index,
428 std::enable_if_t<std::is_convertible_v<const Index&, index_type>,
int> = 0>
433 std::make_index_sequence<extents_type::rank()>{});
437 template <
class Index,
438 std::enable_if_t<std::is_convertible_v<const Index&, index_type>,
int> = 0>
443 std::make_index_sequence<extents_type::rank()>{});
447 template <
class Index,
448 std::enable_if_t<std::is_convertible_v<const Index&, index_type>,
int> = 0>
451 return std::apply([&](
auto... ii) ->
reference {
456 template <
class Index,
457 std::enable_if_t<std::is_convertible_v<const Index&, index_type>,
int> = 0>
489 static constexpr rank_type rank () noexcept {
return extents_type::rank(); }
513 [[nodiscard]]
constexpr bool empty () const noexcept {
return size() == 0; }
521 static constexpr bool is_always_unique () noexcept {
return mapping_type::is_always_unique(); }
523 static constexpr bool is_always_strided () noexcept {
return mapping_type::is_always_strided(); }
545 swap(x.container_, y.container_);
546 swap(x.mapping_, y.mapping_);
555 return lhs.mapping() == rhs.mapping() && lhs.container() == rhs.container();
564 template <
class V,
class E,
class L,
class A,
565 std::enable_if_t<std::is_assignable_v<mdspan<V,E,L,A>,
mdspan_type>,
int> = 0>
572 template <
class V,
class E,
class L,
class A,
573 std::enable_if_t<std::is_assignable_v<mdspan<V,E,L,A>,
const_mdspan_type>,
int> = 0>
580 template <
class AccessorPolicy = Std::default_accessor<element_type>,
582 std::is_assignable_v<mdspan_type, mdspan<element_type,extents_type,layout_type,AccessorPolicy>>,
int> = 0>
590 template <
class AccessorPolicy = Std::default_accessor<const element_type>,
592 std::is_assignable_v<const_mdspan_type, mdspan<const element_type,extents_type,layout_type,AccessorPolicy>>,
int> = 0>
593 constexpr mdspan<const element_type,extents_type,layout_type,AccessorPolicy>
594 to_mdspan (
const AccessorPolicy& a = AccessorPolicy{})
const
608template <
class IndexType, std::size_t... exts,
class Container>
612template <
class Mapping,
class Container>
613mdarray (
const Mapping&,
const Container&)
616template <
class IndexType, std::size_t... exts,
class Container>
620template <
class Mapping,
class Container>
621mdarray (
const Mapping&, Container&&)
624template <
class Element,
class Extents,
class Layout,
class Accessor>
628template <
class IndexType, std::size_t... exts,
class Container,
class Alloc>
632template <
class Mapping,
class Container,
class Alloc>
633mdarray (
const Mapping&,
const Container&,
const Alloc&)
636template <
class IndexType, std::size_t... exts,
class Container,
class Alloc>
640template <
class Mapping,
class Container,
class Alloc>
641mdarray (
const Mapping&, Container&&,
const Alloc&)
644template <
class Element,
class Extents,
class Layout,
class Accessor,
class Alloc>
654template <
class Element,
class Extents,
class Layout,
class Container>
656 typename decltype(std::declval<mdarray<Element, Extents, Layout, Container>>().to_mdspan())::element_type,
Utilities for reduction like operations on ranges.
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
Namespace for features backported from new C++ standards.
Definition default_accessor.hh:10
constexpr auto to_address(T &&p) noexcept
Obtain the address represented by p without forming a reference to the object pointed to by p.
Definition memory.hh:47
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:54
A layout where the rightmost extent has stride 1, and strides increase right-to-left as the product o...
Definition fwd_layouts.hh:30
An owning multi-dimensional array analog of mdspan.
Definition mdarray.hh:69
mdspan< const element_type, extents_type, layout_type > const_mdspan_type
Definition mdarray.hh:91
constexpr mdarray(const mapping_type &m, const container_type &c, const Alloc &a)
Construct from layout mapping, container and allocator.
Definition mdarray.hh:288
typename container_type::const_reference const_reference
Definition mdarray.hh:96
constexpr mdarray(const mapping_type &m, container_type &&c)
Construct from layout mapping and the storage container.
Definition mdarray.hh:194
Container container_type
Definition mdarray.hh:81
Extents extents_type
Definition mdarray.hh:79
constexpr mdarray(const E &e, const container_type &c)
Construct from extents and the storage container.
Definition mdarray.hh:174
static constexpr bool is_always_exhaustive() noexcept
Definition mdarray.hh:522
constexpr mdspan< const element_type, extents_type, layout_type, AccessorPolicy > to_mdspan(const AccessorPolicy &a=AccessorPolicy{}) const
Conversion function to mdspan.
Definition mdarray.hh:594
constexpr index_type stride(rank_type r) const
The stride along the specified dimension.
Definition mdarray.hh:516
constexpr bool is_unique() const noexcept
Definition mdarray.hh:525
constexpr index_type extent(rank_type r) const noexcept
Number of elements in the r'th dimension of the tensor.
Definition mdarray.hh:498
constexpr mdarray(const extents_type &e, const Alloc &a)
Construct from the extents of the array and allocator.
Definition mdarray.hh:243
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:495
mapping_type mapping_
Definition mdarray.hh:601
constexpr mdarray(const mdspan< OtherElementType, OtherExtents, OtherLayoutPolicy, Accessor > &other)
Converting constructor from mdspan.
Definition mdarray.hh:229
typename layout_type::template mapping< extents_type > mapping_type
Definition mdarray.hh:84
constexpr const_pointer container_data() const noexcept
Direct access to the underlying const data in the container.
Definition mdarray.hh:537
constexpr mdarray(const extents_type &e, const value_type &v)
Construct from extents and initial value.
Definition mdarray.hh:155
constexpr mdarray(const mapping_type &m, const Alloc &a)
Construct from the layout mapping of the array and allocator.
Definition mdarray.hh:250
constexpr pointer container_data() noexcept
Direct access to the underlying data in the container.
Definition mdarray.hh:534
constexpr bool is_exhaustive() const noexcept
Definition mdarray.hh:526
decltype(Std::to_address(std::declval< container_type >().begin())) pointer
Definition mdarray.hh:93
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:408
constexpr const extents_type & extents() const noexcept
Number of elements in all dimensions of the array,.
Definition mdarray.hh:468
constexpr bool is_strided() const noexcept
Definition mdarray.hh:527
constexpr mdarray(const mapping_type &m, const container_type &c)
Construct from layout mapping and the storage container.
Definition mdarray.hh:188
static constexpr bool is_always_unique() noexcept
Definition mdarray.hh:521
constexpr mdarray(const mapping_type &m, container_type &&c, const Alloc &a)
Construct from layout mapping, container and allocator.
Definition mdarray.hh:296
constexpr mdarray(const E &e, container_type &&c)
Construct from extents and the storage container.
Definition mdarray.hh:182
constexpr const container_type & container() const noexcept
The underlying storage container.
Definition mdarray.hh:474
constexpr std::size_t container_size() const
Size of the underlying container.
Definition mdarray.hh:510
typename extents_type::size_type size_type
Definition mdarray.hh:87
static constexpr rank_type rank() noexcept
Number of dimensions of the array.
Definition mdarray.hh:489
constexpr bool empty() const noexcept
Check whether the index space is empty.
Definition mdarray.hh:513
constexpr mdarray(const extents_type &e, container_type &&c, const Alloc &a)
Construct from extents, container and allocator.
Definition mdarray.hh:280
mdspan< element_type, extents_type, layout_type > mdspan_type
Definition mdarray.hh:90
constexpr size_type size() const noexcept
Size of the multi-dimensional index space.
Definition mdarray.hh:501
friend constexpr bool operator==(const mdarray &lhs, const mdarray &rhs) noexcept
Definition mdarray.hh:553
friend constexpr void swap(mdarray &x, mdarray &y) noexcept
Definition mdarray.hh:542
constexpr const mapping_type & mapping() const noexcept
Index mapping of a layout policy.
Definition mdarray.hh:471
Element element_type
Definition mdarray.hh:78
constexpr mdarray(const mapping_type &m, const value_type &v, const Alloc &a)
Construct from layout mapping, initial value and allocator.
Definition mdarray.hh:264
constexpr mdarray(const extents_type &e, const value_type &v, const Alloc &a)
Construct from extents, initial value and allocator.
Definition mdarray.hh:257
decltype(Std::to_address(std::declval< container_type >().cbegin())) const_pointer
Definition mdarray.hh:95
typename container_type::reference reference
Definition mdarray.hh:94
constexpr mdspan< element_type, extents_type, layout_type, AccessorPolicy > to_mdspan(const AccessorPolicy &a=AccessorPolicy{})
Conversion function to mdspan.
Definition mdarray.hh:584
element_type value_type
Definition mdarray.hh:83
LayoutPolicy layout_type
Definition mdarray.hh:80
constexpr container_type && extract_container() &&noexcept
Move the container out of the mdarray.
Definition mdarray.hh:482
constexpr mdarray(const extents_type &e, const container_type &c, const Alloc &a)
Construct from extents, container and allocator.
Definition mdarray.hh:272
typename extents_type::rank_type rank_type
Definition mdarray.hh:88
static constexpr rank_type rank_dynamic() noexcept
Number of dimension with dynamic size.
Definition mdarray.hh:492
constexpr reference operator()(Indices... indices)
Access element at position (i0,i1,...)
Definition mdarray.hh:363
constexpr mdarray(const extents_type &e)
Construct from the extents of the array.
Definition mdarray.hh:138
container_type container_
Definition mdarray.hh:600
typename extents_type::index_type index_type
Definition mdarray.hh:86
constexpr mdarray(IndexTypes... exts)
Construct from the dynamic extents.
Definition mdarray.hh:133
static constexpr bool is_always_strided() noexcept
Definition mdarray.hh:523
A multi-dimensional non-owning array view.
Definition mdspan.hh:64
constexpr index_type extent(rank_type r) const noexcept
Number of elements in the r'th dimension of the tensor.
Definition mdspan.hh:275
constexpr size_type size() const noexcept
The number of elements accessible by this multi-dimensional span.
Definition mdspan.hh:278
A contiguous sequence of elements with static or dynamic extent.
Definition span.hh:126