summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Derek Mauro <dmauro@google.com>2023-08-16 11:59:48 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2023-08-16 12:01:08 -0700
commit9a6d9c6eae90f4a5ddb162b8ef49af1e321c9769 (patch)
tree8cceabaee3b9fb3245d3574ce8f4c3bfbbd6dd12
parent17a3ac4bcc9b16aa1ae020a2f7067008d627ad88 (diff)
Use Abseil's implementation of absl::rotl and absl::rotr for libc++
prior to 18.0 to workaround libc++ having the wrong signature for these functions. Upstream issue: https://github.com/llvm/llvm-project/issues/64544 The preprocessor conditions were inverted for readability as the conditions became more complex. PiperOrigin-RevId: 557559472 Change-Id: Ibf7a2651e13a0d2a91846bc0d72ba3a44f56747b
-rw-r--r--absl/numeric/bits.h58
1 files changed, 40 insertions, 18 deletions
diff --git a/absl/numeric/bits.h b/absl/numeric/bits.h
index 5ed36f52..4b90d3fa 100644
--- a/absl/numeric/bits.h
+++ b/absl/numeric/bits.h
@@ -49,9 +49,22 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
-#if !(defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L)
-// rotating
+// https://github.com/llvm/llvm-project/issues/64544
+// libc++ had the wrong signature for std::rotl and std::rotr
+// prior to libc++ 18.0.
+//
+// b/289016048 requires a workaround for _LIBCPP_GOOGLE3.
+#if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) && \
+ (!defined(_LIBCPP_VERSION) || _LIBCPP_VERSION >= 180000) && \
+ !defined(_LIBCPP_GOOGLE3)
+
+using std::rotl;
+using std::rotr;
+
+#else
+
+// Rotating functions
template <class T>
ABSL_MUST_USE_RESULT constexpr
typename std::enable_if<std::is_unsigned<T>::value, T>::type
@@ -66,6 +79,20 @@ ABSL_MUST_USE_RESULT constexpr
return numeric_internal::RotateRight(x, s);
}
+#endif
+
+// b/289016048 requires a workaround for _LIBCPP_GOOGLE3.
+#if (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) && \
+ !defined(_LIBCPP_GOOGLE3)
+
+using std::countl_one;
+using std::countl_zero;
+using std::countr_one;
+using std::countr_zero;
+using std::popcount;
+
+#else
+
// Counting functions
//
// While these functions are typically constexpr, on some platforms, they may
@@ -107,19 +134,20 @@ ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline
popcount(T x) noexcept {
return numeric_internal::Popcount(x);
}
-#else // defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L
-
-using std::countl_one;
-using std::countl_zero;
-using std::countr_one;
-using std::countr_zero;
-using std::popcount;
-using std::rotl;
-using std::rotr;
#endif
-#if !(defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L)
+// b/289016048 requires a workaround for _LIBCPP_GOOGLE3.
+#if (defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L) && \
+ !defined(_LIBCPP_GOOGLE3)
+
+using std::bit_ceil;
+using std::bit_floor;
+using std::bit_width;
+using std::has_single_bit;
+
+#else
+
// Returns: true if x is an integral power of two; false otherwise.
template <class T>
constexpr inline typename std::enable_if<std::is_unsigned<T>::value, bool>::type
@@ -162,12 +190,6 @@ ABSL_INTERNAL_CONSTEXPR_CLZ inline
return has_single_bit(x) ? T{1} << (bit_width(x) - 1)
: numeric_internal::BitCeilNonPowerOf2(x);
}
-#else // defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L
-
-using std::bit_ceil;
-using std::bit_floor;
-using std::bit_width;
-using std::has_single_bit;
#endif