5#ifndef DUNE_COMMON_STD_EXTENTS_HH 
    6#define DUNE_COMMON_STD_EXTENTS_HH 
   13#if __has_include(<version>) 
   17#include <dune/common/indices.hh> 
   18#include <dune/common/std/no_unique_address.hh> 
   19#include <dune/common/std/impl/fwd_layouts.hh> 
   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()};
 
   79  using rank_type = std::size_t;
 
   80  using index_type = IndexType;
 
   81  using size_type = std::make_unsigned_t<index_type>;
 
   88  static constexpr rank_type 
rank () noexcept { 
return rank_; }
 
   91  static constexpr rank_type 
rank_dynamic () noexcept { 
return rank_dynamic_; }
 
   97    return array_type{exts...}[r];
 
  101  constexpr index_type 
extent (rank_type r) 
const noexcept 
  104    if (std::size_t e = 
static_extent(r); e != std::dynamic_extent)
 
  105      return index_type(e);
 
  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
 
  127    init_dynamic_extents<
sizeof...(e)>(std::array<index_type,
sizeof...(e)>{index_type(e)...});
 
  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)) || ... ) ||
 
  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>;
 
  180    for (rank_type i = 0; i < 
rank(); ++i)
 
  181      if (I(a.extent(i)) != I(b.extent(i)))
 
  189  constexpr size_type product () const noexcept
 
  192    for (rank_type i = 0; i < 
rank(); ++i)
 
  198  template <
class OtherIndexType, std::size_t... otherExts>
 
  199  static constexpr std::array<index_type,
sizeof...(otherExts)>
 
  203      return std::array<index_type,
sizeof...(otherExts)>{index_type(e.extent(ii))...}; },
 
  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());
 
  218        for (rank_type i = 0, j = 0; i < 
rank(); ++i) {
 
  220            dynamic_extents_[j++] = e[i];
 
  228  using dynamic_extents_type = 
typename Impl::DynamicExtentsArray<index_type,
rank_dynamic()>::type;
 
  229  DUNE_NO_UNIQUE_ADDRESS dynamic_extents_type dynamic_extents_;
 
  231  template <
class, std::size_t...> 
friend class extents;
 
  232  friend struct layout_left;
 
  233  friend struct layout_right;
 
  234  friend struct layout_stride;
 
  240template <
class IndexType, 
class Seq>
 
  243template <
class IndexType, std::size_t... I>
 
  244struct DExtentsImpl<IndexType, 
std::integer_sequence<std::size_t,I...>>
 
  246  using type = Std::extents<IndexType, (void(I), std::dynamic_extent)...>;
 
  257template <
class IndexType, std::
size_t R>
 
  258using dextents = 
typename Impl::DExtentsImpl<IndexType, std::make_integer_sequence<std::size_t,R>>::type;
 
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() 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 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
 
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 index_type extent(rank_type r) const noexcept
Return the extent of dimension i
Definition: extents.hh:101
 
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 auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
 
Namespace for features backported from new C++ standards.
Definition: algorithm.hh:19