[ADT] Add llvm::has_single_bit helper similar to the c++20 std::has_single_bit implementation

Converted the llvm::isPowerOf2_32/64 helpers into wrappers
This commit is contained in:
Simon Pilgrim 2022-08-23 19:50:52 +01:00
parent 7171615099
commit 336a4e03a4
3 changed files with 24 additions and 2 deletions

View File

@ -34,6 +34,11 @@ inline To bit_cast(const From &from) noexcept {
return to;
}
template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
constexpr inline bool has_single_bit(T Value) noexcept {
return (Value != 0) && ((Value & (Value - 1)) == 0);
}
namespace detail {
template <typename T, std::size_t SizeOfT> struct PopulationCounter {
static int count(T Value) {

View File

@ -486,12 +486,12 @@ constexpr inline bool isShiftedMask_64(uint64_t Value) {
/// Return true if the argument is a power of two > 0.
/// Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
constexpr inline bool isPowerOf2_32(uint32_t Value) {
return Value && !(Value & (Value - 1));
return llvm::has_single_bit(Value);
}
/// Return true if the argument is a power of two > 0 (64 bit edition.)
constexpr inline bool isPowerOf2_64(uint64_t Value) {
return Value && !(Value & (Value - 1));
return llvm::has_single_bit(Value);
}
/// Count the number of ones from the most significant bit to the first

View File

@ -31,6 +31,23 @@ TEST(BitTest, BitCast) {
llvm::bit_cast<double>(llvm::bit_cast<uint64_t>(kValueF64)));
}
TEST(BitTest, HasSingleBit) {
EXPECT_FALSE(llvm::has_single_bit(0U));
EXPECT_FALSE(llvm::has_single_bit(0ULL));
EXPECT_FALSE(llvm::has_single_bit(~0U));
EXPECT_FALSE(llvm::has_single_bit(~0ULL));
EXPECT_TRUE(llvm::has_single_bit(1U));
EXPECT_TRUE(llvm::has_single_bit(1ULL));
static const int8_t kValueS8 = -128;
EXPECT_TRUE(llvm::has_single_bit(static_cast<uint8_t>(kValueS8)));
static const int16_t kValueS16 = -32768;
EXPECT_TRUE(llvm::has_single_bit(static_cast<uint16_t>(kValueS16)));
}
TEST(BitTest, PopCount) {
EXPECT_EQ(0, llvm::popcount(0U));
EXPECT_EQ(0, llvm::popcount(0ULL));