userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
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
<
concepts
>
8
#
include
<
cstddef
>
9
#
include
<
iterator
>
10
#
include
<
string
>
11
#
include
<
type_traits
>
12
13
USERVER_NAMESPACE_BEGIN
14
15
namespace
formats::common {
16
17
/// @see formats::common::ItemsWrapper
18
template
<
typename
Value>
19
struct
ItemsWrapperValue final {
20
std::string key;
21
typename
decltype
(std::declval<Value&>().begin())::reference value;
22
};
23
24
/// @brief Wrapper for handy python-like iteration over a map.
25
///
26
/// See formats::common::Items() for usage example
27
template
<
typename
Value>
28
class
ItemsWrapper final {
29
public
:
30
/// Exposition-only, do not instantiate directly, use `iterator` and
31
/// `const_iterator` aliases instead.
32
template
<
bool
Const>
33
class
Iterator final {
34
using
Base = std::conditional_t<Const,
const
Value, Value>;
35
using
RawIterator =
decltype
(std::declval<Base&>().begin());
36
37
public
:
38
using
iterator_category = std::forward_iterator_tag;
39
using
difference_type = std::ptrdiff_t;
40
using
value_type = ItemsWrapperValue<Base>;
41
using
reference = value_type;
42
using
pointer =
void
;
43
44
/// @cond
45
Iterator() =
default
;
46
47
explicit
Iterator(RawIterator it)
48
: it_(std::move(it))
49
{}
50
/// @endcond
51
52
Iterator(
const
Iterator& other) =
default
;
53
Iterator(Iterator&& other)
noexcept
=
default
;
54
55
Iterator& operator=(
const
Iterator& other) =
default
;
56
Iterator& operator=(Iterator&& other)
noexcept
=
default
;
57
58
reference operator*()
const
{
return
{it_.GetName(), *it_}; }
59
60
Iterator operator++(
int
) {
61
auto
it = *
this
;
62
++*
this
;
63
return
it;
64
}
65
66
Iterator& operator++() {
67
++it_;
68
return
*
this
;
69
}
70
71
bool
operator==(
const
Iterator& other)
const
{
return
it_ == other.it_; }
72
73
private
:
74
RawIterator it_;
75
};
76
77
/// @brief Satisfies `std::forward_iterator`, `std::common_iterator`,
78
/// with `std::iter_reference_t` equal to
79
/// formats::common::ItemsWrapperValue<Value>.
80
using
iterator
= Iterator<
false
>;
81
82
/// @brief Satisfies `std::forward_iterator`, `std::common_iterator`,
83
/// with `std::iter_reference_t` equal to
84
/// formats::common::ItemsWrapperValue<const Value>.
85
using
const_iterator
= Iterator<
true
>;
86
87
/// @cond
88
explicit
ItemsWrapper(Value&& value)
89
: value_(
static_cast
<Value&&>(value))
90
{}
91
/// @endcond
92
93
iterator
begin() {
return
iterator
(value_.begin()); }
94
iterator
end() {
return
iterator
(value_.end()); }
95
const_iterator
begin()
const
{
return
const_iterator
(value_.begin()); }
96
const_iterator
end()
const
{
return
const_iterator
(value_.end()); }
97
98
private
:
99
Value value_;
100
};
101
102
/// @brief Wrapper for handy python-like iteration over a map
103
///
104
/// @snippet universal/src/formats/common/items_test.cpp Items const iteration
105
///
106
/// To move out values:
107
/// @snippet universal/src/formats/common/items_test.cpp Items move values
108
///
109
/// ## Example usage:
110
///
111
/// @snippet universal/src/formats/common/items_test.cpp Items Example Usage - Simple object
112
template
<
typename
Value>
113
ItemsWrapper<Value>
Items
(Value&& value) {
114
// when passed an lvalue, store by reference
115
// when passed an rvalue, store by value
116
return
ItemsWrapper<Value>(
static_cast
<Value&&>(value));
117
}
118
119
}
// namespace formats::common
120
121
USERVER_NAMESPACE_END
userver
formats
common
items.hpp
Generated on
for userver by
Doxygen
1.17.0