3#include <initializer_list>
8#include <userver/formats/json_fwd.hpp>
9#include <userver/formats/parse/to.hpp>
10#include <userver/http/predefined_header.hpp>
11#include <userver/utils/fast_pimpl.hpp>
13USERVER_NAMESPACE_BEGIN
38class HeaderMap
final {
45 using iterator = Iterator;
46 using const_iterator = ConstIterator;
48 using key_type = std::string;
49 using mapped_type = std::string;
52 class TooManyHeadersException
final :
public std::runtime_error {
53 using std::runtime_error::runtime_error;
60 HeaderMap(std::initializer_list<std::pair<std::string, std::string>> headers);
63 HeaderMap(std::initializer_list<std::pair<PredefinedHeader, std::string>> headers);
70 template <
typename InputIt>
81 HeaderMap&
operator=(
const HeaderMap& other);
83 HeaderMap&
operator=(HeaderMap&& other)
noexcept;
86 void reserve(std::size_t capacity);
88 std::size_t
size()
const noexcept;
90 bool empty()
const noexcept;
96 std::size_t
count(std::string_view key)
const noexcept;
98 std::size_t
count(
const PredefinedHeader& key)
const noexcept;
100 template <std::size_t Size>
101 [[noreturn]] std::size_t count(
const char (&)[Size])
const noexcept {
102 ReportMisuse<Size>();
106 bool contains(std::string_view key)
const noexcept;
108 bool contains(
const PredefinedHeader& key)
const noexcept;
110 template <std::size_t Size>
111 [[noreturn]]
bool contains(
const char (&)[Size])
const noexcept {
112 ReportMisuse<Size>();
120 std::string&
operator[](std::string&& key);
124 std::string&
operator[](std::string_view key);
126 std::string&
operator[](
const PredefinedHeader& key);
128 template <std::size_t Size>
129 [[noreturn]] std::string& operator[](
const char (&)[Size]) {
130 ReportMisuse<Size>();
135 Iterator
find(std::string_view key)
noexcept;
137 ConstIterator
find(std::string_view key)
const noexcept;
141 Iterator
find(
const PredefinedHeader& key)
noexcept;
143 ConstIterator
find(
const PredefinedHeader& key)
const noexcept;
145 template <std::size_t Size>
146 [[noreturn]] Iterator find(
const char (&)[Size])
noexcept;
148 template <std::size_t Size>
149 [[noreturn]] ConstIterator find(
const char (&)[Size])
const noexcept;
153 template <
typename... Args>
154 void emplace(std::string_view key, Args&&... args) {
155 Emplace(std::move(key), std::forward<Args>(args)...);
160 template <
typename... Args>
161 void emplace(std::string key, Args&&... args) {
162 Emplace(std::move(key), std::forward<Args>(args)...);
167 template <
typename... Args>
168 void try_emplace(std::string key, Args&&... args) {
169 Emplace(std::move(key), std::forward<Args>(args)...);
174 template <
typename InputIt>
175 void insert(InputIt first, InputIt last);
179 void insert(
const std::pair<std::string, std::string>& kvp);
182 void insert(std::pair<std::string, std::string>&& kvp);
194 void InsertOrAppend(
const PredefinedHeader& key, std::string value);
199 Iterator
erase(Iterator it);
203 Iterator
erase(ConstIterator it);
207 Iterator
erase(std::string_view key);
209 Iterator
erase(
const PredefinedHeader& key);
211 template <std::size_t Size>
212 [[noreturn]] Iterator erase(
const char (&)[Size]);
216 std::string&
at(std::string_view key);
218 std::string&
at(
const PredefinedHeader& key);
221 const std::string&
at(std::string_view key)
const;
223 const std::string&
at(
const PredefinedHeader& key)
const;
225 template <std::size_t Size>
226 [[noreturn]] std::string& at(
const char (&)[Size]) {
227 ReportMisuse<Size>();
229 template <std::size_t Size>
230 [[noreturn]]
const std::string& at(
const char (&)[Size])
const {
231 ReportMisuse<Size>();
235 Iterator
begin()
noexcept;
237 ConstIterator
begin()
const noexcept;
239 ConstIterator
cbegin()
const noexcept;
242 Iterator
end()
noexcept;
244 ConstIterator
end()
const noexcept;
246 ConstIterator
cend()
const noexcept;
250 bool operator==(
const HeaderMap& other)
const noexcept;
263 friend class TestsHelper;
265 template <
typename KeyType,
typename... Args>
266 void Emplace(KeyType&& key, Args&&... args);
268 template <std::size_t Size>
269 [[noreturn]]
static void ReportMisuse();
271 utils::FastPimpl<header_map::Map, 272, 8> impl_;
274template <
typename InputIt>
275HeaderMap::
HeaderMap(InputIt first, InputIt last) : HeaderMap{} {
279template <
typename InputIt>
280void HeaderMap::
insert(InputIt first, InputIt last) {
281 for (; first != last; ++first) {
286template <
typename KeyType,
typename... Args>
287void HeaderMap::Emplace(KeyType&& key, Args&&... args) {
288 static_assert(std::is_rvalue_reference_v<
decltype(key)>);
291 auto& value = operator[](std::move(key));
293 value = std::string{std::forward<Args>(args)...};
297template <std::size_t Size>
298void HeaderMap::ReportMisuse() {
301 "Please create a 'constexpr PredefinedHeader' and use that "
302 "instead of passing header name as a string literal."
306namespace header_map {
308class MapEntry
final {
313 MapEntry(std::string&& key, std::string&& value);
315 MapEntry(
const MapEntry& other);
316 MapEntry& operator=(
const MapEntry& other);
317 MapEntry(MapEntry&& other)
noexcept;
318 MapEntry& operator=(MapEntry&& other)
noexcept;
320 std::pair<
const std::string, std::string>& Get();
321 const std::pair<
const std::string, std::string>& Get()
const;
323 std::pair<std::string, std::string>& GetMutable();
325 bool operator==(
const MapEntry& other)
const;
339 std::pair<std::string, std::string> mutable_value;
340 std::pair<
const std::string, std::string> value;
348class HeaderMap::Iterator
final {
350 using iterator_category = std::forward_iterator_tag;
351 using difference_type = std::ptrdiff_t;
352 using value_type = std::pair<
const std::string, std::string>;
353 using reference = value_type&;
354 using const_reference =
const value_type&;
355 using pointer = value_type*;
356 using const_pointer =
const value_type*;
361 using UnderlyingIterator = std::vector<header_map::MapEntry>::reverse_iterator;
364 explicit Iterator(UnderlyingIterator it);
367 Iterator(
const Iterator& other);
368 Iterator(Iterator&& other)
noexcept;
369 Iterator& operator=(
const Iterator& other);
370 Iterator& operator=(Iterator&& other)
noexcept;
372 Iterator operator++(
int);
373 Iterator& operator++();
375 reference operator*();
376 const_reference operator*()
const;
377 pointer operator->();
378 const_pointer operator->()
const;
380 bool operator==(
const Iterator& other)
const;
381 bool operator!=(
const Iterator& other)
const;
383 bool operator==(
const ConstIterator& other)
const;
386 friend class HeaderMap::ConstIterator;
388 UnderlyingIterator it_{};
391class HeaderMap::ConstIterator
final {
393 using iterator_category = std::forward_iterator_tag;
394 using difference_type = std::ptrdiff_t;
395 using value_type = std::pair<
const std::string, std::string>;
396 using reference =
const value_type&;
397 using const_reference =
const value_type&;
398 using pointer =
const value_type*;
399 using const_pointer =
const value_type*;
404 using UnderlyingIterator = std::vector<header_map::MapEntry>::const_reverse_iterator;
407 explicit ConstIterator(UnderlyingIterator it);
410 ConstIterator(
const ConstIterator& other);
411 ConstIterator(ConstIterator&& other)
noexcept;
412 ConstIterator& operator=(
const ConstIterator& other);
413 ConstIterator& operator=(ConstIterator&& other)
noexcept;
415 ConstIterator operator++(
int);
416 ConstIterator& operator++();
418 reference operator*();
419 const_reference operator*()
const;
420 pointer operator->();
421 const_pointer operator->()
const;
423 bool operator==(
const ConstIterator& other)
const;
424 bool operator!=(
const ConstIterator& other)
const;
426 bool operator==(
const Iterator& other)
const;
429 friend class HeaderMap::Iterator;
431 UnderlyingIterator it_{};
434template <std::size_t Size>
435HeaderMap::Iterator HeaderMap::find(
const char (&)[Size])
noexcept {
436 ReportMisuse<Size>();
439template <std::size_t Size>
440HeaderMap::ConstIterator HeaderMap::find(
const char (&)[Size])
const noexcept {
441 ReportMisuse<Size>();
444template <std::size_t Size>
445HeaderMap::Iterator HeaderMap::erase(
const char (&)[Size]) {
446 ReportMisuse<Size>();