aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/misc/cast-inl.h
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.com>2024-11-16 20:38:23 +0300
committerbabenko <babenko@yandex-team.com>2024-11-16 20:48:13 +0300
commite0ece3a670de1090fcb097575f087364742a9ef6 (patch)
treeffd23facff0d9a46b0b4cc9319e04fd81d95ca1b /library/cpp/yt/misc/cast-inl.h
parent7b47721c45973354fb158e64e2f14edc6fd41f52 (diff)
downloadydb-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.h13
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",