Commit 2de126cc by Abseil Team Committed by Copybara-Service

Change implementation of OnlyLiteralZero to only fail if the second overload is…

Change implementation of OnlyLiteralZero to only fail if the second overload is chosen, not in overload resolution.

PiperOrigin-RevId: 508031321
Change-Id: I6981371fbc6498047babe3468f3343090f8bda47
parent f8fa267e
...@@ -44,29 +44,28 @@ namespace compare_internal { ...@@ -44,29 +44,28 @@ namespace compare_internal {
using value_type = int8_t; using value_type = int8_t;
template <typename T> class OnlyLiteralZero {
struct Fail { // A private type which cannot be named to explicitly cast to it.
static_assert(sizeof(T) < 0, "Only literal `0` is allowed."); struct MatchLiteralZero;
};
// We need the NullPtrT template to avoid triggering the modernize-use-nullptr public:
// ClangTidy warning in user code. // Accept only literal zero since it can be implicitly converted to a pointer
template <typename NullPtrT = std::nullptr_t> // type. nullptr constants will be caught by the other constructor which
struct OnlyLiteralZero { // accepts a nullptr_t.
constexpr OnlyLiteralZero(NullPtrT) noexcept {} // NOLINT constexpr OnlyLiteralZero(MatchLiteralZero *) noexcept {} // NOLINT
// Fails compilation when `nullptr` or integral type arguments other than // Fails compilation when `nullptr` or integral type arguments other than
// `int` are passed. This constructor doesn't accept `int` because literal `0` // `int` are passed. This constructor doesn't accept `int` because literal `0`
// has type `int`. Literal `0` arguments will be implicitly converted to // has type `int`. Literal `0` arguments will be implicitly converted to
// `std::nullptr_t` and accepted by the above constructor, while other `int` // `std::nullptr_t` and accepted by the above constructor, while other `int`
// arguments will fail to be converted and cause compilation failure. // arguments will fail to be converted and cause compilation failure.
template < template <typename T, typename = typename std::enable_if<
typename T,
typename = typename std::enable_if<
std::is_same<T, std::nullptr_t>::value || std::is_same<T, std::nullptr_t>::value ||
(std::is_integral<T>::value && !std::is_same<T, int>::value)>::type, (std::is_integral<T>::value &&
typename = typename Fail<T>::type> !std::is_same<T, int>::value)>::type>
OnlyLiteralZero(T); // NOLINT OnlyLiteralZero(T) { // NOLINT
static_assert(sizeof(T) < 0, "Only literal `0` is allowed.");
}
}; };
enum class eq : value_type { enum class eq : value_type {
...@@ -163,18 +162,18 @@ class weak_equality ...@@ -163,18 +162,18 @@ class weak_equality
// Comparisons // Comparisons
friend constexpr bool operator==( friend constexpr bool operator==(
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { weak_equality v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ == 0; return v.value_ == 0;
} }
friend constexpr bool operator!=( friend constexpr bool operator!=(
weak_equality v, compare_internal::OnlyLiteralZero<>) noexcept { weak_equality v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ != 0; return v.value_ != 0;
} }
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
weak_equality v) noexcept { weak_equality v) noexcept {
return 0 == v.value_; return 0 == v.value_;
} }
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
weak_equality v) noexcept { weak_equality v) noexcept {
return 0 != v.value_; return 0 != v.value_;
} }
...@@ -214,18 +213,18 @@ class strong_equality ...@@ -214,18 +213,18 @@ class strong_equality
} }
// Comparisons // Comparisons
friend constexpr bool operator==( friend constexpr bool operator==(
strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept { strong_equality v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ == 0; return v.value_ == 0;
} }
friend constexpr bool operator!=( friend constexpr bool operator!=(
strong_equality v, compare_internal::OnlyLiteralZero<>) noexcept { strong_equality v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ != 0; return v.value_ != 0;
} }
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
strong_equality v) noexcept { strong_equality v) noexcept {
return 0 == v.value_; return 0 == v.value_;
} }
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
strong_equality v) noexcept { strong_equality v) noexcept {
return 0 != v.value_; return 0 != v.value_;
} }
...@@ -277,50 +276,50 @@ class partial_ordering ...@@ -277,50 +276,50 @@ class partial_ordering
} }
// Comparisons // Comparisons
friend constexpr bool operator==( 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; return v.is_ordered() && v.value_ == 0;
} }
friend constexpr bool operator!=( 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; return !v.is_ordered() || v.value_ != 0;
} }
friend constexpr bool operator<( 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; return v.is_ordered() && v.value_ < 0;
} }
friend constexpr bool operator<=( 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; return v.is_ordered() && v.value_ <= 0;
} }
friend constexpr bool operator>( 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; return v.is_ordered() && v.value_ > 0;
} }
friend constexpr bool operator>=( 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; 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 { partial_ordering v) noexcept {
return v.is_ordered() && 0 == v.value_; 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 { partial_ordering v) noexcept {
return !v.is_ordered() || 0 != v.value_; 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 { partial_ordering v) noexcept {
return v.is_ordered() && 0 < v.value_; 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 { partial_ordering v) noexcept {
return v.is_ordered() && 0 <= v.value_; 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 { partial_ordering v) noexcept {
return v.is_ordered() && 0 > v.value_; 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 { partial_ordering v) noexcept {
return v.is_ordered() && 0 >= v.value_; return v.is_ordered() && 0 >= v.value_;
} }
...@@ -369,50 +368,50 @@ class weak_ordering ...@@ -369,50 +368,50 @@ class weak_ordering
} }
// Comparisons // Comparisons
friend constexpr bool operator==( friend constexpr bool operator==(
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ == 0; return v.value_ == 0;
} }
friend constexpr bool operator!=( friend constexpr bool operator!=(
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ != 0; return v.value_ != 0;
} }
friend constexpr bool operator<( friend constexpr bool operator<(
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ < 0; return v.value_ < 0;
} }
friend constexpr bool operator<=( friend constexpr bool operator<=(
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ <= 0; return v.value_ <= 0;
} }
friend constexpr bool operator>( friend constexpr bool operator>(
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ > 0; return v.value_ > 0;
} }
friend constexpr bool operator>=( friend constexpr bool operator>=(
weak_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { weak_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ >= 0; return v.value_ >= 0;
} }
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
weak_ordering v) noexcept { weak_ordering v) noexcept {
return 0 == v.value_; return 0 == v.value_;
} }
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
weak_ordering v) noexcept { weak_ordering v) noexcept {
return 0 != v.value_; return 0 != v.value_;
} }
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
weak_ordering v) noexcept { weak_ordering v) noexcept {
return 0 < v.value_; return 0 < v.value_;
} }
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
weak_ordering v) noexcept { weak_ordering v) noexcept {
return 0 <= v.value_; return 0 <= v.value_;
} }
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
weak_ordering v) noexcept { weak_ordering v) noexcept {
return 0 > v.value_; return 0 > v.value_;
} }
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
weak_ordering v) noexcept { weak_ordering v) noexcept {
return 0 >= v.value_; return 0 >= v.value_;
} }
...@@ -468,50 +467,50 @@ class strong_ordering ...@@ -468,50 +467,50 @@ class strong_ordering
} }
// Comparisons // Comparisons
friend constexpr bool operator==( friend constexpr bool operator==(
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ == 0; return v.value_ == 0;
} }
friend constexpr bool operator!=( friend constexpr bool operator!=(
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ != 0; return v.value_ != 0;
} }
friend constexpr bool operator<( friend constexpr bool operator<(
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ < 0; return v.value_ < 0;
} }
friend constexpr bool operator<=( friend constexpr bool operator<=(
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ <= 0; return v.value_ <= 0;
} }
friend constexpr bool operator>( friend constexpr bool operator>(
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ > 0; return v.value_ > 0;
} }
friend constexpr bool operator>=( friend constexpr bool operator>=(
strong_ordering v, compare_internal::OnlyLiteralZero<>) noexcept { strong_ordering v, compare_internal::OnlyLiteralZero) noexcept {
return v.value_ >= 0; return v.value_ >= 0;
} }
friend constexpr bool operator==(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
strong_ordering v) noexcept { strong_ordering v) noexcept {
return 0 == v.value_; return 0 == v.value_;
} }
friend constexpr bool operator!=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
strong_ordering v) noexcept { strong_ordering v) noexcept {
return 0 != v.value_; return 0 != v.value_;
} }
friend constexpr bool operator<(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator<(compare_internal::OnlyLiteralZero,
strong_ordering v) noexcept { strong_ordering v) noexcept {
return 0 < v.value_; return 0 < v.value_;
} }
friend constexpr bool operator<=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator<=(compare_internal::OnlyLiteralZero,
strong_ordering v) noexcept { strong_ordering v) noexcept {
return 0 <= v.value_; return 0 <= v.value_;
} }
friend constexpr bool operator>(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator>(compare_internal::OnlyLiteralZero,
strong_ordering v) noexcept { strong_ordering v) noexcept {
return 0 > v.value_; return 0 > v.value_;
} }
friend constexpr bool operator>=(compare_internal::OnlyLiteralZero<>, friend constexpr bool operator>=(compare_internal::OnlyLiteralZero,
strong_ordering v) noexcept { strong_ordering v) noexcept {
return 0 >= v.value_; return 0 >= v.value_;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment