4#ifndef TETL_SPAN_SPAN_HPP
5#define TETL_SPAN_SPAN_HPP
7#include <etl/_config/all.hpp>
9#include <etl/_array/array.hpp>
10#include <etl/_array/c_array.hpp>
11#include <etl/_contracts/check.hpp>
12#include <etl/_cstddef/byte.hpp>
13#include <etl/_iterator/begin.hpp>
14#include <etl/_iterator/data.hpp>
15#include <etl/_iterator/end.hpp>
16#include <etl/_iterator/iter_reference_t.hpp>
17#include <etl/_iterator/next.hpp>
18#include <etl/_iterator/rbegin.hpp>
19#include <etl/_iterator/rend.hpp>
20#include <etl/_iterator/reverse_iterator.hpp>
21#include <etl/_iterator/size.hpp>
22#include <etl/_limits/numeric_limits.hpp>
23#include <etl/_ranges/borrowed_range.hpp>
24#include <etl/_ranges/enable_borrowed_range.hpp>
25#include <etl/_ranges/range_reference_t.hpp>
26#include <etl/_ranges/size.hpp>
27#include <etl/_ranges/sized_range.hpp>
28#include <etl/_span/dynamic_extent.hpp>
29#include <etl/_type_traits/conditional.hpp>
30#include <etl/_type_traits/declval.hpp>
31#include <etl/_type_traits/is_array.hpp>
32#include <etl/_type_traits/is_const.hpp>
33#include <etl/_type_traits/is_convertible.hpp>
34#include <etl/_type_traits/remove_cvref.hpp>
35#include <etl/_type_traits/remove_pointer.hpp>
36#include <etl/_type_traits/remove_reference.hpp>
37#include <etl/_type_traits/type_identity.hpp>
61inline constexpr auto is_span =
false;
63template <
typename T, size_t Size>
64inline constexpr auto is_span<etl::span<T, Size>> =
true;
66template <
typename From,
typename To>
67concept span_convertible_from = is_convertible_v<From (*)[], To (*)[]>;
69template <size_t Offset, size_t Count, size_t Extent>
70[[nodiscard]]
consteval auto subspan_extent() -> size_t
76 return Extent - Offset;
83template <
typename T, size_t Extent>
85 using element_type = T;
86 using value_type =
etl::remove_cv_t<T>;
87 using size_type =
etl::size_t;
88 using difference_type =
etl::ptrdiff_t;
90 using const_pointer = T
const*;
92 using const_reference = T
const&;
94 using reverse_iterator =
etl::reverse_iterator<iterator>;
98 static constexpr size_type
extent = Extent;
105 constexpr span()
noexcept
111 template <
typename It>
112 requires detail::span_convertible_from<remove_reference_t<iter_reference_t<It>>, T>
114 : _storage{first,
count}
121 constexpr span(c_array<type_identity_t<T>, N>& arr)
noexcept
122 : _storage{&arr[0], N}
127 template <detail::span_convertible_from<T> U, size_t N>
129 constexpr span(
array<U, N>& arr)
noexcept
130 : _storage{arr.data(), arr.size()}
135 template <detail::span_convertible_from<T> U, size_t N>
137 constexpr span(
array<U, N>
const& arr)
noexcept
138 : _storage{arr.data(), arr.size()}
143 template <
typename R>
146 and (
ranges::borrowed_range<R>
or is_const_v<T>)
147 and not is_array_v<remove_cvref_t<R>>
148 and not is_etl_array<R>
149 and not detail::is_span<R>
150 and detail::span_convertible_from<remove_reference_t<
ranges::range_reference_t<R>>, T>
152 explicit(extent != dynamic_extent)
constexpr span(R&& r)
157 template <detail::span_convertible_from<T> U, size_t N>
159 explicit(extent != dynamic_extent
and N == dynamic_extent)
constexpr span(span<U, N>
const& source)
noexcept
160 : _storage{source.data(), source.size()}
165 constexpr span(span
const& other)
noexcept =
default;
169 [[nodiscard]]
constexpr auto begin()
const noexcept -> iterator
171 return _storage.data();
177 [[nodiscard]]
constexpr auto end()
const noexcept -> iterator
185 [[nodiscard]]
constexpr auto rbegin()
const noexcept -> reverse_iterator
187 return reverse_iterator(
end());
194 [[nodiscard]]
constexpr auto rend()
const noexcept -> reverse_iterator
196 return reverse_iterator(
begin());
201 [[nodiscard]]
constexpr auto front()
const -> reference
203 TETL_PRECONDITION(
not empty());
209 [[nodiscard]]
constexpr auto back()
const -> reference
211 TETL_PRECONDITION(
not empty());
218 [[nodiscard]]
constexpr auto operator[](size_type idx)
const -> reference
220 TETL_PRECONDITION(idx < size());
225 [[nodiscard]]
constexpr auto data()
const noexcept -> pointer
227 return _storage.data();
231 [[nodiscard]]
constexpr auto size()
const noexcept -> size_type
233 return _storage.size();
237 [[nodiscard]]
constexpr auto size_bytes()
const noexcept -> size_type
239 return size() *
sizeof(element_type);
243 [[nodiscard]]
constexpr auto empty()
const noexcept ->
bool
250 template <size_t Count>
251 [[nodiscard]]
constexpr auto first()
const -> span<element_type, Count>
253 static_assert(Count <= Extent);
254 return span<element_type, Count>{
data(),
static_cast<size_type>(Count)};
261 TETL_PRECONDITION(count <= size());
262 return {
data(),
static_cast<size_type>(count)};
267 template <size_t Count>
268 [[nodiscard]]
constexpr auto last()
const -> span<element_type, Count>
270 static_assert(Count <= Extent);
271 return span<element_type, Count>{
data() + (
size() - Count),
static_cast<size_type>(Count)};
278 TETL_PRECONDITION(count <= size());
279 return {
data() + (
size() - count),
static_cast<size_type>(count)};
287 [[nodiscard]]
constexpr auto subspan()
const -> span<T, detail::subspan_extent<Offset, Count, Extent>()>
289 static_assert(Offset <= Extent);
290 static_assert(Count ==
dynamic_extent or Count <= Extent - Offset);
292 auto const ptr =
data() + Offset;
294 return span<T, detail::subspan_extent<Offset, Count, Extent>()>{ptr, sz};
304 TETL_PRECONDITION(offset <= size());
305 TETL_PRECONDITION(count != dynamic_extent ? (count <= size() - offset) :
true);
307 return {
data() + offset,
static_cast<size_type>(sz)};
311 struct static_storage {
312 constexpr static_storage() =
default;
313 constexpr static_storage(T* ptr, size_type )
noexcept
318 [[nodiscard]]
constexpr auto data()
const noexcept
322 [[nodiscard]]
constexpr auto size()
const noexcept
331 struct dynamic_storage {
332 constexpr dynamic_storage() =
default;
333 constexpr dynamic_storage(T* ptr, size_type sz)
noexcept
339 [[nodiscard]]
constexpr auto data()
const noexcept
343 [[nodiscard]]
constexpr auto size()
const noexcept
350 etl::size_t _size{0};
353 using storage = conditional_t<Extent ==
dynamic_extent, dynamic_storage, static_storage>;
358template <
typename Type, size_t Extent>
359span(c_array<Type, Extent>&) -> span<Type, Extent>;
362template <
typename Type, size_t Size>
366template <
typename Type, size_t Size>
367span(
array<Type, Size>
const&) -> span<Type
const, Size>;
371span(R&&) -> span<remove_reference_t<
ranges::range_reference_t<R>>>;
374template <
typename T, etl::size_t Extent>
375inline constexpr bool enable_borrowed_range<etl::span<T, Extent>> =
true;
379template <
typename T, etl::size_t N>
380inline constexpr etl::size_t span_as_bytes_size = N == etl::dynamic_extent ? etl::dynamic_extent :
sizeof(T) * N;
390template <
typename T, size_t N>
391[[nodiscard]]
auto as_bytes(span<T, N> s)
noexcept -> span<
byte const, detail::span_as_bytes_size<T, N>>
393 return {
reinterpret_cast<
byte const*>(s.data()), s.size_bytes()};
404template <
typename T, size_t N>
405 requires(
not is_const_v<T>)
408 return {
reinterpret_cast<
byte*>(s.data()), s.size_bytes()};
constexpr auto size
Definition size.hpp:65
constexpr auto dynamic_extent
etl::dynamic_extent is a constant of type etl::size_t that is used to differentiate etl::span of stat...
Definition dynamic_extent.hpp:15
auto as_bytes(span< T, N > s) noexcept -> span< byte const, detail::span_as_bytes_size< T, N > >
Obtains a view to the object representation of the elements of the span s.
Definition span.hpp:391
auto as_writable_bytes(span< T, N > s) noexcept -> span< byte, detail::span_as_bytes_size< T, N > >
Obtains a view to the object representation of the elements of the span s.
Definition span.hpp:406
Definition ranges_in_fun_result.hpp:12
Definition adjacent_find.hpp:9
span(array< Type, Size > const &) -> span< Type const, Size >
span(array< Type, Size > &) -> span< Type, Size >
span(c_array< Type, Extent > &) -> span< Type, Extent >
enum TETL_MAY_ALIAS byte
etl::byte is a distinct type that implements the concept of byte as specified in the C++ language def...
Definition byte.hpp:22
span(R &&) -> span< remove_reference_t< ranges::range_reference_t< R > > >
A container that encapsulates fixed size arrays.
Definition array.hpp:49
static constexpr size_type extent
The number of elements in the sequence, or etl::dynamic_extent if dynamic.
Definition span.hpp:98
constexpr auto subspan(size_type offset, size_type count=dynamic_extent) const -> span< T, dynamic_extent >
Obtains a span that is a view over the Count elements of this span starting at offset Offset....
Definition span.hpp:301
constexpr auto rbegin() const noexcept -> reverse_iterator
Returns a reverse iterator to the first element of the reversed span. It corresponds to the last elem...
Definition span.hpp:185
constexpr auto last() const -> span< element_type, Count >
Obtains a span that is a view over the last Count elements of this span. The program is ill-formed if...
Definition span.hpp:268
explicit(extent !=dynamic_extent) const expr span(It first
Constructs a span.
constexpr auto size_bytes() const noexcept -> size_type
Returns the number of elements in the span.
Definition span.hpp:237
constexpr auto rend() const noexcept -> reverse_iterator
Returns a reverse iterator to the element following the last element of the reversed span....
Definition span.hpp:194
size_type count
Definition span.hpp:114
constexpr auto subspan() const -> span< T, detail::subspan_extent< Offset, Count, Extent >()>
Obtains a span that is a view over the Count elements of this span starting at offset Offset....
Definition span.hpp:287
constexpr auto end() const noexcept -> iterator
Returns an iterator to the element following the last element of the span. This element acts as a pla...
Definition span.hpp:177
constexpr auto operator[](size_type idx) const -> reference
Returns a reference to the idx-th element of the sequence. The behavior is undefined if idx is out of...
Definition span.hpp:218
constexpr auto first() const -> span< element_type, Count >
Obtains a span that is a view over the first Count elements of this span. The program is ill-formed i...
Definition span.hpp:251
constexpr auto data() const noexcept -> pointer
Returns a pointer to the beginning of the sequence.
Definition span.hpp:225
constexpr auto begin() const noexcept -> iterator
Returns an iterator to the first element of the span. If the span is empty, the returned iterator wil...
Definition span.hpp:169
constexpr auto empty() const noexcept -> bool
Checks if the span is empty.
Definition span.hpp:243
constexpr auto last(size_type count) const -> span< element_type, dynamic_extent >
Obtains a span that is a view over the last Count elements of this span. The behavior is undefined if...
Definition span.hpp:276
constexpr auto back() const -> reference
Returns a reference to the last element in the span. Calling front on an empty span results in undefi...
Definition span.hpp:209
constexpr auto first(size_type count) const -> span< element_type, dynamic_extent >
Obtains a span that is a view over the first Count elements of this span. The behavior is undefined i...
Definition span.hpp:259
constexpr auto front() const -> reference
Returns a reference to the first element in the span. Calling front on an empty span results in undef...
Definition span.hpp:201
constexpr auto size() const noexcept -> size_type
Returns the number of elements in the span.
Definition span.hpp:231