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
bool
operator==(
const
ParseItemsIterator& other)
const
noexcept
{
60
UASSERT
(parser_ ==
nullptr
|| other.parser_ ==
nullptr
);
61
return
parser_ == other.parser_;
62
}
63
64
private
:
65
NYdb::TValueParser* parser_{
nullptr
};
66
const
ParseContext* context_{
nullptr
};
67
};
68
69
}
// namespace impl
70
71
/// @cond
72
struct
InsertColumn
;
73
using
InsertRow = std::vector<
InsertColumn
>;
74
/// @endcond
75
76
template
<
typename
T>
77
requires
meta::
kIsRange
<T> && (!meta::
kIsMap
<T>)
78
struct
ValueTraits
<T> {
79
using
ValueType = meta::
RangeValueType
<T>;
80
81
static
T Parse(NYdb::TValueParser& parser,
const
ParseContext& context) {
82
parser.OpenList();
83
#
if
__cpp_lib_ranges_to_container
>=
202202L
84
T result =
85
std::ranges::subrange{
86
impl::ParseItemsIterator<ValueType>{parser, context},
87
impl::ParseItemsIterator<ValueType>{},
88
} |
89
std::ranges::to<T>();
90
#
else
91
T result(impl::ParseItemsIterator<ValueType>{parser, context}, impl::ParseItemsIterator<ValueType>{});
92
#
endif
93
parser.CloseList();
94
return
result;
95
}
96
97
template
<
typename
Builder,
typename
U =
const
T&>
98
static
void
Write(NYdb::TValueBuilderBase<Builder>& builder, U&& value) {
99
bool
list_opened =
false
;
100
for
(
auto
&& item : value) {
101
if
(!list_opened) {
102
builder.BeginList();
103
list_opened =
true
;
104
}
105
builder.AddListItem();
106
ydb
::
Write
(
builder
,
item
)
;
107
}
108
if
(list_opened) {
109
builder.EndList();
110
}
else
if
constexpr
(std::is_same_v<ValueType, InsertRow>) {
111
// Legacy behavior. Sometimes YDB will throw here due to insufficient type
112
// info.
113
builder.EmptyList();
114
}
else
{
115
builder.EmptyList(
ValueTraits
<ValueType>::MakeType());
116
}
117
}
118
119
static
NYdb::TType MakeType() {
120
NYdb::TTypeBuilder builder;
121
builder.List(
ValueTraits
<ValueType>::MakeType());
122
return
builder.Build();
123
}
124
};
125
126
template
<
typename
T>
127
requires
meta::
kIsRange
<T> && (!meta::
kIsMap
<T>)
128
struct
ValueTraits
<std::optional<T>> : impl::GenericOptionalValueTraits<T> {};
129
130
}
// namespace ydb
131
132
USERVER_NAMESPACE_END
userver
ydb
io
list.hpp
Generated on
for userver by
Doxygen
1.17.0