5#ifndef DUNE_COMMON_STD_SPAN_HH 
    6#define DUNE_COMMON_STD_SPAN_HH 
   13#if __has_include(<span>) 
   19#if __has_include(<version>) 
   24#include <dune/common/std/memory.hh> 
   31#if __cpp_lib_span >= 202002L 
   39template <std::
size_t Extent>
 
   43  using size_type = std::size_t;
 
   46  constexpr SpanSize () = 
default;
 
   48  constexpr SpanSize ([[maybe_unused]] size_type 
size) 
noexcept 
   54  constexpr SpanSize ([[maybe_unused]] Iter first, [[maybe_unused]] Iter last) 
noexcept 
   56    assert((std::distance(first,last) == Extent));
 
   59  constexpr size_type 
size () 
const noexcept { 
return Extent; }
 
   66  using size_type = std::size_t;
 
   69  constexpr SpanSize (size_type 
size = 0) noexcept
 
   74  constexpr SpanSize (Iter first, Iter last) noexcept
 
   75    : size_(std::distance(first,last))
 
   78  constexpr size_type 
size () 
const noexcept { 
return size_; }
 
   85struct TypeIdentity { 
using type = T; };
 
   88using TypeIdentity_t = 
typename TypeIdentity<T>::type;
 
  132template <
class Element, std::
size_t Extent = Std::dynamic_extent>
 
  134    : 
public Impl::SpanSize<Extent>
 
  136  using base_type = Impl::SpanSize<Extent>; 
 
  138  static_assert(std::is_object_v<Element> && !std::is_abstract_v<Element>);
 
  141  using element_type = Element;
 
  142  using value_type = std::remove_cv_t<element_type>;
 
  143  using size_type = std::size_t;
 
  144  using difference_type = std::ptrdiff_t;
 
  145  using pointer = element_type*;
 
  146  using reference = element_type&;
 
  147  using const_reference  = 
const element_type&;
 
  148  using iterator = pointer;
 
  149  using reverse_iterator = std::reverse_iterator<iterator>;
 
  150#if __cpp_lib_ranges_as_const >202311L 
  151  using const_iterator = std::const_iterator<iterator>;
 
  152  using const_reverse_iterator = std::const_iterator<reverse_iterator>;
 
  154  using const_iterator = 
const iterator;
 
  155  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 
  159  static constexpr size_type extent = Extent;
 
  166  template <std::size_t e = extent,
 
  174  template <
class Iter,
 
  175    class U = std::remove_reference_t<decltype(*std::declval<Iter>())>,
 
  176    std::enable_if_t<std::is_convertible_v<U(*)[], element_type(*)[]>, 
int> = 0>
 
  177  #if __cpp_conditional_explicit >= 201806L 
  186  template <
class Iter,
 
  187    class U = std::remove_reference_t<decltype(*std::declval<Iter>())>,
 
  188    std::enable_if_t<std::is_convertible_v<U(*)[], element_type(*)[]>, 
int> = 0>
 
  189  #if __cpp_conditional_explicit >= 201806L 
  198  template <
class Range,
 
  199    decltype(std::begin(std::declval<Range>()), std::end(std::declval<Range>()), 
bool{}) = 
true,
 
  200    std::enable_if_t<not std::is_array_v<Range>, 
int> = 0>
 
  201  #
if __cpp_conditional_explicit >= 201806L
 
  209  template <std::size_t N, std::size_t e = extent,
 
  211  constexpr span (Impl::TypeIdentity_t<element_type> (&
data)[N]) 
noexcept 
  217  template <
class T, 
size_t N, std::size_t e = extent,
 
  219    std::enable_if_t<std::is_convertible_v<T(*)[], element_type(*)[]>, 
int> = 0>
 
  220  constexpr span (std::array<T, N>& arr) noexcept
 
  226  template <
class T, 
size_t N, std::size_t e = extent,
 
  228    std::enable_if_t<std::is_convertible_v<
