Skip to content

Commit 3d400c6

Browse files
[libc][support][UInt] implement 128b popcount
We could have used this in the implementation of UInt::has_single_bit, but has_single_bit has a perhaps useful early return.
1 parent 362d263 commit 3d400c6

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

libc/src/__support/UInt.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,17 @@ bit_cast(const UInt<Bits> &from) {
10821082
return cpp::bit_cast<To>(from.val);
10831083
}
10841084

1085+
// Specialization of cpp::popcount ('bit.h') for BigInt.
1086+
template <typename T>
1087+
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, int>
1088+
popcount(T value) {
1089+
int bits = 0;
1090+
for (auto word : value.val)
1091+
if (word)
1092+
bits += popcount(word);
1093+
return bits;
1094+
}
1095+
10851096
// Specialization of cpp::has_single_bit ('bit.h') for BigInt.
10861097
template <typename T>
10871098
[[nodiscard]] LIBC_INLINE constexpr cpp::enable_if_t<is_big_int_v<T>, bool>

libc/test/src/__support/CPP/bit_test.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@
1515

1616
namespace LIBC_NAMESPACE::cpp {
1717

18-
using UnsignedTypesNoBigInt = testing::TypeList<
19-
#if defined(LIBC_TYPES_HAS_INT128)
20-
__uint128_t,
21-
#endif // LIBC_TYPES_HAS_INT128
22-
unsigned char, unsigned short, unsigned int, unsigned long,
23-
unsigned long long>;
24-
2518
using UnsignedTypes = testing::TypeList<
2619
#if defined(LIBC_TYPES_HAS_INT128)
2720
__uint128_t,
@@ -228,7 +221,7 @@ TEST(LlvmLibcBitTest, Rotr) {
228221
rotr<uint64_t>(0x12345678deadbeefULL, -19));
229222
}
230223

231-
TYPED_TEST(LlvmLibcBitTest, CountOnes, UnsignedTypesNoBigInt) {
224+
TYPED_TEST(LlvmLibcBitTest, CountOnes, UnsignedTypes) {
232225
EXPECT_EQ(popcount(T(0)), 0);
233226
for (int i = 0; i != cpp::numeric_limits<T>::digits; ++i)
234227
EXPECT_EQ(popcount<T>(cpp::numeric_limits<T>::max() >> i),

0 commit comments

Comments
 (0)