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);
64 std::initializer_list<std::pair<PredefinedHeader, std::string>> headers);
71 template <
typename InputIt>
82 HeaderMap&
operator=(
const HeaderMap& other);
84 HeaderMap&
operator=(HeaderMap&& other)
noexcept;
87 void reserve(std::size_t capacity);
89 std::size_t
size()
const noexcept;
91 bool empty()
const noexcept;
97 std::size_t
count(std::string_view key)
const noexcept;
99 std::size_t
count(
const PredefinedHeader& key)
const noexcept;
101 template <std::size_t Size>
102 [[noreturn]] std::size_t count(
const char (&)[Size])
const noexcept {
103 ReportMisuse<Size>();
107 bool contains(std::string_view key)
const noexcept;
109 bool contains(
const PredefinedHeader& key)
const noexcept;
111 template <std::size_t Size>
112 [[noreturn]]
bool contains(
const char (&)[Size])
const noexcept {
113 ReportMisuse<Size>();
121 std::string&
operator[](std::string&& key);
125 std::string&
operator[](std::string_view key);
127 std::string&
operator[](
const PredefinedHeader& key);
129 template <std::size_t Size>
130 [[noreturn]] std::string& operator[](
const char (&)[Size]) {
131 ReportMisuse<Size>();
136 Iterator
find(std::string_view key)
noexcept;
138 ConstIterator
find(std::string_view key)
const noexcept;
142 Iterator
find(
const PredefinedHeader& key)
noexcept;
144 ConstIterator
find(
const PredefinedHeader& key)
const noexcept;
146 template <std::size_t Size>
147 [[noreturn]] Iterator find(
const char (&)[Size])
noexcept;
149 template <std::size_t Size>
150 [[noreturn]] ConstIterator find(
const char (&)[Size])
const noexcept;
154 template <
typename... Args>
155 void emplace(std::string_view key, Args&&... args) {
156 Emplace(std::move(key), std::forward<Args>(args)...);
161 template <
typename... Args>
162 void emplace(std::string key, Args&&... args) {
163 Emplace(std::move(key), std::forward<Args>(args)...);
168 template <
typename... Args>
169 void try_emplace(std::string key, Args&&... args) {
170 Emplace(std::move(key), std::forward<Args>(args)...);
175 template <
typename InputIt>
176 void insert(InputIt first, InputIt last);
180 void insert(
const std::pair<std::string, std::string>& kvp);
183 void insert(std::pair<std::string, std::string>&& kvp);
195 void InsertOrAppend(
const PredefinedHeader& key, std::string value);
200 Iterator
erase(Iterator it);
204 Iterator
erase(ConstIterator it);
208 Iterator
erase(std::string_view key);
210 Iterator
erase(
const PredefinedHeader& key);
212 template <std::size_t Size>
213 [[noreturn]] Iterator erase(
const char (&)[Size]);
217 std::string&
at(std::string_view key);
219 std::string&
at(
const PredefinedHeader& key);
222 const std::string&
at(std::string_view key)
const;
224 const std::string&
at(
const PredefinedHeader& key)
const;
226 template <std::size_t Size>
227 [[noreturn]] std::string& at(
const char (&)[Size]) {
228 ReportMisuse<Size>();
230 template <std::size_t Size>
231 [[noreturn]]
const std::string& at(
const char (&)[Size])
const {
232 ReportMisuse<Size>();
236 Iterator
begin()
noexcept;
238 ConstIterator
begin()
const noexcept;
240 ConstIterator
cbegin()
const noexcept;
243 Iterator
end()
noexcept;
245 ConstIterator
end()
const noexcept;
247 ConstIterator
cend()
const noexcept;
251 bool operator==(
const HeaderMap& other)
const noexcept;
264 friend class TestsHelper;
266 template <
typename KeyType,
typename... Args>
267 void Emplace(KeyType&& key, Args&&... args);
269 template <std::size_t Size>
270 [[noreturn]]
static void ReportMisuse();
272 utils::FastPimpl<header_map::Map, 272, 8> impl_;
275template <
typename InputIt>
276HeaderMap::
HeaderMap(InputIt first, InputIt last) : HeaderMap{} {
280template <
typename InputIt>
281void HeaderMap::
insert(InputIt first, InputIt last) {
282 for (; first != last; ++first) {
287template <
typename KeyType,
typename... Args>
288void HeaderMap::Emplace(KeyType&& key, Args&&... args) {
289 static_assert(std::is_rvalue_reference_v<
decltype(key)>);
292 auto& value = operator[](std::move(key));
294 value = std::string{std::forward<Args>(args)...};
298template <std::size_t Size>
299void HeaderMap::ReportMisuse() {
301 "Please create a 'constexpr PredefinedHeader' and use that "
302 "instead of passing header name as a string literal.");
305namespace header_map {
307class MapEntry
final {
312 MapEntry(std::string&& key, std::string&& value);
314 MapEntry(
const MapEntry& other);
315 MapEntry& operator=(
const MapEntry& other);
316 MapEntry(MapEntry&& other)
noexcept;
317 MapEntry& operator=(MapEntry&& other)
noexcept;
319 std::pair<
const std::string, std::string>& Get();
320 const std::pair<
const std::string, std::string>& Get()
const;
322 std::pair<std::string, std::string>& GetMutable();
324 bool operator==(
const MapEntry& other)
const;
338 std::pair<std::string, std::string> mutable_value;
339 std::pair<
const std::string, std::string> value;
347class HeaderMap::Iterator
final {
349 using iterator_category = std::forward_iterator_tag;
350 using difference_type = std::ptrdiff_t;
351 using value_type = std::pair<
const std::string, std::string>;
352 using reference = value_type&;
353 using const_reference =
const value_type&;
354 using pointer = value_type*;
355 using const_pointer =
const value_type*;
360 using UnderlyingIterator =
361 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 =
405 std::vector<header_map::MapEntry>::const_reverse_iterator;
408 explicit ConstIterator(UnderlyingIterator it);
411 ConstIterator(
const ConstIterator& other);
412 ConstIterator(ConstIterator&& other)
noexcept;
413 ConstIterator& operator=(
const ConstIterator& other);
414 ConstIterator& operator=(ConstIterator&& other)
noexcept;
416 ConstIterator operator++(
int);
417 ConstIterator& operator++();
419 reference operator*();
420 const_reference operator*()
const;
421 pointer operator->();
422 const_pointer operator->()
const;
424 bool operator==(
const ConstIterator& other)
const;
425 bool operator!=(
const ConstIterator& other)
const;
427 bool operator==(
const Iterator& other)
const;
430 friend class HeaderMap::Iterator;
432 UnderlyingIterator it_{};
435template <std::size_t Size>
436HeaderMap::Iterator HeaderMap::find(
const char (&)[Size])
noexcept {
437 ReportMisuse<Size>();
440template <std::size_t Size>
441HeaderMap::ConstIterator HeaderMap::find(
const char (&)[Size])
const noexcept {
442 ReportMisuse<Size>();
445template <std::size_t Size>
446HeaderMap::Iterator HeaderMap::erase(
const char (&)[Size]) {
447 ReportMisuse<Size>();