18#include "absl/flags/flag.h"
19#include "absl/log/check.h"
22 "threshold to count bits with buckets");
28#define BIT_COUNT_RANGE(size, zero) \
29 uint##size##_t BitCountRange##size(const uint##size##_t* const bits, \
30 uint##size##_t start, \
31 uint##size##_t end) { \
32 if (static_cast<int##size##_t>(end - start) > \
33 absl::GetFlag(FLAGS_bitset_small_bitset_count)) { \
34 const int offset_start = BitOffset##size(start); \
35 const int pos_start = BitPos##size(start); \
36 const int offset_end = BitOffset##size(end); \
37 const int pos_end = BitPos##size(end); \
38 if (offset_end == offset_start) { \
39 return BitCount##size(bits[offset_start] & \
40 OneRange##size(pos_start, pos_end)); \
42 uint##size##_t bit_count = zero; \
44 BitCount##size(bits[offset_start] & IntervalUp##size(pos_start)); \
45 for (int offset = offset_start + 1; offset < offset_end; ++offset) { \
46 bit_count += BitCount##size(bits[offset]); \
49 BitCount##size(bits[offset_end] & IntervalDown##size(pos_end)); \
53 uint##size##_t bit_count = zero; \
54 for (uint##size##_t i = start; i <= end; ++i) { \
55 bit_count += IsBitSet##size(bits, i); \
66#define IS_EMPTY_RANGE(size) \
67 bool IsEmptyRange##size(const uint##size##_t* const bits, \
68 uint##size##_t start, uint##size##_t end) { \
69 const int offset_start = BitOffset##size(start); \
70 const int pos_start = BitPos##size(start); \
71 const int offset_end = BitOffset##size(end); \
72 const int pos_end = BitPos##size(end); \
73 if (offset_end == offset_start) { \
74 if (bits[offset_start] & OneRange##size(pos_start, pos_end)) { \
78 if (bits[offset_start] & IntervalUp##size(pos_start)) { \
81 for (int offset = offset_start + 1; offset < offset_end; ++offset) { \
86 if (bits[offset_end] & IntervalDown##size(pos_end)) { \
98#define LEAST_SIGNIFCANT_BIT_POSITION(size) \
99 int##size##_t LeastSignificantBitPosition##size( \
100 const uint##size##_t* const bits, uint##size##_t start, \
101 uint##size##_t end) { \
102 DCHECK_LE(start, end); \
103 if (IsBitSet##size(bits, start)) { \
106 const int offset_start = BitOffset##size(start); \
107 const int offset_end = BitOffset##size(end); \
108 const int pos_start = BitPos##size(start); \
109 if (offset_start == offset_end) { \
110 const int pos_end = BitPos##size(end); \
111 const uint##size##_t active_range = \
112 bits[offset_start] & OneRange##size(pos_start, pos_end); \
113 if (active_range) { \
114 return BitShift##size(offset_start) + \
115 LeastSignificantBitPosition##size(active_range); \
119 const uint##size##_t start_mask = \
120 bits[offset_start] & IntervalUp##size(pos_start); \
122 return BitShift##size(offset_start) + \
123 LeastSignificantBitPosition##size(start_mask); \
125 for (int offset = offset_start + 1; offset < offset_end; ++offset) { \
126 if (bits[offset]) { \
127 return BitShift##size(offset) + \
128 LeastSignificantBitPosition##size(bits[offset]); \
131 const int pos_end = BitPos##size(end); \
132 const uint##size##_t active_range = \
133 bits[offset_end] & IntervalDown##size(pos_end); \
134 if (active_range) { \
135 return BitShift##size(offset_end) + \
136 LeastSignificantBitPosition##size(active_range); \
147#undef LEAST_SIGNIFCANT_BIT_POSITION
149#define MOST_SIGNIFICANT_BIT_POSITION(size) \
150 int##size##_t MostSignificantBitPosition##size( \
151 const uint##size##_t* const bits, uint##size##_t start, \
152 uint##size##_t end) { \
153 DCHECK_GE(end, start); \
154 if (IsBitSet##size(bits, end)) { \
157 const int offset_start = BitOffset##size(start); \
158 const int offset_end = BitOffset##size(end); \
159 const int pos_end = BitPos##size(end); \
160 if (offset_start == offset_end) { \
161 const int pos_start = BitPos##size(start); \
162 const uint##size##_t active_range = \
163 bits[offset_start] & OneRange##size(pos_start, pos_end); \
164 if (active_range) { \
165 return BitShift##size(offset_end) + \
166 MostSignificantBitPosition##size(active_range); \
171 const uint##size##_t end_mask = \
172 bits[offset_end] & IntervalDown##size(pos_end); \
174 return BitShift##size(offset_end) + \
175 MostSignificantBitPosition##size(end_mask); \
177 for (int offset = offset_end - 1; offset > offset_start; --offset) { \
178 if (bits[offset]) { \
179 return BitShift##size(offset) + \
180 MostSignificantBitPosition##size(bits[offset]); \
183 const int pos_start = BitPos##size(start); \
184 const uint##size##_t active_range = \
185 bits[offset_start] & IntervalUp##size(pos_start); \
186 if (active_range) { \
187 return BitShift##size(offset_start) + \
188 MostSignificantBitPosition##size(active_range); \
199#undef MOST_SIGNIFICANT_BIT_POSITION
201#define UNSAFE_LEAST_SIGNIFICANT_BIT_POSITION(size) \
202 int##size##_t UnsafeLeastSignificantBitPosition##size( \
203 const uint##size##_t* const bits, uint##size##_t start, \
204 uint##size##_t end) { \
205 DCHECK_LE(start, end); \
206 DCHECK(IsBitSet##size(bits, end)); \
207 if (IsBitSet##size(bits, start)) { \
210 const int offset_start = BitOffset##size(start); \
211 const int offset_end = BitOffset##size(end); \
212 const int pos_start = BitPos##size(start); \
213 const uint##size##_t start_mask = \
214 bits[offset_start] & IntervalUp##size(pos_start); \
216 return BitShift##size(offset_start) + \
217 LeastSignificantBitPosition##size(start_mask); \
219 for (int offset = offset_start + 1; offset <= offset_end; ++offset) { \
220 if (bits[offset]) { \
221 return BitShift##size(offset) + \
222 LeastSignificantBitPosition##size(bits[offset]); \
231#undef UNSAFE_LEAST_SIGNIFICANT_BIT_POSITION
233#define UNSAFE_MOST_SIGNIFICANT_BIT_POSITION(size) \
234 int##size##_t UnsafeMostSignificantBitPosition##size( \
235 const uint##size##_t* const bits, uint##size##_t start, \
236 uint##size##_t end) { \
237 DCHECK_GE(end, start); \
238 DCHECK(IsBitSet##size(bits, start)); \
239 if (IsBitSet##size(bits, end)) { \
242 const int offset_start = BitOffset##size(start); \
243 const int offset_end = BitOffset##size(end); \
244 const int pos_end = BitPos##size(end); \
245 const uint##size##_t end_mask = \
246 bits[offset_end] & IntervalDown##size(pos_end); \
248 return BitShift##size(offset_end) + \
249 MostSignificantBitPosition##size(end_mask); \
251 for (int offset = offset_end - 1; offset >= offset_start; --offset) { \
252 if (bits[offset]) { \
253 return BitShift##size(offset) + \
254 MostSignificantBitPosition##size(bits[offset]); \
263#undef UNSAFE_MOST_SIGNIFICANT_BIT_POSITION
#define LEAST_SIGNIFCANT_BIT_POSITION(size)
#define UNSAFE_MOST_SIGNIFICANT_BIT_POSITION(size)
#define MOST_SIGNIFICANT_BIT_POSITION(size)
#define IS_EMPTY_RANGE(size)
#define BIT_COUNT_RANGE(size, zero)
-------— Bit Operations -------—
ABSL_FLAG(int, bitset_small_bitset_count, 8, "threshold to count bits with buckets")
#define UNSAFE_LEAST_SIGNIFICANT_BIT_POSITION(size)
In SWIG mode, we don't want anything besides these top-level includes.