5 #ifndef DUNE_COMMON_STD_EXTENTS_HH 6 #define DUNE_COMMON_STD_EXTENTS_HH 12 #include <type_traits> 13 #if __has_include(<version>) 24 template <
class IndexType, std::
size_t n>
25 struct DynamicExtentsArray
27 using type = std::array<IndexType,n>;
30 template <
class IndexType>
31 struct DynamicExtentsArray<IndexType,0>
35 IndexType operator[](std::size_t )
const {
return 0; }
53 template <
class IndexType, std::size_t... exts>
56 static_assert(std::is_integral_v<IndexType>);
59 static constexpr std::size_t rank_ =
sizeof...(exts);
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)
76 static constexpr std::array<std::size_t,rank_+1> dynamic_index_{make_dynamic_index()};
97 return array_type{exts...}[r];
107 return dynamic_extents_[dynamic_index_[r]];
117 constexpr
extents () noexcept = default;
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,
134 std::enable_if_t<(N == rank() || N == rank_dynamic()), 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,
147 std::enable_if_t<(N == rank() || N == rank_dynamic()), 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,
160 #if __cpp_conditional_explicit >= 201806L 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];
228 using dynamic_extents_type =
typename Impl::DynamicExtentsArray<index_type,rank_dynamic()>::type;
231 template <
class, std::size_t...>
friend class extents;
240 template <
class IndexType,
class Seq>
243 template <
class IndexType, std::size_t... I>
244 struct DExtentsImpl<IndexType,
std::integer_sequence<std::size_t,I...>>
257 template <
class IndexType, std::
size_t R>
258 using dextents =
typename Impl::DExtentsImpl<IndexType, std::make_integer_sequence<std::size_t,R>>::type;
262 #endif // DUNE_COMMON_STD_EXTENTS_HH Namespace for features backported from new C++ standards.
Definition: algorithm.hh:19
friend struct layout_stride
Definition: extents.hh:234
std::size_t rank_type
Definition: extents.hh:79
std::make_unsigned_t< index_type > size_type
Definition: extents.hh:81
constexpr index_type extent(rank_type r) const noexcept
Return the extent of dimension i
Definition: extents.hh:101
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:489
decltype(auto) constexpr unpackIntegerSequence(F &&f, [[maybe_unused]] std::integer_sequence< I, i... > sequence)
Unpack an std::integer_sequence<I,i...> to std::integral_constant<I,i>...
Definition: indices.hh:124
friend class extents
Definition: extents.hh:231
#define DUNE_NO_UNIQUE_ADDRESS
Definition: no_unique_address.hh:24
constexpr extents() noexcept=default
The default constructor requires that all exts are not std::dynamic_extent.
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
friend struct layout_right
Definition: extents.hh:233
static constexpr rank_type rank_dynamic() noexcept
The number of dimensions with dynamic extent.
Definition: extents.hh:91
static constexpr rank_type rank() noexcept
The total number of dimensions.
Definition: extents.hh:88
Multidimensional index space with dynamic and static extents.This class template represents a multidi...
Definition: extents.hh:54
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
friend struct layout_left
Definition: extents.hh:232
I i
Definition: hybridmultiindex.hh:328
IndexType index_type
Definition: extents.hh:80
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
constexpr extents(const extents< I, e... > &other) noexcept
Definition: extents.hh:165
constexpr std::size_t dynamic_extent
A constant of type std::size_t that is used to differentiate std::span of static and dynamic extent...
Definition: span.hh:29