userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
result_mapper.hpp
1
#
pragma
once
2
3
#
include
<
iterator
>
4
#
include
<
memory
>
5
#
include
<
optional
>
6
#
include
<
type_traits
>
7
#
include
<
utility
>
8
9
#
include
<
boost
/
pfr
/
core
.
hpp
>
10
11
#
include
<
userver
/
storages
/
clickhouse
/
impl
/
block_wrapper_fwd
.
hpp
>
12
#
include
<
userver
/
storages
/
clickhouse
/
impl
/
iterators_helper
.
hpp
>
13
#
include
<
userver
/
storages
/
clickhouse
/
io
/
columns
/
column_wrapper
.
hpp
>
14
#
include
<
userver
/
storages
/
clickhouse
/
io
/
io_fwd
.
hpp
>
15
16
USERVER_NAMESPACE_BEGIN
17
18
namespace
storages::
clickhouse
::
io
{
19
20
class
IteratorsTester;
21
22
template
<
typename
MappedType>
23
class
ColumnsMapper
final
{
24
public
:
25
explicit
ColumnsMapper(
clickhouse
::impl::BlockWrapper& block)
26
: block_{block}
27
{}
28
29
template
<
typename
Field, size_t Index>
30
void
operator()(Field& field, std::integral_constant<size_t, Index> i) {
31
using
ColumnType = std::tuple_element_t<Index, MappedType>;
32
static_assert
(std::is_same_v<Field,
typename
ColumnType::container_type>);
33
34
auto
column = ColumnType{
io
::
columns
::GetWrappedColumn(block_, i)};
35
field.reserve(column.Size());
36
for
(
auto
& it : column) {
37
field.push_back(std::move(it));
38
}
39
}
40
41
private
:
42
clickhouse
::impl::BlockWrapper& block_;
43
};
44
45
template
<
typename
Row>
46
class
RowsMapper
final
{
47
public
:
48
using
MappedType =
typename
CppToClickhouse
<Row>::mapped_type;
49
explicit
RowsMapper(
clickhouse
::impl::BlockWrapperPtr&& block)
50
: block_{block.release()}
51
{
52
IteratorsHelperT::Init(begin_iterators_, end_iterators_, *block_);
53
}
54
~RowsMapper() =
default
;
55
56
using
IteratorsTupleT =
clickhouse
::impl::IteratorsTupleT<MappedType>;
57
58
class
Iterator
final
{
59
public
:
60
using
iterator_category = std::forward_iterator_tag;
61
using
difference_type = std::ptrdiff_t;
62
using
value_type = Row;
63
using
reference = value_type&;
64
using
pointer = value_type*;
65
66
Iterator() =
default
;
67
Iterator(IteratorsTupleT iterators);
68
69
Iterator operator++(
int
);
70
Iterator& operator++();
71
reference operator*()
const
;
72
pointer operator->()
const
;
73
74
bool
operator==(
const
Iterator& other)
const
;
75
bool
operator!=(
const
Iterator& other)
const
;
76
77
friend
class
IteratorsTester;
78
79
private
:
80
Row& UpdateValue()
const
;
81
82
class
FieldMapper
final
{
83
public
:
84
FieldMapper(
const
IteratorsTupleT& iterators)
85
: iterators_{iterators}
86
{}
87
88
template
<
typename
Field, size_t Index>
89
void
operator()(Field& field, [[maybe_unused]] std::integral_constant<size_t, Index> i)
const
{
90
if
constexpr
(kCanMoveFromIterators) {
91
field = std::move(*std::get<Index>(iterators_));
92
}
else
{
93
field = *std::get<Index>(iterators_);
94
}
95
}
96
97
private
:
98
const
IteratorsTupleT& iterators_;
99
};
100
101
IteratorsTupleT iterators_;
102
mutable
std::optional<Row> current_value_ = std::nullopt;
103
};
104
105
Iterator begin()
const
{
return
Iterator{begin_iterators_}; }
106
Iterator end()
const
{
return
Iterator{end_iterators_}; }
107
108
friend
class
IteratorsTester;
109
110
private
:
111
template
<
typename
TypesTuple>
112
struct
IteratorValuesAreNoexceptMovable;
113
114
template
<
typename
... Ts>
115
struct
IteratorValuesAreNoexceptMovable<std::tuple<Ts...>>
116
: std::conjunction<std::is_nothrow_move_constructible<
typename
Ts::iterator::value_type>...> {};
117
118
static
constexpr
auto
kCanMoveFromIterators = IteratorValuesAreNoexceptMovable<MappedType>::value;
119
120
using
IteratorsHelperT =
clickhouse
::impl::IteratorsHelper<MappedType>;
121
122
clickhouse
::impl::BlockWrapperPtr block_;
123
IteratorsTupleT begin_iterators_{};
124
IteratorsTupleT end_iterators_{};
125
};
126
127
template
<
typename
Row>
128
RowsMapper<Row>::Iterator::Iterator(IteratorsTupleT iterators)
129
: iterators_{std::move(iterators)}
130
{}
131
132
template
<
typename
Row>
133
typename
RowsMapper<Row>::Iterator RowsMapper<Row>::Iterator::operator++(
int
) {
134
Iterator old{};
135
old.iterators_ = IteratorsHelperT::PostfixIncrement(iterators_);
136
old.current_value_ = std::move_if_noexcept(current_value_);
137
current_value_.reset();
138
139
return
old;
140
}
141
142
template
<
typename
Row>
143
typename
RowsMapper<Row>::Iterator& RowsMapper<Row>::Iterator::operator++() {
144
IteratorsHelperT::PrefixIncrement(iterators_);
145
current_value_.reset();
146
147
return
*
this
;
148
}
149
150
template
<
typename
Row>
151
typename
RowsMapper<Row>::Iterator::reference RowsMapper<Row>::Iterator::operator*()
const
{
152
return
UpdateValue();
153
}
154
155
template
<
typename
Row>
156
typename
RowsMapper<Row>::Iterator::pointer RowsMapper<Row>::Iterator::operator->()
const
{
157
return
&UpdateValue();
158
}
159
160
template
<
typename
Row>
161
Row& RowsMapper<Row>::Iterator::UpdateValue()
const
{
162
if
(!current_value_.has_value()) {
163
Row result{};
164
boost::pfr::for_each_field(result, FieldMapper{iterators_});
165
current_value_.emplace(std::move(result));
166
}
167
168
return
*current_value_;
169
}
170
171
template
<
typename
Row>
172
bool
RowsMapper<Row>::Iterator::operator==(
const
Iterator& other)
const
{
173
return
iterators_ == other.iterators_;
174
}
175
176
template
<
typename
Row>
177
bool
RowsMapper<Row>::Iterator::operator!=(
const
Iterator& other)
const
{
178
return
!((*
this
) == other);
179
}
180
181
}
// namespace storages::clickhouse::io
182
183
USERVER_NAMESPACE_END
userver
storages
clickhouse
io
result_mapper.hpp
Generated on
for userver by
Doxygen
1.17.0