diff options
Diffstat (limited to 'absl/types/compare.h')
-rw-r--r-- | absl/types/compare.h | 182 |
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. |