const T(*)[], element_type(*)[]>, 
int> = 0>
 
  229  constexpr span (
const std::array<T, N>& arr) noexcept
 
  235  template <
class E = element_type,
 
  236    std::enable_if_t<std::is_const_v<E>, 
int> = 0>
 
  237  #if __cpp_conditional_explicit >= 201806L 
  240  constexpr span (std::initializer_list<value_type> il)
 
  241    : base_type(il.size())
 
  246  constexpr span (
const span& other) 
noexcept = 
default;
 
  249  template <
class OtherElementType, std::size_t OtherExtent,
 
  251    std::enable_if_t<std::is_convertible_v<OtherElementType(*)[], element_type(*)[]>, 
int> = 0>
 
  252  #if __cpp_conditional_explicit >= 201806L 
  256    : base_type(s.size())
 
  270  constexpr iterator 
begin () const noexcept { 
return data_; }
 
  273  constexpr iterator 
end () const noexcept { 
return data_ + size(); }
 
  276  constexpr const_iterator 
cbegin () const noexcept { 
return data_; }
 
  279  constexpr const_iterator 
cend () const noexcept { 
return data_ + size(); }
 
  282  constexpr reverse_iterator 
rbegin() const noexcept { 
return reverse_iterator{
end()}; }
 
  285  constexpr reverse_iterator 
rend() const noexcept { 
return reverse_iterator{
begin()}; }
 
  288  constexpr const_reverse_iterator  
crbegin() const noexcept { 
return reverse_iterator{
end()}; }
 
  291  constexpr const_reverse_iterator  
crend() const noexcept { 
return reverse_iterator{
begin()}; }
 
  302    assert(not 
empty() && 
"front of empty span does not exist");
 
  307  constexpr reference 
back ()
 const 
  309    assert(not 
empty() && 
"front of empty span does not exist");
 
  310    return data_[size()-1];
 
  314  constexpr reference 
at (size_type i)
 const 
  317      throw std::out_of_range(
"Index " + std::to_string(i) + 
" out of range.");
 
  322  constexpr reference 
operator[] (size_type i)
 const { 
return data_[i]; }
 
  325  constexpr pointer 
data () const noexcept { 
return data_; }
 
  334  template <std::
size_t Count>
 
  337    static_assert(Count <= Extent);
 
  338    assert(Count <= size());
 
  343  template <std::
size_t Count>
 
  346    static_assert(Count <= Extent);
 
  347    assert(Count <= size());
 
  353  static constexpr std::size_t subspan_extent (std::size_t O, std::size_t C) 
noexcept 
  366  template <std::
size_t Offset, std::
size_t Count = Std::dynamic_extent>
 
  367  constexpr span<element_type, subspan_extent(Offset,Count)> 
