5#ifndef DUNE_COMMON_STD_EXTENTS_HH
6#define DUNE_COMMON_STD_EXTENTS_HH
12#if __has_include(<version>)
23template <
class IndexType, std::
size_t n>
24struct DynamicExtentsArray
26 using type = std::array<IndexType,n>;
29template <
class IndexType>
30struct DynamicExtentsArray<IndexType,0>
34 IndexType operator[](std::size_t )
const {
return 0; }
52template <
class IndexType, std::size_t... exts>
55 static_assert(std::is_integral_v<IndexType>);
58 static constexpr std::size_t rank_ =
sizeof...(exts);
62 using array_type = std::array<std::size_t,rank_>;
65 static constexpr std::array<std::size_t,rank_+1> make_dynamic_index()
67 std::array<std::size_t,rank_+1> di{{}};
68 for (std::size_t i = 0; i < rank_; ++i)
75 static constexpr std::array<std::size_t,rank_+1> dynamic_index_{make_dynamic_index()};
96 return array_type{exts...}[r];
106 return dynamic_extents_[dynamic_index_[r]];
120 template <class... IndexTypes,
121 std::enable_if_t<(... &&
std::is_convertible_v<IndexTypes,
index_type>),
int> = 0,
122 std::enable_if_t<(sizeof...(IndexTypes) ==
rank() || sizeof...(IndexTypes) ==
rank_dynamic()),
int> = 0,
123 std::enable_if_t<(... &&
std::is_nothrow_constructible_v<
index_type, IndexTypes>),
int> = 0>
124 constexpr explicit
extents (IndexTypes... e) noexcept
131 template <
class I, std::size_t N,
132 std::enable_if_t<std::is_convertible_v<I, index_type>,
int> = 0,
134 #
if __cpp_conditional_explicit >= 201806L
137 constexpr extents (
const std::array<I,N>& e)
noexcept
139 init_dynamic_extents<N>(e);
144 template <
class I, std::size_t N,
145 std::enable_if_t<std::is_convertible_v<I, index_type>,
int> = 0,
147 std::enable_if_t<std::is_nothrow_constructible_v<index_type, const I&>,
int> = 0>
148 #
if __cpp_conditional_explicit >= 201806L
153 init_dynamic_extents<N>(e);
156 template <
class I, std::size_t... e,
157 std::enable_if_t<(
sizeof...(e) ==
rank()),
int> = 0,
159 #if __cpp_conditional_explicit >= 201806L
162 (std::numeric_limits<index_type>::max() < std::numeric_limits<I>::max()))
166 init_dynamic_extents<
sizeof...(e)>(as_array(other));
173 template <
class OtherIndexType, std::size_t... otherExts>
176 if (a.rank() != b.rank())
178 using I = std::common_type_t<index_type, OtherIndexType>;
180 if (I(a.extent(i)) != I(b.extent(i)))
188 constexpr size_type product () const noexcept
197 template <
class OtherIndexType, std::size_t... otherExts>
198 static constexpr std::array<
index_type,
sizeof...(otherExts)>
203 std::make_index_sequence<
sizeof...(otherExts)>{});
207 template <std::
size_t N,
class Container>
208 constexpr void init_dynamic_extents (
const Container& e)
noexcept
214 dynamic_extents_[i] = e[i];
216 assert(e.size() ==
rank());
219 dynamic_extents_[j++] = e[i];
228 [[no_unique_address]] dynamic_extents_type dynamic_extents_;
230 template <
class, std::size_t...>
friend class extents;
239template <
class IndexType,
class Seq>
242template <
class IndexType, std::size_t... I>
243struct DExtentsImpl<IndexType,
std::integer_sequence<std::size_t,I...>>
245 template <std::
size_t>
246 using dynamic = std::integral_constant<std::size_t,Std::dynamic_extent>;
258template <
class IndexType, std::
size_t R>
259using dextents =
typename Impl::DExtentsImpl<IndexType, std::make_integer_sequence<std::size_t,R>>::type;
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:259
Namespace for features backported from new C++ standards.
Definition default_accessor.hh:10
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:26
Multidimensional index space with dynamic and static extents.
Definition extents.hh:54
static constexpr rank_type rank_dynamic() noexcept
The number of dimensions with dynamic extent.
Definition extents.hh:90
constexpr extents(const extents< I, e... > &other) noexcept
Definition extents.hh:164
std::size_t rank_type
Definition extents.hh:78
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:87
friend struct layout_stride
Definition extents.hh:233
friend struct layout_left
Definition extents.hh:231
friend struct layout_right
Definition extents.hh:232
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:174
std::make_unsigned_t< index_type > size_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:93
friend class extents
Definition extents.hh:230
constexpr index_type extent(rank_type r) const noexcept
Return the extent of dimension i
Definition extents.hh:100
IndexType index_type
Definition extents.hh:79
A contiguous sequence of elements with static or dynamic extent.
Definition span.hh:126