NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
bit.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_MEMORY_BIT_HPP__
2#define NEFORCE_CORE_MEMORY_BIT_HPP__
3
11
13NEFORCE_BEGIN_NAMESPACE__
14
15NEFORCE_BEGIN_CONSTANTS__
16
22
30NEFORCE_INLINE17 constexpr byte_t POPCOUNT_TABLE[256] = {
31 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2,
32 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3,
33 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,
34 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4,
35 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4,
36 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6,
37 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
38 // BitManipulation
40
41NEFORCE_END_CONSTANTS__
42
48
49#ifdef NEFORCE_ARCH_BITS_64
50
58constexpr int popcount64(const uint64_t x) noexcept {
59 return constants::POPCOUNT_TABLE[static_cast<byte_t>(x & 0xFFULL)] +
60 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 8) & 0xFFULL)] +
61 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 16) & 0xFFULL)] +
62 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 24) & 0xFFULL)] +
63 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 32) & 0xFFULL)] +
64 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 40) & 0xFFULL)] +
65 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 48) & 0xFFULL)] +
66 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 56) & 0xFFULL)];
67}
68
76NEFORCE_CONSTEXPR14 int clz64(uint64_t x) noexcept {
77 if (x == 0) {
78 return 64;
79 }
80 int n = 0;
81 if (x <= 0x00000000FFFFFFFFULL) {
82 n += 32;
83 x <<= 32;
84 }
85 if (x <= 0x0000FFFFFFFFFFFFULL) {
86 n += 16;
87 x <<= 16;
88 }
89 if (x <= 0x00FFFFFFFFFFFFFFULL) {
90 n += 8;
91 x <<= 8;
92 }
93 if (x <= 0x0FFFFFFFFFFFFFFFULL) {
94 n += 4;
95 x <<= 4;
96 }
97 if (x <= 0x3FFFFFFFFFFFFFFFULL) {
98 n += 2;
99 x <<= 2;
100 }
101 if (x <= 0x7FFFFFFFFFFFFFFFULL) {
102 n += 1;
103 }
104 return n;
105}
106
107#endif
108
116constexpr int popcount32(const uint32_t x) noexcept {
117 return constants::POPCOUNT_TABLE[static_cast<byte_t>(x & 0xFFU)] +
118 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 8) & 0xFFU)] +
119 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 16) & 0xFFU)] +
120 constants::POPCOUNT_TABLE[static_cast<byte_t>((x >> 24) & 0xFFU)];
121}
122
130NEFORCE_CONSTEXPR14 int clz32(uint32_t x) noexcept {
131 if (x == 0) {
132 return 32;
133 }
134 int n = 0;
135 if (x <= 0x0000FFFFU) {
136 n += 16;
137 x <<= 16;
138 }
139 if (x <= 0x00FFFFFFU) {
140 n += 8;
141 x <<= 8;
142 }
143 if (x <= 0x0FFFFFFFU) {
144 n += 4;
145 x <<= 4;
146 }
147 if (x <= 0x3FFFFFFFU) {
148 n += 2;
149 x <<= 2;
150 }
151 if (x <= 0x7FFFFFFFU) {
152 n += 1;
153 }
154 return n;
155}
156
164constexpr int popcount(const uintptr_t x) noexcept {
165#ifdef NEFORCE_ARCH_BITS_64
166 return popcount64(x);
167#else
168 return popcount32(x);
169#endif
170}
171
179constexpr int countl_zero(const uintptr_t x) noexcept {
180#ifdef NEFORCE_ARCH_BITS_64
181 return clz64(x);
182#else
183 return clz32(x);
184#endif
185}
186
194constexpr int countl_one(const uintptr_t x) noexcept { return countl_zero(~x); }
195
203constexpr int countr_zero(const uintptr_t x) noexcept { return popcount((x & (~x + 1)) - 1); }
204
212constexpr int countr_one(const uintptr_t x) noexcept { return countr_zero(~x); }
213
214
220constexpr int lowest_set_bit_pos(const intptr_t x) noexcept { return x == 0 ? -1 : countr_zero(x); }
221
227NEFORCE_CONSTEXPR14 int highest_set_bit_pos(const intptr_t x) noexcept {
228 if (x == 0) {
229 return -1;
230 }
231#ifdef NEFORCE_ARCH_BITS_64
232 return 63 - clz64(x);
233#else
234 return 31 - clz32(x);
235#endif
236}
237
238
246NEFORCE_CONSTEXPR14 bool parity32(uint32_t x) noexcept {
247 x ^= x >> 16;
248 x ^= x >> 8;
249 x ^= x >> 4;
250 x ^= x >> 2;
251 x ^= x >> 1;
252 return (x & 1) != 0;
253}
254
255#ifdef NEFORCE_ARCH_BITS_64
256
262NEFORCE_CONSTEXPR14 bool parity64(uint64_t x) noexcept {
263 x ^= x >> 32;
264 x ^= x >> 16;
265 x ^= x >> 8;
266 x ^= x >> 4;
267 x ^= x >> 2;
268 x ^= x >> 1;
269 return (x & 1) != 0;
270}
271
272#endif
273
281constexpr bool parity(const uintptr_t x) noexcept {
282#ifdef NEFORCE_ARCH_BITS_64
283 return parity64(x);
284#else
285 return parity32(x);
286#endif
287}
288
289
295constexpr int bit_width(const uintptr_t x) noexcept {
296#ifdef NEFORCE_ARCH_BITS_64
297 return x == 0 ? 0 : 64 - countl_zero(x);
298#else
299 return x == 0 ? 0 : 32 - countl_zero(x);
300#endif
301}
302
308constexpr uintptr_t bit_floor(const uintptr_t x) noexcept { return x == 0 ? 0 : uintptr_t{1} << (bit_width(x) - 1); }
309
315NEFORCE_CONSTEXPR14 uint64_t bit_ceil(const uintptr_t x) noexcept {
316 if (x <= 1) {
317 return 1;
318 }
319 const uint64_t floor = bit_floor(x);
320 return floor == x ? x : floor << 1;
321}
322
328constexpr bool has_single_bit(const uintptr_t x) noexcept { return x != 0 && (x & (x - 1)) == 0; }
329
336NEFORCE_CONSTEXPR14 uint32_t rotate_l32(const uint32_t x, const int s) noexcept {
337 constexpr int bits = 32;
338 const int shift = ((s % bits) + bits) % bits;
339 if (shift == 0) {
340 return x;
341 }
342 return (x << shift) | (x >> (bits - shift));
343}
344
351NEFORCE_CONSTEXPR14 uint32_t rotate_r32(const uint32_t x, const int s) noexcept { return rotate_l32(x, -s); }
352
353#ifdef NEFORCE_ARCH_BITS_64
354
361NEFORCE_CONSTEXPR14 uint64_t rotate_l64(const uint64_t x, const int s) noexcept {
362 constexpr int bits = 64;
363 const int shift = ((s % bits) + bits) % bits;
364 if (shift == 0) {
365 return x;
366 }
367 return (x << shift) | (x >> (bits - shift));
368}
369
376NEFORCE_CONSTEXPR14 uint64_t rotate_r64(const uint64_t x, const int s) noexcept { return rotate_l64(x, -s); }
377
378#endif
379
388NEFORCE_CONSTEXPR14 int rotate_l(const uintptr_t x, const int s) noexcept {
389#ifdef NEFORCE_ARCH_BITS_64
390 return rotate_l64(x, s);
391#else
392 return rotate_l32(x, s);
393#endif
394}
395
404NEFORCE_CONSTEXPR14 int rotate_r(const uintptr_t x, const int s) noexcept {
405#ifdef NEFORCE_ARCH_BITS_64
406 return rotate_r64(x, s);
407#else
408 return rotate_r32(x, s);
409#endif
410}
411
412
420constexpr uintptr_t bit_extract(const uintptr_t x, const int pos, const int len) noexcept {
421 return (x >> pos) & ((uintptr_t{1} << len) - 1);
422}
423
432NEFORCE_CONSTEXPR14 uintptr_t bit_insert(const uintptr_t x, const uintptr_t bits, const int pos,
433 const int len) noexcept {
434 const uintptr_t mask = ((uintptr_t{1} << len) - 1) << pos;
435 return (x & ~mask) | ((bits << pos) & mask);
436}
437
438
444NEFORCE_CONSTEXPR14 uint32_t reverse_bits32(uint32_t x) noexcept {
445 x = ((x >> 1) & 0x55555555U) | ((x & 0x55555555U) << 1);
446 x = ((x >> 2) & 0x33333333U) | ((x & 0x33333333U) << 2);
447 x = ((x >> 4) & 0x0F0F0F0FU) | ((x & 0x0F0F0F0FU) << 4);
448 x = ((x >> 8) & 0x00FF00FFU) | ((x & 0x00FF00FFU) << 8);
449 x = ((x >> 16) & 0x0000FFFFU) | ((x & 0x0000FFFFU) << 16);
450 return x;
451}
452
453#ifdef NEFORCE_ARCH_BITS_64
454
460NEFORCE_CONSTEXPR14 uint64_t reverse_bits64(uint64_t x) noexcept {
461 x = ((x >> 1) & 0x5555555555555555ULL) | ((x & 0x5555555555555555ULL) << 1);
462 x = ((x >> 2) & 0x3333333333333333ULL) | ((x & 0x3333333333333333ULL) << 2);
463 x = ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL) | ((x & 0x0F0F0F0F0F0F0F0FULL) << 4);
464 x = ((x >> 8) & 0x00FF00FF00FF00FFULL) | ((x & 0x00FF00FF00FF00FFULL) << 8);
465 x = ((x >> 16) & 0x0000FFFF0000FFFFULL) | ((x & 0x0000FFFF0000FFFFULL) << 16);
466 x = (x >> 32) | (x << 32);
467 return x;
468}
469
470#endif
471
479constexpr uintptr_t reverse_bits(const uintptr_t x) noexcept {
480#ifdef NEFORCE_ARCH_BITS_64
481 return reverse_bits64(x);
482#else
483 return reverse_bits32(x);
484#endif
485}
486
487
494constexpr uintptr_t mask_from_to(const int from, const int to) noexcept {
495 return ((uintptr_t{1} << (to - from + 1)) - 1) << from;
496}
497 // BitManipulation
499
500NEFORCE_END_NAMESPACE__
501#endif // NEFORCE_CORE_MEMORY_BIT_HPP__
constexpr bool parity(const uintptr_t x) noexcept
计算整数的奇偶性
constexpr int countl_one(const uintptr_t x) noexcept
计算整数前导1的个数
NEFORCE_CONSTEXPR14 bool parity32(uint32_t x) noexcept
计算32位整数的奇偶性
constexpr int popcount32(const uint32_t x) noexcept
计算32位整数中1的个数
NEFORCE_CONSTEXPR14 uint32_t rotate_r32(const uint32_t x, const int s) noexcept
32位整数循环右移
NEFORCE_CONSTEXPR14 int highest_set_bit_pos(const intptr_t x) noexcept
获取最高设置位的位置
constexpr uintptr_t mask_from_to(const int from, const int to) noexcept
生成从from到to的位掩码
constexpr int lowest_set_bit_pos(const intptr_t x) noexcept
获取最低设置位的位置,从0开始
constexpr uintptr_t reverse_bits(const uintptr_t x) noexcept
反转整数的位顺序
constexpr int popcount(const uintptr_t x) noexcept
计算整数中1的个数
NEFORCE_CONSTEXPR14 int clz32(uint32_t x) noexcept
计算32位整数前导零的个数
NEFORCE_CONSTEXPR14 uint32_t rotate_l32(const uint32_t x, const int s) noexcept
32位整数循环左移
NEFORCE_CONSTEXPR14 uintptr_t bit_insert(const uintptr_t x, const uintptr_t bits, const int pos, const int len) noexcept
向整数中插入指定位段
NEFORCE_INLINE17 constexpr byte_t POPCOUNT_TABLE[256]
popcount查找表
定义 bit.hpp:30
NEFORCE_CONSTEXPR14 int rotate_l(const uintptr_t x, const int s) noexcept
整数循环左移
NEFORCE_CONSTEXPR14 uint32_t reverse_bits32(uint32_t x) noexcept
反转32位整数的位顺序
constexpr int countr_one(const uintptr_t x) noexcept
计算整数尾随1的个数
NEFORCE_CONSTEXPR14 uint64_t bit_ceil(const uintptr_t x) noexcept
获取不小于x的最小2的幂
constexpr uintptr_t bit_extract(const uintptr_t x, const int pos, const int len) noexcept
从整数中提取指定位段
constexpr bool has_single_bit(const uintptr_t x) noexcept
检查整数是否为2的幂
constexpr int countl_zero(const uintptr_t x) noexcept
计算整数前导零的个数
constexpr uintptr_t bit_floor(const uintptr_t x) noexcept
获取不大于x的最大2的幂
NEFORCE_CONSTEXPR14 int rotate_r(const uintptr_t x, const int s) noexcept
整数循环右移
constexpr int bit_width(const uintptr_t x) noexcept
计算表示整数所需的最小位宽
constexpr int countr_zero(const uintptr_t x) noexcept
计算整数尾随零的个数
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
NEFORCE_CONST_FUNCTION NEFORCE_CONSTEXPR14 decimal_t floor(const decimal_t x) noexcept
向下取整
int64_t intptr_t
可容纳指针的有符号整数类型
uint64_t uintptr_t
可容纳指针的无符号整数类型
基本类型别名