5#ifndef DUNE_COMMON_STD_MDSPAN_HH 
    6#define DUNE_COMMON_STD_MDSPAN_HH 
   12#if __has_include(<version>) 
   16#include <dune/common/indices.hh> 
   17#include <dune/common/std/default_accessor.hh> 
   18#include <dune/common/std/extents.hh> 
   19#include <dune/common/std/layout_right.hh> 
   20#include <dune/common/std/no_unique_address.hh> 
   62template <
class Element, 
class Extents, 
class LayoutPolicy = Std::layout_right,
 
   63          class AccessorPolicy = Std::default_accessor<Element>>
 
   66  static_assert(std::is_object_v<Element>);
 
   67  static_assert(!std::is_abstract_v<Element>);
 
   68  static_assert(!std::is_array_v<Element>);
 
   69  static_assert(std::is_same_v<Element, typename AccessorPolicy::element_type>);
 
   72  using element_type =  Element;
 
   73  using extents_type = Extents;
 
   74  using layout_type = LayoutPolicy;
 
   75  using accessor_type = AccessorPolicy;
 
   77  using value_type =    std::remove_cv_t<Element>;
 
   78  using mapping_type = 
typename layout_type::template mapping<extents_type>;
 
   79  using index_type = 
typename extents_type::index_type;
 
   80  using size_type = 
typename extents_type::size_type;
 
   81  using rank_type = 
typename extents_type::rank_type;
 
   82  using data_handle_type = 
typename accessor_type::data_handle_type;
 
   83  using reference = 
typename accessor_type::reference;
 
   87  static_assert(std::is_nothrow_move_constructible_v<mapping_type>);
 
   88  static_assert(std::is_nothrow_move_assignable_v<mapping_type>);
 
   89  static_assert(std::is_nothrow_swappable_v<mapping_type>);
 
   92  static_assert(std::is_nothrow_move_constructible_v<accessor_type>);
 
   93  static_assert(std::is_nothrow_move_assignable_v<accessor_type>);
 
   94  static_assert(std::is_nothrow_swappable_v<accessor_type>);
 
  101  template <
class E = extents_type, 
class D = data_handle_type, 
class M = mapping_type, 
class A = accessor_type,
 
  102    std::enable_if_t<(E::rank_dynamic() > 0), 
int> = 0,
 
  103    std::enable_if_t<std::is_default_constructible_v<D>, 
int> = 0,
 
  104    std::enable_if_t<std::is_default_constructible_v<M>, 
int> = 0,
 
  105    std::enable_if_t<std::is_default_constructible_v<A>, 
int> = 0>
 
  113  template <
class... IndexTypes,
 
  114    class E = extents_type, 
class M = mapping_type, 
class A = accessor_type,
 
  115    std::enable_if_t<(
sizeof...(IndexTypes) == E::rank() || 
sizeof...(IndexTypes) == E::rank_dynamic()), 
int> = 0,
 
  116    std::enable_if_t<(... && std::is_convertible_v<IndexTypes, index_type>), 
int> = 0,
 
  117    std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type, IndexTypes>), 
int> = 0,
 
  118    std::enable_if_t<std::is_constructible_v<M, E>, 
int> = 0,
 
  119    std::enable_if_t<std::is_default_constructible_v<A>, 
int> = 0>
 
  120  explicit constexpr mdspan (data_handle_type p, IndexTypes... exts)
 
  121    : 
mdspan(std::move(p), extents_type(index_type(std::move(exts))...))
 
  125  template <
class IndexType, std::size_t N,
 
  126    std::enable_if_t<std::is_convertible_v<const IndexType&, index_type>, 
int> = 0,
 
  127    std::enable_if_t<std::is_nothrow_constructible_v<index_type,const IndexType&>, 
int> = 0,
 
  128    std::enable_if_t<(N == extents_type::rank_dynamic() || N == extents_type::rank()), 
int> = 0>
 
  129  #
if __cpp_conditional_explicit >= 201806L
 
  130  explicit(N != extents_type::rank_dynamic())
 
  132  constexpr mdspan (data_handle_type p, std::span<IndexType,N> exts)
 
  133    : 
