29 if (
bits.is_empty()) {
34 constexpr int64_t max_index = std::numeric_limits<IntT>::max() - 1;
37 auto append_range = [&](
const IndexRange range) {
39 builder.
add_range(IntT(range.start()), IntT(range.one_after_last()));
42 auto process_bit_int = [&](
const BitInt value,
49 if (masked_value == 0) {
53 if (masked_value ==
mask) {
58 const int64_t bit_i_to_output_offset = start - start_bit;
64 BitInt current_value = masked_value;
65 while (current_value != 0) {
71 if (find_unset_value == 0) {
74 append_range(range.
shift(bit_i_to_output_offset));
81 append_range(range.
shift(bit_i_to_output_offset));
110 for (; int_i + 1 < ints_to_check; int_i += 2) {
112 const __m128i group = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(start + int_i));
114 const bool group_is_zero = _mm_testz_si128(group, group);
119 for (
int j = 0; j < 2; j++) {
121 start[int_i + j], 0, BitsPerInt, ranges.
prefix.
size() + (int_i + j) * BitsPerInt);
127 for (; int_i < ints_to_check; int_i++) {
128 process_bit_int(start[int_i], 0, BitsPerInt, ranges.
prefix.
size() + int_i * BitsPerInt);