5 #ifndef DUNE_COMMON_STD_SPAN_HH 6 #define DUNE_COMMON_STD_SPAN_HH 13 #if __has_include(<span>) 18 #include <type_traits> 19 #if __has_include(<version>) 31 #if __cpp_lib_span >= 202002L 39 template <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_; }
85 struct TypeIdentity {
using type = T; };
88 using TypeIdentity_t =
typename TypeIdentity<T>::type;
132 template <
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,
167 std::enable_if_t<(e == dynamic_extent || e == 0), int> = 0>
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,
210 std::enable_if_t<(e == Std::dynamic_extent || e == N), int> = 0>
211 constexpr
span (Impl::TypeIdentity_t<element_type> (&
data)[N]) noexcept
217 template <
class T,
size_t N, std::size_t e =
extent,
218 std::enable_if_t<(e == Std::dynamic_extent || e == N), int> = 0,
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,
227 std::enable_if_t<(e == Std::dynamic_extent || e == N), int> = 0,
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,
250 std::enable_if_t<(extent == Std::dynamic_extent || OtherExtent == Std::dynamic_extent || extent == OtherExtent), int> = 0,
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; }
425 template <
class T, std::
size_t N>
429 template <
class ElementType,
class I, std::size_t Extent,
430 std::enable_if_t<std::is_convertible_v<I,std::size_t>,
int> = 0>
431 span (ElementType*, std::integral_constant<I,Extent>)
432 -> span<ElementType, Extent>;
434 template <
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>
437 span (ElementType*, I)
438 -> span<ElementType, Std::dynamic_extent>;
440 template <
class Iter,
441 class Element = std::remove_reference_t<decltype(*std::declval<Iter>())>>
443 -> span<Element, Std::dynamic_extent>;
445 template <
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>;
452 template <
class T,
size_t N>
453 span (std::array<T, N>&) -> span<T, N>;
455 template <
class T,
size_t N>
456 span (
const std::array<T, N>&) -> span<const T, N>;
460 #endif // __cpp_lib_span 464 #endif // DUNE_COMMON_STD_SPAN_HH constexpr const_reverse_iterator crbegin() const noexcept
Returns a reverse iterator starting at the end.
Definition: span.hh:288
constexpr span< element_type, Count > first() const
Obtains a subspan consisting of the first Count elements of the sequence.
Definition: span.hh:335
constexpr span() noexcept
Default construct an empty span.
Definition: span.hh:168
Namespace for features backported from new C++ standards.
Definition: algorithm.hh:19
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
pointer iterator
Definition: span.hh:148
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 reverse_iterator rbegin() const noexcept
Returns a reverse iterator starting at the end.
Definition: span.hh:282
constexpr size_type size_bytes() const noexcept
Returns the size of the sequence in bytes.
Definition: span.hh:411
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.hh:155
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
constexpr reference front() const
Access the first element.
Definition: span.hh:300
constexpr span(std::array< T, N > &arr) noexcept
Constructs a span that is a view over the array.
Definition: span.hh:220
constexpr reverse_iterator rend() const noexcept
Returns a reverse iterator ending at the beginning.
Definition: span.hh:285
constexpr const_reverse_iterator crend() const noexcept
Returns a reverse iterator ending at the beginning.
Definition: span.hh:291
span(const std::array< T, N > &) -> span< const T, N >
I i
Definition: hybridmultiindex.hh:328
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
element_type & reference
Definition: span.hh:146
constexpr span(const std::array< T, N > &arr) noexcept
Constructs a span that is a view over the const array.
Definition: span.hh:229
A contiguous sequence of elements with static or dynamic extent.
Definition: span.hh:133
constexpr pointer data() const noexcept
Direct access to the underlying contiguous storage.
Definition: span.hh:325
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 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
const iterator const_iterator
Definition: span.hh:154
constexpr span & operator=(const span &other) noexcept=default
Copy assignment operator.
constexpr reference back() const
Access the last element.
Definition: span.hh:307
std::reverse_iterator< iterator > reverse_iterator
Definition: span.hh:149
element_type * pointer
Definition: span.hh:145
std::size_t size_type
Definition: span.hh:143
std::remove_cv_t< element_type > value_type
Definition: span.hh:142
Element element_type
Definition: span.hh:141
constexpr bool empty() const noexcept
Checks if the sequence is empty.
Definition: span.hh:414
constexpr reference at(size_type i) const
Access specified element with bounds checking.
Definition: span.hh:314
A few common exception classes.
constexpr span< element_type, Count > last() const
Obtains a subspan consisting of the last Count elements of the sequence.
Definition: span.hh:344
constexpr reference operator[](size_type i) const
Access specified element.
Definition: span.hh:322
constexpr span(Range &range)
Constructs a span that is a view over the range [range.begin(), range.end())
Definition: span.hh:204
std::ptrdiff_t difference_type
Definition: span.hh:144
constexpr const_iterator cbegin() const noexcept
Returns an iterator to the beginning.
Definition: span.hh:276
static constexpr size_type extent
Definition: span.hh:159
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
span(T(&)[N]) -> span< T, N >
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 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 iterator end() const noexcept
Returns an iterator to the end.
Definition: span.hh:273
const element_type & const_reference
Definition: span.hh:147
constexpr iterator begin() const noexcept
Returns an iterator to the beginning.
Definition: span.hh:270