8#include <userver/utils/small_string_fwd.hpp> 
    9#include <userver/utils/trivial_map.hpp> 
   11USERVER_NAMESPACE_BEGIN
 
   17inline constexpr std::size_t kTypicalHeadersSize = 1024;
 
   18using HeadersString = utils::
SmallString<kTypicalHeadersSize>;
 
   27struct UnsafeConstexprHasher 
final {
 
   28  constexpr std::size_t operator()(std::string_view str) 
const noexcept {
 
   29    constexpr std::uint64_t mul = (0xc6a4a793UL << 32UL) + 0x5bd1e995UL;
 
   31    std::uint64_t hash = seed_ ^ (str.size() * mul);
 
   32    while (str.size() >= 8) {
 
   33      const std::uint64_t data = ShiftMix(Load8(str.data()) * mul) * mul;
 
   40      const std::uint64_t data = LoadN(str.data(), str.size());
 
   45    hash = ShiftMix(hash) * mul;
 
   46    hash = ShiftMix(hash);
 
   51  static constexpr inline std::uint64_t ShiftMix(std::uint64_t v) 
noexcept {
 
   55  static constexpr inline std::uint64_t Load8(
const char* data) 
noexcept {
 
   56    return LoadN(data, 8);
 
   59  static constexpr inline std::uint64_t LoadN(
const char* data,
 
   60                                              std::size_t n) 
noexcept {
 
   67    constexpr std::uint64_t kDeliberatelyBrokenLowercaseMask =
 
   70    std::uint64_t result = kDeliberatelyBrokenLowercaseMask >> (8 * (8 - n));
 
   71    for (std::size_t i = 0; i < n; ++i) {
 
   72      const std::uint8_t c = data[i];
 
   73      result |= 
static_cast<std::uint64_t>(c) << (8 * i);
 
   85  std::uint64_t seed_{54999};
 
   89inline constexpr utils::TrivialBiMap kKnownHeadersLowercaseMap =
 
   92          .Case(
"content-type", std::int8_t{1})
 
   93          .Case(
"content-encoding", 2)
 
   94          .Case(
"content-length", 3)
 
   95          .Case(
"transfer-encoding", 4)
 
   98          .Case(
"accept-encoding", 7)
 
   99          .Case(
"accept-language", 8)
 
  100          .Case(
"x-yataxi-api-key", 9)
 
  101          .Case(
"user-agent", 10)
 
  102          .Case(
"x-request-application", 11)
 
  105          .Case(
"access-control-allow-headers", 14)
 
  108          .Case(
"set-cookie", 17)
 
  109          .Case(
"connection", 18)
 
  111          .Case(
"x-yarequestid", 20)
 
  112          .Case(
"x-yatraceid", 21)
 
  113          .Case(
"x-yaspanid", 22)
 
  114          .Case(
"x-requestid", 23)
 
  115          .Case(
"x-backend-server", 24)
 
  116          .Case(
"x-taxi-envoyproxy-dstvhost", 25)
 
  118          .Case(
"x-yataxi-allow-auth-request", 27)
 
  119          .Case(
"x-yataxi-allow-auth-response", 28)
 
  120          .Case(
"x-yataxi-server-hostname", 29)
 
  121          .Case(
"x-yataxi-client-timeoutms", 30)
 
  122          .Case(
"x-yataxi-deadline-expired", 31)
 
  123          .Case(
"x-yataxi-ratelimited-by", 32)
 
  124          .Case(
"x-yataxi-ratelimit-reason", 33)
 
  125          .Case(
"x-b3-traceid", 34)
 
  126          .Case(
"x-b3-spanid", 35)
 
  127          .Case(
"x-b3-sampled", 36)
 
  128          .Case(
"x-b3-parentspanid", 37)
 
  129          .Case(
"traceparent", 38)
 
  130          .Case(
"tracestate", 39);
 
  135inline constexpr std::int8_t kNoHeaderIndexLookup = -1;
 
  136inline constexpr std::int8_t kNoHeaderIndexInsertion = -2;
 
  137static_assert(kNoHeaderIndexLookup != kNoHeaderIndexInsertion);
 
  138static_assert(kNoHeaderIndexLookup != 0 && kNoHeaderIndexInsertion != 0);
 
  141constexpr std::int8_t GetHeaderIndexForLookup(std::string_view key) {
 
  142  const auto opt = kKnownHeadersLowercaseMap.TryFindICaseByFirst(key);
 
  143  return opt.value_or(kNoHeaderIndexLookup);
 
  149inline std::int8_t GetHeaderIndexForInsertion(std::string_view key) {
 
  150  const auto opt = kKnownHeadersLowercaseMap.TryFindICaseByFirst(key);
 
  151  return opt.value_or(kNoHeaderIndexInsertion);
 
  156namespace header_map {
 
  171class PredefinedHeader 
final {
 
  173  explicit constexpr PredefinedHeader(std::string_view name)
 
  175        hash{impl::UnsafeConstexprHasher{}(name)},
 
  176        header_index{impl::GetHeaderIndexForLookup(name)} {}
 
  178  constexpr operator std::string_view() 
const { 
return name; }
 
  180  explicit operator std::string() 
const { 
return std::string{name}; }
 
  183  friend class header_map::Danger;
 
  184  friend class header_map::Map;
 
  187  const std::string_view name;
 
  190  const std::size_t hash;
 
  198  const std::int8_t header_index;
 
  206struct fmt::formatter<USERVER_NAMESPACE::http::headers::PredefinedHeader>
 
  207    : fmt::formatter<std::string_view> {
 
  208  template <
typename FormatContext>
 
  209  auto format(
const USERVER_NAMESPACE::http::headers::PredefinedHeader& value,
 
  210              FormatContext& ctx) 
const -> 
decltype(ctx.out()) {
 
  211    return formatter<std::string_view>::format(std::string_view{value}, ctx);