5#ifndef DUNE_COMMON_STD_SPAN_HH
6#define DUNE_COMMON_STD_SPAN_HH
16#if __has_include(<version>)
26inline constexpr std::size_t
dynamic_extent = std::numeric_limits<std::size_t>::max();
30template <std::
size_t Extent>
34 using size_type = std::size_t;
37 constexpr SpanSize () =
default;
39 constexpr SpanSize ([[maybe_unused]] size_type size)
noexcept
45 constexpr SpanSize ([[maybe_unused]] Iter first, [[maybe_unused]] Iter last)
noexcept
47 assert((std::distance(first,last) == Extent));
50 constexpr size_type size () const noexcept {
return Extent; }
57 using size_type = std::size_t;
60 constexpr SpanSize (size_type size = 0) noexcept
65 constexpr SpanSize (Iter first, Iter last) noexcept
66 : size_(std::distance(first,last))
69 constexpr size_type size () const noexcept {
return size_; }
76struct TypeIdentity {
using type = T; };
79using TypeIdentity_t =
typename TypeIdentity<T>::type;
123template <
class Element, std::
size_t Extent = Std::dynamic_extent>
125 :
public Impl::SpanSize<Extent>
127 using base_type = Impl::SpanSize<Extent>;
129 static_assert(std::is_object_v<Element> && !std::is_abstract_v<Element>);
141#if __cpp_lib_ranges_as_const >202311L
157 template <std::size_t e =
extent,
165 template <
class Iter,
166 class U = std::remove_reference_t<decltype(*std::declval<Iter>())>,
167 std::enable_if_t<std::is_convertible_v<U(*)[],
element_type(*)[]>,
int> = 0>
168 #if __cpp_conditional_explicit >= 201806L
177 template <
class Iter,
178 class U = std::remove_reference_t<decltype(*std::declval<Iter>())>,
179 std::enable_if_t<std::is_convertible_v<U(*)[],
element_type(*)[]>,
int> = 0>
180 #if __cpp_conditional_explicit >= 201806L
189 template <
class Range,
190 decltype(std::begin(std::declval<Range>()), std::end(std::declval<Range>()),
bool{}) =
true,
191 std::enable_if_t<not std::is_array_v<Range>,
int> = 0>
192 #
if __cpp_conditional_explicit >= 201806L
200 template <std::size_t N, std::size_t e =
extent,
202 constexpr span (Impl::TypeIdentity_t<element_type> (&
data)[N]) noexcept
208 template <
class T,
size_t N, std::size_t e =
extent,
210 std::enable_if_t<std::is_convertible_v<T(*)[],
element_type(*)[]>,
int> = 0>
211 constexpr span (std::array<T, N>& arr) noexcept
217 template <
class T,
size_t N, std::size_t e =
extent,
219 std::enable_if_t<std::is_convertible_v<
const T(*)[],
element_type(*)[]>,
int> = 0>
220 constexpr span (
const std::array<T, N>& arr) noexcept
227 std::enable_if_t<std::is_const_v<E>,
int> = 0>
228 #if __cpp_conditional_explicit >= 201806L
231 constexpr span (std::initializer_list<value_type> il)
232 : base_type(il.size())
237 constexpr span (
const span& other)
noexcept =
default;
240 template <
class OtherElementType, std::size_t OtherExtent,
242 std::enable_if_t<std::is_convertible_v<OtherElementType(*)[],
element_type(*)[]>,
int> = 0>
243 #if __cpp_conditional_explicit >= 201806L
247 : base_type(s.size())
264 constexpr iterator end () const noexcept {
return data_ + size(); }
293 assert(not
empty() &&
"front of empty span does not exist");
300 assert(not
empty() &&
"front of empty span does not exist");
301 return data_[size()-1];
308 throw std::out_of_range(
"Index " + std::to_string(i) +
" out of range.");
325 template <std::
size_t Count>
328 static_assert(Count <= Extent);
329 assert(Count <= size());
334 template <std::
size_t Count>
337 static_assert(Count <= Extent);
338 assert(Count <= size());
344 static constexpr std::size_t subspan_extent (std::size_t O, std::size_t C)
noexcept
357 template <std::
size_t Offset, std::
size_t Count = Std::dynamic_extent>
360 static_assert(Offset <= Extent && (Count ==
Std::dynamic_extent || Count <= Extent - Offset));
369 assert(count <= size());
376 assert(count <= size());
399 using base_type::size;
405 [[nodiscard]]
constexpr bool empty () const noexcept {
return size() == 0; }
416template <
class T, std::
size_t N>
420template <
class ElementType,
class I, std::size_t Extent,
421 std::enable_if_t<std::is_convertible_v<I,std::size_t>,
int> = 0>
422span (ElementType*, std::integral_constant<I,Extent>)
425template <
class ElementType,
class I,
426 std::enable_if_t<std::is_integral_v<I>,
int> = 0,
427 std::enable_if_t<std::is_convertible_v<I,std::size_t>,
int> = 0>
432 class Element = std::remove_reference_t<decltype(*std::declval<Iter>())>>
436template <
class Range,
437 class First =
decltype(std::begin(std::declval<Range>())),
438 class Last =
decltype(std::end(std::declval<Range>())),
439 class Element = std::remove_reference_t<
decltype(*std::declval<First>())>>
443template <
class T,
size_t N>
446template <
class T,
size_t N>
A few common exception classes.
static StaticIntegralRange< T, to, from > range(std::integral_constant< T, from >, std::integral_constant< T, to >) noexcept
Definition rangeutilities.hh:312
Namespace for features backported from new C++ standards.
Definition default_accessor.hh:10
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:26
A contiguous sequence of elements with static or dynamic extent.
Definition span.hh:126
std::ptrdiff_t difference_type
Definition span.hh:135
const element_type & const_reference
Definition span.hh:138
constexpr reference front() const
Access the first element.
Definition span.hh:291
element_type & reference
Definition span.hh:137
constexpr span(const span &other) noexcept=default
Copy constructor.
pointer iterator
Definition span.hh:139
static constexpr size_type extent
Definition span.hh:150
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition span.hh:261
constexpr const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition span.hh:267
constexpr span(std::array< T, N > &arr) noexcept
Constructs a span that is a view over the array.
Definition span.hh:211
std::reverse_iterator< iterator > reverse_iterator
Definition span.hh:140
constexpr iterator end() const noexcept
Returns an iterator to the end.
Definition span.hh:264
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:385
constexpr span & operator=(const span &other) noexcept=default
Copy assignment operator.
std::size_t size_type
Definition span.hh:134
element_type * pointer
Definition span.hh:136
constexpr reference at(size_type i) const
Access specified element with bounds checking.
Definition span.hh:305
std::remove_cv_t< element_type > value_type
Definition span.hh:133
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:367
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:358
const iterator const_iterator
Definition span.hh:145
constexpr const_reverse_iterator crend() const noexcept
Returns a reverse iterator ending at the beginning.
Definition span.hh:282
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator ending at the beginning.
Definition span.hh:276
constexpr pointer data() const noexcept
Direct access to the underlying contiguous storage.
Definition span.hh:316
constexpr size_type size_bytes() const noexcept
Returns the size of the sequence in bytes.
Definition span.hh:402
constexpr const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator starting at the end.
Definition span.hh:279
Element element_type
Definition span.hh:132
constexpr bool empty() const noexcept
Checks if the sequence is empty.
Definition span.hh:405
constexpr span< element_type, Count > last() const
Obtains a subspan consisting of the last Count elements of the sequence.
Definition span.hh:335
constexpr span(Range &range)
Constructs a span that is a view over the range [range.begin(), range.end())
Definition span.hh:195
constexpr reverse_iterator rbegin() const noexcept
Returns a reverse iterator starting at the end.
Definition span.hh:273
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:374
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition span.hh:146
constexpr span(Impl::TypeIdentity_t< element_type >(&data)[N]) noexcept
Constructs a span that is a view over the C-array.
Definition span.hh:202
constexpr const_iterator cend() const noexcept
Returns an iterator to the end.
Definition span.hh:270
constexpr span< element_type, Count > first() const
Obtains a subspan consisting of the first Count elements of the sequence.
Definition span.hh:326
constexpr reference back() const
Access the last element.
Definition span.hh:298
constexpr span(const std::array< T, N > &arr) noexcept
Constructs a span that is a view over the const array.
Definition span.hh:220
constexpr reference operator[](size_type i) const
Access specified element.
Definition span.hh:313