userver: userver/formats/common/items.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
items.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/formats/common/items.hpp
4/// @brief @copybrief formats::common::Items()
5/// @ingroup userver_universal
6
7#include <cstddef>
8#include <iterator>
9#include <string>
10#include <type_traits>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace formats::common {
15
16/// @brief Wrapper for handy python-like iteration over a map.
17///
18/// See formats::common::Items() for usage example
19template <typename Value>
20class ItemsWrapper final {
21 public:
22 class Iterator {
23 public:
24 using RawIterator = decltype(std::declval<Value>().begin());
25
26 struct ItValue {
27 std::string key;
28 typename RawIterator::reference value;
29 };
30
31 using iterator_category = std::forward_iterator_tag;
32 using difference_type = std::ptrdiff_t;
33 using value_type = ItValue;
34 using reference = ItValue;
35
36 explicit Iterator(RawIterator it) : it_(it) {}
37 Iterator(const Iterator& other) = default;
38 Iterator(Iterator&& other) noexcept = default;
39
40 Iterator& operator=(const Iterator& other) = default;
41 Iterator& operator=(Iterator&& other) noexcept = default;
42
43 ItValue operator*() const { return {it_.GetName(), *it_}; }
44
45 Iterator operator++(int) {
46 auto it = *this;
47 return {it++};
48 }
49
50 Iterator& operator++() {
51 ++it_;
52 return *this;
53 }
54
55 bool operator==(const Iterator& other) const { return it_ == other.it_; }
56
57 bool operator!=(const Iterator& other) const { return !(*this == other); }
58
59 private:
60 RawIterator it_;
61 };
62
63 ItemsWrapper(Value&& value) : value_(static_cast<Value&&>(value)) {}
64
65 auto begin() const { return cbegin(); }
66 auto end() const { return cend(); }
67 auto cbegin() const { return Iterator(value_.begin()); }
68 auto cend() const { return Iterator(value_.end()); }
69
70 private:
71 Value value_;
72};
73
74/// @brief Wrapper for handy python-like iteration over a map
75///
76/// @code
77/// for (const auto& [name, value]: Items(map)) ...
78/// @endcode
79template <typename Value>
80ItemsWrapper<Value> Items(Value&& value) {
81 // when passed an lvalue, store by reference
82 // when passed an rvalue, store by value
83 return ItemsWrapper<Value>(static_cast<Value&&>(value));
84}
85
86} // namespace formats::common
87
88USERVER_NAMESPACE_END