diff options
Diffstat (limited to 'abseil-cpp/absl/types/compare.h')
-rw-r--r-- | abseil-cpp/absl/types/compare.h | 145 |
1 files changed, 77 insertions, 68 deletions
diff --git a/abseil-cpp/absl/types/compare.h b/abseil-cpp/absl/types/compare.h index 3d6baa1..2b89b69 100644 --- a/abseil-cpp/absl/types/compare.h +++ b/abseil-cpp/absl/types/compare.h @@ -36,6 +36,7 @@ #include <type_traits> #include "absl/base/attributes.h" +#include "absl/base/macros.h" #include "absl/meta/type_traits.h" namespace absl { @@ -44,29 +45,37 @@ namespace compare_internal { using value_type = int8_t; -template <typename T> -struct Fail { - static_assert(sizeof(T) < 0, "Only literal `0` is allowed."); -}; - -// We need the NullPtrT template to avoid triggering the modernize-use-nullptr -// ClangTidy warning in user code. -template <typename NullPtrT = std::nullptr_t> -struct OnlyLiteralZero { - constexpr OnlyLiteralZero(NullPtrT) noexcept {} // NOLINT +class OnlyLiteralZero { + public: +#if ABSL_HAVE_ATTRIBUTE(enable_if) + // On clang, we can avoid triggering modernize-use-nullptr by only enabling + // this overload when the value is a compile time integer constant equal to 0. + // + // In c++20, this could be a static_assert in a consteval function. + constexpr OnlyLiteralZero(int n) // NOLINT + __attribute__((enable_if(n == 0, "Only literal `0` is allowed."))) {} +#else // ABSL_HAVE_ATTRIBUTE(enable_if) + // Accept only literal zero since it can be implicitly converted to a pointer + // to member type. nullptr constants will be caught by the other constructor + // which accepts a nullptr_t. + // + // This constructor is not used for clang since it triggers + // modernize-use-nullptr. + constexpr OnlyLiteralZero(int OnlyLiteralZero::*) noexcept {} // NOLINT +#endif // Fails compilation when `nullptr` or integral type arguments other than // `int` are passed. This constructor doesn't accept `int` because literal `0` // has type `int`. Literal `0` arguments will be implicitly converted to // `std::nullptr_t` and accepted by the above constructor, while other `int` // arguments will fail to be converted and cause compilation failure. - template < - typename T, - typename = typename std::enable_if< - std::is_same<T, std::nullptr_t>::value || - (std::is_integral<T>::value && !std::is_same<T, int>::value)>::type, - typename = typename Fail<T>::type> - OnlyLiteralZero(T); // NOLINT + template <typename T, typename = typename std::enable_if< + std::is_same<T, std::nullptr_t>::value || + (std::is_integral<T>::value && + !std::is_same<T, int>::value)>::type> + OnlyLiteralZero(T) { // NOLINT + static_assert(sizeof(T) < 0, "Only literal `0` is allowed."); + } }; enum class eq : value_type { @@ -163,18 +172,18 @@ class weak_equality // Comparisons friend constexpr bool operator==( - weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_equality v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ == 0; } friend constexpr bool operator!=( - weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_equality v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ != 0; } - friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator==(compare_internal::OnlyLiteralZero, weak_equality v) noexcept { return 0 == v.value_; } - friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator!=(compare_internal::OnlyLiteralZero, weak_equality v) noexcept { return 0 != v.value_; } @@ -214,18 +223,18 @@ class strong_equality } // Comparisons friend constexpr bool operator==( - strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_equality v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ == 0; } friend constexpr bool operator!=( - strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_equality v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ != 0; } - friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator==(compare_internal::OnlyLiteralZero, strong_equality v) noexcept { return 0 == v.value_; } - friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator!=(compare_internal::OnlyLiteralZero, strong_equality v) noexcept { return 0 != v.value_; } @@ -277,50 +286,50 @@ class partial_ordering } // Comparisons friend constexpr bool operator==( - partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + partial_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.is_ordered() && v.value_ == 0; } friend constexpr bool operator!=( - partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + partial_ordering v, compare_internal::OnlyLiteralZero) noexcept { return !v.is_ordered() || v.value_ != 0; } friend constexpr bool operator<( - partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + partial_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.is_ordered() && v.value_ < 0; } friend constexpr bool operator<=( - partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + partial_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.is_ordered() && v.value_ <= 0; } friend constexpr bool operator>( - partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + partial_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.is_ordered() && v.value_ > 0; } friend constexpr bool operator>=( - partial_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + partial_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.is_ordered() && v.value_ >= 0; } - friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator==(compare_internal::OnlyLiteralZero, partial_ordering v) noexcept { return v.is_ordered() && 0 == v.value_; } - friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator!=(compare_internal::OnlyLiteralZero, partial_ordering v) noexcept { return !v.is_ordered() || 0 != v.value_; } - friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator<(compare_internal::OnlyLiteralZero, partial_ordering v) noexcept { return v.is_ordered() && 0 < v.value_; } - friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator<=(compare_internal::OnlyLiteralZero, partial_ordering v) noexcept { return v.is_ordered() && 0 <= v.value_; } - friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator>(compare_internal::OnlyLiteralZero, partial_ordering v) noexcept { return v.is_ordered() && 0 > v.value_; } - friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator>=(compare_internal::OnlyLiteralZero, partial_ordering v) noexcept { return v.is_ordered() && 0 >= v.value_; } @@ -369,50 +378,50 @@ class weak_ordering } // Comparisons friend constexpr bool operator==( - weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ == 0; } friend constexpr bool operator!=( - weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ != 0; } friend constexpr bool operator<( - weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ < 0; } friend constexpr bool operator<=( - weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ <= 0; } friend constexpr bool operator>( - weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ > 0; } friend constexpr bool operator>=( - weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + weak_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ >= 0; } - friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator==(compare_internal::OnlyLiteralZero, weak_ordering v) noexcept { return 0 == v.value_; } - friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator!=(compare_internal::OnlyLiteralZero, weak_ordering v) noexcept { return 0 != v.value_; } - friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator<(compare_internal::OnlyLiteralZero, weak_ordering v) noexcept { return 0 < v.value_; } - friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator<=(compare_internal::OnlyLiteralZero, weak_ordering v) noexcept { return 0 <= v.value_; } - friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator>(compare_internal::OnlyLiteralZero, weak_ordering v) noexcept { return 0 > v.value_; } - friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator>=(compare_internal::OnlyLiteralZero, weak_ordering v) noexcept { return 0 >= v.value_; } @@ -468,50 +477,50 @@ class strong_ordering } // Comparisons friend constexpr bool operator==( - strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ == 0; } friend constexpr bool operator!=( - strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ != 0; } friend constexpr bool operator<( - strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ < 0; } friend constexpr bool operator<=( - strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ <= 0; } friend constexpr bool operator>( - strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ > 0; } friend constexpr bool operator>=( - strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { + strong_ordering v, compare_internal::OnlyLiteralZero) noexcept { return v.value_ >= 0; } - friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator==(compare_internal::OnlyLiteralZero, strong_ordering v) noexcept { return 0 == v.value_; } - friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator!=(compare_internal::OnlyLiteralZero, strong_ordering v) noexcept { return 0 != v.value_; } - friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator<(compare_internal::OnlyLiteralZero, strong_ordering v) noexcept { return 0 < v.value_; } - friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator<=(compare_internal::OnlyLiteralZero, strong_ordering v) noexcept { return 0 <= v.value_; } - friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator>(compare_internal::OnlyLiteralZero, strong_ordering v) noexcept { return 0 > v.value_; } - friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, + friend constexpr bool operator>=(compare_internal::OnlyLiteralZero, strong_ordering v) noexcept { return 0 >= v.value_; } @@ -544,9 +553,9 @@ namespace compare_internal { // Helper functions to do a boolean comparison of two keys given a boolean // or three-way comparator. // SFINAE prevents implicit conversions to bool (such as from int). -template <typename Bool, - absl::enable_if_t<std::is_same<bool, Bool>::value, int> = 0> -constexpr bool compare_result_as_less_than(const Bool r) { return r; } +template <typename BoolT, + absl::enable_if_t<std::is_same<bool, BoolT>::value, int> = 0> +constexpr bool compare_result_as_less_than(const BoolT r) { return r; } constexpr bool compare_result_as_less_than(const absl::weak_ordering r) { return r < 0; } @@ -574,8 +583,8 @@ constexpr absl::weak_ordering compare_result_as_ordering( template < typename Compare, typename K, typename LK, - absl::enable_if_t<!std::is_same<bool, std::invoke_result_t<Compare, - const K &, const LK &>>::value, + absl::enable_if_t<!std::is_same<bool, absl::result_of_t<Compare( + const K &, const LK &)>>::value, int> = 0> constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, const K &x, const LK &y) { @@ -583,8 +592,8 @@ constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, } template < typename Compare, typename K, typename LK, - absl::enable_if_t<std::is_same<bool, std::invoke_result_t<Compare, - const K &, const LK &>>::value, + absl::enable_if_t<std::is_same<bool, absl::result_of_t<Compare( + const K &, const LK &)>>::value, int> = 0> constexpr absl::weak_ordering do_three_way_comparison(const Compare &compare, const K &x, const LK &y) { |