11 #include <type_traits> 13 #include <core/util/code_optimization.hpp> 17 #define bitsizeof(t) (8*sizeof(t)) 21 #define _ENABLE_IF_UINT(T) \ 22 typename std::enable_if<std::is_same<T, uint8_t>::value \ 23 || std::is_same<T, uint16_t>::value \ 24 || std::is_same<T, uint32_t>::value \ 25 || std::is_same<T, uint64_t>::value \ 26 || std::is_same<T, unsigned int>::value \ 27 || std::is_same<T, unsigned long>::value \ 28 || std::is_same<T, unsigned long long>::value \ 29 || std::is_same<T, uint128_t>::value>::type* = 0 34 bool static constexpr __bitsize_gt(
unsigned n) {
35 return n < bitsizeof(T);
38 #define _ENABLE_IF_BITSIZE_GT(T, n) \ 39 typename std::enable_if<__bitsize_gt<T>(n)>::type* = 0 41 #define _ENABLE_IF_BITSIZE_LEQ(T, n) \ 42 typename std::enable_if<!__bitsize_gt<T>(n)>::type* = 0 53 return ( ! ((x) & ((x) - 1) ) );
63 static inline bool bit_on(T x,
unsigned int bit, _ENABLE_IF_UINT(T)) {
64 return !!(x & (T(1) << bit));
75 static inline bool bit_off(T x,
unsigned int bit, _ENABLE_IF_UINT(T))
77 return (x & (T(1) << bit) ) == 0;
87 static inline void set_bit_off(T& x,
unsigned int bit, _ENABLE_IF_UINT(T))
89 x &= (~((T(1) << bit)));
99 static inline void set_bit_on(T& x,
unsigned int bit, _ENABLE_IF_UINT(T))
110 template <
typename T>
111 static inline void flip_bit(T& x,
unsigned int bit, _ENABLE_IF_UINT(T))
124 template <
typename T>
125 static inline T
bit_mask(
unsigned int n_bits, _ENABLE_IF_UINT(T)) {
127 static constexpr
unsigned int _n_mask = ~static_cast<
unsigned int>(bitsizeof(T) - 1);
129 return UNLIKELY(n_bits & _n_mask) ? T(-1) : (T(1) << n_bits) - 1;
139 template <
typename T>
140 static inline T
bit_mask(
size_t index_begin,
unsigned int index_end, _ENABLE_IF_UINT(T)) {
141 return bit_mask<T>(index_begin) ^ bit_mask<T>(index_end);
145 #pragma clang diagnostic push 146 #pragma clang diagnostic ignored "-Wshift-count-overflow" 153 template <
typename T>
156 if(
sizeof(
unsigned int) >=
sizeof(T))
157 return __builtin_popcount((
unsigned int)v);
158 else if(
sizeof(
unsigned long) >=
sizeof(T))
159 return __builtin_popcountl((
unsigned long)v);
160 else if(
sizeof(
unsigned long long) >=
sizeof(T))
161 return __builtin_popcountll((
unsigned long long)v);
162 else if(bitsizeof(
unsigned long long) == 64 && bitsizeof(T) == 128)
165 return (__builtin_popcountll((
unsigned long long)(v))
166 + __builtin_popcountll((
unsigned long long)(uint64_t(uint128_t(v) >> 64))));
168 unsigned int bitcount = 0;
170 for(
size_t i = 0; i < bitsizeof(T); i += bitsizeof(
unsigned long long) ) {
171 bitcount += __builtin_popcountll( (
unsigned long long)(vt) );
172 vt = T(uint128_t(vt) >> bitsizeof(
unsigned long long));
180 #pragma clang diagnostic pop 182 template <
int n,
typename T>
183 static inline void __n_trailing_zeros_disect(
184 T& v,
int& c, _ENABLE_IF_BITSIZE_GT(T, n)) {
186 if( T(v << (bitsizeof(T) - n)) == 0) {
192 template <
int n,
typename T>
193 static inline void __n_trailing_zeros_disect(
194 T& v,
int& c, _ENABLE_IF_BITSIZE_LEQ(T, n)) {
205 template <
typename T>
207 if(!v)
return bitsizeof(T);
209 if(
sizeof(
unsigned int) >=
sizeof(T))
210 return __builtin_ctz((
unsigned int)v);
211 else if(
sizeof(
unsigned long) >=
sizeof(T))
212 return __builtin_ctzl((
unsigned long)v);
213 else if(
sizeof(
unsigned long long) >=
sizeof(T))
214 return __builtin_ctzll((
unsigned long long)v);
215 else if(bitsizeof(
unsigned long long) == 64 && bitsizeof(T) == 128)
216 return ((uint64_t(v) != 0)
217 ? __builtin_ctzll((
unsigned long long)v)
218 : (64 + __builtin_ctzll((
unsigned long long)(uint128_t(v) >> 64))));
225 __n_trailing_zeros_disect<128>(v, c);
226 __n_trailing_zeros_disect<64>(v, c);
227 __n_trailing_zeros_disect<32>(v, c);
228 __n_trailing_zeros_disect<16>(v, c);
229 __n_trailing_zeros_disect<8>(v, c);
230 __n_trailing_zeros_disect<4>(v, c);
231 __n_trailing_zeros_disect<2>(v, c);
232 __n_trailing_zeros_disect<1>(v, c);
247 template <
typename T>
259 template <
typename T>
267 template <
int n,
typename T>
268 static inline void __n_leading_zeros_disect(T& v,
int& c, _ENABLE_IF_BITSIZE_GT(T, n)) {
269 if((v >> (bitsizeof(T) - n)) == 0) {
274 template <
int n,
typename T>
275 static inline void __n_leading_zeros_disect(T& v,
int& c, _ENABLE_IF_BITSIZE_LEQ(T, n))
286 template <
typename T>
289 if(!v)
return bitsizeof(T);
292 if(
sizeof(
unsigned int) >=
sizeof(T))
293 return __builtin_clz((
unsigned int)v) - (bitsizeof(
unsigned int) - bitsizeof(T));
294 else if(
sizeof(
unsigned long) >=
sizeof(T))
295 return __builtin_clzl((
unsigned long)v) - (bitsizeof(
unsigned long) - bitsizeof(T));
296 else if(
sizeof(
unsigned long long) >=
sizeof(T))
297 return __builtin_clzll((
unsigned long long)v) - (bitsizeof(
unsigned long long) - bitsizeof(T));
298 else if(bitsizeof(
unsigned long long) == 64 && bitsizeof(v) == 128)
299 return (((uint128_t(v) >> 64) != 0)
300 ? __builtin_clzll((
unsigned long long)(uint128_t(v) >> 64))
301 : (64 + __builtin_clzll((
unsigned long long)(v))));
308 __n_leading_zeros_disect<128>(v, c);
309 __n_leading_zeros_disect<64>(v, c);
310 __n_leading_zeros_disect<32>(v, c);
311 __n_leading_zeros_disect<16>(v, c);
312 __n_leading_zeros_disect<8>(v, c);
313 __n_leading_zeros_disect<4>(v, c);
314 __n_leading_zeros_disect<2>(v, c);
315 __n_leading_zeros_disect<1>(v, c);
330 template <
typename T>
342 template <
typename T>
355 template <
typename T>
368 template <
typename T>
382 template <
typename T>
384 return (!! pow2_idx) * bit_mask<T>(pow2_idx) & v;
393 template <
typename T>
394 static inline bool first_n_bits_on(
const T& v,
unsigned int top_bit, _ENABLE_IF_UINT(T)) {
395 return (v & bit_mask<T>(top_bit)) == bit_mask<T>(top_bit);
static unsigned int n_trailing_zeros(T v, _ENABLE_IF_UINT(T))
static T bitwise_pow2_mod(const T &v, unsigned pow2_idx, _ENABLE_IF_UINT(T))
static unsigned int n_leading_zeros(T v, _ENABLE_IF_UINT(T))
static unsigned int num_bits_on(T v, _ENABLE_IF_UINT(T))
static unsigned int n_trailing_ones(const T &v, _ENABLE_IF_UINT(T))
static unsigned int bitwise_log2_floor(const T &v, _ENABLE_IF_UINT(T))
static bool bit_on(T x, unsigned int bit, _ENABLE_IF_UINT(T))
static bool is_power_of_2(const T &x, _ENABLE_IF_UINT(T))
static unsigned int index_last_on_bit(const T &v, _ENABLE_IF_UINT(T))
static void flip_bit(T &x, unsigned int bit, _ENABLE_IF_UINT(T))
static T bit_mask(unsigned int n_bits, _ENABLE_IF_UINT(T))
static void set_bit_on(T &x, unsigned int bit, _ENABLE_IF_UINT(T))
static unsigned int n_leading_ones(T v, _ENABLE_IF_UINT(T))
static bool first_n_bits_on(const T &v, unsigned int top_bit, _ENABLE_IF_UINT(T))
static unsigned int bitwise_log2_ceil(const T &v, _ENABLE_IF_UINT(T))
static void set_bit_off(T &x, unsigned int bit, _ENABLE_IF_UINT(T))
static unsigned int index_first_on_bit(const T &v, _ENABLE_IF_UINT(T))
static bool bit_off(T x, unsigned int bit, _ENABLE_IF_UINT(T))