30 constexpr int64_t max_index = std::numeric_limits<IntT>::max() - 1;
35 builder.
add_range(IntT(range.start()), IntT(range.one_after_last()));
38 auto process_bit_int = [&](
const BitInt value,
44 const BitInt masked_value = mask & value;
45 if (masked_value == 0) {
49 if (masked_value == mask) {
54 const int64_t bit_i_to_output_offset = start - start_bit;
60 BitInt current_value = masked_value;
61 while (current_value != 0) {
67 if (find_unset_value == 0) {
70 append_range(range.shift(bit_i_to_output_offset));
77 append_range(range.shift(bit_i_to_output_offset));
79 current_value &= ~mask_first_n_bits(next_unset_bit_i);
92 if (!ranges.prefix.is_empty()) {
99 if (!ranges.aligned.is_empty()) {
106 for (; int_i + 1 < ints_to_check; int_i += 2) {
108 const __m128i group = _mm_loadu_si128(
reinterpret_cast<const __m128i *
>(start + int_i));
110 const bool group_is_zero = _mm_testz_si128(group, group);
115 for (
int j = 0; j < 2; j++) {
123 for (; int_i < ints_to_check; int_i++) {
129 if (!ranges.suffix.is_empty()) {
132 last_int, 0, ranges.suffix.size(), ranges.prefix.size() + ranges.aligned.size());