diff options
author | h0pless <h0pless@yandex-team.com> | 2024-05-15 16:02:34 +0300 |
---|---|---|
committer | h0pless <h0pless@yandex-team.com> | 2024-05-15 16:18:32 +0300 |
commit | 1c3cea8ba893a97b04ddc33ad381f17d2bf05ef8 (patch) | |
tree | 31dba695a2633d58213313d7c00e51fb3316e319 | |
parent | 60692c0c917cc24ca10fd4c1c0155090bd0f851c (diff) | |
download | ydb-1c3cea8ba893a97b04ddc33ad381f17d2bf05ef8.tar.gz |
Improve support for DontSerializeDefault; Add DontSerializeDefault to fix snapshot divergence when rolling 23.2
964925e3330bb2bc336b4c2721370bbd33f05f34
-rw-r--r-- | yt/yt/core/ytree/yson_struct_detail-inl.h | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/yt/yt/core/ytree/yson_struct_detail-inl.h b/yt/yt/core/ytree/yson_struct_detail-inl.h index c34a934c162..fefe704afb6 100644 --- a/yt/yt/core/ytree/yson_struct_detail-inl.h +++ b/yt/yt/core/ytree/yson_struct_detail-inl.h @@ -18,20 +18,58 @@ namespace NYT::NYTree { namespace NPrivate { -// TODO(shakurov): get rid of this once concept support makes it into the standard -// library implementation. Use equality-comparability instead. +//////////////////////////////////////////////////////////////////////////////// + +namespace NDetail { + +//////////////////////////////////////////////////////////////////////////////// + +template <class T> +concept CTupleLike = requires { + std::tuple_size<T>{}; +}; + +template <class T> +concept CContainerLike = requires { + typename T::value_type; +}; + +template <class T> +struct TEqualityComparableHelper +{ + constexpr static bool Value = std::equality_comparable<T>; +}; + +template <class T, size_t... I> +constexpr bool IsSequenceEqualityComparable(std::index_sequence<I...> /*sequence*/) +{ + return (TEqualityComparableHelper<typename std::tuple_element<I, T>::type>::Value && ...); +} + +template <CTupleLike T> +struct TEqualityComparableHelper<T> +{ + constexpr static bool Value = IsSequenceEqualityComparable<T>(std::make_index_sequence<std::tuple_size<T>::value>()); +}; + +template <CContainerLike T> +struct TEqualityComparableHelper<T> +{ + constexpr static bool Value = TEqualityComparableHelper<typename T::value_type>::Value; +}; + +} // namespace NDetail + +//////////////////////////////////////////////////////////////////////////////// + +// TODO(h0pless): Get rid of this once containers will have constraints for equality operator. +// Once this will be the case, it should be safe to use std::equality_comparable here instead. template <class T> -concept SupportsDontSerializeDefaultImpl = - std::is_arithmetic_v<T> || - std::is_same_v<T, TString> || - std::is_same_v<T, TDuration> || - std::is_same_v<T, TGuid> || - std::is_same_v<T, std::optional<std::vector<TString>>> || - std::is_same_v<T, THashSet<TString>>; +concept CRecursivelyEqualityComparable = NDetail::TEqualityComparableHelper<T>::Value; template <class T> -concept SupportsDontSerializeDefault = - SupportsDontSerializeDefaultImpl<typename TWrapperTraits<T>::TRecursiveUnwrapped>; +concept CSupportsDontSerializeDefault = + CRecursivelyEqualityComparable<typename TWrapperTraits<T>::TRecursiveUnwrapped>; //////////////////////////////////////////////////////////////////////////////// @@ -654,7 +692,7 @@ template <class TValue> bool TYsonStructParameter<TValue>::CanOmitValue(const TYsonStructBase* self) const { const auto& value = FieldAccessor_->GetValue(self); - if constexpr (NPrivate::SupportsDontSerializeDefault<TValue>) { + if constexpr (NPrivate::CSupportsDontSerializeDefault<TValue>) { if (!SerializeDefault_ && value == (*DefaultCtor_)()) { return true; } @@ -745,7 +783,7 @@ TYsonStructParameter<TValue>& TYsonStructParameter<TValue>::DontSerializeDefault // We should check for equality-comparability here but it is rather hard // to do the deep validation. static_assert( - NPrivate::SupportsDontSerializeDefault<TValue>, + NPrivate::CSupportsDontSerializeDefault<TValue>, "DontSerializeDefault requires |Parameter| to be TString, TDuration, an arithmetic type or an optional of those"); SerializeDefault_ = false; |