10#include <userver/utils/assert.hpp>
12USERVER_NAMESPACE_BEGIN
19struct TypeIdentityImpl final {
24using TypeIdentity =
typename TypeIdentityImpl<T>::type;
34 constexpr span()
noexcept : span(
nullptr,
nullptr) {}
36 constexpr span(T* begin, T* end)
noexcept : begin_(begin), end_(end) {
37 UASSERT((begin !=
nullptr && end !=
nullptr && begin <= end) || (begin ==
nullptr && end ==
nullptr));
40 constexpr span(T* begin, std::size_t size)
noexcept : begin_(begin), end_(begin + size) {
41 UASSERT(begin !=
nullptr || size == 0);
46 typename = std::enable_if_t<
48 (std::is_lvalue_reference_v<Container> || std::is_const_v<T>)&&
50 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<Container>>, span> &&
52 std::is_convertible_v<
decltype(std::data(std::declval<Container&>())), T*>>>
54 constexpr span(Container&& cont)
noexcept : span(std::data(cont), std::size(cont)) {}
56 template <std::size_t Size>
57 constexpr span(impl::TypeIdentity<T> (&array)[Size])
noexcept
58 : span(std::data(array), std::size(array)) {}
60 constexpr T* begin()
const noexcept {
return begin_; }
61 constexpr T* end()
const noexcept {
return end_; }
63 constexpr T* data()
const noexcept {
return begin_; }
64 constexpr std::size_t size()
const noexcept {
return end_ - begin_; }
65 constexpr bool empty()
const noexcept {
return size() == 0; }
67 constexpr span<T> first(std::size_t count)
const noexcept {
69 return span{begin_, begin_ + count};
72 constexpr span<T> last(std::size_t count)
const noexcept {
74 return span{end_ - count, end_};
77 constexpr span<T> subspan(std::size_t offset)
const noexcept {
79 return span{begin_ + offset, end_};
82 constexpr span<T> subspan(
86 UASSERT(offset + count <= size());
87 return span{begin_ + offset, begin_ + offset + count};
90 constexpr T& operator[](std::size_t index)
const noexcept {
100template <
typename Container>
101span(Container&& cont) -> span<std::remove_reference_t<
decltype(*std::begin(cont))>>;
105span<
const std::byte>
as_bytes(span<T> s)
noexcept {
106 const auto*
const data =
reinterpret_cast<
const std::byte*>(s.data());
107 return {data, data + s.size() *
sizeof(T)};
113 static_assert(!std::is_const_v<T>);
114 auto*
const data =
reinterpret_cast<std::byte*>(s.data());
115 return {data, data + s.size() *
sizeof(T)};
128template <
typename T,
typename Enabler>
129struct range_const_iterator;
132struct range_const_iterator<USERVER_NAMESPACE::
utils::span<T>,
void> {
133 using type =
typename USERVER_NAMESPACE::
utils::span<T>::iterator;