MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
bit.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_MEMORY_BIT_HPP__
2#define MSTL_CORE_MEMORY_BIT_HPP__
3
11
14
20
28MSTL_INLINE17 constexpr byte_t POPCOUNT_TABLE[256] = {
29 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,
30 1,2,2,3,2,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,
31 1,2,2,3,2,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,
32 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,6,7,
33 1,2,2,3,2,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,
34 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,6,7,
35 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,6,7,
36 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
37};
38
40
46
47#ifdef MSTL_DATA_BUS_WIDTH_64__
48
56constexpr int popcount64(const uint64_t x) noexcept {
57 return
58 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>(x & 0xFFULL)] +
59 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 8) & 0xFFULL)] +
60 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 16) & 0xFFULL)] +
61 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 24) & 0xFFULL)] +
62 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 32) & 0xFFULL)] +
63 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 40) & 0xFFULL)] +
64 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 48) & 0xFFULL)] +
65 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 56) & 0xFFULL)];
66}
67
75MSTL_CONSTEXPR14 int clz64(uint64_t x) noexcept {
76 if (x == 0) return 64;
77 int n = 0;
78 if (x <= 0x00000000FFFFFFFFULL) { n += 32; x <<= 32; }
79 if (x <= 0x0000FFFFFFFFFFFFULL) { n += 16; x <<= 16; }
80 if (x <= 0x00FFFFFFFFFFFFFFULL) { n += 8; x <<= 8; }
81 if (x <= 0x0FFFFFFFFFFFFFFFULL) { n += 4; x <<= 4; }
82 if (x <= 0x3FFFFFFFFFFFFFFFULL) { n += 2; x <<= 2; }
83 if (x <= 0x7FFFFFFFFFFFFFFFULL) { n += 1; }
84 return n;
85}
86
87#endif
88
96constexpr int popcount32(const uint32_t x) noexcept {
97 return
98 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>(x & 0xFFU)] +
99 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 8) & 0xFFU)] +
100 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 16) & 0xFFU)] +
101 _CONSTANTS POPCOUNT_TABLE[static_cast<byte_t>((x >> 24) & 0xFFU)];
102}
103
111MSTL_CONSTEXPR14 int clz32(uint32_t x) noexcept {
112 if (x == 0) return 32;
113 int n = 0;
114 if (x <= 0x0000FFFFU) { n += 16; x <<= 16; }
115 if (x <= 0x00FFFFFFU) { n += 8; x <<= 8; }
116 if (x <= 0x0FFFFFFFU) { n += 4; x <<= 4; }
117 if (x <= 0x3FFFFFFFU) { n += 2; x <<= 2; }
118 if (x <= 0x7FFFFFFFU) { n += 1; }
119 return n;
120}
121
129constexpr int popcount(const uintptr_t x) noexcept {
130#ifdef MSTL_DATA_BUS_WIDTH_64__
131 return popcount64(x);
132#else
133 return popcount32(x);
134#endif
135}
136
144constexpr int countl_zero(const uintptr_t x) noexcept {
145#ifdef MSTL_DATA_BUS_WIDTH_64__
146 return clz64(x);
147#else
148 return clz32(x);
149#endif
150}
151
159constexpr int countl_one(const uintptr_t x) noexcept {
160 return countl_zero(~x);
161}
162
170constexpr int countr_zero(const uintptr_t x) noexcept {
171 return popcount((x & (~x + 1)) - 1);
172}
173
181constexpr int countr_one(const uintptr_t x) noexcept {
182 return countr_zero(~x);
183}
184
185
191constexpr int lowest_set_bit_pos(const intptr_t x) noexcept {
192 return x == 0 ? -1 : countr_zero(x);
193}
194
200MSTL_CONSTEXPR14 int highest_set_bit_pos(const intptr_t x) noexcept {
201 if (x == 0) return -1;
202#ifdef MSTL_DATA_BUS_WIDTH_64__
203 return 63 - clz64(x);
204#else
205 return 31 - clz32(x);
206#endif
207}
208
209
217MSTL_CONSTEXPR14 bool parity32(uint32_t x) noexcept {
218 x ^= x >> 16;
219 x ^= x >> 8;
220 x ^= x >> 4;
221 x ^= x >> 2;
222 x ^= x >> 1;
223 return (x & 1) != 0;
224}
225
226#ifdef MSTL_DATA_BUS_WIDTH_64__
227
233MSTL_CONSTEXPR14 bool parity64(uint64_t x) noexcept {
234 x ^= x >> 32;
235 x ^= x >> 16;
236 x ^= x >> 8;
237 x ^= x >> 4;
238 x ^= x >> 2;
239 x ^= x >> 1;
240 return (x & 1) != 0;
241}
242
243#endif
244
252constexpr bool parity(const uintptr_t x) noexcept {
253#ifdef MSTL_DATA_BUS_WIDTH_64__
254 return parity64(x);
255#else
256 return parity32(x);
257#endif
258}
259 // BitCounting
261
267
273constexpr int bit_width(const uintptr_t x) noexcept {
274#ifdef MSTL_DATA_BUS_WIDTH_64__
275 return x == 0 ? 0 : 64 - countl_zero(x);
276#else
277 return x == 0 ? 0 : 32 - countl_zero(x);
278#endif
279}
280
286constexpr uintptr_t bit_floor(const uintptr_t x) noexcept {
287 return x == 0 ? 0 : uintptr_t{1} << (bit_width(x) - 1);
288}
289
295MSTL_CONSTEXPR14 uint64_t bit_ceil(const uintptr_t x) noexcept {
296 if (x <= 1) return 1;
297 const uint64_t floor = bit_floor(x);
298 return floor == x ? x : floor << 1;
299}
300
306constexpr bool has_single_bit(const uintptr_t x) noexcept {
307 return x != 0 && (x & (x - 1)) == 0;
308}
309
316MSTL_CONSTEXPR14 uint32_t rotate_l32(const uint32_t x, const int s) noexcept {
317 constexpr int bits = 32;
318 int shift = s % bits;
319 if (shift < 0) shift += bits;
320 if (shift == 0) return x;
321 return (x << shift) | (x >> (bits - shift));
322}
323
330MSTL_CONSTEXPR14 uint32_t rotate_r32(const uint32_t x, const int s) noexcept {
331 constexpr int bits = 32;
332 int shift = s % bits;
333 if (shift < 0) shift += bits;
334 if (shift == 0) return x;
335 return (x >> shift) | (x << (bits - shift));
336}
337
338#ifdef MSTL_DATA_BUS_WIDTH_64__
339
346MSTL_CONSTEXPR14 uint64_t rotate_l64(const uint64_t x, const int s) noexcept {
347 constexpr int bits = 64;
348 int shift = s % bits;
349 if (shift < 0) shift += bits;
350 if (shift == 0) return x;
351 return (x << shift) | (x >> (bits - shift));
352}
353
360MSTL_CONSTEXPR14 uint64_t rotate_r64(const uint64_t x, const int s) noexcept {
361 constexpr int bits = 64;
362 int shift = s % bits;
363 if (shift < 0) shift += bits;
364 if (shift == 0) return x;
365 return (x >> shift) | (x << (bits - shift));
366}
367
368#endif
369
378MSTL_CONSTEXPR14 int rotate_l(const uintptr_t x, const int s) noexcept {
379#ifdef MSTL_DATA_BUS_WIDTH_64__
380 return rotate_l64(x, s);
381#else
382 return rotate_l32(x, s);
383#endif
384}
385
394MSTL_CONSTEXPR14 int rotate_r(const uintptr_t x, const int s) noexcept {
395#ifdef MSTL_DATA_BUS_WIDTH_64__
396 return rotate_r64(x, s);
397#else
398 return rotate_r32(x, s);
399#endif
400}
401
402
410constexpr uintptr_t bit_extract(const uintptr_t x, const int pos, const int len) noexcept {
411 return (x >> pos) & ((uintptr_t{1} << len) - 1);
412}
413
422MSTL_CONSTEXPR14 uintptr_t bit_insert(const uintptr_t x, const uintptr_t bits, const int pos, const int len) noexcept {
423 const uintptr_t mask = ((uintptr_t{1} << len) - 1) << pos;
424 return (x & ~mask) | ((bits << pos) & mask);
425}
426
427
433MSTL_CONSTEXPR14 uint32_t reverse_bits32(uint32_t x) noexcept {
434 x = ((x >> 1) & 0x55555555U) | ((x & 0x55555555U) << 1);
435 x = ((x >> 2) & 0x33333333U) | ((x & 0x33333333U) << 2);
436 x = ((x >> 4) & 0x0F0F0F0FU) | ((x & 0x0F0F0F0FU) << 4);
437 x = ((x >> 8) & 0x00FF00FFU) | ((x & 0x00FF00FFU) << 8);
438 x = ((x >> 16) & 0x0000FFFFU) | ((x & 0x0000FFFFU) << 16);
439 return x;
440}
441
442#ifdef MSTL_DATA_BUS_WIDTH_64__
443
449MSTL_CONSTEXPR14 uint64_t reverse_bits64(uint64_t x) noexcept {
450 x = ((x >> 1) & 0x5555555555555555ULL) | ((x & 0x5555555555555555ULL) << 1);
451 x = ((x >> 2) & 0x3333333333333333ULL) | ((x & 0x3333333333333333ULL) << 2);
452 x = ((x >> 4) & 0x0F0F0F0F0F0F0F0FULL) | ((x & 0x0F0F0F0F0F0F0F0FULL) << 4);
453 x = ((x >> 8) & 0x00FF00FF00FF00FFULL) | ((x & 0x00FF00FF00FF00FFULL) << 8);
454 x = ((x >> 16) & 0x0000FFFF0000FFFFULL) | ((x & 0x0000FFFF0000FFFFULL) << 16);
455 x = (x >> 32) | (x << 32);
456 return x;
457}
458
459#endif
460
468constexpr uintptr_t reverse_bits(const uintptr_t x) noexcept {
469#ifdef MSTL_DATA_BUS_WIDTH_64__
470 return reverse_bits64(x);
471#else
472 return reverse_bits32(x);
473#endif
474}
475
476
483constexpr uintptr_t mask_from_to(const int from, const int to) noexcept {
484 return ((uintptr_t{1} << (to - from + 1)) - 1) << from;
485}
486 // BitManipulation
488
490#endif // MSTL_CORE_MEMORY_BIT_HPP__
MSTL_CONSTEXPR14 int clz32(uint32_t x) noexcept
计算32位整数前导零的个数
constexpr bool parity(const uintptr_t x) noexcept
计算整数的奇偶性
constexpr int countl_one(const uintptr_t x) noexcept
计算整数前导1的个数
constexpr int popcount32(const uint32_t x) noexcept
计算32位整数中1的个数
定义 bit.hpp:96
constexpr int lowest_set_bit_pos(const intptr_t x) noexcept
获取最低设置位的位置,从0开始
constexpr int popcount(const uintptr_t x) noexcept
计算整数中1的个数
MSTL_CONSTEXPR14 int highest_set_bit_pos(const intptr_t x) noexcept
获取最高设置位的位置
MSTL_CONSTEXPR14 bool parity32(uint32_t x) noexcept
计算32位整数的奇偶性
constexpr int countr_one(const uintptr_t x) noexcept
计算整数尾随1的个数
constexpr int countl_zero(const uintptr_t x) noexcept
计算整数前导零的个数
constexpr int countr_zero(const uintptr_t x) noexcept
计算整数尾随零的个数
constexpr uintptr_t mask_from_to(const int from, const int to) noexcept
生成从from到to的位掩码
constexpr uintptr_t reverse_bits(const uintptr_t x) noexcept
反转整数的位顺序
MSTL_CONSTEXPR14 uint32_t reverse_bits32(uint32_t x) noexcept
反转32位整数的位顺序
MSTL_CONSTEXPR14 uint64_t bit_ceil(const uintptr_t x) noexcept
获取不小于x的最小2的幂
MSTL_CONSTEXPR14 int rotate_r(const uintptr_t x, const int s) noexcept
整数循环右移
MSTL_CONSTEXPR14 int rotate_l(const uintptr_t x, const int s) noexcept
整数循环左移
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的幂
MSTL_CONSTEXPR14 uint32_t rotate_r32(const uint32_t x, const int s) noexcept
32位整数循环右移
constexpr uintptr_t bit_floor(const uintptr_t x) noexcept
获取不大于x的最大2的幂
MSTL_CONSTEXPR14 uint32_t rotate_l32(const uint32_t x, const int s) noexcept
32位整数循环左移
constexpr int bit_width(const uintptr_t x) noexcept
计算表示整数所需的最小位宽
MSTL_CONSTEXPR14 uintptr_t bit_insert(const uintptr_t x, const uintptr_t bits, const int pos, const int len) noexcept
向整数中插入指定位段
unsigned char byte_t
字节类型,定义为无符号字符
unsigned int uint32_t
32位无符号整数类型
unsigned long long uint64_t
64位无符号整数类型
MSTL_CONST_FUNCTION MSTL_CONSTEXPR14 decimal_t floor(const decimal_t x) noexcept
向下取整
#define MSTL_END_CONSTANTS__
结束constants命名空间
#define _CONSTANTS
constants命名空间前缀
#define MSTL_BEGIN_CONSTANTS__
开始constants命名空间
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
int64_t intptr_t
可容纳指针的有符号整数类型
uint64_t uintptr_t
可容纳指针的无符号整数类型
MSTL基本类型别名