Commit 1bae23e3 by Abseil Team Committed by Mark Barolak

Export of internal Abseil changes

--
dab5caab05d89d03066ef92584660688595a3aaf by Mark Barolak <mbar@google.com>:

Add absl::Status and absl::StatusOr to absl/README.md

Import of https://github.com/abseil/abseil-cpp/pull/863

PiperOrigin-RevId: 347857368

--
1ca3c7a96417cd6e6d62f4dc36fd5ddaa61cfa20 by Chris Kennelly <ckennelly@google.com>:

Leverage integer power-of-2 functions and bit counting library in Abseil.

PiperOrigin-RevId: 347816486

--
e5cbe05879fd65dce7875e2e0105331a1615d89b by Chris Kennelly <ckennelly@google.com>:

Mitigate narrowing warning on MSVC.

If sizeof(x) <= sizeof(uint32_t), no truncation occurs when casting to
uint32_t, but the compiler cannot always determine this.

PiperOrigin-RevId: 347696526

--
079dff64cb175d282d9e22dfb4a522199ffdae2e by Benjamin Barenblat <bbaren@google.com>:

Avoid libgcc -NaN narrowing bug

When testing -NaN parsing, avoid narrowing -NaN from double to float.
This avoids a bug in libgcc
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251).

PiperOrigin-RevId: 347654751

--
2e78a7634865aeef6765e1f447e96cf8d9985059 by Chris Kennelly <ckennelly@google.com>:

Mark popcount helpers as inline.

These are conditionally constexpr, so we need to add inline to cover the
non-constexpr builds to avoid ODR violations.

PiperOrigin-RevId: 347620138

--
437fbb363aea1654179f102dcdd607ec33c1af1e by Chris Kennelly <ckennelly@google.com>:

Use explicit narrowing cast.

This is never invoked in practice, but compilers with -Wimplicit-int-conversion
may trigger when sizeof(T) > sizeof(uint16_t) prior to determining this never
runs.

