@@ -300,11 +300,12 @@ template <typename T> [[nodiscard]] T bit_ceil(T Value) {
300300 return T (1 ) << llvm::bit_width<T>(Value - 1u );
301301}
302302
303- namespace detail {
304- template <typename T, std::size_t SizeOfT> struct PopulationCounter {
305- static int count (T Value) {
306- // Generic version, forward to 32 bits.
307- static_assert (SizeOfT <= 4 , " Not implemented!" );
303+ // / Count the number of set bits in a value.
304+ // / Ex. popcount(0xF000F000) = 8
305+ // / Returns 0 if the word is zero.
306+ template <typename T, typename = std::enable_if_t <std::is_unsigned_v<T>>>
307+ [[nodiscard]] inline int popcount (T Value) noexcept {
308+ if constexpr (sizeof (T) <= 4 ) {
308309#if defined(__GNUC__)
309310 return (int )__builtin_popcount (Value);
310311#else
@@ -313,11 +314,7 @@ template <typename T, std::size_t SizeOfT> struct PopulationCounter {
313314 v = (v & 0x33333333 ) + ((v >> 2 ) & 0x33333333 );
314315 return int (((v + (v >> 4 ) & 0xF0F0F0F ) * 0x1010101 ) >> 24 );
315316#endif
316- }
317- };
318-
319- template <typename T> struct PopulationCounter <T, 8 > {
320- static int count (T Value) {
317+ } else if constexpr (sizeof (T) <= 8 ) {
321318#if defined(__GNUC__)
322319 return (int )__builtin_popcountll (Value);
323320#else
@@ -327,16 +324,9 @@ template <typename T> struct PopulationCounter<T, 8> {
327324 v = (v + (v >> 4 )) & 0x0F0F0F0F0F0F0F0FULL ;
328325 return int ((uint64_t )(v * 0x0101010101010101ULL ) >> 56 );
329326#endif
327+ } else {
328+ static_assert (sizeof (T) == 0 , " T must be 8 bytes or less" );
330329 }
331- };
332- } // namespace detail
333-
334- // / Count the number of set bits in a value.
335- // / Ex. popcount(0xF000F000) = 8
336- // / Returns 0 if the word is zero.
337- template <typename T, typename = std::enable_if_t <std::is_unsigned_v<T>>>
338- [[nodiscard]] inline int popcount (T Value) noexcept {
339- return detail::PopulationCounter<T, sizeof (T)>::count (Value);
340330}
341331
342332// Forward-declare rotr so that rotl can use it.
0 commit comments