mdspan(std::move(p), extents_type(exts))
 
  137  template <
class IndexType, std::size_t N,
 
  138    std::enable_if_t<std::is_convertible_v<IndexType, index_type>, 
int> = 0,
 
  139    std::enable_if_t<(N == extents_type::rank_dynamic() || N == extents_type::rank()), 
int> = 0>
 
  140  #
if __cpp_conditional_explicit >= 201806L
 
  141  explicit(N != extents_type::rank_dynamic())
 
  143  constexpr mdspan (data_handle_type p, 
const std::array<IndexType,N>& exts)
 
  144    : 
mdspan(std::move(p), extents_type(exts))
 
  148  template <
class M = mapping_type,
 
  149    std::enable_if_t<std::is_constructible_v<M, const extents_type&>, 
int> = 0>
 
  150  constexpr mdspan (data_handle_type p, 
const extents_type& e)
 
  155  template <
class A = accessor_type,
 
  156    std::enable_if_t<std::is_default_constructible_v<A>, 
int> = 0>
 
  157  constexpr mdspan (data_handle_type p, 
const mapping_type& m)
 
  158    : 
mdspan(
std::move(p), m, accessor_type{})
 
  162  constexpr mdspan (data_handle_type p, 
const mapping_type& m, 
const accessor_type& a)
 
  163    : data_handle_(
std::move(p))
 
  170  template <
class OtherElementType, 
class OtherExtends, 
class OtherLayoutPolicy, 
class OtherAccessor,
 
  171    std::enable_if_t<std::is_constructible_v<mapping_type, const typename OtherLayoutPolicy::template mapping<OtherExtends>&>, 
int> = 0,
 
  172    std::enable_if_t<std::is_constructible_v<accessor_type, const OtherAccessor&>, 
int> = 0>
 
  173  #if __cpp_conditional_explicit >= 201806L 
  174  explicit(!std::is_convertible_v<const typename OtherLayoutPolicy::template mapping<OtherExtends>&, mapping_type>
 
  175    || !std::is_convertible_v<const OtherAccessor&, accessor_type>)
 
  192  template <
class... Indices,
 
  193    std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()), 
int> = 0,
 
  194    std::enable_if_t<(... && std::is_convertible_v<Indices, index_type>), 
int> = 0,
 
  195    std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,Indices>), 
int> = 0>
 
  196  constexpr reference 
operator() (Indices... indices) 
const 
  198    return accessor_.access(data_handle_, mapping_(index_type(std::move(indices))...));
 
  201#if __cpp_multidimensional_subscript >= 202110L 
  204  template <
class... Indices,
 
  205  std::enable_if_t<(
sizeof...(Indices) == extents_type::rank()), 
int> = 0,
 
  206  std::enable_if_t<(... && std::is_convertible_v<Indices, index_type>), 
int> = 0,
 
  207  std::enable_if_t<(... && std::is_nothrow_constructible_v<index_type,Indices>), 
int> = 0>
 
  208  constexpr reference 
operator[] (Indices... indices)
 const 
  210    return accessor_.access(data_handle_, mapping_(index_type(std::move(indices))...));
 
  217  template <
class Index, 
class E = extents_type,
 
  218    std::enable_if_t<std::is_convertible_v<Index,index_type>, 
int> = 0,
 
  219    std::enable_if_t<(E::rank() == 1), 
int> = 0>
 
  220  constexpr reference 
operator[] (Index index) 
const 
  222    return accessor_.access(data_handle_, mapping_(index_type(std::move(index))));
 
  228  template <
class Index,
 
  229    std::enable_if_t<std::is_convertible_v<const Index&, index_type>, 
int> = 0,
 
  230    std::enable_if_t<std::is_nothrow_constructible_v<index_type, const Index&>, 
int> = 0>
 
  231  constexpr reference 
operator[] (std::span<Index,extents_type::rank()> indices)
 const 
  234      return accessor_.access(data_handle_, mapping_(index_type(indices[ii])...)); },
 
  235      std::make_index_sequence<extents_type::rank()>{});
 
  239  template <
