diff options
author | babenko <babenko@yandex-team.com> | 2024-11-16 20:38:23 +0300 |
---|---|---|
committer | babenko <babenko@yandex-team.com> | 2024-11-16 20:48:13 +0300 |
commit | e0ece3a670de1090fcb097575f087364742a9ef6 (patch) | |
tree | ffd23facff0d9a46b0b4cc9319e04fd81d95ca1b /library/cpp/yt/misc/cast-inl.h | |
parent | 7b47721c45973354fb158e64e2f14edc6fd41f52 (diff) | |
download | ydb-e0ece3a670de1090fcb097575f087364742a9ef6.tar.gz |
YT-22885: Handle unknown values in (Try)CheckedEnumCast
commit_hash:5ce8019253cdb971d1af36350e3efa3a4ec8545c
Diffstat (limited to 'library/cpp/yt/misc/cast-inl.h')
-rw-r--r-- | library/cpp/yt/misc/cast-inl.h | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/library/cpp/yt/misc/cast-inl.h b/library/cpp/yt/misc/cast-inl.h index 50920f0193..5e5a0d90ee 100644 --- a/library/cpp/yt/misc/cast-inl.h +++ b/library/cpp/yt/misc/cast-inl.h @@ -119,7 +119,7 @@ T CheckedIntegralCast(S value) template <class T, class S> requires TEnumTraits<T>::IsEnum -constexpr std::optional<T> TryCheckedEnumCast(S value) +constexpr std::optional<T> TryCheckedEnumCast(S value, bool enableUnknown) { auto underlying = TryCheckedIntegralCast<std::underlying_type_t<T>>(value); [[unlikely]] if (!underlying) { @@ -127,6 +127,15 @@ constexpr std::optional<T> TryCheckedEnumCast(S value) } auto candidate = static_cast<T>(*underlying); [[unlikely]] if (!TEnumTraits<T>::IsValidValue(candidate)) { + if (enableUnknown) { + if constexpr (constexpr auto optionalUnknownValue = TEnumTraits<T>::TryGetUnknownValue()) { + if constexpr (TEnumTraits<T>::IsBitEnum) { + return static_cast<T>(*underlying & ToUnderlying(TEnumTraits<T>::GetAllSetValue())) | *optionalUnknownValue; + } else { + return *optionalUnknownValue; + } + } + } return std::nullopt; } return candidate; @@ -136,7 +145,7 @@ template <class T, class S> requires TEnumTraits<T>::IsEnum T CheckedEnumCast(S value) { - auto result = TryCheckedEnumCast<T>(value); + auto result = TryCheckedEnumCast<T>(value, /*enableUnknown*/ true); [[unlikely]] if (!result) { if constexpr (std::is_signed_v<S>) { throw TSimpleException(Sprintf("Error casting %s value \"%" PRIi64 "\" to enum %s", |