diff options
author | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2023-11-20 13:44:15 +0300 |
---|---|---|
committer | arkady-e1ppa <arkady-e1ppa@yandex-team.com> | 2023-11-20 15:45:50 +0300 |
commit | 7bca0d82d7ee4f4f2ea4ffe559da7e48265fae2c (patch) | |
tree | 626d31512ba244f9351934eb05b4f7d35503b635 | |
parent | cb92dabe792f1ce1ba168fdb3f5ad796736ab924 (diff) | |
download | ydb-7bca0d82d7ee4f4f2ea4ffe559da7e48265fae2c.tar.gz |
YT-19593: Constexpr friendliness in strong typedef plus TAllocationId uses it now
-rw-r--r-- | library/cpp/yt/misc/strong_typedef-inl.h | 45 | ||||
-rw-r--r-- | library/cpp/yt/misc/strong_typedef.h | 6 |
2 files changed, 45 insertions, 6 deletions
diff --git a/library/cpp/yt/misc/strong_typedef-inl.h b/library/cpp/yt/misc/strong_typedef-inl.h index 0a1bd9427a..59ff7cbce2 100644 --- a/library/cpp/yt/misc/strong_typedef-inl.h +++ b/library/cpp/yt/misc/strong_typedef-inl.h @@ -60,6 +60,32 @@ constexpr T&& TStrongTypedef<T, TTag>::Underlying() && return std::move(Underlying_); } +template <class T, class TTag> +constexpr bool TStrongTypedef<T, TTag>::operator==(const TStrongTypedef& rhs) const +noexcept(std::same_as<T, void> || noexcept(Underlying_ == rhs.Underlying_)) +{ + //! NB: We add a constexpr branch to keep constexprness of the function + //! without making extra specializations explicitly. + if constexpr (std::same_as<T, void>) { + return true; + } + + return Underlying_ == rhs.Underlying_; +} + +template <class T, class TTag> +constexpr auto TStrongTypedef<T, TTag>::operator<=>(const TStrongTypedef& rhs) const +noexcept(std::same_as<T, void> || noexcept(Underlying_ <=> rhs.Underlying_)) +{ + //! NB: We add a constexpr branch to keep constexprness of the function + //! without making extra specializations explicitly. + if constexpr (std::same_as<T, void>) { + return std::strong_ordering::equal; + } + + return Underlying_ <=> rhs.Underlying_; +} + //////////////////////////////////////////////////////////////////////////////// template <class T> @@ -117,13 +143,22 @@ struct hash<NYT::TStrongTypedef<T, TTag>> //////////////////////////////////////////////////////////////////////////////// -template <class T> -struct THash; - template <class T, class TTag> struct THash<NYT::TStrongTypedef<T, TTag>> - : public std::hash<NYT::TStrongTypedef<T, TTag>> -{ }; +{ + size_t operator()(const NYT::TStrongTypedef<T, TTag>& value) const + { + static constexpr bool IsTHashable = requires (T val) { + { THash<T>()(val) } -> std::same_as<size_t>; + }; + + if constexpr (IsTHashable) { + return THash<T>()(value.Underlying()); + } else { + return std::hash<T>()(value.Underlying()); + } + } +}; //////////////////////////////////////////////////////////////////////////////// diff --git a/library/cpp/yt/misc/strong_typedef.h b/library/cpp/yt/misc/strong_typedef.h index 545029db8d..d42f9e1f74 100644 --- a/library/cpp/yt/misc/strong_typedef.h +++ b/library/cpp/yt/misc/strong_typedef.h @@ -30,7 +30,11 @@ public: constexpr explicit operator const T&() const; constexpr explicit operator T&(); - constexpr auto operator<=>(const TStrongTypedef& rhs) const = default; + constexpr bool operator==(const TStrongTypedef& rhs) const + noexcept(std::same_as<T, void> || noexcept(Underlying_ == rhs.Underlying_)); + + constexpr auto operator<=>(const TStrongTypedef& rhs) const + noexcept(std::same_as<T, void> || noexcept(Underlying_ <=> rhs.Underlying_)); constexpr T& Underlying() &; constexpr const T& Underlying() const &; |