28 #include <type_traits>
33 template<
typename ElementType,
size_t Extent = dynamic_extent>
39 template<
typename E,
size_t S>
46 static constexpr
size_t size =
S;
63 template<
typename T,
size_t S>
70 template<
typename T,
size_t N>
74 template<
typename,
typename =
void>
79 std::void_t<decltype(std::size(std::declval<T>())),
80 decltype(std::data(std::declval<T>()))>>
84 template<
typename C,
typename U = std::remove_cvref_t<C>>
89 !std::is_array_v<U> &&
94 template<
typename,
typename,
typename =
void>
97 template<
typename T,
typename E>
99 : std::is_convertible<std::remove_pointer_t<decltype(std::data(std::declval<T>()))> (*)[], E (*)[]>
103 template<
typename,
typename =
size_t>
114 template<
typename ElementType,
size_t Extent>
116 : std::integral_constant<size_t, sizeof(ElementType) * Extent> {};
117 template<
typename ElementType>
119 : std::integral_constant<size_t, dynamic_extent> {};
124 template<
typename ElementType,
size_t Extent>
128 "A span must have an extent greater than or equal to zero, "
129 "or a dynamic extent");
130 static_assert(std::is_object_v<ElementType>,
131 "A span's ElementType must be an object type (not a "
132 "reference type or void)");
134 "A span's ElementType must be a complete type (not a forward "
136 static_assert(!std::is_abstract_v<ElementType>,
137 "A span's ElementType cannot be an abstract class type");
157 template<
size_t E = Extent, std::enable_if_t<(E == 0) || (E == dynamic_extent),
int> = 0>
163 : storage(ptr,
count)
169 : storage(first_elem, last_elem - first_elem)
192 constexpr
span(std::array<value_type, N>& arr) noexcept
193 : storage(arr.data(),
N)
203 constexpr
span(
const std::array<value_type, N>& arr) noexcept
204 : storage(arr.data(),
N)
208 template<
typename Container,
209 std::enable_if_t<detail::is_container<Container>::value &&
212 constexpr
span(Container& cont)
213 : storage(std::
data(cont), std::
size(cont))
218 template<
typename Container,
219 std::enable_if_t<detail::is_container<Container>::value &&
222 constexpr
span(
const Container& cont)
223 : storage(std::
data(cont), std::
size(cont))
228 constexpr
span(
const span& other) noexcept =
default;
230 template<
typename OtherElementType,
232 std::enable_if_t<(Extent == OtherExtent || Extent ==
dynamic_extent) &&
233 std::is_convertible_v<OtherElementType (*)[], ElementType (*)[]>,
236 : storage(other.data(), other.size())
242 constexpr
span& operator=(const
span& other) noexcept = default;
245 template<
size_t Count>
248 assert(Count <=
size());
249 return {
data(), Count};
252 template<
size_t Count>
255 assert(Count <=
size());
256 return {
data() + (
size() - Count), Count};
259 template<ptrdiff_t Offset,
size_t Count = dynamic_extent>
265 template<ptrdiff_t Offset,
size_t Count = dynamic_extent>
268 assert((Offset >= 0 && Offset <=
size()) &&
270 return {
data() + Offset,
290 assert((offset <=
size()) &&
300 [[nodiscard]] constexpr
bool empty() const noexcept {
return size() == 0; }
305 assert(idx <
size());
306 return *(
data() + idx);
337 storage_type storage;
340 template<
typename ElementType,
size_t Extent>
344 return {
reinterpret_cast<const uint8_t*
>(s.data()), s.size_bytes()};
347 template<
typename ElementType,
349 std::enable_if_t<!std::is_const_v<ElementType>,
int> = 0>
353 return {
reinterpret_cast<uint8_t*
>(s.data()), s.size_bytes()};
constexpr span< element_type, Count > first() const
constexpr span< element_type, dynamic_extent > first(index_type count) const
std::remove_cv_t< ElementType > value_type
std::reverse_iterator< const_iterator > const_reverse_iterator
constexpr span(const span &other) noexcept=default
constexpr span() noexcept
constexpr reference operator[](index_type idx) const
constexpr span< element_type, Count > last() const
ptrdiff_t difference_type
constexpr span(pointer first_elem, pointer last_elem)
const ElementType * const_iterator
constexpr pointer data() const noexcept
constexpr subspan_return_t< Offset, Count > subspan() const
constexpr index_type size_bytes() const noexcept
constexpr span(const std::array< value_type, N > &arr) noexcept
constexpr span(Container &cont)
constexpr const_iterator cbegin() const noexcept
constexpr span< element_type, dynamic_extent > last(index_type count) const
constexpr span(element_type(&arr)[N]) noexcept
std::reverse_iterator< iterator > reverse_iterator
constexpr iterator begin() const noexcept
constexpr auto rbegin() const noexcept
constexpr reference back() const
constexpr reference front() const
constexpr index_type size() const noexcept
constexpr auto crbegin() const noexcept
constexpr auto crend() const noexcept
constexpr const_iterator cend() const noexcept
static constexpr index_type extent
constexpr auto rend() const noexcept
constexpr span(pointer ptr, index_type count)
constexpr iterator end() const noexcept
constexpr span(std::array< value_type, N > &arr) noexcept
constexpr span(const Container &cont)
constexpr span(const span< OtherElementType, OtherExtent > &other) noexcept
constexpr span< element_type, dynamic_extent > subspan(index_type offset, index_type count=dynamic_extent) const
constexpr bool empty() const noexcept
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
size_t size(std::string_view utf8)
span< const uint8_t, detail::calculate_byte_size< ElementType, Extent >::value > as_bytes(span< ElementType, Extent > s) noexcept
span< uint8_t, detail::calculate_byte_size< ElementType, Extent >::value > as_writable_bytes(span< ElementType, Extent > s) noexcept
constexpr size_t dynamic_extent
static constexpr bool value
constexpr span_storage() noexcept=default
static constexpr size_t size
constexpr span_storage() noexcept=default