Skip to content

Commit d17871f

Browse files
committed
Add ones_count and zeros_count bitwise utilities.
1 parent 3450a1f commit d17871f

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

include/bitcoin/system/impl/math/bits.ipp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ constexpr size_t right_ones(Value value) NOEXCEPT
7373
return to_unsigned(std::countr_one<Value>(value));
7474
}
7575

76+
template <typename Value, if_unsigned_integer<Value>>
77+
constexpr size_t ones_count(Value value) NOEXCEPT
78+
{
79+
return to_unsigned(std::popcount<Value>(value));
80+
}
81+
82+
template <typename Value, if_unsigned_integer<Value>>
83+
constexpr size_t zeros_count(Value value) NOEXCEPT
84+
{
85+
return to_unsigned(std::popcount<Value>(bit_not(value)));
86+
}
87+
7688
// Bitwise logical operations.
7789
// ----------------------------------------------------------------------------
7890

include/bitcoin/system/math/bits.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ constexpr size_t left_ones(Value value) NOEXCEPT;
5151
template <typename Value, if_unsigned_integer<Value> = true>
5252
constexpr size_t right_ones(Value value) NOEXCEPT;
5353

54+
// Because std::popcount (C++20) function returns int.
55+
template <typename Value, if_unsigned_integer<Value> = true>
56+
constexpr size_t ones_count(Value value) NOEXCEPT;
57+
template <typename Value, if_unsigned_integer<Value> = true>
58+
constexpr size_t zeros_count(Value value) NOEXCEPT;
59+
5460
/// Bitwise logical operations.
5561
/// ---------------------------------------------------------------------------
5662

test/math/bits.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ static_assert(right_zeros(uint8_t{ 0b11111111 }) == 0);
123123
static_assert(right_zeros(uint8_t{ 0b00011100 }) == 2);
124124
static_assert(right_zeros(uint8_t{ 0b00011101 }) == 0);
125125

126+
static_assert(zeros_count(uint8_t{ 0b00000000 }) == 8);
127+
static_assert(zeros_count(uint8_t{ 0b11111111 }) == 0);
128+
static_assert(zeros_count(uint8_t{ 0b01111111 }) == 1);
129+
static_assert(zeros_count(uint8_t{ 0b11100011 }) == 3);
130+
126131
// ones
127132

128133
static_assert(left_ones(uint8_t{ 0b00000000 }) == 0);
@@ -135,6 +140,11 @@ static_assert(right_ones(uint8_t{ 0b11111111 }) == 8);
135140
static_assert(right_ones(uint8_t{ 0b11111110 }) == 0);
136141
static_assert(right_ones(uint8_t{ 0b11100011 }) == 2);
137142

143+
static_assert(ones_count(uint8_t{ 0b00000000 }) == 0);
144+
static_assert(ones_count(uint8_t{ 0b11111111 }) == 8);
145+
static_assert(ones_count(uint8_t{ 0b11110000 }) == 4);
146+
static_assert(ones_count(uint8_t{ 0b00011110 }) == 4);
147+
138148
// ones_complement (NOT)
139149
// inverts all bits (~n, !bool)
140150
static_assert(bit_not(-4) == 3);

0 commit comments

Comments
 (0)