aboutsummaryrefslogtreecommitdiff
path: root/absl/types/compare.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/types/compare.h')
-rw-r--r--absl/types/compare.h182
1 files changed, 44 insertions, 138 deletions
diff --git a/absl/types/compare.h b/absl/types/compare.h
index 1a965e97..3cf4a917 100644
--- a/absl/types/compare.h
+++ b/absl/types/compare.h
@@ -16,43 +16,75 @@
// compare.h
// -----------------------------------------------------------------------------
//
-// This header file defines the `absl::weak_equality`, `absl::strong_equality`,
-// `absl::partial_ordering`, `absl::weak_ordering`, and `absl::strong_ordering`
-// types for storing the results of three way comparisons.
+// This header file defines the `absl::partial_ordering`, `absl::weak_ordering`,
+// and `absl::strong_ordering` types for storing the results of three way
+// comparisons.
//
// Example:
// absl::weak_ordering compare(const std::string& a, const std::string& b);
//
// These are C++11 compatible versions of the C++20 corresponding types
-// (`std::weak_equality`, etc.) and are designed to be drop-in replacements
+// (`std::partial_ordering`, etc.) and are designed to be drop-in replacements
// for code compliant with C++20.
#ifndef ABSL_TYPES_COMPARE_H_
#define ABSL_TYPES_COMPARE_H_
+#include "absl/base/config.h"
+
+#ifdef ABSL_USES_STD_ORDERING
+
+#include <compare> // IWYU pragma: export
+#include <type_traits>
+
+#include "absl/meta/type_traits.h"
+
+#else
+
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <type_traits>
#include "absl/base/attributes.h"
+#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
+
+#ifdef ABSL_USES_STD_ORDERING
+
+using std::partial_ordering;
+using std::strong_ordering;
+using std::weak_ordering;
+
+#else
+
namespace compare_internal {
using value_type = int8_t;
class OnlyLiteralZero {
- // A private type which cannot be named to explicitly cast to it.
- struct MatchLiteralZero;
-
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
- // type. nullptr constants will be caught by the other constructor which
- // accepts a nullptr_t.
- constexpr OnlyLiteralZero(MatchLiteralZero *) noexcept {} // NOLINT
+ // 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`
@@ -112,20 +144,6 @@ enum class ncmp : value_type { unordered = -127 };
// in the header file (for performance) without using inline variables (which
// aren't available in C++11).
template <typename T>
-struct weak_equality_base {
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequivalent);
-};
-
-template <typename T>
-struct strong_equality_base {
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequal);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(nonequivalent);
-};
-
-template <typename T>
struct partial_ordering_base {
ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
@@ -150,104 +168,6 @@ struct strong_ordering_base {
} // namespace compare_internal
-class weak_equality
- : public compare_internal::weak_equality_base<weak_equality> {
- explicit constexpr weak_equality(compare_internal::eq v) noexcept
- : value_(static_cast<compare_internal::value_type>(v)) {}
- friend struct compare_internal::weak_equality_base<weak_equality>;
-
- public:
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_equality, equivalent);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_equality, nonequivalent);
-
- // Comparisons
- friend constexpr bool operator==(
- weak_equality v, compare_internal::OnlyLiteralZero) noexcept {
- return v.value_ == 0;
- }
- friend constexpr bool operator!=(
- weak_equality v, compare_internal::OnlyLiteralZero) noexcept {
- return v.value_ != 0;
- }
- friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
- weak_equality v) noexcept {
- return 0 == v.value_;
- }
- friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
- weak_equality v) noexcept {
- return 0 != v.value_;
- }
- friend constexpr bool operator==(weak_equality v1,
- weak_equality v2) noexcept {
- return v1.value_ == v2.value_;
- }
- friend constexpr bool operator!=(weak_equality v1,
- weak_equality v2) noexcept {
- return v1.value_ != v2.value_;
- }
-
- private:
- compare_internal::value_type value_;
-};
-ABSL_COMPARE_INLINE_INIT(weak_equality, equivalent,
- compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(weak_equality, nonequivalent,
- compare_internal::eq::nonequivalent);
-
-class strong_equality
- : public compare_internal::strong_equality_base<strong_equality> {
- explicit constexpr strong_equality(compare_internal::eq v) noexcept
- : value_(static_cast<compare_internal::value_type>(v)) {}
- friend struct compare_internal::strong_equality_base<strong_equality>;
-
- public:
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, equal);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, nonequal);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, equivalent);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_equality, nonequivalent);
-
- // Conversion
- constexpr operator weak_equality() const noexcept { // NOLINT
- return value_ == 0 ? weak_equality::equivalent
- : weak_equality::nonequivalent;
- }
- // Comparisons
- friend constexpr bool operator==(
- strong_equality v, compare_internal::OnlyLiteralZero) noexcept {
- return v.value_ == 0;
- }
- friend constexpr bool operator!=(
- strong_equality v, compare_internal::OnlyLiteralZero) noexcept {
- return v.value_ != 0;
- }
- friend constexpr bool operator==(compare_internal::OnlyLiteralZero,
- strong_equality v) noexcept {
- return 0 == v.value_;
- }
- friend constexpr bool operator!=(compare_internal::OnlyLiteralZero,
- strong_equality v) noexcept {
- return 0 != v.value_;
- }
- friend constexpr bool operator==(strong_equality v1,
- strong_equality v2) noexcept {
- return v1.value_ == v2.value_;
- }
- friend constexpr bool operator!=(strong_equality v1,
- strong_equality v2) noexcept {
- return v1.value_ != v2.value_;
- }
-
- private:
- compare_internal::value_type value_;
-};
-ABSL_COMPARE_INLINE_INIT(strong_equality, equal, compare_internal::eq::equal);
-ABSL_COMPARE_INLINE_INIT(strong_equality, nonequal,
- compare_internal::eq::nonequal);
-ABSL_COMPARE_INLINE_INIT(strong_equality, equivalent,
- compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(strong_equality, nonequivalent,
- compare_internal::eq::nonequivalent);
-
class partial_ordering
: public compare_internal::partial_ordering_base<partial_ordering> {
explicit constexpr partial_ordering(compare_internal::eq v) noexcept
@@ -269,11 +189,6 @@ class partial_ordering
ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater);
ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered);
- // Conversion
- constexpr operator weak_equality() const noexcept { // NOLINT
- return value_ == 0 ? weak_equality::equivalent
- : weak_equality::nonequivalent;
- }
// Comparisons
friend constexpr bool operator==(
partial_ordering v, compare_internal::OnlyLiteralZero) noexcept {
@@ -357,10 +272,6 @@ class weak_ordering
ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater);
// Conversions
- constexpr operator weak_equality() const noexcept { // NOLINT
- return value_ == 0 ? weak_equality::equivalent
- : weak_equality::nonequivalent;
- }
constexpr operator partial_ordering() const noexcept { // NOLINT
return value_ == 0 ? partial_ordering::equivalent
: (value_ < 0 ? partial_ordering::less
@@ -448,13 +359,6 @@ class strong_ordering
ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater);
// Conversions
- constexpr operator weak_equality() const noexcept { // NOLINT
- return value_ == 0 ? weak_equality::equivalent
- : weak_equality::nonequivalent;
- }
- constexpr operator strong_equality() const noexcept { // NOLINT
- return value_ == 0 ? strong_equality::equal : strong_equality::nonequal;
- }
constexpr operator partial_ordering() const noexcept { // NOLINT
return value_ == 0 ? partial_ordering::equivalent
: (value_ < 0 ? partial_ordering::less
@@ -537,6 +441,8 @@ ABSL_COMPARE_INLINE_INIT(strong_ordering, greater,
#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL
#undef ABSL_COMPARE_INLINE_INIT
+#endif // ABSL_USES_STD_ORDERING
+
namespace compare_internal {
// We also provide these comparator adapter functions for internal absl use.