| 144 | /** Compute the smallest power of two that is larger than val. */ |
| 145 | template<typename I> |
| 146 | static inline int CountBits(I val, int max) { |
| 147 | #if defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L |
| 148 | // c++20 impl |
| 149 | (void)max; |
| 150 | return std::bit_width(val); |
| 151 | #elif defined(_MSC_VER) |
| 152 | (void)max; |
| 153 | unsigned long index; |
| 154 | unsigned char ret; |
| 155 | if (std::numeric_limits<I>::digits <= 32) { |
| 156 | ret = _BitScanReverse(&index, val); |
| 157 | } else { |
| 158 | ret = _BitScanReverse64(&index, val); |
| 159 | } |
| 160 | if (!ret) return 0; |
| 161 | return index + 1; |
| 162 | #elif HAVE_CLZ |
| 163 | (void)max; |
| 164 | if (val == 0) return 0; |
| 165 | if (std::numeric_limits<unsigned>::digits >= std::numeric_limits<I>::digits) { |
| 166 | return std::numeric_limits<unsigned>::digits - __builtin_clz(val); |
| 167 | } else if (std::numeric_limits<unsigned long>::digits >= std::numeric_limits<I>::digits) { |
| 168 | return std::numeric_limits<unsigned long>::digits - __builtin_clzl(val); |
| 169 | } else { |
| 170 | return std::numeric_limits<unsigned long long>::digits - __builtin_clzll(val); |
| 171 | } |
| 172 | #else |
| 173 | while (max && (val >> (max - 1) == 0)) --max; |
| 174 | return max; |
| 175 | #endif |
| 176 | } |
| 177 | |
| 178 | template<typename I, int BITS> |
| 179 | class BitsInt { |