Commit 5e4ea1ce by Abseil Team Committed by rogeeff

Export of internal Abseil changes

--
7473df9e4922c589f6b27cf546aad097381ae552 by Martijn Vels <mvels@google.com>:

Make ABSL_ASSUME publicly available

PiperOrigin-RevId: 430540224
Change-Id: I760e2d86e3a0b676cd2a6d26e0225a77381e948f

--
c83e38bc421f715b3c1e20150c2f1ffe8e633028 by Abseil Team <absl-team@google.com>:

Alias absl::bind_front to std::bind_front if available

This avoids ambiguity between the two when enabling C++20.

PiperOrigin-RevId: 430486679
GitOrigin-RevId: 7473df9e4922c589f6b27cf546aad097381ae552
Change-Id: I1e9bba09a8946480ce10ddd28e86b6c86191d38c
parent 0ad7994f
...@@ -181,22 +181,7 @@ ...@@ -181,22 +181,7 @@
#define ABSL_PREDICT_TRUE(x) (x) #define ABSL_PREDICT_TRUE(x) (x)
#endif #endif
// ABSL_INTERNAL_ASSUME(cond) // Platform and compilation mode dependent implementation of ABSL_ASSUME.
// Informs the compiler that a condition is always true and that it can assume
// it to be true for optimization purposes. The call has undefined behavior if
// the condition is false.
// In !NDEBUG mode, the condition is checked with an assert().
// NOTE: The expression must not have side effects, as it will only be evaluated
// in some compilation modes and not others.
//
// Example:
//
// int x = ...;
// ABSL_INTERNAL_ASSUME(x >= 0);
// // The compiler can optimize the division to a simple right shift using the
// // assumption specified above.
// int y = x / 16;
//
#if !defined(NDEBUG) #if !defined(NDEBUG)
#define ABSL_INTERNAL_ASSUME(cond) assert(cond) #define ABSL_INTERNAL_ASSUME(cond) assert(cond)
#elif ABSL_HAVE_BUILTIN(__builtin_assume) #elif ABSL_HAVE_BUILTIN(__builtin_assume)
...@@ -215,6 +200,24 @@ ...@@ -215,6 +200,24 @@
} while (0) } while (0)
#endif #endif
// ABSL_ASSUME(cond)
// Informs the compiler that a condition is always true and that it can assume
// it to be true for optimization purposes. The call has undefined behavior if
// the condition is false.
// In !NDEBUG mode, the condition is checked with an assert().
// NOTE: The expression must not have side effects, as it may only be evaluated
// in some compilation modes and not others.
//
// Example:
//
// int x = ...;
// ABSL_ASSUME(x >= 0);
// // The compiler can optimize the division to a simple right shift using the
// // assumption specified above.
// int y = x / 16;
//
#define ABSL_ASSUME(cond) ABSL_INTERNAL_ASSUME(cond)
// ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond) // ABSL_INTERNAL_UNIQUE_SMALL_NAME(cond)
// This macro forces small unique name on a static file level symbols like // This macro forces small unique name on a static file level symbols like
// static local variables or static functions. This is intended to be used in // static local variables or static functions. This is intended to be used in
......
...@@ -200,7 +200,7 @@ constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { ...@@ -200,7 +200,7 @@ constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
template <typename T> template <typename T>
uint32_t TrailingZeros(T x) { uint32_t TrailingZeros(T x) {
ABSL_INTERNAL_ASSUME(x != 0); ABSL_ASSUME(x != 0);
return static_cast<uint32_t>(countr_zero(x)); return static_cast<uint32_t>(countr_zero(x));
} }
...@@ -809,7 +809,7 @@ class raw_hash_set { ...@@ -809,7 +809,7 @@ class raw_hash_set {
iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) { iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {
// This assumption helps the compiler know that any non-end iterator is // This assumption helps the compiler know that any non-end iterator is
// not equal to any end iterator. // not equal to any end iterator.
ABSL_INTERNAL_ASSUME(ctrl != nullptr); ABSL_ASSUME(ctrl != nullptr);
} }
void skip_empty_or_deleted() { void skip_empty_or_deleted() {
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_ #ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_
#define ABSL_FUNCTIONAL_BIND_FRONT_H_ #define ABSL_FUNCTIONAL_BIND_FRONT_H_
#if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
#include <functional> // For std::bind_front.
#endif // defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
#include "absl/functional/internal/front_binder.h" #include "absl/functional/internal/front_binder.h"
#include "absl/utility/utility.h" #include "absl/utility/utility.h"
...@@ -46,7 +50,8 @@ ABSL_NAMESPACE_BEGIN ...@@ -46,7 +50,8 @@ ABSL_NAMESPACE_BEGIN
// specified. More importantly, it provides more reliable correctness guarantees // specified. More importantly, it provides more reliable correctness guarantees
// than `std::bind()`; while `std::bind()` will silently ignore passing more // than `std::bind()`; while `std::bind()` will silently ignore passing more
// parameters than expected, for example, `absl::bind_front()` will report such // parameters than expected, for example, `absl::bind_front()` will report such
// mis-uses as errors. // mis-uses as errors. In C++20, `absl::bind_front` is replaced by
// `std::bind_front`.
// //
// absl::bind_front(a...) can be seen as storing the results of // absl::bind_front(a...) can be seen as storing the results of
// std::make_tuple(a...). // std::make_tuple(a...).
...@@ -170,6 +175,9 @@ ABSL_NAMESPACE_BEGIN ...@@ -170,6 +175,9 @@ ABSL_NAMESPACE_BEGIN
// // Doesn't copy "hi". // // Doesn't copy "hi".
// absl::bind_front(Print, absl::string_view(hi))("Chuk"); // absl::bind_front(Print, absl::string_view(hi))("Chuk");
// //
#if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
using std::bind_front;
#else // defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
template <class F, class... BoundArgs> template <class F, class... BoundArgs>
constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front( constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front(
F&& func, BoundArgs&&... args) { F&& func, BoundArgs&&... args) {
...@@ -177,6 +185,7 @@ constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front( ...@@ -177,6 +185,7 @@ constexpr functional_internal::bind_front_t<F, BoundArgs...> bind_front(
absl::in_place, absl::forward<F>(func), absl::in_place, absl::forward<F>(func),
absl::forward<BoundArgs>(args)...); absl::forward<BoundArgs>(args)...);
} }
#endif // defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
......
...@@ -59,7 +59,7 @@ static void BM_bitwidth_nonzero(benchmark::State& state) { ...@@ -59,7 +59,7 @@ static void BM_bitwidth_nonzero(benchmark::State& state) {
while (state.KeepRunningBatch(count)) { while (state.KeepRunningBatch(count)) {
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
const T value = values[i]; const T value = values[i];
ABSL_INTERNAL_ASSUME(value > 0); ABSL_ASSUME(value > 0);
benchmark::DoNotOptimize(value); benchmark::DoNotOptimize(value);
} }
} }
......
...@@ -42,11 +42,11 @@ namespace { ...@@ -42,11 +42,11 @@ namespace {
// Returns: 2 // Returns: 2
inline ABSL_ATTRIBUTE_ALWAYS_INLINE int Fls128(uint128 n) { inline ABSL_ATTRIBUTE_ALWAYS_INLINE int Fls128(uint128 n) {
if (uint64_t hi = Uint128High64(n)) { if (uint64_t hi = Uint128High64(n)) {
ABSL_INTERNAL_ASSUME(hi != 0); ABSL_ASSUME(hi != 0);
return 127 - countl_zero(hi); return 127 - countl_zero(hi);
} }
const uint64_t low = Uint128Low64(n); const uint64_t low = Uint128Low64(n);
ABSL_INTERNAL_ASSUME(low != 0); ABSL_ASSUME(low != 0);
return 63 - countl_zero(low); return 63 - countl_zero(low);
} }
......
...@@ -716,7 +716,7 @@ inline void CordRepBtree::AlignBegin() { ...@@ -716,7 +716,7 @@ inline void CordRepBtree::AlignBegin() {
// size, and then do overlapping load/store of up to 4 pointers (inlined as // size, and then do overlapping load/store of up to 4 pointers (inlined as
// XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a) // XMM, YMM or ZMM load/store) and up to 2 pointers (XMM / YMM), which is a)
// compact and b) not clobbering any registers. // compact and b) not clobbering any registers.
ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); ABSL_ASSUME(new_end <= kMaxCapacity);
#ifdef __clang__ #ifdef __clang__
#pragma unroll 1 #pragma unroll 1
#endif #endif
...@@ -734,7 +734,7 @@ inline void CordRepBtree::AlignEnd() { ...@@ -734,7 +734,7 @@ inline void CordRepBtree::AlignEnd() {
const size_t new_end = end() + delta; const size_t new_end = end() + delta;
set_begin(new_begin); set_begin(new_begin);
set_end(new_end); set_end(new_end);
ABSL_INTERNAL_ASSUME(new_end <= kMaxCapacity); ABSL_ASSUME(new_end <= kMaxCapacity);
#ifdef __clang__ #ifdef __clang__
#pragma unroll 1 #pragma unroll 1
#endif #endif
......
...@@ -320,7 +320,7 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv, ...@@ -320,7 +320,7 @@ bool ConvertIntArg(T v, const FormatConversionSpecImpl conv,
return ConvertFloatImpl(static_cast<double>(v), conv, sink); return ConvertFloatImpl(static_cast<double>(v), conv, sink);
default: default:
ABSL_INTERNAL_ASSUME(false); ABSL_ASSUME(false);
} }
if (conv.is_basic()) { if (conv.is_basic()) {
......
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