PiperOrigin-RevId: 347609857
GitOrigin-RevId: dab5caab05d89d03066ef92584660688595a3aaf
Change-Id: I6296ddffe7ec646f8ce121138f21e1e85a2cff4b
parent 6df644c5
...@@ -10,7 +10,6 @@ set(ABSL_INTERNAL_DLL_FILES ...@@ -10,7 +10,6 @@ set(ABSL_INTERNAL_DLL_FILES
"base/const_init.h" "base/const_init.h"
"base/dynamic_annotations.h" "base/dynamic_annotations.h"
"base/internal/atomic_hook.h" "base/internal/atomic_hook.h"
"base/internal/bits.h"
"base/internal/cycleclock.cc" "base/internal/cycleclock.cc"
"base/internal/cycleclock.h" "base/internal/cycleclock.h"
"base/internal/direct_mmap.h" "base/internal/direct_mmap.h"
......
...@@ -80,8 +80,8 @@ Abseil contains the following C++ library components: ...@@ -80,8 +80,8 @@ Abseil contains the following C++ library components:
* [`numeric`](absl/numeric/) * [`numeric`](absl/numeric/)
<br /> The `numeric` library contains C++11-compatible 128-bit integers. <br /> The `numeric` library contains C++11-compatible 128-bit integers.
* [`status`](absl/status/) * [`status`](absl/status/)
<br /> The `status` library is used within Google for error handling utilizing the <br /> The `status` contains abstractions for error handling, specifically
following two main abstractions: `absl::Status` and `absl::StatusOr<T>`. `absl::Status` and `absl::StatusOr<T>`.
* [`strings`](absl/strings/) * [`strings`](absl/strings/)
<br /> The `strings` library contains a variety of strings routines and <br /> The `strings` library contains a variety of strings routines and
utilities, including a C++11-compatible version of the C++17 utilities, including a C++11-compatible version of the C++17
......
...@@ -587,31 +587,6 @@ cc_test( ...@@ -587,31 +587,6 @@ cc_test(
) )
cc_library( cc_library(
name = "bits",
hdrs = ["internal/bits.h"],
linkopts = ABSL_DEFAULT_LINKOPTS,
visibility = [
"//absl:__subpackages__",
],
deps = [
":config",
":core_headers",
],
)
cc_test(
name = "bits_test",
size = "small",
srcs = ["internal/bits_test.cc"],
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":bits",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "exponential_biased", name = "exponential_biased",
srcs = ["internal/exponential_biased.cc"], srcs = ["internal/exponential_biased.cc"],
hdrs = ["internal/exponential_biased.h"], hdrs = ["internal/exponential_biased.h"],
......
...@@ -520,30 +520,6 @@ absl_cc_test( ...@@ -520,30 +520,6 @@ absl_cc_test(
absl_cc_library( absl_cc_library(
NAME NAME
internal_bits
HDRS
"internal/bits.h"
COPTS
${ABSL_DEFAULT_COPTS}
DEPS
absl::config
absl::core_headers
)
absl_cc_test(
NAME
internal_bits_test
SRCS
"internal/bits_test.cc"
COPTS
${ABSL_TEST_COPTS}
DEPS
absl::internal_bits
gtest_main
)
absl_cc_library(
NAME
exponential_biased exponential_biased
SRCS SRCS
"internal/exponential_biased.cc" "internal/exponential_biased.cc"
......
// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef ABSL_BASE_INTERNAL_BITS_H_
#define ABSL_BASE_INTERNAL_BITS_H_
// This file contains bitwise ops which are implementation details of various
// absl libraries.
#include <cstdint>
#include "absl/base/config.h"
// Clang on Windows has __builtin_clzll; otherwise we need to use the
// windows intrinsic functions.
#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#if defined(_M_X64)
#pragma intrinsic(_BitScanReverse64)
#pragma intrinsic(_BitScanForward64)
#endif
#pragma intrinsic(_BitScanReverse)
#pragma intrinsic(_BitScanForward)
#endif
#include "absl/base/attributes.h"
#if defined(_MSC_VER) && !defined(__clang__)
// We can achieve something similar to attribute((always_inline)) with MSVC by
// using the __forceinline keyword, however this is not perfect. MSVC is
// much less aggressive about inlining, and even with the __forceinline keyword.
#define ABSL_BASE_INTERNAL_FORCEINLINE __forceinline
#else
// Use default attribute inline.
#define ABSL_BASE_INTERNAL_FORCEINLINE inline ABSL_ATTRIBUTE_ALWAYS_INLINE
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) {
int zeroes = 60;
if (n >> 32) {
zeroes -= 32;
n >>= 32;
}
if (n >> 16) {
zeroes -= 16;
n >>= 16;
}
if (n >> 8) {
zeroes -= 8;
n >>= 8;
}
if (n >> 4) {
zeroes -= 4;
n >>= 4;
}
return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) {
#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64)
// MSVC does not have __buitin_clzll. Use _BitScanReverse64.
unsigned long result = 0; // NOLINT(runtime/int)
if (_BitScanReverse64(&result, n)) {
return 63 - result;
}
return 64;
#elif defined(_MSC_VER) && !defined(__clang__)
// MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse
unsigned long result = 0; // NOLINT(runtime/int)
if ((n >> 32) &&
_BitScanReverse(&result, static_cast<unsigned long>(n >> 32))) {
return 31 - result;
}
if (_BitScanReverse(&result, static_cast<unsigned long>(n))) {
return 63 - result;
}
return 64;
#elif defined(__GNUC__) || defined(__clang__)
// Use __builtin_clzll, which uses the following instructions:
// x86: bsr
// ARM64: clz
// PPC: cntlzd
static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
"__builtin_clzll does not take 64-bit arg");
// Handle 0 as a special case because __builtin_clzll(0) is undefined.
if (n == 0) {
return 64;
}
return __builtin_clzll(n);
#else
return CountLeadingZeros64Slow(n);
#endif
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32Slow(uint64_t n) {
int zeroes = 28;
if (n >> 16) {
zeroes -= 16;
n >>= 16;
}
if (n >> 8) {
zeroes -= 8;
n >>= 8;
}
if (n >> 4) {
zeroes -= 4;
n >>= 4;
}
return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes;
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32(uint32_t n) {
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long result = 0; // NOLINT(runtime/int)
if (_BitScanReverse(&result, n)) {
return 31 - result;
}
return 32;
#elif defined(__GNUC__) || defined(__clang__)
// Use __builtin_clz, which uses the following instructions:
// x86: bsr
// ARM64: clz
// PPC: cntlzd
static_assert(sizeof(int) == sizeof(n),
"__builtin_clz does not take 32-bit arg");
// Handle 0 as a special case because __builtin_clz(0) is undefined.
if (n == 0) {
return 32;
}
return __builtin_clz(n);
#else
return CountLeadingZeros32Slow(n);
#endif
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64Slow(uint64_t n) {
int c = 63;
n &= ~n + 1;
if (n & 0x00000000FFFFFFFF) c -= 32;
if (n & 0x0000FFFF0000FFFF) c -= 16;
if (n & 0x00FF00FF00FF00FF) c -= 8;
if (n & 0x0F0F0F0F0F0F0F0F) c -= 4;
if (n & 0x3333333333333333) c -= 2;
if (n & 0x5555555555555555) c -= 1;
return c;
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64(uint64_t n) {
#if defined(_MSC_VER) && !defined(__clang__) && defined(_M_X64)
unsigned long result = 0; // NOLINT(runtime/int)
_BitScanForward64(&result, n);
return result;
#elif defined(_MSC_VER) && !defined(__clang__)
unsigned long result = 0; // NOLINT(runtime/int)
if (static_cast<uint32_t>(n) == 0) {
_BitScanForward(&result, static_cast<unsigned long>(n >> 32));
return result + 32;
}
_BitScanForward(&result, static_cast<unsigned long>(n));
return result;
#elif defined(__GNUC__) || defined(__clang__)
static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int)
"__builtin_ctzll does not take 64-bit arg");
return __builtin_ctzll(n);
#else
return CountTrailingZerosNonZero64Slow(n);
#endif
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32Slow(uint32_t n) {
int c = 31;
n &= ~n + 1;
if (n & 0x0000FFFF) c -= 16;
if (n & 0x00FF00FF) c -= 8;
if (n & 0x0F0F0F0F) c -= 4;
if (n & 0x33333333) c -= 2;
if (n & 0x55555555) c -= 1;
return c;
}
ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) {
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long result = 0; // NOLINT(runtime/int)
_BitScanForward(&result, n);
return result;
#elif defined(__GNUC__) || defined(__clang__)
static_assert(sizeof(int) == sizeof(n),
"__builtin_ctz does not take 32-bit arg");
return __builtin_ctz(n);
#else
return CountTrailingZerosNonZero32Slow(n);
#endif
}
#undef ABSL_BASE_INTERNAL_FORCEINLINE
} // namespace base_internal
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_BASE_INTERNAL_BITS_H_
// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "absl/base/internal/bits.h"
#include "gtest/gtest.h"
namespace {
int CLZ64(uint64_t n) {
int fast = absl::base_internal::CountLeadingZeros64(n);
int slow = absl::base_internal::CountLeadingZeros64Slow(n);
EXPECT_EQ(fast, slow) << n;
return fast;
}
TEST(BitsTest, CountLeadingZeros64) {
EXPECT_EQ(64, CLZ64(uint64_t{}));
EXPECT_EQ(0, CLZ64(~uint64_t{}));
for (int index = 0; index < 64; index++) {
uint64_t x = static_cast<uint64_t>(1) << index;
const auto cnt = 63 - index;
ASSERT_EQ(cnt, CLZ64(x)) << index;
ASSERT_EQ(cnt, CLZ64(x + x - 1)) << index;
}
}
int CLZ32(uint32_t n) {
int fast = absl::base_internal::CountLeadingZeros32(n);
int slow = absl::base_internal::CountLeadingZeros32Slow(n);
EXPECT_EQ(fast, slow) << n;
return fast;
}
TEST(BitsTest, CountLeadingZeros32) {
EXPECT_EQ(32, CLZ32(uint32_t{}));
EXPECT_EQ(0, CLZ32(~uint32_t{}));
for (int index = 0; index < 32; index++) {
uint32_t x = static_cast<uint32_t>(1) << index;
const auto cnt = 31 - index;
ASSERT_EQ(cnt, CLZ32(x)) << index;
ASSERT_EQ(cnt, CLZ32(x + x - 1)) << index;
ASSERT_EQ(CLZ64(x), CLZ32(x) + 32);
}
}
int CTZ64(uint64_t n) {
int fast = absl::base_internal::CountTrailingZerosNonZero64(n);
int slow = absl::base_internal::CountTrailingZerosNonZero64Slow(n);
EXPECT_EQ(fast, slow) << n;
return fast;
}
TEST(BitsTest, CountTrailingZerosNonZero64) {
EXPECT_EQ(0, CTZ64(~uint64_t{}));
for (int index = 0; index < 64; index++) {
uint64_t x = static_cast<uint64_t>(1) << index;
const auto cnt = index;
ASSERT_EQ(cnt, CTZ64(x)) << index;
ASSERT_EQ(cnt, CTZ64(~(x - 1))) << index;
}
}
int CTZ32(uint32_t n) {
int fast = absl::base_internal::CountTrailingZerosNonZero32(n);
int slow = absl::base_internal::CountTrailingZerosNonZero32Slow(n);
EXPECT_EQ(fast, slow) << n;
return fast;
}
TEST(BitsTest, CountTrailingZerosNonZero32) {
EXPECT_EQ(0, CTZ32(~uint32_t{}));
for (int index = 0; index < 32; index++) {
uint32_t x = static_cast<uint32_t>(1) << index;
const auto cnt = index;
ASSERT_EQ(cnt, CTZ32(x)) << index;
ASSERT_EQ(cnt, CTZ32(~(x - 1))) << index;
}
}
} // namespace
...@@ -599,12 +599,12 @@ cc_library( ...@@ -599,12 +599,12 @@ cc_library(
":hashtablez_sampler", ":hashtablez_sampler",
":have_sse", ":have_sse",
":layout", ":layout",
"//absl/base:bits",
"//absl/base:config", "//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/base:endian", "//absl/base:endian",
"//absl/memory", "//absl/memory",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits",
"//absl/utility", "//absl/utility",
], ],
) )
......
...@@ -665,7 +665,7 @@ absl_cc_library( ...@@ -665,7 +665,7 @@ absl_cc_library(
COPTS COPTS
${ABSL_DEFAULT_COPTS} ${ABSL_DEFAULT_COPTS}
DEPS DEPS
absl::internal_bits absl::bits
absl::compressed_tuple absl::compressed_tuple
absl::config absl::config
absl::container_common absl::container_common
......
...@@ -102,7 +102,6 @@ ...@@ -102,7 +102,6 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "absl/base/internal/bits.h"
#include "absl/base/internal/endian.h" #include "absl/base/internal/endian.h"
#include "absl/base/optimization.h" #include "absl/base/optimization.h"
#include "absl/base/port.h" #include "absl/base/port.h"
...@@ -116,6 +115,7 @@ ...@@ -116,6 +115,7 @@
#include "absl/container/internal/layout.h" #include "absl/container/internal/layout.h"
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/utility/utility.h" #include "absl/utility/utility.h"
namespace absl { namespace absl {
...@@ -190,17 +190,8 @@ constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) { ...@@ -190,17 +190,8 @@ constexpr bool IsNoThrowSwappable(std::false_type /* is_swappable */) {
template <typename T> template <typename T>
int TrailingZeros(T x) { int TrailingZeros(T x) {
return sizeof(T) == 8 ? base_internal::CountTrailingZerosNonZero64( ABSL_INTERNAL_ASSUME(x != 0);
static_cast<uint64_t>(x)) return countr_zero(x);
: base_internal::CountTrailingZerosNonZero32(
static_cast<uint32_t>(x));
}
template <typename T>
int LeadingZeros(T x) {
return sizeof(T) == 8
? base_internal::CountLeadingZeros64(static_cast<uint64_t>(x))
: base_internal::CountLeadingZeros32(static_cast<uint32_t>(x));
} }
// An abstraction over a bitmask. It provides an easy way to iterate through the // An abstraction over a bitmask. It provides an easy way to iterate through the
...@@ -233,11 +224,7 @@ class BitMask { ...@@ -233,11 +224,7 @@ class BitMask {
int LowestBitSet() const { int LowestBitSet() const {
return container_internal::TrailingZeros(mask_) >> Shift; return container_internal::TrailingZeros(mask_) >> Shift;
} }
int HighestBitSet() const { int HighestBitSet() const { return (bit_width(mask_) - 1) >> Shift; }
return (sizeof(T) * CHAR_BIT - container_internal::LeadingZeros(mask_) -
1) >>
Shift;
}
BitMask begin() const { return *this; } BitMask begin() const { return *this; }
BitMask end() const { return BitMask(0); } BitMask end() const { return BitMask(0); }
...@@ -249,7 +236,7 @@ class BitMask { ...@@ -249,7 +236,7 @@ class BitMask {
int LeadingZeros() const { int LeadingZeros() const {
constexpr int total_significant_bits = SignificantBits << Shift; constexpr int total_significant_bits = SignificantBits << Shift;
constexpr int extra_bits = sizeof(T) * 8 - total_significant_bits; constexpr int extra_bits = sizeof(T) * 8 - total_significant_bits;
return container_internal::LeadingZeros(mask_ << extra_bits) >> Shift; return countl_zero(mask_ << extra_bits) >> Shift;
} }
private: private:
...@@ -380,8 +367,8 @@ struct GroupSse2Impl { ...@@ -380,8 +367,8 @@ struct GroupSse2Impl {
// Returns the number of trailing empty or deleted elements in the group. // Returns the number of trailing empty or deleted elements in the group.
uint32_t CountLeadingEmptyOrDeleted() const { uint32_t CountLeadingEmptyOrDeleted() const {
auto special = _mm_set1_epi8(kSentinel); auto special = _mm_set1_epi8(kSentinel);
return TrailingZeros( return TrailingZeros(static_cast<uint32_t>(
_mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1); _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1));
} }
void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const {
...@@ -476,7 +463,7 @@ void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity); ...@@ -476,7 +463,7 @@ void ConvertDeletedToEmptyAndFullToDeleted(ctrl_t* ctrl, size_t capacity);
// Rounds up the capacity to the next power of 2 minus 1, with a minimum of 1. // Rounds up the capacity to the next power of 2 minus 1, with a minimum of 1.
inline size_t NormalizeCapacity(size_t n) { inline size_t NormalizeCapacity(size_t n) {
return n ? ~size_t{} >> LeadingZeros(n) : 1; return n ? ~size_t{} >> countl_zero(n) : 1;
} }
// We use 7/8th as maximum load factor. // We use 7/8th as maximum load factor.
......
...@@ -64,7 +64,7 @@ cc_library( ...@@ -64,7 +64,7 @@ cc_library(
copts = ABSL_DEFAULT_COPTS, copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
"//absl/base:bits", ":bits",
"//absl/base:config", "//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
], ],
......
...@@ -55,7 +55,7 @@ absl_cc_library( ...@@ -55,7 +55,7 @@ absl_cc_library(
DEPS DEPS
absl::config absl::config
absl::core_headers absl::core_headers
absl::internal_bits absl::bits
PUBLIC PUBLIC
) )
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#include <string> #include <string>
#include <type_traits> #include <type_traits>
#include "absl/base/internal/bits.h"
#include "absl/base/optimization.h" #include "absl/base/optimization.h"
#include "absl/numeric/bits.h"
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
...@@ -43,11 +43,11 @@ namespace { ...@@ -43,11 +43,11 @@ namespace {
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_INTERNAL_ASSUME(hi != 0);
return 127 - base_internal::CountLeadingZeros64(hi); return 127 - countl_zero(hi);
} }
const uint64_t low = Uint128Low64(n); const uint64_t low = Uint128Low64(n);
ABSL_INTERNAL_ASSUME(low != 0); ABSL_INTERNAL_ASSUME(low != 0);
return 63 - base_internal::CountLeadingZeros64(low); return 63 - countl_zero(low);
} }
// Long division/modulo for uint128 implemented using the shift-subtract // Long division/modulo for uint128 implemented using the shift-subtract
......
...@@ -89,7 +89,8 @@ ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft( ...@@ -89,7 +89,8 @@ ABSL_MUST_USE_RESULT ABSL_ATTRIBUTE_ALWAYS_INLINE constexpr T RotateLeft(
static_cast<T>(x >> ((-s) & (std::numeric_limits<T>::digits - 1))); static_cast<T>(x >> ((-s) & (std::numeric_limits<T>::digits - 1)));
} }
ABSL_INTERNAL_CONSTEXPR_POPCOUNT int Popcount32(uint32_t x) noexcept { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount32(uint32_t x) noexcept {
#if ABSL_HAVE_BUILTIN(__builtin_popcount) #if ABSL_HAVE_BUILTIN(__builtin_popcount)
static_assert(sizeof(unsigned int) == sizeof(x), static_assert(sizeof(unsigned int) == sizeof(x),
"__builtin_popcount does not take 32-bit arg"); "__builtin_popcount does not take 32-bit arg");
...@@ -101,7 +102,8 @@ ABSL_INTERNAL_CONSTEXPR_POPCOUNT int Popcount32(uint32_t x) noexcept { ...@@ -101,7 +102,8 @@ ABSL_INTERNAL_CONSTEXPR_POPCOUNT int Popcount32(uint32_t x) noexcept {
#endif #endif
} }
ABSL_INTERNAL_CONSTEXPR_POPCOUNT int Popcount64(uint64_t x) noexcept { ABSL_ATTRIBUTE_ALWAYS_INLINE ABSL_INTERNAL_CONSTEXPR_POPCOUNT inline int
Popcount64(uint64_t x) noexcept {
#if ABSL_HAVE_BUILTIN(__builtin_popcountll) #if ABSL_HAVE_BUILTIN(__builtin_popcountll)
static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int) static_assert(sizeof(unsigned long long) == sizeof(x), // NOLINT(runtime/int)
"__builtin_popcount does not take 64-bit arg"); "__builtin_popcount does not take 64-bit arg");
...@@ -231,11 +233,11 @@ CountLeadingZeroes(T x) { ...@@ -231,11 +233,11 @@ CountLeadingZeroes(T x) {
"T must have a power-of-2 size"); "T must have a power-of-2 size");
static_assert(sizeof(T) <= sizeof(uint64_t), "T too large"); static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
return sizeof(T) <= sizeof(uint16_t) return sizeof(T) <= sizeof(uint16_t)
? CountLeadingZeroes16(x) - ? CountLeadingZeroes16(static_cast<uint16_t>(x)) -
(std::numeric_limits<uint16_t>::digits - (std::numeric_limits<uint16_t>::digits -
std::numeric_limits<T>::digits) std::numeric_limits<T>::digits)
: (sizeof(T) <= sizeof(uint32_t) : (sizeof(T) <= sizeof(uint32_t)
? CountLeadingZeroes32(x) - ? CountLeadingZeroes32(static_cast<uint32_t>(x)) -
(std::numeric_limits<uint32_t>::digits - (std::numeric_limits<uint32_t>::digits -
std::numeric_limits<T>::digits) std::numeric_limits<T>::digits)
: CountLeadingZeroes64(x)); : CountLeadingZeroes64(x));
...@@ -314,9 +316,10 @@ CountTrailingZeroes(T x) noexcept { ...@@ -314,9 +316,10 @@ CountTrailingZeroes(T x) noexcept {
static_assert(sizeof(T) <= sizeof(uint64_t), "T too large"); static_assert(sizeof(T) <= sizeof(uint64_t), "T too large");
return x == 0 ? std::numeric_limits<T>::digits return x == 0 ? std::numeric_limits<T>::digits
: (sizeof(T) <= sizeof(uint16_t) : (sizeof(T) <= sizeof(uint16_t)
? CountTrailingZeroesNonzero16(x) ? CountTrailingZeroesNonzero16(static_cast<uint16_t>(x))
: (sizeof(T) <= sizeof(uint32_t) : (sizeof(T) <= sizeof(uint32_t)
? CountTrailingZeroesNonzero32(x) ? CountTrailingZeroesNonzero32(
static_cast<uint32_t>(x))
: CountTrailingZeroesNonzero64(x))); : CountTrailingZeroesNonzero64(x)));
} }
......
...@@ -69,6 +69,7 @@ cc_library( ...@@ -69,6 +69,7 @@ cc_library(
"//absl/base:config", "//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits",
"//absl/random/internal:distribution_caller", "//absl/random/internal:distribution_caller",
"//absl/random/internal:fast_uniform_bits", "//absl/random/internal:fast_uniform_bits",
"//absl/random/internal:fastmath", "//absl/random/internal:fastmath",
......
...@@ -673,7 +673,7 @@ absl_cc_library( ...@@ -673,7 +673,7 @@ absl_cc_library(
LINKOPTS LINKOPTS
${ABSL_DEFAULT_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS}
DEPS DEPS
absl::internal_bits absl::bits
absl::random_internal_fastmath absl::random_internal_fastmath
absl::random_internal_traits absl::random_internal_traits
absl::type_traits absl::type_traits
...@@ -690,7 +690,7 @@ absl_cc_library( ...@@ -690,7 +690,7 @@ absl_cc_library(
LINKOPTS LINKOPTS
${ABSL_DEFAULT_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS}
DEPS DEPS
absl::internal_bits absl::bits
absl::config absl::config
absl::int128 absl::int128
) )
...@@ -706,7 +706,7 @@ absl_cc_library( ...@@ -706,7 +706,7 @@ absl_cc_library(
LINKOPTS LINKOPTS
${ABSL_DEFAULT_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS}
DEPS DEPS
absl::internal_bits absl::bits
) )
# Internal-only target, do not depend on directly. # Internal-only target, do not depend on directly.
...@@ -902,7 +902,7 @@ absl_cc_test( ...@@ -902,7 +902,7 @@ absl_cc_test(
LINKOPTS LINKOPTS
${ABSL_DEFAULT_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS}
DEPS DEPS
absl::internal_bits absl::bits
absl::flags absl::flags
absl::random_internal_generate_real absl::random_internal_generate_real
gtest_main gtest_main
...@@ -1201,7 +1201,7 @@ absl_cc_test( ...@@ -1201,7 +1201,7 @@ absl_cc_test(
${ABSL_DEFAULT_LINKOPTS} ${ABSL_DEFAULT_LINKOPTS}
DEPS DEPS
absl::random_internal_wide_multiply absl::random_internal_wide_multiply
absl::internal_bits absl::bits
absl::int128 absl::int128
gtest_main gtest_main
) )
...@@ -175,8 +175,8 @@ cc_library( ...@@ -175,8 +175,8 @@ cc_library(
deps = [ deps = [
":fastmath", ":fastmath",
":traits", ":traits",
"//absl/base:bits",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits",
], ],
) )
...@@ -187,7 +187,7 @@ cc_library( ...@@ -187,7 +187,7 @@ cc_library(
], ],
copts = ABSL_DEFAULT_COPTS, copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = ["//absl/base:bits"], deps = ["//absl/numeric:bits"],
) )
cc_library( cc_library(
...@@ -197,8 +197,8 @@ cc_library( ...@@ -197,8 +197,8 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":traits", ":traits",
"//absl/base:bits",
"//absl/base:config", "//absl/base:config",
"//absl/numeric:bits",
"//absl/numeric:int128", "//absl/numeric:int128",
], ],
) )
...@@ -229,6 +229,7 @@ cc_library( ...@@ -229,6 +229,7 @@ cc_library(
":iostream_state_saver", ":iostream_state_saver",
"//absl/base:config", "//absl/base:config",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits",
"//absl/numeric:int128", "//absl/numeric:int128",
], ],
) )
...@@ -400,8 +401,8 @@ cc_test( ...@@ -400,8 +401,8 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":generate_real", ":generate_real",
"//absl/base:bits",
"//absl/flags:flag", "//absl/flags:flag",
"//absl/numeric:bits",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
], ],
) )
...@@ -634,7 +635,7 @@ cc_test( ...@@ -634,7 +635,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":wide_multiply", ":wide_multiply",
"//absl/base:bits", "//absl/numeric:bits",
"//absl/numeric:int128", "//absl/numeric:int128",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
], ],
......
...@@ -22,27 +22,22 @@ ...@@ -22,27 +22,22 @@
#include <cmath> #include <cmath>
#include <cstdint> #include <cstdint>
#include "absl/base/internal/bits.h" #include "absl/numeric/bits.h"
namespace absl { namespace absl {
ABSL_NAMESPACE_BEGIN ABSL_NAMESPACE_BEGIN
namespace random_internal { namespace random_internal {
// Returns the position of the first bit set.
inline int LeadingSetBit(uint64_t n) {
return 64 - base_internal::CountLeadingZeros64(n);
}
// Compute log2(n) using integer operations. // Compute log2(n) using integer operations.
// While std::log2 is more accurate than std::log(n) / std::log(2), for // While std::log2 is more accurate than std::log(n) / std::log(2), for
// very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2, // very large numbers--those close to std::numeric_limits<uint64_t>::max() - 2,
// for instance--std::log2 rounds up rather than down, which introduces // for instance--std::log2 rounds up rather than down, which introduces
// definite skew in the results. // definite skew in the results.
inline int IntLog2Floor(uint64_t n) { inline int IntLog2Floor(uint64_t n) {
return (n <= 1) ? 0 : (63 - base_internal::CountLeadingZeros64(n)); return (n <= 1) ? 0 : (63 - countl_zero(n));
} }
inline int IntLog2Ceil(uint64_t n) { inline int IntLog2Ceil(uint64_t n) {
return (n <= 1) ? 0 : (64 - base_internal::CountLeadingZeros64(n - 1)); return (n <= 1) ? 0 : (64 - countl_zero(n - 1));
} }
inline double StirlingLogFactorial(double n) { inline double StirlingLogFactorial(double n) {
...@@ -55,18 +50,6 @@ inline double StirlingLogFactorial(double n) { ...@@ -55,18 +50,6 @@ inline double StirlingLogFactorial(double n) {
(1.0 / 360.0) * ninv * ninv * ninv; (1.0 / 360.0) * ninv * ninv * ninv;
} }
// Rotate value right.
//
// We only implement the uint32_t / uint64_t versions because
// 1) those are the only ones we use, and
// 2) those are the only ones where clang detects the rotate idiom correctly.
inline constexpr uint32_t rotr(uint32_t value, uint8_t bits) {
return (value >> (bits & 31)) | (value << ((-bits) & 31));
}
inline constexpr uint64_t rotr(uint64_t value, uint8_t bits) {
return (value >> (bits & 63)) | (value << ((-bits) & 63));
}
} // namespace random_internal } // namespace random_internal
ABSL_NAMESPACE_END ABSL_NAMESPACE_END
} // namespace absl } // namespace absl
......
...@@ -27,19 +27,6 @@ ...@@ -27,19 +27,6 @@
namespace { namespace {
TEST(DistributionImplTest, LeadingSetBit) {
using absl::random_internal::LeadingSetBit;
constexpr uint64_t kZero = 0;
EXPECT_EQ(0, LeadingSetBit(kZero));
EXPECT_EQ(64, LeadingSetBit(~kZero));
for (int index = 0; index < 64; index++) {
uint64_t x = static_cast<uint64_t>(1) << index;
EXPECT_EQ(index + 1, LeadingSetBit(x)) << index;
EXPECT_EQ(index + 1, LeadingSetBit(x + x - 1)) << index;
}
}
TEST(FastMathTest, IntLog2FloorTest) { TEST(FastMathTest, IntLog2FloorTest) {
using absl::random_internal::IntLog2Floor; using absl::random_internal::IntLog2Floor;
constexpr uint64_t kZero = 0; constexpr uint64_t kZero = 0;
......
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
#include "absl/base/internal/bits.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/random/internal/fastmath.h" #include "absl/random/internal/fastmath.h"
#include "absl/random/internal/traits.h" #include "absl/random/internal/traits.h"
...@@ -120,7 +120,7 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) { ...@@ -120,7 +120,7 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
// Number of leading zeros is mapped to the exponent: 2^-clz // Number of leading zeros is mapped to the exponent: 2^-clz
// bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0 // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
int clz = base_internal::CountLeadingZeros64(bits); int clz = countl_zero(bits);
bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits. bits <<= (IncludeZero ? clz : (clz & 63)); // remove 0-bits.
exp -= clz; // set the exponent. exp -= clz; // set the exponent.
bits >>= (63 - kExp); bits >>= (63 - kExp);
......
...@@ -20,8 +20,8 @@ ...@@ -20,8 +20,8 @@
#include <string> #include <string>
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "absl/base/internal/bits.h"
#include "absl/flags/flag.h" #include "absl/flags/flag.h"
#include "absl/numeric/bits.h"
ABSL_FLAG(int64_t, absl_random_test_trials, 50000, ABSL_FLAG(int64_t, absl_random_test_trials, 50000,
"Number of trials for the probability tests."); "Number of trials for the probability tests.");
...@@ -413,7 +413,6 @@ TEST(GenerateRealTest, U64ToDoubleSignedTest) { ...@@ -413,7 +413,6 @@ TEST(GenerateRealTest, U64ToDoubleSignedTest) {
} }
TEST(GenerateRealTest, ExhaustiveFloat) { TEST(GenerateRealTest, ExhaustiveFloat) {
using absl::base_internal::CountLeadingZeros64;
auto ToFloat = [](uint64_t a) { auto ToFloat = [](uint64_t a) {
return GenerateRealFromBits<float, GeneratePositiveTag, true>(a); return GenerateRealFromBits<float, GeneratePositiveTag, true>(a);
}; };
...@@ -464,7 +463,7 @@ TEST(GenerateRealTest, ExhaustiveFloat) { ...@@ -464,7 +463,7 @@ TEST(GenerateRealTest, ExhaustiveFloat) {
// Adjust decrement and check value based on how many leading 0 // Adjust decrement and check value based on how many leading 0
// bits are set in the current value. // bits are set in the current value.
const int clz = CountLeadingZeros64(x); const int clz = absl::countl_zero(x);
if (clz < kDig) { if (clz < kDig) {
dec <<= (kDig - clz); dec <<= (kDig - clz);
chk = (~uint64_t(0)) >> (clz + 1); chk = (~uint64_t(0)) >> (clz + 1);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h" #include "absl/numeric/int128.h"
#include "absl/random/internal/fastmath.h" #include "absl/random/internal/fastmath.h"
#include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/iostream_state_saver.h"
...@@ -261,7 +262,7 @@ struct pcg_xsl_rr_128_64 { ...@@ -261,7 +262,7 @@ struct pcg_xsl_rr_128_64 {
uint64_t rotate = h >> 58u; uint64_t rotate = h >> 58u;
uint64_t s = Uint128Low64(state) ^ h; uint64_t s = Uint128Low64(state) ^ h;
#endif #endif
return random_internal::rotr(s, rotate); return rotr(s, rotate);
} }
}; };
...@@ -281,8 +282,8 @@ struct pcg_xsh_rr_64_32 { ...@@ -281,8 +282,8 @@ struct pcg_xsh_rr_64_32 {
using state_type = uint64_t; using state_type = uint64_t;
using result_type = uint32_t; using result_type = uint32_t;
inline uint32_t operator()(uint64_t state) { inline uint32_t operator()(uint64_t state) {
return random_internal::rotr( return rotr(static_cast<uint32_t>(((state >> 18) ^ state) >> 27),
static_cast<uint32_t>(((state >> 18) ^ state) >> 27), state >> 59); state >> 59);
} }
}; };
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#endif #endif
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/base/internal/bits.h" #include "absl/numeric/bits.h"
#include "absl/numeric/int128.h" #include "absl/numeric/int128.h"
#include "absl/random/internal/traits.h" #include "absl/random/internal/traits.h"
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "absl/random/internal/wide_multiply.h" #include "absl/random/internal/wide_multiply.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "absl/base/internal/bits.h"
#include "absl/numeric/int128.h" #include "absl/numeric/int128.h"
using absl::random_internal::MultiplyU64ToU128; using absl::random_internal::MultiplyU64ToU128;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <ostream> #include <ostream>
#include <type_traits> #include <type_traits>
#include "absl/numeric/bits.h"
#include "absl/random/internal/fastmath.h" #include "absl/random/internal/fastmath.h"
#include "absl/random/internal/generate_real.h" #include "absl/random/internal/generate_real.h"
#include "absl/random/internal/iostream_state_saver.h" #include "absl/random/internal/iostream_state_saver.h"
...@@ -68,8 +69,10 @@ class log_uniform_int_distribution { ...@@ -68,8 +69,10 @@ class log_uniform_int_distribution {
if (base_ == 2) { if (base_ == 2) {
// Determine where the first set bit is on range(), giving a log2(range) // Determine where the first set bit is on range(), giving a log2(range)
// value which can be used to construct bounds. // value which can be used to construct bounds.
log_range_ = (std::min)(random_internal::LeadingSetBit(range()), log_range_ =
std::numeric_limits<unsigned_type>::digits); (std::min)(bit_width(range()),
static_cast<unsigned_type>(
std::numeric_limits<unsigned_type>::digits));
} else { } else {
// NOTE: Computing the logN(x) introduces error from 2 sources: // NOTE: Computing the logN(x) introduces error from 2 sources:
// 1. Conversion of int to double loses precision for values >= // 1. Conversion of int to double loses precision for values >=
......
...@@ -69,7 +69,6 @@ cc_library( ...@@ -69,7 +69,6 @@ cc_library(
deps = [ deps = [
":internal", ":internal",
"//absl/base", "//absl/base",
"//absl/base:bits",
"//absl/base:config", "//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/base:endian", "//absl/base:endian",
...@@ -77,6 +76,7 @@ cc_library( ...@@ -77,6 +76,7 @@ cc_library(
"//absl/base:throw_delegate", "//absl/base:throw_delegate",
"//absl/memory", "//absl/memory",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits",
"//absl/numeric:int128", "//absl/numeric:int128",
], ],
) )
...@@ -663,11 +663,11 @@ cc_library( ...@@ -663,11 +663,11 @@ cc_library(
visibility = ["//visibility:private"], visibility = ["//visibility:private"],
deps = [ deps = [
":strings", ":strings",
"//absl/base:bits",
"//absl/base:config", "//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/functional:function_ref", "//absl/functional:function_ref",
"//absl/meta:type_traits", "//absl/meta:type_traits",
"//absl/numeric:bits",
"//absl/numeric:int128", "//absl/numeric:int128",
"//absl/types:optional", "//absl/types:optional",
"//absl/types:span", "//absl/types:span",
......
...@@ -56,7 +56,7 @@ absl_cc_library( ...@@ -56,7 +56,7 @@ absl_cc_library(
DEPS DEPS
absl::strings_internal absl::strings_internal
absl::base absl::base
absl::internal_bits absl::bits
absl::config absl::config
absl::core_headers absl::core_headers
absl::endian absl::endian
...@@ -406,7 +406,7 @@ absl_cc_library( ...@@ -406,7 +406,7 @@ absl_cc_library(
COPTS COPTS
${ABSL_DEFAULT_COPTS} ${ABSL_DEFAULT_COPTS}
DEPS DEPS
absl::internal_bits absl::bits
absl::strings absl::strings
absl::config absl::config
absl::core_headers absl::core_headers
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <cstring> #include <cstring>
#include "absl/base/casts.h" #include "absl/base/casts.h"
#include "absl/base/internal/bits.h" #include "absl/numeric/bits.h"
#include "absl/numeric/int128.h" #include "absl/numeric/int128.h"
#include "absl/strings/internal/charconv_bigint.h" #include "absl/strings/internal/charconv_bigint.h"
#include "absl/strings/internal/charconv_parse.h" #include "absl/strings/internal/charconv_parse.h"
...@@ -242,11 +242,11 @@ struct CalculatedFloat { ...@@ -242,11 +242,11 @@ struct CalculatedFloat {
// Returns the bit width of the given uint128. (Equivalently, returns 128 // Returns the bit width of the given uint128. (Equivalently, returns 128
// minus the number of leading zero bits.) // minus the number of leading zero bits.)
int BitWidth(uint128 value) { unsigned BitWidth(uint128 value) {
if (Uint128High64(value) == 0) { if (Uint128High64(value) == 0) {
return 64 - base_internal::CountLeadingZeros64(Uint128Low64(value)); return static_cast<unsigned>(bit_width(Uint128Low64(value)));
} }
return 128 - base_internal::CountLeadingZeros64(Uint128High64(value)); return 128 - countl_zero(Uint128High64(value));
} }
// Calculates how far to the right a mantissa needs to be shifted to create a // Calculates how far to the right a mantissa needs to be shifted to create a
...@@ -519,7 +519,7 @@ CalculatedFloat CalculateFromParsedHexadecimal( ...@@ -519,7 +519,7 @@ CalculatedFloat CalculateFromParsedHexadecimal(
const strings_internal::ParsedFloat& parsed_hex) { const strings_internal::ParsedFloat& parsed_hex) {
uint64_t mantissa = parsed_hex.mantissa; uint64_t mantissa = parsed_hex.mantissa;
int exponent = parsed_hex.exponent; int exponent = parsed_hex.exponent;
int mantissa_width = 64 - base_internal::CountLeadingZeros64(mantissa); auto mantissa_width = static_cast<unsigned>(bit_width(mantissa));
const int shift = NormalizedShiftSize<FloatType>(mantissa_width, exponent); const int shift = NormalizedShiftSize<FloatType>(mantissa_width, exponent);
bool result_exact; bool result_exact;
exponent += shift; exponent += shift;
......
...@@ -653,7 +653,9 @@ TEST(FromChars, NaNFloats) { ...@@ -653,7 +653,9 @@ TEST(FromChars, NaNFloats) {
negative_from_chars_float); negative_from_chars_float);
EXPECT_TRUE(std::signbit(negative_from_chars_float)); EXPECT_TRUE(std::signbit(negative_from_chars_float));
EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float)); EXPECT_FALSE(Identical(negative_from_chars_float, from_chars_float));
from_chars_float = std::copysign(from_chars_float, -1.0); // Use the (float, float) overload of std::copysign to prevent narrowing;
// see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98251.
from_chars_float = std::copysign(from_chars_float, -1.0f);
EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float)); EXPECT_TRUE(Identical(negative_from_chars_float, from_chars_float));
} }
} }
......
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
#include "absl/base/attributes.h" #include "absl/base/attributes.h"
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/base/internal/bits.h"
#include "absl/base/optimization.h" #include "absl/base/optimization.h"
#include "absl/functional/function_ref.h" #include "absl/functional/function_ref.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h" #include "absl/numeric/int128.h"
#include "absl/strings/numbers.h" #include "absl/strings/numbers.h"
#include "absl/types/optional.h" #include "absl/types/optional.h"
...@@ -315,12 +315,11 @@ class FractionalDigitGenerator { ...@@ -315,12 +315,11 @@ class FractionalDigitGenerator {
}; };
// Count the number of leading zero bits. // Count the number of leading zero bits.
int LeadingZeros(uint64_t v) { return base_internal::CountLeadingZeros64(v); } int LeadingZeros(uint64_t v) { return countl_zero(v); }
int LeadingZeros(uint128 v) { int LeadingZeros(uint128 v) {
auto high = static_cast<uint64_t>(v >> 64); auto high = static_cast<uint64_t>(v >> 64);
auto low = static_cast<uint64_t>(v); auto low = static_cast<uint64_t>(v);
return high != 0 ? base_internal::CountLeadingZeros64(high) return high != 0 ? countl_zero(high) : 64 + countl_zero(low);
: 64 + base_internal::CountLeadingZeros64(low);
} }
// Round up the text digits starting at `p`. // Round up the text digits starting at `p`.
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
#include <utility> #include <utility>
#include "absl/base/attributes.h" #include "absl/base/attributes.h"
#include "absl/base/internal/bits.h"
#include "absl/base/internal/raw_logging.h" #include "absl/base/internal/raw_logging.h"
#include "absl/numeric/bits.h"
#include "absl/strings/ascii.h" #include "absl/strings/ascii.h"
#include "absl/strings/charconv.h" #include "absl/strings/charconv.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
...@@ -303,7 +303,7 @@ static std::pair<uint64_t, uint64_t> Mul32(std::pair<uint64_t, uint64_t> num, ...@@ -303,7 +303,7 @@ static std::pair<uint64_t, uint64_t> Mul32(std::pair<uint64_t, uint64_t> num,
uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95); uint64_t bits128_up = (bits96_127 >> 32) + (bits64_127 < bits64_95);
if (bits128_up == 0) return {bits64_127, bits0_63}; if (bits128_up == 0) return {bits64_127, bits0_63};
int shift = 64 - base_internal::CountLeadingZeros64(bits128_up); auto shift = static_cast<unsigned>(bit_width(bits128_up));
uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift)); uint64_t lo = (bits0_63 >> shift) + (bits64_127 << (64 - shift));
uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift)); uint64_t hi = (bits64_127 >> shift) + (bits128_up << (64 - shift));
return {hi, lo}; return {hi, lo};
...@@ -334,7 +334,7 @@ static std::pair<uint64_t, uint64_t> PowFive(uint64_t num, int expfive) { ...@@ -334,7 +334,7 @@ static std::pair<uint64_t, uint64_t> PowFive(uint64_t num, int expfive) {
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5}; 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5};
result = Mul32(result, powers_of_five[expfive & 15]); result = Mul32(result, powers_of_five[expfive & 15]);
int shift = base_internal::CountLeadingZeros64(result.first); int shift = countl_zero(result.first);
if (shift != 0) { if (shift != 0) {
result.first = (result.first << shift) + (result.second >> (64 - shift)); result.first = (result.first << shift) + (result.second >> (64 - shift));
result.second = (result.second << shift); result.second = (result.second << shift);
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include <type_traits> #include <type_traits>
#include "absl/base/config.h" #include "absl/base/config.h"
#include "absl/base/internal/bits.h"
#ifdef __SSE4_2__ #ifdef __SSE4_2__
// TODO(jorg): Remove this when we figure out the right way // TODO(jorg): Remove this when we figure out the right way
// to swap bytes on SSE 4.2 that works with the compilers // to swap bytes on SSE 4.2 that works with the compilers
...@@ -48,6 +47,7 @@ ...@@ -48,6 +47,7 @@
#endif #endif
#include "absl/base/macros.h" #include "absl/base/macros.h"
#include "absl/base/port.h" #include "absl/base/port.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h" #include "absl/numeric/int128.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
...@@ -240,7 +240,7 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) { ...@@ -240,7 +240,7 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
} }
#endif #endif
// | 0x1 so that even 0 has 1 digit. // | 0x1 so that even 0 has 1 digit.
return 16 - absl::base_internal::CountLeadingZeros64(val | 0x1) / 4; return 16 - countl_zero(val | 0x1) / 4;
} }
} // namespace numbers_internal } // namespace numbers_internal
......
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