userver
C++ Async Framework
Loading...
Searching...
No Matches
struct_subsets.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/utils/struct_subsets.hpp
4
/// @brief Utilities for creating a struct with a subset of fields of the
5
/// original struct, with conversions between them.
6
7
#
include
<
type_traits
>
8
#
include
<
utility
>
9
10
#
include
<
boost
/
preprocessor
/
empty
.
hpp
>
11
#
include
<
boost
/
preprocessor
/
seq
/
for_each
.
hpp
>
12
13
#
include
<
userver
/
utils
/
impl
/
boost_variadic_to_seq
.
hpp
>
14
#
include
<
userver
/
utils
/
impl
/
internal_tag
.
hpp
>
15
16
USERVER_NAMESPACE_BEGIN
17
18
namespace
utils::impl {
19
20
struct
RequireSemicolon;
21
22
struct
NonMovable
final
{
23
constexpr
explicit
NonMovable(InternalTag)
noexcept
{}
24
};
25
26
template
<
typename
T>
27
constexpr
auto
IsDefinedAndAggregate() ->
decltype
(
static_cast
<
void
>(
sizeof
(T)),
false
) {
28
return
std::is_aggregate_v<T>;
29
}
30
31
template
<
typename
/*T*/
,
typename
... Args>
32
constexpr
auto
IsDefinedAndAggregate(Args...) ->
bool
{
33
return
false
;
34
}
35
36
}
// namespace utils::impl
37
38
USERVER_NAMESPACE_END
39
40
/// @cond
41
42
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
43
#
define
USERVER_IMPL_STRUCT_MAP
(
r
,
data
,
elem
)
std
::
forward
<
OtherDeps
>
(
other
)
.
elem
,
44
45
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
46
#
define
USERVER_IMPL_MAKE_FROM_SUPERSET
(
Self
,
...
)
47
template
<
typename
OtherDeps
>
48
static
Self
MakeFromSupersetImpl
(
OtherDeps
&&
other
,
USERVER_NAMESPACE
::
utils
::
impl
::
InternalTag
)
{
49
return
{
BOOST_PP_SEQ_FOR_EACH
(
50
USERVER_IMPL_STRUCT_MAP
,
51
BOOST_PP_EMPTY
(
)
,
52
USERVER_IMPL_VARIADIC_TO_SEQ
(
__VA_ARGS__
)
53
)
}
;
54
}
55
56
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
57
#
define
USERVER_IMPL_STRUCT_SUBSET_MAP
(
r
,
data
,
elem
)
58
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */
59
decltype
(
data
::
elem
)
elem
;
60
61
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
62
#
define
USERVER_IMPL_STRUCT_SUBSET_REF_MAP
(
r
,
data
,
elem
)
63
/* NOLINTNEXTLINE(bugprone-macro-parentheses) */
64
std
::
add_const_t
<
decltype
(
data
::
elem
)
>
&
elem
;
65
66
/// @endcond
67
68
/// @brief Should be invoked inside a manually defined "root" struct to enable
69
/// conversions from it to subset structs created by
70
/// @ref USERVER_DEFINE_STRUCT_SUBSET and @ref USERVER_DEFINE_STRUCT_SUBSET_REF.
71
///
72
/// @hideinitializer
73
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
74
#
define
USERVER_ALLOW_CONVERSIONS_TO_SUBSET
(
)
75
template
<
76
typename
Other
,
77
std
::
enable_if_t
<
USERVER_NAMESPACE
::
utils
::
impl
::
IsDefinedAndAggregate
<
Other
>
(
)
,
int
>
Enable
=
0
>
78
/*implicit*/
operator
Other
(
)
const
&
{
79
return
Other
::
MakeFromSupersetImpl
(
*
this
,
USERVER_NAMESPACE
::
utils
::
impl
::
InternalTag
{
}
)
;
80
}
81
82
template
<
83
typename
Other
,
84
std
::
enable_if_t
<
USERVER_NAMESPACE
::
utils
::
impl
::
IsDefinedAndAggregate
<
Other
>
(
)
,
int
>
Enable
=
0
>
85
/*implicit*/
operator
Other
(
)
&&
{
86
return
Other
::
MakeFromSupersetImpl
(
std
::
move
(
*
this
)
,
USERVER_NAMESPACE
::
utils
::
impl
::
InternalTag
{
}
)
;
87
}
88
89
friend
struct
USERVER_NAMESPACE
::
utils
::
impl
::
RequireSemicolon
90
91
/// @brief Defines a struct containing a subset of data members
92
/// from @a OriginalDependencies.
93
///
94
/// Implicit conversions (by copy and by move) are allowed from any superset
95
/// struct to the @a SubsetStruct, as long as the names of the data members
96
/// match, and the superset struct is either defined using
97
/// @ref USERVER_DEFINE_STRUCT_SUBSET or @ref USERVER_DEFINE_STRUCT_SUBSET_REF,
98
/// or it contains @ref USERVER_ALLOW_CONVERSIONS_TO_SUBSET.
99
///
100
/// Usage example:
101
/// @snippet utils/struct_subsets_test.cpp deps definitions
102
/// @snippet utils/struct_subsets_test.cpp deps usage
103
///
104
/// @param SubsetStruct the name of the subset struct to define
105
/// @param OriginalStruct the name of the superset struct, including its
106
/// namespace if needed
107
/// @param ... names of the data members to copy
108
///
109
/// @hideinitializer
110
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
111
#
define
USERVER_DEFINE_STRUCT_SUBSET
(
SubsetStruct
,
OriginalStruct
,
...
)
112
struct
SubsetStruct
{
113
BOOST_PP_SEQ_FOR_EACH
(
114
USERVER_IMPL_STRUCT_SUBSET_MAP
,
115
OriginalStruct
,
116
USERVER_IMPL_VARIADIC_TO_SEQ
(
__VA_ARGS__
)
117
)
118
119
USERVER_IMPL_MAKE_FROM_SUPERSET
(
SubsetStruct
,
__VA_ARGS__
)
120
121
USERVER_ALLOW_CONVERSIONS_TO_SUBSET
(
)
;
122
}
123
124
/// @brief Defines a struct containing a subset of data members
125
/// from @a OriginalDependencies. Appends `const&` to types of all non-reference
126
/// data members.
127
///
128
/// Implicit conversions (by copy and by move) are allowed from any superset
129
/// struct to the @a SubsetStruct, as long as the names of the data members
130
/// match, and the superset struct is either defined using
131
/// @ref USERVER_DEFINE_STRUCT_SUBSET or @ref USERVER_DEFINE_STRUCT_SUBSET_REF,
132
/// or it contains @ref USERVER_ALLOW_CONVERSIONS_TO_SUBSET.
133
///
134
/// `*Ref` structs can be used for parameters of utility functions to avoid
135
/// copying non-reference data members.
136
///
137
/// Usage example:
138
/// @snippet utils/struct_subsets_test.cpp ref definitions
139
/// @snippet utils/struct_subsets_test.cpp ref usage
140
///
141
/// @param SubsetStructRef the name of the subset struct to define, it should
142
/// typically contain `*Ref` suffix to underline that it needs the original
143
/// backing struct to work
144
/// @param OriginalStruct the name of the superset struct, including its
145
/// namespace if needed
146
/// @param ... names of the data members to copy
147
///
148
/// @hideinitializer
149
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
150
#
define
USERVER_DEFINE_STRUCT_SUBSET_REF
(
SubsetStructRef
,
OriginalStruct
,
...
)
151
struct
SubsetStructRef
{
152
BOOST_PP_SEQ_FOR_EACH
(
153
USERVER_IMPL_STRUCT_SUBSET_REF_MAP
,
154
OriginalStruct
,
155
USERVER_IMPL_VARIADIC_TO_SEQ
(
__VA_ARGS__
)
156
)
157
158
/* Protects against copying into async functions */
159
USERVER_NAMESPACE
::
utils
::
impl
::
NonMovable
_impl_non_movable
{
USERVER_NAMESPACE
::
utils
::
impl
::
InternalTag
{
}
}
;
160
161
USERVER_IMPL_MAKE_FROM_SUPERSET
(
SubsetStructRef
,
__VA_ARGS__
)
162
163
USERVER_ALLOW_CONVERSIONS_TO_SUBSET
(
)
;
164
}
userver
utils
struct_subsets.hpp
Generated on Tue Dec 30 2025 09:18:24 for userver by
Doxygen
1.9.8