userver
C++ Async Framework
Toggle main menu visibility
Loading...
Searching...
No Matches
aggregates.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/dump/aggregates.hpp
4
/// @brief Dumping support for aggregates
5
///
6
/// @ingroup userver_dump_read_write
7
8
#
include
<
type_traits
>
9
10
#
include
<
boost
/
pfr
/
core
.
hpp
>
11
#
include
<
boost
/
pfr
/
tuple_size
.
hpp
>
12
13
#
include
<
userver
/
dump
/
operations
.
hpp
>
14
15
USERVER_NAMESPACE_BEGIN
16
17
namespace
dump
{
18
19
template
<
typename
T>
20
struct
IsDumpedAggregate
{};
21
22
namespace
impl {
23
24
// Only the non-specialized IsDumpedAggregate struct is defined,
25
// the specializations are declared without a definition
26
template
<
typename
T>
27
concept
IsDumpedAggregateSpecialized =
requires
{
sizeof
(
IsDumpedAggregate
<T>); };
28
29
template
<
typename
T, std::size_t... Indices>
30
constexpr
bool
AreAllDumpable(std::index_sequence<Indices...>) {
31
return
(
kIsDumpable
<boost::pfr::tuple_element_t<Indices, T>> && ...);
32
}
33
34
template
<
typename
T>
35
constexpr
bool
IsDumpableAggregate() {
36
if
constexpr
(std::is_aggregate_v<T> && !IsDumpedAggregateSpecialized<T>) {
37
constexpr
auto
kSize = boost::pfr::tuple_size_v<T>;
38
static_assert
(
39
AreAllDumpable<T>(std::make_index_sequence<kSize>{}),
40
"One of the member of an aggregate that was marked as dumpable "
41
"with dump::IsDumpedAggregate is not dumpable. Did you forget "
42
"to include <userver/dump/common.hpp>, "
43
"<userver/dump/common_containers.hpp> or some other header with "
44
"Read and Write functions declarations?"
45
);
46
return
true
;
47
}
else
{
48
return
false
;
49
}
50
}
51
52
template
<
typename
T, std::size_t... Indices>
53
T ReadAggregate(
Reader
& reader, std::index_sequence<Indices...>) {
54
// `Read`s are guaranteed to occur left-to-right in brace-init
55
return
T{reader.Read<boost::pfr::tuple_element_t<Indices, T>>()...};
56
}
57
58
}
// namespace impl
59
60
/// @brief Aggregates dumping support
61
///
62
/// To enable dumps and loads for an aggregate, add in the global namespace:
63
///
64
/// @snippet core/src/dump/aggregates_test.cpp IsDumpedAggregate declaration
65
///
66
/// @warning Don't forget to increment format-version if data layout changes
67
template
<
typename
T>
68
requires
(impl::IsDumpableAggregate<T>())
69
void
Write
(
Writer
& writer,
const
T& value) {
70
boost::pfr::for_each_field(value, [&writer](
const
auto
& field) { writer.Write(field); });
71
}
72
73
/// @brief Aggregates deserialization from dump support
74
///
75
/// To enable dumps and loads for an aggregate, add in the global namespace:
76
///
77
/// @snippet core/src/dump/aggregates_test.cpp IsDumpedAggregate declaration
78
///
79
/// @warning Don't forget to increment format-version if data layout changes
80
template
<
typename
T>
81
requires
(impl::IsDumpableAggregate<T>())
82
T
Read
(
Reader
& reader,
To
<T>) {
83
constexpr
auto
kSize = boost::pfr::tuple_size_v<T>;
84
return
impl::ReadAggregate<T>(reader, std::make_index_sequence<kSize>{});
85
}
86
87
}
// namespace dump
88
89
USERVER_NAMESPACE_END
userver
dump
aggregates.hpp
Generated on
for userver by
Doxygen
1.17.0