Commit c98bd9c8 by Abseil Team Committed by Copybara-Service

Three-way comparison spaceship <=> operators for Cord.

This is portable because cord already has `operator<` etc., which will be unaffected. This just allows C++ >= 20 users to explicitly call `operator<=>`.

PiperOrigin-RevId: 646951415
Change-Id: I1432e224bd5dc09b99d56a1d27e95078463adf45
parent 3ff94461
...@@ -600,6 +600,7 @@ cc_library( ...@@ -600,6 +600,7 @@ cc_library(
"//absl/functional:function_ref", "//absl/functional:function_ref",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits", "//absl/numeric:bits",
"//absl/types:compare",
"//absl/types:optional", "//absl/types:optional",
"//absl/types:span", "//absl/types:span",
], ],
...@@ -925,6 +926,7 @@ cc_test( ...@@ -925,6 +926,7 @@ cc_test(
"//absl/log", "//absl/log",
"//absl/log:check", "//absl/log:check",
"//absl/random", "//absl/random",
"//absl/types:compare",
"//absl/types:optional", "//absl/types:optional",
"@com_google_googletest//:gtest", "@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
......
...@@ -705,6 +705,7 @@ absl_cc_library( ...@@ -705,6 +705,7 @@ absl_cc_library(
absl::compressed_tuple absl::compressed_tuple
absl::config absl::config
absl::container_memory absl::container_memory
absl::compare
absl::core_headers absl::core_headers
absl::crc_cord_state absl::crc_cord_state
absl::endian absl::endian
......
...@@ -96,6 +96,7 @@ ...@@ -96,6 +96,7 @@
#include "absl/strings/internal/resize_uninitialized.h" #include "absl/strings/internal/resize_uninitialized.h"
#include "absl/strings/internal/string_constant.h" #include "absl/strings/internal/string_constant.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/compare.h"
#include "absl/types/optional.h" #include "absl/types/optional.h"
namespace absl { namespace absl {
...@@ -849,6 +850,38 @@ class Cord { ...@@ -849,6 +850,38 @@ class Cord {
friend bool operator==(const Cord& lhs, const Cord& rhs); friend bool operator==(const Cord& lhs, const Cord& rhs);
friend bool operator==(const Cord& lhs, absl::string_view rhs); friend bool operator==(const Cord& lhs, absl::string_view rhs);
#ifdef __cpp_impl_three_way_comparison
// Cords support comparison with other Cords and string_views via operator<
// and others; here we provide a wrapper for the C++20 three-way comparison
// <=> operator.
static inline std::strong_ordering ConvertCompareResultToStrongOrdering(
int c) {
if (c == 0) {
return std::strong_ordering::equal;
} else if (c < 0) {
return std::strong_ordering::less;
} else {
return std::strong_ordering::greater;
}
}
friend inline std::strong_ordering operator<=>(const Cord& x, const Cord& y) {
return ConvertCompareResultToStrongOrdering(x.Compare(y));
}
friend inline std::strong_ordering operator<=>(const Cord& lhs,
absl::string_view rhs) {
return ConvertCompareResultToStrongOrdering(lhs.Compare(rhs));
}
friend inline std::strong_ordering operator<=>(absl::string_view lhs,
const Cord& rhs) {
return ConvertCompareResultToStrongOrdering(-rhs.Compare(lhs));
}
#endif
friend absl::Nullable<const CordzInfo*> GetCordzInfoForTesting( friend absl::Nullable<const CordzInfo*> GetCordzInfoForTesting(
const Cord& cord); const Cord& cord);
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h" #include "absl/strings/str_format.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "absl/types/compare.h"
#include "absl/types/optional.h" #include "absl/types/optional.h"
// convenience local constants // convenience local constants
...@@ -3283,6 +3284,31 @@ TEST(CrcCordTest, ChecksummedEmptyCordEstimateMemoryUsage) { ...@@ -3283,6 +3284,31 @@ TEST(CrcCordTest, ChecksummedEmptyCordEstimateMemoryUsage) {
EXPECT_NE(cord.EstimatedMemoryUsage(), 0); EXPECT_NE(cord.EstimatedMemoryUsage(), 0);
} }
TEST(CordThreeWayComparisonTest, CompareCords) {
#ifndef __cpp_impl_three_way_comparison
GTEST_SKIP() << "C++20 three-way <=> comparison not supported";
#else
EXPECT_EQ(absl::Cord("a") <=> absl::Cord("a"), std::strong_ordering::equal);
EXPECT_EQ(absl::Cord("aaaa") <=> absl::Cord("aaab"),
std::strong_ordering::less);
EXPECT_EQ(absl::Cord("baaa") <=> absl::Cord("a"),
std::strong_ordering::greater);
#endif
}
TEST(CordThreeWayComparisonTest, CompareCordsAndStringViews) {
#ifndef __cpp_impl_three_way_comparison
GTEST_SKIP() << "C++20 three-way <=> comparison not supported";
#else
EXPECT_EQ(absl::string_view("a") <=> absl::Cord("a"),
std::strong_ordering::equal);
EXPECT_EQ(absl::Cord("a") <=> absl::string_view("b"),
std::strong_ordering::less);
EXPECT_EQ(absl::string_view("b") <=> absl::Cord("a"),
std::strong_ordering::greater);
#endif
}
#if defined(GTEST_HAS_DEATH_TEST) && defined(ABSL_INTERNAL_CORD_HAVE_SANITIZER) #if defined(GTEST_HAS_DEATH_TEST) && defined(ABSL_INTERNAL_CORD_HAVE_SANITIZER)
// Returns an expected poison / uninitialized death message expression. // Returns an expected poison / uninitialized death message expression.
......
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