summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Marcin Kowalczyk <qrczak@google.com>2023-12-05 08:47:14 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-12-05 08:48:09 -0800
commitf845e60acd880dbf07788a5a2c0dbad0f9c57231 (patch)
tree004d2977ebac75185dc68e0e675a5fc6ef118ea0
parent7b6c17e378224844d8663a410da2da5353b205b9 (diff)
Make `absl::{partial,weak,strong}_ordering` aliases for the `std::` ordering
types when they are available. This makes them interchangeable in contexts known to be compiled as C++20. This also makes `absl::` ordering types compatible with `<=>`, allowing to unconditionally use `absl::` spelling for types but conditionally use `<=>` when available. PiperOrigin-RevId: 588085408 Change-Id: I1aa5247f0e31acbb838ee76829b7a13c74b0a94f
-rw-r--r--absl/base/config.h32
-rw-r--r--absl/base/options.h26
-rw-r--r--absl/types/BUILD.bazel1
-rw-r--r--absl/types/CMakeLists.txt1
-rw-r--r--absl/types/compare.h24
-rw-r--r--ci/absl_alternate_options.h1
6 files changed, 85 insertions, 0 deletions
diff --git a/absl/base/config.h b/absl/base/config.h
index b0e7fe8b..0fb66927 100644
--- a/absl/base/config.h
+++ b/absl/base/config.h
@@ -609,6 +609,22 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_STD_STRING_VIEW 1
#endif
+// ABSL_HAVE_STD_ORDERING
+//
+// Checks whether C++20 std::{partial,weak,strong}_ordering are available.
+//
+// __cpp_lib_three_way_comparison is missing on libc++
+// (https://github.com/llvm/llvm-project/issues/73953) so treat it as defined
+// when building in C++20 mode.
+#ifdef ABSL_HAVE_STD_ORDERING
+#error "ABSL_HAVE_STD_ORDERING cannot be directly set."
+#elif (defined(__cpp_lib_three_way_comparison) && \
+ __cpp_lib_three_way_comparison >= 201907L) || \
+ (defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
+ ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L)
+#define ABSL_HAVE_STD_ORDERING 1
+#endif
+
// ABSL_USES_STD_ANY
//
// Indicates whether absl::any is an alias for std::any.
@@ -671,6 +687,22 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#error options.h is misconfigured.
#endif
+// ABSL_USES_STD_ORDERING
+//
+// Indicates whether absl::{partial,weak,strong}_ordering are aliases for the
+// std:: ordering types.
+#if !defined(ABSL_OPTION_USE_STD_ORDERING)
+#error options.h is misconfigured.
+#elif ABSL_OPTION_USE_STD_ORDERING == 0 || \
+ (ABSL_OPTION_USE_STD_ORDERING == 2 && !defined(ABSL_HAVE_STD_ORDERING))
+#undef ABSL_USES_STD_ORDERING
+#elif ABSL_OPTION_USE_STD_ORDERING == 1 || \
+ (ABSL_OPTION_USE_STD_ORDERING == 2 && defined(ABSL_HAVE_STD_ORDERING))
+#define ABSL_USES_STD_ORDERING 1
+#else
+#error options.h is misconfigured.
+#endif
+
// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION
// SEH exception from emplace for variant<SomeStruct> when constructing the
// struct can throw. This defeats some of variant_test and
diff --git a/absl/base/options.h b/absl/base/options.h
index 5c162a38..a169658f 100644
--- a/absl/base/options.h
+++ b/absl/base/options.h
@@ -176,6 +176,32 @@
#define ABSL_OPTION_USE_STD_VARIANT 2
+// ABSL_OPTION_USE_STD_ORDERING
+//
+// This option controls whether absl::{partial,weak,strong}_ordering are
+// implemented as aliases to the std:: ordering types, or as an independent
+// implementation.
+//
+// A value of 0 means to use Abseil's implementation. This requires only C++11
+// support, and is expected to work on every toolchain we support.
+//
+// A value of 1 means to use aliases. This requires that all code using Abseil
+// is built in C++20 mode or later.
+//
+// A value of 2 means to detect the C++ version being used to compile Abseil,
+// and use an alias only if working std:: ordering types are available. This
+// option is useful when you are building your program from source. It should
+// not be used otherwise -- for example, if you are distributing Abseil in a
+// binary package manager -- since in mode 2, they will name different types,
+// with different mangled names and binary layout, depending on the compiler
+// flags passed by the end user. For more info, see
+// https://abseil.io/about/design/dropin-types.
+//
+// User code should not inspect this macro. To check in the preprocessor if
+// the ordering types are aliases of std:: ordering types, use the feature macro
+// ABSL_USES_STD_ORDERING.
+
+#define ABSL_OPTION_USE_STD_ORDERING 2
// ABSL_OPTION_USE_INLINE_NAMESPACE
// ABSL_OPTION_INLINE_NAMESPACE_NAME
diff --git a/absl/types/BUILD.bazel b/absl/types/BUILD.bazel
index 3d5cf012..31a5daa2 100644
--- a/absl/types/BUILD.bazel
+++ b/absl/types/BUILD.bazel
@@ -293,6 +293,7 @@ cc_library(
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/meta:type_traits",
],
diff --git a/absl/types/CMakeLists.txt b/absl/types/CMakeLists.txt
index 1adf3c72..024c2c39 100644
--- a/absl/types/CMakeLists.txt
+++ b/absl/types/CMakeLists.txt
@@ -284,6 +284,7 @@ absl_cc_library(
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
+ absl::config
absl::core_headers
absl::type_traits
PUBLIC
diff --git a/absl/types/compare.h b/absl/types/compare.h
index ab0543c0..3cf4a917 100644
--- a/absl/types/compare.h
+++ b/absl/types/compare.h
@@ -30,6 +30,17 @@
#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>
@@ -39,8 +50,19 @@
#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;
@@ -419,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.
diff --git a/ci/absl_alternate_options.h b/ci/absl_alternate_options.h
index 82d2ecf8..a5638591 100644
--- a/ci/absl_alternate_options.h
+++ b/ci/absl_alternate_options.h
@@ -22,6 +22,7 @@
#define ABSL_OPTION_USE_STD_OPTIONAL 0
#define ABSL_OPTION_USE_STD_STRING_VIEW 0
#define ABSL_OPTION_USE_STD_VARIANT 0
+#define ABSL_OPTION_USE_STD_ORDERING 0
#define ABSL_OPTION_USE_INLINE_NAMESPACE 1
#define ABSL_OPTION_INLINE_NAMESPACE_NAME ns
#define ABSL_OPTION_HARDENED 1