5#ifndef DUNE_COMMON_STD_SPAN_HH
6#define DUNE_COMMON_STD_SPAN_HH
13#if __has_include(<span>)
19#if __has_include(<version>)
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>);
150#if __cpp_lib_ranges_as_const >202311L
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
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())
273 constexpr iterator end () const noexcept {
return data_ + size(); }
302 assert(not
empty() &&
"front of empty span does not exist");
309 assert(not
empty() &&
"front of empty span does not exist");
310 return data_[size()-1];
317 throw std::out_of_range(
"Index " + std::to_string(i) +
" out of range.");
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>
369 static_assert(Offset <= Extent && (Count ==
Std::dynamic_extent || Count <= Extent - Offset));
378 assert(count <= size());
385 assert(count <= size());
408 using base_type::size;
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>)
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>
441 class Element = std::remove_reference_t<decltype(*std::declval<Iter>())>>
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>())>>
452template <
class T,
size_t N>
455template <
class T,
size_t N>
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
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
Namespace for features backported from new C++ standards.
Definition algorithm.hh:19
span(T(&)[N]) -> span< T, N >
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
A contiguous sequence of elements with static or dynamic extent.
Definition span.hh:135
std::ptrdiff_t difference_type
Definition span.hh:144
const element_type & const_reference
Definition span.hh:147
constexpr reference front() const
Access the first element.
Definition span.hh:300
element_type & reference
Definition span.hh:146
constexpr span(const span &other) noexcept=default
Copy constructor.
pointer iterator
Definition span.hh:148
static constexpr size_type extent
Definition span.hh:159
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
std::reverse_iterator< iterator > reverse_iterator
Definition span.hh:149
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() noexcept
Default construct an empty span.
Definition span.hh:168
constexpr span & operator=(const span &other) noexcept=default
Copy assignment operator.
std::size_t size_type
Definition span.hh:143
element_type * pointer
Definition span.hh:145
constexpr reference at(size_type i) const
Access specified element with bounds checking.
Definition span.hh:314
std::remove_cv_t< element_type > value_type
Definition span.hh:142
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
const iterator const_iterator
Definition span.hh:154
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
Element element_type
Definition span.hh:141
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
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition span.hh:155
constexpr span(Impl::TypeIdentity_t< element_type >(&data)[N]) noexcept
Constructs a span that is a view over the C-array.
Definition span.hh:211
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