aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/misc/enum.h
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.com>2023-03-14 09:33:31 +0300
committerbabenko <babenko@yandex-team.com>2023-03-14 09:33:31 +0300
commite10767756146ca0d8e890326e20671aed5182e2b (patch)
tree0d15dded16242ddb4d7b64f5e1d21d425742234e /library/cpp/yt/misc/enum.h
parent9aa65dc165f24925a281f89c975cc5117823934f (diff)
downloadydb-e10767756146ca0d8e890326e20671aed5182e2b.tar.gz
YT-18571: Refactor YT enums to make them Arcadia-friendly
Diffstat (limited to 'library/cpp/yt/misc/enum.h')
-rw-r--r--library/cpp/yt/misc/enum.h183
1 files changed, 103 insertions, 80 deletions
diff --git a/library/cpp/yt/misc/enum.h b/library/cpp/yt/misc/enum.h
index 1353900996..773e1ac4ed 100644
--- a/library/cpp/yt/misc/enum.h
+++ b/library/cpp/yt/misc/enum.h
@@ -4,9 +4,9 @@
#include <util/generic/strbuf.h>
-#include <stdexcept>
-#include <type_traits>
#include <array>
+#include <optional>
+#include <type_traits>
#include <vector>
#include <library/cpp/yt/exception/exception.h>
@@ -22,15 +22,33 @@ namespace NYT {
* (unittests/enum_ut.cpp).
*/
-// Actual overload must be provided with defines DEFINE_ENUM_XXX (see below).
+// The actual overload must be provided with DEFINE_ENUM* (see below).
template <class T>
void GetEnumTraitsImpl(T);
+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;
+ }
+}
+
template <
class T,
- bool = std::is_enum<T>::value &&
- !std::is_convertible<T, int>::value &&
- !std::is_same<void, decltype(GetEnumTraitsImpl(T()))>::value
+ bool = IsEnumDomainSizeKnown<T>()
+>
+struct TEnumTraitsWithKnownDomain
+{ };
+
+template <
+ class T,
+ bool = std::is_enum_v<T> && !std::is_same_v<TEnumTraitsImpl<T>, void>
>
struct TEnumTraits
{
@@ -40,124 +58,122 @@ struct TEnumTraits
};
template <class T>
-struct TEnumTraits<T, true>
+struct TEnumTraitsWithKnownDomain<T, true>
{
- using TImpl = decltype(GetEnumTraitsImpl(T()));
- using TType = T;
- using TUnderlying = typename TImpl::TUnderlying;
-
- static constexpr bool IsEnum = true;
- static constexpr bool IsBitEnum = TImpl::IsBitEnum;
- static constexpr bool IsStringSerializableEnum = TImpl::IsStringSerializableEnum;
+ static constexpr int GetDomainSize();
- static constexpr int DomainSize = TImpl::DomainSize;
+ static constexpr const std::array<TStringBuf, GetDomainSize()>& GetDomainNames();
+ static constexpr const std::array<T, GetDomainSize()>& GetDomainValues();
- static TStringBuf GetTypeName();
+ // For non-bit enums only.
+ static constexpr T GetMinValue()
+ requires (!TEnumTraitsImpl<T>::IsBitEnum);
+ static constexpr T GetMaxValue()
+ requires (!TEnumTraitsImpl<T>::IsBitEnum);
- static const TStringBuf* FindLiteralByValue(TType value);
- static bool FindValueByLiteral(TStringBuf literal, TType* result);
+ // For bit enums only.
+ static std::vector<T> Decompose(T value)
+ requires (TEnumTraitsImpl<T>::IsBitEnum);
+};
- static const std::array<TStringBuf, DomainSize>& GetDomainNames();
- static const std::array<TType, DomainSize>& GetDomainValues();
+template <class T>
+struct TEnumTraits<T, true>
+ : public TEnumTraitsWithKnownDomain<T>
+{
+ static constexpr bool IsEnum = true;
+ static constexpr bool IsBitEnum = TEnumTraitsImpl<T>::IsBitEnum;
+ static constexpr bool IsStringSerializableEnum = TEnumTraitsImpl<T>::IsStringSerializableEnum;
- static TType FromString(TStringBuf str);
- static TString ToString(TType value);
+ static TStringBuf GetTypeName();
- // For non-bit enums only.
- static constexpr TType GetMinValue();
- static constexpr TType GetMaxValue();
+ static std::optional<TStringBuf> FindLiteralByValue(T value);
+ static std::optional<T> FindValueByLiteral(TStringBuf literal);
- // For bit enums only.
- static std::vector<TType> Decompose(TType value);
+ static TString ToString(T value);
+ static T FromString(TStringBuf literal);
};
////////////////////////////////////////////////////////////////////////////////
//! Defines a smart enumeration with a specific underlying type.
/*!
- * \param name Enumeration name.
+ * \param enumType Enumeration enumType.
* \param seq Enumeration domain encoded as a <em>sequence</em>.
* \param underlyingType Underlying type.
*/
-#define DEFINE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, false, false, seq) \
- ENUM__MINMAX \
- ENUM__VALIDATE_UNIQUE(name) \
- ENUM__END_TRAITS(name)
+#define DEFINE_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \
+ ENUM__CLASS(enumType, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(enumType, underlyingType, false, false, seq) \
+ ENUM__VALIDATE_UNIQUE(enumType) \
+ ENUM__END_TRAITS(enumType)
//! Defines a smart enumeration with a specific underlying type.
//! Duplicate enumeration values are allowed.
-#define DEFINE_AMBIGUOUS_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, false, false, seq) \
- ENUM__MINMAX \
- ENUM__END_TRAITS(name)
+#define DEFINE_AMBIGUOUS_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \
+ ENUM__CLASS(enumType, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(enumType, underlyingType, false, false, seq) \
+ ENUM__END_TRAITS(enumType)
//! Defines a smart enumeration with the default |int| underlying type.
-#define DEFINE_ENUM(name, seq) \
- DEFINE_ENUM_WITH_UNDERLYING_TYPE(name, int, seq)
+#define DEFINE_ENUM(enumType, seq) \
+ DEFINE_ENUM_WITH_UNDERLYING_TYPE(enumType, int, seq)
//! Defines a smart enumeration with a specific underlying type.
/*!
- * \param name Enumeration name.
+ * \param enumType Enumeration enumType.
* \param seq Enumeration domain encoded as a <em>sequence</em>.
* \param underlyingType Underlying type.
*/
-#define DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, true, false, seq) \
- ENUM__DECOMPOSE \
- ENUM__VALIDATE_UNIQUE(name) \
- ENUM__END_TRAITS(name) \
- ENUM__BITWISE_OPS(name)
+#define DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \
+ ENUM__CLASS(enumType, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(enumType, underlyingType, true, false, seq) \
+ ENUM__VALIDATE_UNIQUE(enumType) \
+ ENUM__END_TRAITS(enumType) \
+ ENUM__BITWISE_OPS(enumType)
//! Defines a smart enumeration with a specific underlying type.
//! Duplicate enumeration values are allowed.
/*!
- * \param name Enumeration name.
+ * \param enumType Enumeration enumType.
* \param seq Enumeration domain encoded as a <em>sequence</em>.
* \param underlyingType Underlying type.
*/
-#define DEFINE_AMBIGUOUS_BIT_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, true, false, seq) \
- ENUM__DECOMPOSE \
- ENUM__END_TRAITS(name) \
- ENUM__BITWISE_OPS(name)
-
-//! Defines a smart enumeration with the default |unsigned| underlying type.
+#define DEFINE_AMBIGUOUS_BIT_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \
+ ENUM__CLASS(enumType, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(enumType, underlyingType, true, false, seq) \
+ ENUM__END_TRAITS(enumType) \
+ ENUM__BITWISE_OPS(enumType)
+
+//! Defines a smart enumeration with the default |unsigned int| underlying type.
/*!
- * \param name Enumeration name.
+ * \param enumType Enumeration enumType.
* \param seq Enumeration domain encoded as a <em>sequence</em>.
*/
-#define DEFINE_BIT_ENUM(name, seq) \
- DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(name, unsigned, seq)
+#define DEFINE_BIT_ENUM(enumType, seq) \
+ DEFINE_BIT_ENUM_WITH_UNDERLYING_TYPE(enumType, unsigned int, seq)
//! Defines a smart enumeration with a specific underlying type and IsStringSerializable attribute.
/*!
- * \param name Enumeration name.
+ * \param enumType Enumeration enumType.
* \param seq Enumeration domain encoded as a <em>sequence</em>.
* \param underlyingType Underlying type.
*/
-#define DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, false, true, seq) \
- ENUM__MINMAX \
- ENUM__VALIDATE_UNIQUE(name) \
- ENUM__END_TRAITS(name) \
+#define DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \
+ ENUM__CLASS(enumType, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(enumType, underlyingType, false, true, seq) \
+ ENUM__VALIDATE_UNIQUE(enumType) \
+ ENUM__END_TRAITS(enumType) \
//! Defines a smart enumeration with a specific underlying type and IsStringSerializable attribute.
//! Duplicate enumeration values are allowed.
-#define DEFINE_AMBIGUOUS_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, underlyingType, seq) \
- ENUM__CLASS(name, underlyingType, seq) \
- ENUM__BEGIN_TRAITS(name, underlyingType, false, true, seq) \
- ENUM__MINMAX \
- ENUM__END_TRAITS(name)
+#define DEFINE_AMBIGUOUS_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(enumType, underlyingType, seq) \
+ ENUM__CLASS(enumType, underlyingType, seq) \
+ ENUM__BEGIN_TRAITS(enumType, underlyingType, false, true, seq) \
+ ENUM__END_TRAITS(enumType)
//! Defines a smart enumeration with the default |int| underlying type and IsStringSerializable attribute.
-#define DEFINE_STRING_SERIALIZABLE_ENUM(name, seq) \
- DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(name, int, seq)
+#define DEFINE_STRING_SERIALIZABLE_ENUM(enumType, seq) \
+ DEFINE_STRING_SERIALIZABLE_ENUM_WITH_UNDERLYING_TYPE(enumType, int, seq)
////////////////////////////////////////////////////////////////////////////////
@@ -199,20 +215,27 @@ public:
static bool IsDomainValue(E value);
private:
- using TUnderlying = typename TEnumTraits<E>::TUnderlying;
+ using TUnderlying = std::underlying_type_t<E>;
static constexpr int N = static_cast<TUnderlying>(Max) - static_cast<TUnderlying>(Min) + 1;
std::array<T, N> Items_;
};
////////////////////////////////////////////////////////////////////////////////
+//! Replace with |std::to_underlying| in C++23.
+template <typename E>
+ requires std::is_enum_v<E>
+constexpr std::underlying_type_t<E> ToUnderlying(E value) noexcept;
+
//! Returns |true| iff the enumeration value is not bitwise zero.
-template <typename E, typename = std::enable_if_t<NYT::TEnumTraits<E>::IsBitEnum, E>>
-bool Any(E value);
+template <typename E>
+ requires TEnumTraits<E>::IsBitEnum
+constexpr bool Any(E value) noexcept;
//! Returns |true| iff the enumeration value is bitwise zero.
-template <typename E, typename = std::enable_if_t<NYT::TEnumTraits<E>::IsBitEnum, E>>
-bool None(E value);
+template <typename E>
+ requires TEnumTraits<E>::IsBitEnum
+constexpr bool None(E value) noexcept;
////////////////////////////////////////////////////////////////////////////////