ascii-chat 0.6.0
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
bits.h
Go to the documentation of this file.
1#pragma once
2
29#include <stdint.h>
30#include <stdbool.h>
31#include <stddef.h>
32
33#if defined(_MSC_VER) && !defined(__clang__)
34#include <intrin.h>
35#endif
36
37/* ============================================================================
38 * Power-of-Two Operations
39 * ============================================================================
40 */
41
61static inline bool is_power_of_two(size_t n) {
62 return n && !(n & (n - 1));
63}
64
84static inline size_t next_power_of_two(size_t n) {
85 if (n == 0)
86 return 1;
87 n--;
88 n |= n >> 1;
89 n |= n >> 2;
90 n |= n >> 4;
91 n |= n >> 8;
92 n |= n >> 16;
93 if (sizeof(size_t) > 4) {
94 n |= n >> 32;
95 }
96 return n + 1;
97}
98
99/* ============================================================================
100 * Leading/Trailing Zero Detection
101 * ============================================================================
102 */
103
126static inline int find_first_set_bit(uint64_t mask) {
127#if defined(__GNUC__) || defined(__clang__)
128 // GCC/Clang builtin (fast hardware instruction on modern CPUs)
129 if (mask == 0)
130 return 64;
131 return __builtin_ctzll(mask);
132#elif defined(_MSC_VER) && defined(_M_X64)
133 // Microsoft Visual C++ x64 intrinsic
134 unsigned long index;
135 if (_BitScanForward64(&index, mask)) {
136 return (int)index;
137 }
138 return 64; // No bits set
139#elif defined(_MSC_VER)
140 // MSVC x86 fallback
141 unsigned long index;
142 if (_BitScanForward(&index, (unsigned long)mask)) {
143 return (int)index;
144 }
145 if (_BitScanForward(&index, (unsigned long)(mask >> 32))) {
146 return 32 + (int)index;
147 }
148 return 64; // No bits set
149#else
150 // De Bruijn sequence fallback: O(1) with ~4-5 CPU cycles
151 // Portable and production-tested (used in LLVM, GCC)
152 if (mask == 0)
153 return 64;
154
155 static const int debruijn_table[64] = {0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
156 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
157 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
158 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12};
159
160 // Isolate rightmost bit and hash using De Bruijn multiplication
161 return debruijn_table[((mask & -mask) * 0x022fdd63cc95386dULL) >> 58];
162#endif
163}
164
165/* ============================================================================
166 * Bit Counting Operations
167 * ============================================================================
168 */
169
187static inline int count_set_bits(uint64_t x) {
188#if defined(__GNUC__) || defined(__clang__)
189 return __builtin_popcountll(x);
190#elif defined(_MSC_VER) && defined(_M_X64)
191 return (int)__popcnt64(x);
192#else
193 // Software fallback
194 int count = 0;
195 while (x) {
196 count += x & 1;
197 x >>= 1;
198 }
199 return count;
200#endif
201}
202
unsigned long long uint64_t
Definition common.h:59