10#include <boost/preprocessor/empty.hpp>
11#include <boost/preprocessor/seq/for_each.hpp>
13#include <userver/utils/forward_like.hpp>
14#include <userver/utils/impl/boost_variadic_to_seq.hpp>
15#include <userver/utils/impl/internal_tag.hpp>
17USERVER_NAMESPACE_BEGIN
19namespace utils::impl {
21struct RequireSemicolon;
23struct NonMovable
final {
24 constexpr explicit NonMovable(InternalTag)
noexcept {}
28constexpr auto IsDefinedAndAggregate() ->
decltype(
static_cast<
void>(
sizeof(T)),
false) {
29 return std::is_aggregate_v<T>;
32template <
typename ,
typename... Args>
33constexpr auto IsDefinedAndAggregate(Args...) ->
bool {
37template <
typename TOwner,
typename TMember>
38USERVER_IMPL_NODEBUG_INLINE_FUNC
decltype(
auto) ForwardLikeExplicit(TMember& member)
noexcept {
39 if constexpr (std::is_lvalue_reference_v<TOwner> || std::is_lvalue_reference_v<TMember>) {
42 return std::move(member);
46template <
typename TOwner,
typename TMember>
47USERVER_IMPL_NODEBUG_INLINE_FUNC
decltype(
auto) ForwardLikeExplicit(
const TMember& member)
noexcept {
58#define USERVER_IMPL_STRUCT_MAP(r, data, elem)
59 USERVER_NAMESPACE
::utils::impl::ForwardLikeExplicit<OtherDeps, decltype(other.elem)>(other.elem),
62#define USERVER_IMPL_MAKE_FROM_SUPERSET(Self, ...)
63 template <typename OtherDeps>
64 static Self MakeFromSupersetImpl(OtherDeps&& other, USERVER_NAMESPACE
::utils::impl::InternalTag) {
65 return {BOOST_PP_SEQ_FOR_EACH
(
66 USERVER_IMPL_STRUCT_MAP
,
68 USERVER_IMPL_VARIADIC_TO_SEQ
(__VA_ARGS__)
73#define USERVER_IMPL_STRUCT_SUBSET_MAP(r, data, elem)
75 decltype(data::elem) elem;
78#define USERVER_IMPL_STRUCT_SUBSET_REF_MAP(r, data, elem)
80 std::add_const_t<decltype(data::elem)>& elem;
90#define USERVER_ALLOW_CONVERSIONS_TO_SUBSET()
91 template <typename Other>
92 requires(USERVER_NAMESPACE
::utils::impl::IsDefinedAndAggregate<Other>()) operator
Other() const& {
93 return Other::MakeFromSupersetImpl(*this, USERVER_NAMESPACE
::utils::impl::InternalTag{});
96 template <typename Other>
97 requires(USERVER_NAMESPACE
::utils::impl::IsDefinedAndAggregate<Other>()) operator
Other()&& {
98 return Other::MakeFromSupersetImpl(std::move(*this), USERVER_NAMESPACE
::utils::impl::InternalTag{});
101 friend struct USERVER_NAMESPACE
::utils::impl::RequireSemicolon
123#define USERVER_DEFINE_STRUCT_SUBSET(SubsetStruct, OriginalStruct, ...)
124 struct SubsetStruct {
125 BOOST_PP_SEQ_FOR_EACH
(
126 USERVER_IMPL_STRUCT_SUBSET_MAP
,
128 USERVER_IMPL_VARIADIC_TO_SEQ
(__VA_ARGS__)
131 USERVER_IMPL_MAKE_FROM_SUPERSET
(SubsetStruct, __VA_ARGS__)
162#define USERVER_DEFINE_STRUCT_SUBSET_REF(SubsetStructRef, OriginalStruct, ...)
163 struct SubsetStructRef {
164 BOOST_PP_SEQ_FOR_EACH
(
165 USERVER_IMPL_STRUCT_SUBSET_REF_MAP
,
167 USERVER_IMPL_VARIADIC_TO_SEQ
(__VA_ARGS__)
171 USERVER_NAMESPACE
::utils::impl::NonMovable _impl_non_movable{USERVER_NAMESPACE
::utils::impl::InternalTag{}};
173 USERVER_IMPL_MAKE_FROM_SUPERSET
(SubsetStructRef, __VA_ARGS__)