8#if __has_include
(<span>)
12#if __cpp_lib_span >= 202002L
13#include <boost/version.hpp>
18#include <userver/utils/assert.hpp>
21USERVER_NAMESPACE_BEGIN
25#if __cpp_lib_span >= 202002L
|| defined(DOXYGEN)
34using std::as_writable_bytes;
44 constexpr span()
noexcept : span(
nullptr,
nullptr) {}
46 constexpr span(T* begin, T* end)
noexcept : begin_(begin), end_(end) {
47 UASSERT((begin !=
nullptr && end !=
nullptr && begin <= end) ||
48 (begin ==
nullptr && end ==
nullptr));
53 typename = std::enable_if_t<
56 (std::is_lvalue_reference_v<Container> || std::is_const_v<T>)&&
58 !std::is_same_v<std::remove_cv_t<std::remove_reference_t<Container>>,
61 constexpr span(Container&& cont)
noexcept
62 : span(std::data(cont), std::data(cont) + std::size(cont)) {}
64 constexpr T* begin()
const noexcept {
return begin_; }
65 constexpr T* end()
const noexcept {
return end_; }
67 constexpr T* data()
const noexcept {
return begin_; }
68 constexpr std::size_t size()
const noexcept {
return end_ - begin_; }
69 constexpr bool empty()
const noexcept {
return size() == 0; }
71 constexpr span<T> first(std::size_t count)
const noexcept {
73 return span{begin_, begin_ + count};
76 constexpr span<T> last(std::size_t count)
const noexcept {
78 return span{end_ - count, end_};
81 constexpr span<T> subspan(std::size_t offset)
const noexcept {
83 return span{begin_ + offset, end_};
86 constexpr span<T> subspan(std::size_t offset, std::size_t count)
const
88 UASSERT(offset + count <= size());
89 return span{begin_ + offset, begin_ + offset + count};
92 constexpr T& operator[](std::size_t index)
const noexcept {
102template <
typename Container>
103span(Container&& cont)
104 -> span<std::remove_reference_t<
decltype(*std::begin(cont))>>;
108span<
const std::byte> as_bytes(span<T> s)
noexcept {
109 const auto*
const data =
reinterpret_cast<
const std::byte*>(s.data());
110 return {data, data + s.size() *
sizeof(T)};
115span<std::byte> as_writable_bytes(span<T> s)
noexcept {
116 static_assert(!std::is_const_v<T>);
117 auto*
const data =
reinterpret_cast<std::byte*>(s.data());
118 return {data, data + s.size() *
sizeof(T)};
133template <
typename T,
typename Enabler>
134struct range_const_iterator;
136#if __cpp_lib_span >= 202002L
138template <
typename T, std::size_t Extent>
139struct range_const_iterator<std::span<T, Extent>,
void> {
140 using type =
typename std::span<T, Extent>::iterator;
146struct range_const_iterator<USERVER_NAMESPACE::utils::span<T>,
void> {
147 using type =
typename USERVER_NAMESPACE::utils::span<T>::iterator;
157#if __cpp_lib_span >= 202002L
&& BOOST_VERSION < 107700
159namespace boost::container {
161template <
class Pointer,
bool IsConst>
166template <
class Pointer,
bool IsConst>
168struct std::iterator_traits<boost::container::vec_iterator<Pointer, IsConst>> {
169 using iterator_concept = std::contiguous_iterator_tag;
170 using iterator_category = std::random_access_iterator_tag;
172 typename boost::container::vec_iterator<Pointer, IsConst>::value_type;
173 using difference_type =
174 typename boost::container::vec_iterator<Pointer,
175 IsConst>::difference_type;
177 typename boost::container::vec_iterator<Pointer, IsConst>::pointer;
179 typename boost::container::vec_iterator<Pointer, IsConst>::reference;