aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/misc
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.com>2024-10-26 23:13:30 +0300
committerbabenko <babenko@yandex-team.com>2024-10-26 23:30:14 +0300
commit41d598c624442bf6918407466dac3316b8277347 (patch)
tree5895b8823d4f887e1e5ab4f99cbac991dca5ca17 /library/cpp/yt/misc
parentddabd4ddff87ac13bfc87ef02af352216a0f4e13 (diff)
downloadydb-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.h15
-rw-r--r--library/cpp/yt/misc/enum.h36
-rw-r--r--library/cpp/yt/misc/unittests/enum_ut.cpp13
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