userver: userver/ydb/io/tuple.hpp Source File
Loading...
Searching...
No Matches
tuple.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/ydb/io/tuple.hpp
4/// @brief YDB tuple serialization traits
5
6#include <ydb-cpp-sdk/client/value/value.h>
7
8#include <cstddef>
9#include <optional>
10#include <tuple>
11#include <type_traits>
12#include <utility>
13
14#include <userver/utils/assert.hpp>
15#include <userver/utils/constexpr_indices.hpp>
16
17#include <userver/ydb/io/generic_optional.hpp>
18#include <userver/ydb/io/traits.hpp>
19
20USERVER_NAMESPACE_BEGIN
21
22namespace ydb {
23
24namespace impl {
25
26template <typename Tuple, std::size_t... Indices>
27Tuple ParseTupleElements(NYdb::TValueParser& parser, const ParseContext& context, std::index_sequence<Indices...>) {
28 return Tuple{([&] {
29 const bool has_element = parser.TryNextElement();
30 UASSERT(has_element);
31 return ydb::Parse<std::tuple_element_t<Indices, Tuple>>(parser, context);
32 }())...};
33}
34
35template <typename Builder, typename Tuple, std::size_t... Indices>
36void WriteTupleElements(NYdb::TValueBuilderBase<Builder>& builder, const Tuple& value, std::index_sequence<Indices...>) {
37 (([&] {
38 builder.AddElement();
39 ydb::Write(builder, std::get<Indices>(value));
40 }()),
41 ...);
42}
43
44} // namespace impl
45
46template <typename... Args>
47struct ValueTraits<std::tuple<Args...>> {
48 using TupleType = std::tuple<Args...>;
49 static constexpr auto kElementsCount = sizeof...(Args);
50
51 static TupleType Parse(NYdb::TValueParser& parser, const ParseContext& context) {
52 parser.OpenTuple();
53 auto result = impl::ParseTupleElements<TupleType>(parser, context, std::make_index_sequence<kElementsCount>{});
54 parser.CloseTuple();
55 return result;
56 }
57
58 template <typename Builder>
59 static void Write(NYdb::TValueBuilderBase<Builder>& builder, const TupleType& value) {
60 builder.BeginTuple();
61 impl::WriteTupleElements(builder, value, std::make_index_sequence<kElementsCount>{});
62 builder.EndTuple();
63 }
64
65 static NYdb::TType MakeType() {
66 NYdb::TTypeBuilder builder;
67 builder.BeginTuple();
68 (builder.AddElement(ValueTraits<Args>::MakeType()), ...);
69 builder.EndTuple();
70 return builder.Build();
71 }
72};
73
74template <typename... Args>
75struct ValueTraits<std::optional<std::tuple<Args...>>> : impl::GenericOptionalValueTraits<std::tuple<Args...>> {};
76
77} // namespace ydb
78
79USERVER_NAMESPACE_END