class Index,
 
  240    std::enable_if_t<std::is_convertible_v<const Index&, index_type>, 
int> = 0,
 
  241    std::enable_if_t<std::is_nothrow_constructible_v<index_type, const Index&>, 
int> = 0>
 
  242  constexpr reference 
operator[] (
const std::array<Index,extents_type::rank()>& indices)
 const 
  244    return std::apply([&](
auto... ii) -> reference {
 
  245      return accessor_.access(data_handle_, mapping_(index_type(ii)...)); }, indices);
 
  251  constexpr const extents_type& 
extents () const noexcept { 
return mapping_.extents(); }
 
  254  constexpr const mapping_type& 
mapping () const noexcept { 
return mapping_; }
 
  257  constexpr const accessor_type& 
accessor () const noexcept { 
return accessor_; }
 
  260  constexpr const data_handle_type& 
data_handle () const noexcept { 
return data_handle_; };
 
  267  static constexpr rank_type 
rank () noexcept { 
return extents_type::rank(); }
 
  270  static constexpr rank_type 
rank_dynamic () noexcept { 
return extents_type::rank_dynamic(); }
 
  273  static constexpr std::size_t 
static_extent (rank_type r) 
noexcept { 
return extents_type::static_extent(r); }
 
  276  constexpr index_type 
extent (rank_type r) 
const noexcept { 
return extents().extent(r); }
 
  279  constexpr size_type 
size () const noexcept
 
  282    for (rank_type r = 0; r < 
rank(); ++r)
 
  288  [[nodiscard]] 
constexpr bool empty () const noexcept { 
return size() == 0; }
 
  303  constexpr bool is_unique ()
 const { 
return mapping_.is_unique(); }
 
  314  constexpr bool is_strided ()
 const { 
return mapping_.is_strided(); }
 
  317  constexpr index_type 
stride (rank_type r)
 const { 
return mapping_.stride(r); }
 
  324    swap(x.data_handle_, y.data_handle_);
 
  325    swap(x.mapping_, y.mapping_);
 
  326    swap(x.accessor_, y.accessor_);
 
  331  data_handle_type data_handle_;
 
  332  DUNE_NO_UNIQUE_ADDRESS mapping_type mapping_;
 
  333  DUNE_NO_UNIQUE_ADDRESS accessor_type accessor_;
 
  339template <
class CArray,
 
  340  std::enable_if_t<std::is_array_v<CArray>, 
int> = 0,
 
  341  std::enable_if_t<(std::rank_v<CArray> == 1), 
int> = 0>
 
  345template <
class Pointer,
 
  346  std::enable_if_t<std::is_pointer_v<std::remove_reference_t<Pointer>>, 
int> = 0>
 
  350template <
class ElementType, 
class... II,
 
  351  std::enable_if_t<(... && std::is_convertible_v<II,std::size_t>), 
int> = 0,
 
  352  std::enable_if_t<(
sizeof...(II) > 0), 
int> = 0>
 
  353mdspan (ElementType*, II...)
 
  354  -> mdspan<ElementType, 
Std::dextents<std::size_t, 
sizeof...(II)>>;
 
  356template <
class ElementType, 
class SizeType, std::
size_t N>
 
  357mdspan (ElementType*, std::span<SizeType,N>)
 
  358  -> mdspan<ElementType, Std::dextents<std::size_t, N>>;
 
  360template <
class ElementType, 
class SizeType, std::
size_t N>
 
  361mdspan (ElementType*, 
const std::array<SizeType,N>&)
 
  362  -> mdspan<ElementType, Std::dextents<std::size_t, N>>;
 
  364template <
class ElementType, 
class IndexType, std::size_t... exts>
 
  366  -> mdspan<ElementType, 
Std::extents<IndexType,exts...>>;
 
  368template <
class ElementType, 
class Mapping,
 
  369  class Extents = 
typename Mapping::extents_type,
 
  370  class Layout = 
typename Mapping::layout_type>
 
  371mdspan (ElementType*, 
const Mapping&)
 
  372  -> mdspan<ElementType, Extents, Layout>;
 
  374template <
