userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
list.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/ydb/io/list.hpp
4
/// @brief YDB list container serialization traits
5
6
#
include
<
ydb
-
cpp
-
sdk
/
client
/
value
/
value
.
h
>
7
8
#
include
<
iterator
>
9
#
include
<
ranges
>
10
#
include
<
type_traits
>
11
#
include
<
vector
>
// for InsertRow
12
13
#
include
<
userver
/
utils
/
assert
.
hpp
>
14
#
include
<
userver
/
utils
/
meta
.
hpp
>
15
16
#
include
<
userver
/
ydb
/
io
/
generic_optional
.
hpp
>
17
#
include
<
userver
/
ydb
/
io
/
traits
.
hpp
>
18
19
USERVER_NAMESPACE_BEGIN
20
21
namespace
ydb {
22
23
namespace
impl {
24
25
template
<
typename
T>
26
class
ParseItemsIterator final {
27
public
:
28
using
difference_type = std::ptrdiff_t;
29
using
value_type = T;
30
using
reference = T;
31
using
iterator_category = std::input_iterator_tag;
32
33
ParseItemsIterator() =
default
;
34
35
ParseItemsIterator(NYdb::TValueParser& parser,
const
ParseContext& context)
36
: parser_(&parser),
37
context_(&context)
38
{
39
++*
this
;
40
}
41
42
// Trivially copyable.
43
ParseItemsIterator(
const
ParseItemsIterator&) =
default
;
44
ParseItemsIterator& operator=(
const
ParseItemsIterator&) =
default
;
45
46
T operator*()
const
{
47
UASSERT
(parser_ && context_);
48
return
ydb::Parse<T>(*parser_, *context_);
49
}
50
51
ParseItemsIterator& operator++() {
52
UASSERT
(parser_ && context_);
53
if
(!parser_->TryNextListItem()) {
54
parser_ =
nullptr
;
55
}
56
return
*
this
;
57
}
58
59
ParseItemsIterator operator++(
int
) {
60
ParseItemsIterator copy{*
this
};
61
++*
this
;
62
return
copy;
63
}
64
65
bool
operator==(
const
ParseItemsIterator& other)
const
noexcept
{
66
UASSERT
(parser_ ==
nullptr
|| other.parser_ ==
nullptr
);
67
return
parser_ == other.parser_;
68
}
69
70
private
:
71
NYdb::TValueParser* parser_{
nullptr
};
72
const
ParseContext* context_{
nullptr
};
73
};
74
75
}
// namespace impl
76
77
/// @cond
78
struct
InsertColumn
;
79
using
InsertRow = std::vector<
InsertColumn
>;
80
/// @endcond
81
82
template
<
typename
T>
83
requires
meta::
kIsRange
<T> && (!meta::
kIsMap
<T>)
84
struct
ValueTraits
<T> {
85
using
ValueType = meta::
RangeValueType
<T>;
86
87
static
T Parse(NYdb::TValueParser& parser,
const
ParseContext& context) {
88
parser.OpenList();
89
#
if
__cpp_lib_ranges_to_container
>=
202202L
90
T result =
91
std::ranges::subrange{
92
impl::ParseItemsIterator<ValueType>{parser, context},
93
impl::ParseItemsIterator<ValueType>{},
94
} |
95
std::ranges::to<T>();
96
#
else
97
T result(impl::ParseItemsIterator<ValueType>{parser, context}, impl::ParseItemsIterator<ValueType>{});
98
#
endif
99
parser.CloseList();
100
return
result;
101
}
102
103
template
<
typename
Builder,
typename
U =
const
T&>
104
static
void
Write(NYdb::TValueBuilderBase<Builder>& builder, U&& value) {
105
bool
list_opened =
false
;
106
for
(
auto
&& item : value) {
107
if
(!list_opened) {
108
builder.BeginList();
109
list_opened =
true
;
110
}
111
builder.AddListItem();
112
ydb
::
Write
(
builder
,
item
)
;
113
}
114
if
(list_opened) {
115
builder.EndList();
116
}
else
if
constexpr
(std::is_same_v<ValueType, InsertRow>) {
117
// Legacy behavior. Sometimes YDB will throw here due to insufficient type
118
// info.
119
builder.EmptyList();
120
}
else
{
121
builder.EmptyList(
ValueTraits
<ValueType>::MakeType());
122
}
123
}
124
125
static
NYdb::TType MakeType() {
126
NYdb::TTypeBuilder builder;
127
builder.List(
ValueTraits
<ValueType>::MakeType());
128
return
builder.Build();
129
}
130
};
131
132
template
<
typename
T>
133
requires
meta::
kIsRange
<T> && (!meta::
kIsMap
<T>)
134
struct
ValueTraits
<std::optional<T>> : impl::GenericOptionalValueTraits<T> {};
135
136
}
// namespace ydb
137
138
USERVER_NAMESPACE_END
userver
ydb
io
list.hpp
Generated on
for userver by
Doxygen
1.17.0