26template<
typename IntT>
34 constexpr int64_t max_index = std::numeric_limits<IntT>::max() - 1;
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));
83 current_value &= ~mask_first_n_bits(next_unset_bit_i);
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++) {
127 for (; int_i < ints_to_check; int_i++) {
MINLINE unsigned int bitscan_forward_uint64(unsigned long long a)
#define UNUSED_VARS_NDEBUG(...)
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr bool is_empty() const
static constexpr IndexRange from_begin_end(const int64_t begin, const int64_t end)
static constexpr IndexRange from_begin_size(const int64_t begin, const int64_t size)
constexpr int64_t start() const
bool add_range(const T start, const T end)
const BitInt * data() const
const IndexRange & bit_range() const
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
static constexpr BitInt BitIndexMask
static constexpr int64_t BitsPerInt
BitInt * int_containing_bit(BitInt *data, const int64_t bit_index)
void bits_to_index_ranges(const BitSpan bits, IndexRangesBuilder< IntT > &builder)
BitInt mask_first_n_bits(const int64_t n)
BitInt mask_range_bits(const int64_t start, const int64_t size)
AlignedIndexRanges split_index_range_by_alignment(const IndexRange range, const int64_t alignment)