diff options
author | swarmer <swarmer@yandex-team.com> | 2025-03-26 00:18:03 +0300 |
---|---|---|
committer | swarmer <swarmer@yandex-team.com> | 2025-03-26 00:42:48 +0300 |
commit | 8ae7402454c6eeaeb2c7d2c58d401acd51a864f6 (patch) | |
tree | 42158fa19044c0c195b4375b5375964548c4aa1b | |
parent | de900c3367e4ffb43d51b072c370ee6413f93be9 (diff) | |
download | ydb-8ae7402454c6eeaeb2c7d2c58d401acd51a864f6.tar.gz |
[util] SafeIntegerCast: make fast path slightly faster & reduce code size
commit_hash:8adef8417b7bb90754f71cf0a5be075dee84a718
-rw-r--r-- | util/generic/cast.h | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/util/generic/cast.h b/util/generic/cast.h index 882f2ca08fb..69c9471be82 100644 --- a/util/generic/cast.h +++ b/util/generic/cast.h @@ -104,6 +104,14 @@ namespace NPrivate { ((std::is_signed<TSmallInt>::value == std::is_signed<TLargeInt>::value && sizeof(TSmallInt) >= sizeof(TLargeInt)) || (std::is_signed<TSmallInt>::value && sizeof(TSmallInt) > sizeof(TLargeInt))); }; + + template <class TLargeInt> + [[noreturn]] void ThrowBadIntegerCast(const TLargeInt largeInt, const std::type_info& smallIntType, const TStringBuf reason) { + ythrow TBadCastException() << "Conversion '" << TypeName<TLargeInt>() << '{' << largeInt << "}' to '" + << TypeName(smallIntType) + << "', " << reason; + } + } // namespace NPrivate template <class TSmallInt, class TLargeInt> @@ -116,27 +124,22 @@ inline std::enable_if_t<!::NPrivate::TSafelyConvertible<TSmall, TLarge>::Result, using TSmallInt = ::NPrivate::TUnderlyingTypeOrSelf<TSmall>; using TLargeInt = ::NPrivate::TUnderlyingTypeOrSelf<TLarge>; - if (std::is_unsigned<TSmallInt>::value && std::is_signed<TLargeInt>::value) { + if constexpr (std::is_unsigned<TSmallInt>::value && std::is_signed<TLargeInt>::value) { if (IsNegative(largeInt)) { - ythrow TBadCastException() << "Conversion '" << TypeName<TLarge>() << '{' << TLargeInt(largeInt) << "}' to '" - << TypeName<TSmallInt>() - << "', negative value converted to unsigned"; + ::NPrivate::ThrowBadIntegerCast(TLargeInt(largeInt), typeid(TSmallInt), "negative value converted to unsigned"sv); } } TSmallInt smallInt = TSmallInt(largeInt); - if (std::is_signed<TSmallInt>::value && std::is_unsigned<TLargeInt>::value) { + if constexpr (std::is_signed<TSmallInt>::value && std::is_unsigned<TLargeInt>::value) { if (IsNegative(smallInt)) { - ythrow TBadCastException() << "Conversion '" << TypeName<TLarge>() << '{' << TLargeInt(largeInt) << "}' to '" - << TypeName<TSmallInt>() - << "', positive value converted to negative"; + ::NPrivate::ThrowBadIntegerCast(TLargeInt(largeInt), typeid(TSmallInt), "positive value converted to negative"sv); } } if (TLargeInt(smallInt) != largeInt) { - ythrow TBadCastException() << "Conversion '" << TypeName<TLarge>() << '{' << TLargeInt(largeInt) << "}' to '" - << TypeName<TSmallInt>() << "', loss of data"; + ::NPrivate::ThrowBadIntegerCast(TLargeInt(largeInt), typeid(TSmallInt), "loss of data"sv); } return static_cast<TSmall>(smallInt); |