[bits] Define 32/64 bit overloads in bits using templates
In bits.h, instead of relying on C++ overloading for 32/64 bits integers (which can be ambiguous when the input isn't the exact type typedef-ed by uint64_t or uint32_t), use templates and std::enable_if to switch between integers of different sizes. This means that we can get rid of an awkward sizeof check in bit-vector.cc, which was necessary to compile on Mac. Change-Id: Id0eaf0f855cdbd2dc4d7bc1c481037fcd9b73953 Reviewed-on: https://chromium-review.googlesource.com/543480 Commit-Queue: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org> Cr-Commit-Position: refs/heads/master@{#46184}
This commit is contained in:
parent
87f71769c5
commit
d14426f6f9
@ -26,6 +26,33 @@ class CheckedNumeric;
|
||||
|
||||
namespace bits {
|
||||
|
||||
// Define overloaded |Name| for |Name32| and |Name64|, depending on the size of
|
||||
// the given value.
|
||||
//
|
||||
// The overloads are only defined for input types of size 4 and 8, respectively,
|
||||
// using enable_if and SFINAE to disable them otherwise. enable_if<bool,
|
||||
// typename> only has a "type" member if the first parameter is true, in which
|
||||
// case "type" is a typedef to the second member (here, set to "unsigned").
|
||||
// Otherwise, enable_if::type doesn't exist, making the function signature
|
||||
// invalid, and so the entire function is thrown away (without an error) due to
|
||||
// SFINAE.
|
||||
//
|
||||
// Not that we cannot simply check sizeof(T) using an if statement, as we need
|
||||
// both branches of the if to be syntactically valid even if one of the branches
|
||||
// is dead.
|
||||
#define DEFINE_32_64_OVERLOADS(Name) \
|
||||
template <typename T> \
|
||||
inline typename std::enable_if<sizeof(T) == 4, unsigned>::type Name( \
|
||||
T value) { \
|
||||
return Name##32(value); \
|
||||
} \
|
||||
\
|
||||
template <typename T> \
|
||||
inline typename std::enable_if<sizeof(T) == 8, unsigned>::type Name( \
|
||||
T value) { \
|
||||
return Name##64(value); \
|
||||
}
|
||||
|
||||
// CountPopulation32(value) returns the number of bits set in |value|.
|
||||
inline unsigned CountPopulation32(uint32_t value) {
|
||||
#if V8_HAS_BUILTIN_POPCOUNT
|
||||
@ -51,17 +78,7 @@ inline unsigned CountPopulation64(uint64_t value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Overloaded versions of CountPopulation32/64.
|
||||
inline unsigned CountPopulation(uint32_t value) {
|
||||
return CountPopulation32(value);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned CountPopulation(uint64_t value) {
|
||||
return CountPopulation64(value);
|
||||
}
|
||||
|
||||
DEFINE_32_64_OVERLOADS(CountPopulation)
|
||||
|
||||
// CountLeadingZeros32(value) returns the number of zero bits following the most
|
||||
// significant 1 bit in |value| if |value| is non-zero, otherwise it returns 32.
|
||||
@ -148,14 +165,7 @@ inline unsigned CountTrailingZeros64(uint64_t value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Overloaded versions of CountTrailingZeros32/64.
|
||||
inline unsigned CountTrailingZeros(uint32_t value) {
|
||||
return CountTrailingZeros32(value);
|
||||
}
|
||||
|
||||
inline unsigned CountTrailingZeros(uint64_t value) {
|
||||
return CountTrailingZeros64(value);
|
||||
}
|
||||
DEFINE_32_64_OVERLOADS(CountTrailingZeros)
|
||||
|
||||
// Returns true iff |value| is a power of 2.
|
||||
constexpr inline bool IsPowerOfTwo32(uint32_t value) {
|
||||
@ -330,6 +340,8 @@ V8_BASE_EXPORT int64_t SignedSaturatedAdd64(int64_t lhs, int64_t rhs);
|
||||
// checks and returns the result.
|
||||
V8_BASE_EXPORT int64_t SignedSaturatedSub64(int64_t lhs, int64_t rhs);
|
||||
|
||||
#undef DEFINE_32_64_OVERLOADS
|
||||
|
||||
} // namespace bits
|
||||
} // namespace base
|
||||
} // namespace v8
|
||||
|
@ -44,12 +44,7 @@ void BitVector::Iterator::Advance() {
|
||||
int BitVector::Count() const {
|
||||
int count = 0;
|
||||
for (int i = 0; i < data_length_; i++) {
|
||||
uintptr_t data = data_[i];
|
||||
if (sizeof(data) == 8) {
|
||||
count += base::bits::CountPopulation64(data);
|
||||
} else {
|
||||
count += base::bits::CountPopulation32(static_cast<uint32_t>(data));
|
||||
}
|
||||
count += base::bits::CountPopulation(data_[i]);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user