diff options
author | babenko <babenko@yandex-team.com> | 2024-10-26 23:13:30 +0300 |
---|---|---|
committer | babenko <babenko@yandex-team.com> | 2024-10-26 23:30:14 +0300 |
commit | 41d598c624442bf6918407466dac3316b8277347 (patch) | |
tree | 5895b8823d4f887e1e5ab4f99cbac991dca5ca17 /library/cpp/yt/misc | |
parent | ddabd4ddff87ac13bfc87ef02af352216a0f4e13 (diff) | |
download | ydb-41d598c624442bf6918407466dac3316b8277347.tar.gz |
YT-22885: DEFINE_ENUM_UNKNOWN_VALUE, string-related conversions
commit_hash:14c7e42422af750383f04855b4a7ea6b267b92d2
Diffstat (limited to 'library/cpp/yt/misc')
-rw-r--r-- | library/cpp/yt/misc/enum-inl.h | 15 | ||||
-rw-r--r-- | library/cpp/yt/misc/enum.h | 36 | ||||
-rw-r--r-- | library/cpp/yt/misc/unittests/enum_ut.cpp | 13 |
3 files changed, 49 insertions, 15 deletions
diff --git a/library/cpp/yt/misc/enum-inl.h b/library/cpp/yt/misc/enum-inl.h index 5e1d04da1f..6ad9273293 100644 --- a/library/cpp/yt/misc/enum-inl.h +++ b/library/cpp/yt/misc/enum-inl.h @@ -38,6 +38,14 @@ namespace NYT { //////////////////////////////////////////////////////////////////////////////// +template <class T> +constexpr std::optional<T> TryGetEnumUnknownValueImpl(T) +{ + return std::nullopt; +} + +//////////////////////////////////////////////////////////////////////////////// + namespace NDetail { template <typename TValues> @@ -262,6 +270,13 @@ TStringBuf TEnumTraits<T, true>::GetTypeName() } template <class T> +constexpr std::optional<T> TEnumTraits<T, true>::TryGetUnknownValue() +{ + using NYT::TryGetEnumUnknownValueImpl; + return TryGetEnumUnknownValueImpl(T()); +} + +template <class T> std::optional<T> TEnumTraits<T, true>::FindValueByLiteral(TStringBuf literal) { return TEnumTraitsImpl<T>::FindValueByLiteral(literal); diff --git a/library/cpp/yt/misc/enum.h b/library/cpp/yt/misc/enum.h index 4d40ab8ec4..f78d23a06d 100644 --- a/library/cpp/yt/misc/enum.h +++ b/library/cpp/yt/misc/enum.h @@ -33,18 +33,11 @@ template <class T> using TEnumTraitsImpl = decltype(GetEnumTraitsImpl(T())); template <class T> -constexpr bool IsEnumDomainSizeKnown() -{ - if constexpr(requires{ TEnumTraitsImpl<T>::DomainSize; }) { - return true; - } else { - return false; - } -} +constexpr std::optional<T> TryGetEnumUnknownValueImpl(T); template < class T, - bool = IsEnumDomainSizeKnown<T>() + bool DomainSizeKnown = requires{ TEnumTraitsImpl<T>::DomainSize; } > struct TEnumTraitsWithKnownDomain { }; @@ -62,7 +55,7 @@ struct TEnumTraits }; template <class T> -struct TEnumTraitsWithKnownDomain<T, true> +struct TEnumTraitsWithKnownDomain<T, /*DomainSizeKnown*/ true> { static constexpr int GetDomainSize(); @@ -91,6 +84,7 @@ struct TEnumTraits<T, true> static TStringBuf GetTypeName(); + static constexpr std::optional<T> TryGetUnknownValue(); static std::optional<TStringBuf> FindLiteralByValue(T value); static std::optional<T> FindValueByLiteral(TStringBuf literal); @@ -102,7 +96,7 @@ struct TEnumTraits<T, true> //! Defines a smart enumeration with a specific underlying type. /*! - * \param enumType Enumeration enumType. + * \param enumType Enumeration type. * \param seq Enumeration domain encoded as a <em>sequence</em>. * \param underlyingType Underlying type. */ @@ -127,7 +121,7 @@ struct TEnumTraits<T, true> //! Defines a smart enumeration with a specific underlying type. /*! - * \param enumType Enumeration enumType. + * \param enumType Enumeration type. * \param seq Enumeration domain encoded as a <em>sequence</em>. * \param underlyingType Underlying type. */ @@ -142,7 +136,7 @@ struct TEnumTraits<T, true> //! Defines a smart enumeration with a specific underlying type. //! Duplicate enumeration values are allowed. /*! - * \param enumType Enumeration enumType. + * \param enumType Enumeration type. * \param seq Enumeration domain encoded as a <em>sequence</em>. * \param underlyingType Underlying type. */ @@ -155,7 +149,7 @@ struct TEnumTraits<T, true> //! Defines a smart enumeration with the default |unsigned int| underlying type. /*! - * \param enumType Enumeration enumType. + * \param enumType Enumeration type. * \param seq Enumeration domain encoded as a <em>sequence</em>. */ #define DEFINE_BIT_ENUM(enumType, seq) \ @@ -163,7 +157,7 @@ struct TEnumTraits<T, true> //! Defines a smart enumeration with a specific underlying type and IsStringSerializable attribute. /*! - * \param enumType Enumeration enumType. + * \param enumType Enumeration type. * \param seq Enumeration domain encoded as a <em>sequence</em>. * \param underlyingType Underlying type. */ @@ -186,6 +180,18 @@ struct TEnumTraits<T, true> #define DEFINE_STRING_SERIALIZABLE_ENUM(enumType, seq) \ DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(enumType, int, seq) +//! When enum from another representation (e.g. string or protobuf integer), +//! instructs the parser to treat undeclared values as |unknownValue|. +/*! + * \param enumType Enumeration type. + * \param unknownValue A sentinel value of #enumType. + */ +#define DEFINE_ENUM_UNKNOWN_VALUE(enumType, unknownValue) \ + [[maybe_unused]] constexpr std::optional<enumType> TryGetEnumUnknownValueImpl(enumType) \ + { \ + return enumType::unknownValue; \ + } + //////////////////////////////////////////////////////////////////////////////// //! Returns |true| iff the enumeration value is not bitwise zero. diff --git a/library/cpp/yt/misc/unittests/enum_ut.cpp b/library/cpp/yt/misc/unittests/enum_ut.cpp index 63b8666ae1..938ab11581 100644 --- a/library/cpp/yt/misc/unittests/enum_ut.cpp +++ b/library/cpp/yt/misc/unittests/enum_ut.cpp @@ -50,6 +50,13 @@ DEFINE_ENUM_WITH_UNDERLYING_TYPE(ECardinal, char, ((South) (3)) ); +DEFINE_ENUM(EWithUnknown, + (First) + (Second) + (Unknown) +); +DEFINE_ENUM_UNKNOWN_VALUE(EWithUnknown, Unknown); + //////////////////////////////////////////////////////////////////////////////// template <class T, size_t N> @@ -280,6 +287,12 @@ TEST(TEnumTest, Cast) } } +TEST(TEnumTest, UnknownValue) +{ + EXPECT_EQ(TEnumTraits<EColor>::TryGetUnknownValue(), std::nullopt); + EXPECT_EQ(TEnumTraits<EWithUnknown>::TryGetUnknownValue(), EWithUnknown::Unknown); +} + //////////////////////////////////////////////////////////////////////////////// } // namespace |