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;