summaryrefslogtreecommitdiff
path: root/abseil-cpp/absl/types/compare.h
diff options
context:
space:
mode:
Diffstat (limited to 'abseil-cpp/absl/types/compare.h')
-rw-r--r--abseil-cpp/absl/types/compare.h145
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) {