subspan ()
 const 
  369    static_assert(Offset <= Extent && (Count == 
Std::dynamic_extent || Count <= Extent - Offset));
 
  371    return span<element_type, subspan_extent(Offset,Count)>{
 
  378    assert(count <= size());
 
  385    assert(count <= size());
 
  408  using base_type::size;
 
  411  constexpr size_type 
size_bytes () const noexcept { 
return size() * 
sizeof(element_type); }
 
  414  [[nodiscard]] 
constexpr bool empty () const noexcept { 
return size() == 0; }
 
  425template <
class T, std::
size_t N>
 
  429template <
class ElementType, 
class I, std::size_t Extent,
 
  430  std::enable_if_t<std::is_convertible_v<I,std::size_t>, 
int> = 0>
 
  431span (ElementType*, std::integral_constant<I,Extent>)
 
  432  -> span<ElementType, Extent>;
 
  434template <
class ElementType, 
class I,
 
  435  std::enable_if_t<std::is_integral_v<I>, 
int> = 0,
 
  436  std::enable_if_t<std::is_convertible_v<I,std::size_t>, 
int> = 0>
 
  437span (ElementType*, I)
 
  438  -> span<ElementType, Std::dynamic_extent>;
 
  441  class Element = std::remove_reference_t<decltype(*std::declval<Iter>())>>
 
  443  -> span<Element, Std::dynamic_extent>;
 
  445template <
class Range,
 
  446  class First = 
decltype(std::begin(std::declval<Range>())),
 
  447  class Last = 
decltype(std::end(std::declval<Range>())),
 
  448  class Element = std::remove_reference_t<
decltype(*std::declval<First>())>>
 
  450  -> span<Element, Std::dynamic_extent>;
 
  452template <
class T, 
size_t N>
 
  453span (std::array<T, N>&) -> span<T, N>;
 
  455template <
class T, 
size_t N>
 
  456span (
const std::array<T, N>&) -> span<const T, N>;
 
A contiguous sequence of elements with static or dynamic extent.
Definition: span.hh:135
 
constexpr reference front() const
Access the first element.
Definition: span.hh:300
 
constexpr span(const span &other) noexcept=default
Copy constructor.
 
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition: span.hh:270
 
constexpr const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition: span.hh:276
 
constexpr span(std::array< T, N > &arr) noexcept
Constructs a span that is a view over the array.
Definition: span.hh:220
 
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition: span.hh:273
 
constexpr span< element_type, Std::dynamic_extent > subspan(size_type offset, size_type count=Std::dynamic_extent) const
Obtains a subspan consisting of count elements of the sequence starting at offset.
Definition: span.hh:394
 
constexpr span & operator=(const span &other) noexcept=default
Copy assignment operator.
 
constexpr reference at(size_type i) const
Access specified element with bounds checking.
Definition: span.hh:314
 
constexpr span< element_type, Std::dynamic_extent > first(size_type count) const
Obtains a subspan consisting of the first count elements of the sequence.
Definition: span.hh:376
 
constexpr span< element_type, subspan_extent(Offset, Count)> subspan() const
Obtains a subspan consisting of Count elements of the sequence starting at Offset.
Definition: span.hh:367
 
constexpr const_reverse_iterator crend() const noexcept
Returns a reverse iterator ending at the beginning.
Definition: span.hh:291
 
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator ending at the beginning.
Definition: span.hh:285
 
constexpr pointer data() const noexcept
Direct access to the underlying contiguous storage.
Definition: span.hh:325
 
constexpr size_type size_bytes() const noexcept
Returns the size of the sequence in bytes.
Definition: span.hh:411
 
constexpr const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator starting at the end.
Definition: span.hh:288
 
constexpr bool empty() const noexcept
Checks if the sequence is empty.
Definition: span.hh:414
 
constexpr span< element_type, Count > last() const
Obtains a subspan consisting of the last Count elements of the sequence.
Definition: span.hh:344
 
constexpr span(Range &range)
Constructs a span that is a view over the range [range.begin(), range.end())
Definition: span.hh:204
 
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator starting at the end.
Definition: span.hh:282
 
constexpr span< element_type, Std::dynamic_extent > last(size_type count) const
Obtains a subspan consisting of the last count elements of the sequence.
Definition: span.hh:383
 
constexpr const_iterator cend() const noexcept
Returns an iterator to the end.
Definition: span.hh:279
 
constexpr span< element_type, Count > first() const
Obtains a subspan consisting of the first Count elements of the sequence.
Definition: span.hh:335
 
constexpr reference back() const
Access the last element.
Definition: span.hh:307
 
constexpr span(const std::array< T, N > &arr) noexcept
Constructs a span that is a view over the const array.
Definition: span.hh:229
 
constexpr reference operator[](size_type i) const
Access specified element.
Definition: span.hh:322
 
A few common exception classes.
 
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
free standing function for setting up a range based for loop over an integer range for (auto i: range...
Definition: rangeutilities.hh:288
 
Namespace for features backported from new C++ standards.
Definition: algorithm.hh:19
 
constexpr auto to_address(T &&p) noexcept
Obtain the address represented by p without forming a reference to the object pointed to by p.
Definition: memory.hh:47
 
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
 
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75