class Mapping, 
class Accessor,
 
  375  class DataHandle = 
typename Accessor::data_handle_type,
 
  376  class Element = 
typename Accessor::element_type,
 
  377  class Extents = 
typename Mapping::extents_type,
 
  378  class Layout = 
typename Mapping::layout_type>
 
  379mdspan (
const DataHandle&, 
const Mapping&, 
const Accessor&)
 
  380  -> mdspan<Element, Extents, Layout, Accessor>;
 
Multidimensional index space with dynamic and static extents.
Definition: extents.hh:55
 
A multi-dimensional non-owning array view.
Definition: mdspan.hh:65
 
constexpr mdspan(data_handle_type p, const mapping_type &m, const accessor_type &a)
Construct from the pointer to the data of the tensor, an index mapping, and an accessor.
Definition: mdspan.hh:162
 
static constexpr rank_type rank_dynamic() noexcept
Number of dimensions of the tensor.
Definition: mdspan.hh:270
 
static constexpr bool is_always_unique()
Return true only if for every i and j where (i != j || ...) => mapping(i...) != mapping(j....
Definition: mdspan.hh:294
 
constexpr bool is_strided() const
Return true only if for every rank index r of extents there exists an integer sr such that,...
Definition: mdspan.hh:314
 
constexpr mdspan(data_handle_type p, const mapping_type &m)
Construct from the pointer to the data of the tensor and an index mapping.
Definition: mdspan.hh:157
 
constexpr mdspan(data_handle_type p, const extents_type &e)
Construct from the pointer to the data of the tensor and its extents.
Definition: mdspan.hh:150
 
static constexpr bool is_always_exhaustive()
Return true only if for all k in the range [0, mapping.required_span_size() ) there exists an i such ...
Definition: mdspan.hh:297
 
constexpr reference operator[](Index index) const
Access specified element at position [i0] For a rank one mdspan, the operator[i] is added to support ...
Definition: mdspan.hh:220
 
constexpr const extents_type & extents() const noexcept
Number of elements in all dimensions of the tensor,.
Definition: mdspan.hh:251
 
constexpr index_type extent(rank_type r) const noexcept
Number of elements in the r'th dimension of the tensor.
Definition: mdspan.hh:276
 
friend constexpr void swap(mdspan &x, mdspan &y) noexcept
Overloads the std::swap algorithm for std::mdspan. Exchanges the state of x with that of y.
Definition: mdspan.hh:321
 
static constexpr bool is_always_strided()
Return true only if for every rank index r of extents there exists an integer sr such that,...
Definition: mdspan.hh:300
 
constexpr size_type size() const noexcept
The number of elements accessible by this multi-dimensional span.
Definition: mdspan.hh:279
 
constexpr bool empty() const noexcept
Checks if the size of the index space is zero.
Definition: mdspan.hh:288
 
constexpr const accessor_type & accessor() const noexcept
The accessor policy object.
Definition: mdspan.hh:257
 
constexpr bool is_exhaustive() const
Return true only if for all k in the range [0, mapping.required_span_size() ) there exists an i such ...
Definition: mdspan.hh:307
 
static constexpr rank_type rank() noexcept
Number of dimensions of the tensor.
Definition: mdspan.hh:267
 
static constexpr std::size_t static_extent(rank_type r) noexcept
Number of elements in the r'th dimension of the tensor.
Definition: mdspan.hh:273
 
constexpr const mapping_type & mapping() const noexcept
Index mapping of a layout policy.
Definition: mdspan.hh:254
 
constexpr const data_handle_type & data_handle() const noexcept
The pointer to the underlying flat sequence.
Definition: mdspan.hh:260
 
constexpr index_type stride(rank_type r) const
The stride along the specified dimension.
Definition: mdspan.hh:317
 
constexpr bool is_unique() const
Return true only if for every i and j where (i != j || ...) => mapping(i...) != mapping(j....
Definition: mdspan.hh:303
 
constexpr mdspan()
Default constructor value-initializes all members.
Definition: mdspan.hh:106
 
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
 
Namespace for features backported from new C++ standards.
Definition: algorithm.hh:19