diff options
author | babenko <babenko@yandex-team.com> | 2024-10-27 18:54:07 +0300 |
---|---|---|
committer | babenko <babenko@yandex-team.com> | 2024-10-27 19:11:40 +0300 |
commit | 1c41d6078d76a7a377b39d42e99aac3aa034479d (patch) | |
tree | 13f789a76ff26231039dfed7a8ced091b3268a7d /library/cpp | |
parent | b9951884f7c336f1462711cd8ad93645ac0d6d70 (diff) | |
download | ydb-1c41d6078d76a7a377b39d42e99aac3aa034479d.tar.gz |
Add GetAllSetValue and IsKnownValue
commit_hash:cbc39112d8384b8c4bcd2410f0a203466b400c10
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/yt/misc/enum-inl.h | 51 | ||||
-rw-r--r-- | library/cpp/yt/misc/enum.h | 10 | ||||
-rw-r--r-- | library/cpp/yt/misc/unittests/enum_ut.cpp | 16 |
3 files changed, 72 insertions, 5 deletions
diff --git a/library/cpp/yt/misc/enum-inl.h b/library/cpp/yt/misc/enum-inl.h index 6ad9273293..f1fb9f63e1 100644 --- a/library/cpp/yt/misc/enum-inl.h +++ b/library/cpp/yt/misc/enum-inl.h @@ -11,6 +11,7 @@ #include <util/generic/cast.h> #include <algorithm> +#include <numeric> #include <stdexcept> namespace NYT { @@ -140,6 +141,13 @@ constexpr bool CheckDomainNames(const TNames& names) return std::nullopt; \ } \ \ + static constexpr bool IsKnownValue(T value) \ + { \ + return false \ + PP_FOR_EACH(ENUM__IS_KNOWN_VALUE_ITEM, seq) \ + ; \ + } \ + \ static constexpr const std::array<TStringBuf, DomainSize>& GetDomainNames() \ { \ return Names; \ @@ -192,6 +200,19 @@ constexpr bool CheckDomainNames(const TNames& names) #define ENUM__GET_DOMAIN_NAMES_ITEM_ATOMIC(item) \ TStringBuf(PP_STRINGIZE(item)), +#define ENUM__IS_KNOWN_VALUE_ITEM(item) \ + PP_IF( \ + PP_IS_SEQUENCE(item), \ + ENUM__IS_KNOWN_VALUE_ITEM_SEQ, \ + ENUM__IS_KNOWN_VALUE_ITEM_ATOMIC \ + )(item) + +#define ENUM__IS_KNOWN_VALUE_ITEM_SEQ(seq) \ + ENUM__IS_KNOWN_VALUE_ITEM_ATOMIC(PP_ELEMENT(seq, 0)) + +#define ENUM__IS_KNOWN_VALUE_ITEM_ATOMIC(item) \ + || value == T::item + #define ENUM__VALIDATE_UNIQUE(enumType) \ static_assert(IsMonotonic || ::NYT::NDetail::CheckValuesUnique(Values), \ "Enumeration " #enumType " contains duplicate values"); @@ -249,6 +270,13 @@ constexpr T TEnumTraitsWithKnownDomain<T, true>::GetMaxValue() } template <class T> +constexpr T TEnumTraitsWithKnownDomain<T, true>::GetAllSetValue() + requires (TEnumTraitsImpl<T>::IsBitEnum) +{ + return TEnumTraitsImpl<T>::GetAllSetValue(); +} + +template <class T> std::vector<T> TEnumTraitsWithKnownDomain<T, true>::Decompose(T value) requires (TEnumTraitsImpl<T>::IsBitEnum) { @@ -289,6 +317,13 @@ std::optional<TStringBuf> TEnumTraits<T, true>::FindLiteralByValue(T value) } template <class T> +constexpr bool TEnumTraits<T, true>::IsKnownValue(T value) + requires (!TEnumTraitsImpl<T>::IsBitEnum) +{ + return TEnumTraitsImpl<T>::IsKnownValue(value); +} + +template <class T> TString TEnumTraits<T, true>::ToString(T value) { using ::ToString; @@ -323,7 +358,7 @@ T TEnumTraits<T, true>::FromString(TStringBuf literal) return T(ToUnderlying(lhs) op ToUnderlying(rhs)); \ } \ \ - [[maybe_unused]] inline T& operator assignOp (T& lhs, T rhs) \ + [[maybe_unused]] inline constexpr T& operator assignOp (T& lhs, T rhs) \ { \ lhs = T(ToUnderlying(lhs) op ToUnderlying(rhs)); \ return lhs; \ @@ -341,13 +376,13 @@ T TEnumTraits<T, true>::FromString(TStringBuf literal) return T(ToUnderlying(lhs) op rhs); \ } \ \ - [[maybe_unused]] inline T& operator assignOp (T& lhs, size_t rhs) \ + [[maybe_unused]] inline constexpr T& operator assignOp (T& lhs, size_t rhs) \ { \ lhs = T(ToUnderlying(lhs) op rhs); \ return lhs; \ } -#define ENUM__BITWISE_OPS(enumType) \ +#define ENUM__BITWISE_OPS(enumType) \ ENUM__BINARY_BITWISE_OPERATOR(enumType, &=, &) \ ENUM__BINARY_BITWISE_OPERATOR(enumType, |=, | ) \ ENUM__BINARY_BITWISE_OPERATOR(enumType, ^=, ^) \ @@ -355,6 +390,16 @@ T TEnumTraits<T, true>::FromString(TStringBuf literal) ENUM__BIT_SHIFT_OPERATOR(enumType, <<=, << ) \ ENUM__BIT_SHIFT_OPERATOR(enumType, >>=, >> ) +#define ENUM__ALL_SET_VALUE(enumType, seq) \ + static constexpr enumType GetAllSetValue() \ + { \ + return std::accumulate( \ + Values.begin(), \ + Values.end(), \ + enumType(), \ + [] (auto a, auto b) { return a | b; }); \ + } + //////////////////////////////////////////////////////////////////////////////// template <typename E> diff --git a/library/cpp/yt/misc/enum.h b/library/cpp/yt/misc/enum.h index f78d23a06d..d9611b2823 100644 --- a/library/cpp/yt/misc/enum.h +++ b/library/cpp/yt/misc/enum.h @@ -69,6 +69,8 @@ struct TEnumTraitsWithKnownDomain<T, /*DomainSizeKnown*/ true> requires (!TEnumTraitsImpl<T>::IsBitEnum); // For bit enums only. + static constexpr T GetAllSetValue() + requires (TEnumTraitsImpl<T>::IsBitEnum); static std::vector<T> Decompose(T value) requires (TEnumTraitsImpl<T>::IsBitEnum); }; @@ -87,6 +89,8 @@ struct TEnumTraits<T, true> static constexpr std::optional<T> TryGetUnknownValue(); static std::optional<TStringBuf> FindLiteralByValue(T value); static std::optional<T> FindValueByLiteral(TStringBuf literal); + static constexpr bool IsKnownValue(T value) + requires (!TEnumTraitsImpl<T>::IsBitEnum); static TString ToString(T value); static T FromString(TStringBuf literal); @@ -127,10 +131,11 @@ struct TEnumTraits<T, true> */ #define DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \ ENUM__CLASS(enumType, underlyingType, seq) \ + ENUM__BITWISE_OPS(enumType) \ ENUM__BEGIN_TRAITS(enumType, underlyingType, true, false, seq) \ ENUM__VALIDATE_UNIQUE(enumType) \ + ENUM__ALL_SET_VALUE(enumType, seq) \ ENUM__END_TRAITS(enumType) \ - ENUM__BITWISE_OPS(enumType) \ static_assert(true) //! Defines a smart enumeration with a specific underlying type. @@ -142,9 +147,10 @@ struct TEnumTraits<T, true> */ #define DEFINE_AMBIGUOUS_BIT_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \ ENUM__CLASS(enumType, underlyingType, seq) \ + ENUM__BITWISE_OPS(enumType) \ ENUM__BEGIN_TRAITS(enumType, underlyingType, true, false, seq) \ + ENUM__ALL_SET_VALUE(enumType, seq) \ ENUM__END_TRAITS(enumType) \ - ENUM__BITWISE_OPS(enumType) \ static_assert(true) //! Defines a smart enumeration with the default |unsigned int| underlying type. diff --git a/library/cpp/yt/misc/unittests/enum_ut.cpp b/library/cpp/yt/misc/unittests/enum_ut.cpp index 938ab11581..fc7feed227 100644 --- a/library/cpp/yt/misc/unittests/enum_ut.cpp +++ b/library/cpp/yt/misc/unittests/enum_ut.cpp @@ -210,6 +210,22 @@ TEST(TEnumTest, DomainValues) EXPECT_EQ(colorValues, ToVector(TEnumTraits<EColor>::GetDomainValues())); } +TEST(TEnumTest, IsKnownValue) +{ + EXPECT_TRUE(TEnumTraits<ESimple>::IsKnownValue(ESimple::X)); + EXPECT_TRUE(TEnumTraits<ESimple>::IsKnownValue(ESimple::Y)); + EXPECT_TRUE(TEnumTraits<ESimple>::IsKnownValue(ESimple::Z)); + + EXPECT_FALSE(TEnumTraits<ESimple>::IsKnownValue(static_cast<ESimple>(100))); + + EXPECT_TRUE(TEnumTraits<EColor>::IsKnownValue(EColor::Red)); +} + +TEST(TEnumTest, AllSetValue) +{ + EXPECT_EQ(TEnumTraits<EFlag>::GetAllSetValue(), EFlag::_1 | EFlag::_2 | EFlag::_3 | EFlag::_4); +} + TEST(TEnumTest, Decompose1) { auto f = EFlag(0); |