5#ifndef DUNE_COMMON_STD_EXTENTS_HH
6#define DUNE_COMMON_STD_EXTENTS_HH
13#if __has_include(<version>)
24template <
class IndexType, std::
size_t n>
25struct DynamicExtentsArray
27 using type = std::array<IndexType,n>;
30template <
class IndexType>
31struct DynamicExtentsArray<IndexType,0>
35 IndexType
operator[](std::size_t )
const {
return 0; }
53template <
class IndexType, std::size_t... exts>
56 static_assert(std::is_integral_v<IndexType>);
59 static constexpr std::size_t rank_ =
sizeof...(exts);
60 static constexpr std::size_t rank_dynamic_ = ((exts == std::dynamic_extent) + ... + 0);
63 using array_type = std::array<std::size_t,rank_>;
66 static constexpr std::array<std::size_t,rank_+1> make_dynamic_index()
68 std::array<std::size_t,rank_+1> di{{}};
69 for (std::size_t i = 0; i < rank_; ++i)
70 di[i+1] = di[i] + (array_type{exts...}[i] == std::dynamic_extent);
76 static constexpr std::array<std::size_t,rank_+1> dynamic_index_{make_dynamic_index()};
97 return array_type{exts...}[r];
104 if (std::size_t e =
static_extent(r); e != std::dynamic_extent)
107 return dynamic_extents_[dynamic_index_[r]];
121 template <class... IndexTypes,
122 std::enable_if_t<(... &&
std::is_convertible_v<IndexTypes,
index_type>),
int> = 0,
123 std::enable_if_t<(sizeof...(IndexTypes) ==
rank() || sizeof...(IndexTypes) ==
rank_dynamic()),
int> = 0,
124 std::enable_if_t<(... &&
std::is_nothrow_constructible_v<
index_type, IndexTypes>),
int> = 0>
125 constexpr explicit
extents (IndexTypes... e) noexcept
132 template <
class I, std::size_t N,
133 std::enable_if_t<std::is_convertible_v<I, index_type>,
int> = 0,
135 #if __cpp_conditional_explicit >= 201806L
138 constexpr extents (
const std::array<I,N>& e)
noexcept
140 init_dynamic_extents<N>(e);
145 template <
class I, std::size_t N,
146 std::enable_if_t<std::is_convertible_v<I, index_type>,
int> = 0,
148 std::enable_if_t<std::is_nothrow_constructible_v<index_type, const I&>,
int> = 0>
149 #
if __cpp_conditional_explicit >= 201806L
154 init_dynamic_extents<N>(e);
157 template <
class I, std::size_t... e,
158 std::enable_if_t<(
sizeof...(e) ==
rank()),
int> = 0,
159 std::enable_if_t<((e == std::dynamic_extent || exts == std::dynamic_extent || e == exts) &&...),
int> = 0>
160 #if __cpp_conditional_explicit >= 201806L
162 (( (exts != std::dynamic_extent) && (e == std::dynamic_extent)) || ... ) ||
163 (std::numeric_limits<index_type>::max() < std::numeric_limits<I>::max()))
167 init_dynamic_extents<
sizeof...(e)>(as_array(other));
174 template <
class OtherIndexType, std::size_t... otherExts>
177 if (a.rank() != b.rank())
179 using I = std::common_type_t<index_type, OtherIndexType>;
181 if (I(a.extent(i)) != I(b.extent(i)))
189 constexpr size_type product () const noexcept
198 template <
class OtherIndexType, std::size_t... otherExts>
199 static constexpr std::array<
index_type,
sizeof...(otherExts)>
204 std::make_index_sequence<
sizeof...(otherExts)>{});
208 template <std::
size_t N,
class Container>
209 constexpr void init_dynamic_extents (
const Container& e)
noexcept
215 dynamic_extents_[i] = e[i];
217 assert(e.size() ==
rank());
220 dynamic_extents_[j++] = e[i];
231 template <
class, std::size_t...>
friend class extents;
240template <
class IndexType,
class Seq>
243template <
class IndexType, std::size_t... I>
244struct DExtentsImpl<IndexType,
std::integer_sequence<std::size_t,I...>>
257template <
class IndexType, std::
size_t R>
258using dextents =
typename Impl::DExtentsImpl<IndexType, std::make_integer_sequence<std::size_t,R>>
::type;
#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
typename Impl::DExtentsImpl< IndexType, std::make_integer_sequence< std::size_t, R > >::type dextents
Alias of extents of given rank R and purely dynamic extents. See [mdspan.extents.dextents].
Definition extents.hh:258
constexpr reference operator[](difference_type n) const
Dereference element with given offset form this iterator.
Definition iteratorfacades.hh:1207
MPI_Datatype MPITraits< ParallelLocalIndex< T > >::type
Definition plocalindex.hh:317
Namespace for features backported from new C++ standards.
Definition algorithm.hh:19
Multidimensional index space with dynamic and static extents.
Definition extents.hh:55
static constexpr rank_type rank_dynamic() noexcept
The number of dimensions with dynamic extent.
Definition extents.hh:91
constexpr extents(const std::array< I, N > &e) noexcept
Set all dynamic extents by the given integral array [[pre: all static extents correspond to the given...
Definition extents.hh:138
std::size_t rank_type
Definition extents.hh:79
constexpr extents() noexcept=default
The default constructor requires that all exts are not std::dynamic_extent.
static constexpr rank_type rank() noexcept
The total number of dimensions.
Definition extents.hh:88
friend struct layout_stride
Definition extents.hh:234
friend struct layout_left
Definition extents.hh:232
friend struct layout_right
Definition extents.hh:233
constexpr extents(std::span< I, N > e) noexcept
Set all dynamic extents by the given integral array [[pre: all static extents correspond to the given...
Definition extents.hh:152
friend constexpr bool operator==(const extents &a, const extents< OtherIndexType, otherExts... > &b) noexcept
Compare two extents by their rank and all individual extents.
Definition extents.hh:175
std::make_unsigned_t< index_type > size_type
Definition extents.hh:81
static constexpr std::size_t static_extent(rank_type r) noexcept
Return the static extent of dimension r or std::dynamic_extent.
Definition extents.hh:94
friend class extents
Definition extents.hh:231
constexpr index_type extent(rank_type r) const noexcept
Return the extent of dimension i.
Definition extents.hh:101
IndexType index_type
Definition extents.hh:80