/* Find list of up to NUM bits set in BSET starting from and including *NEXT and store in array LIST. Return with actual number of bits found and with *NEXT indicating where search stopped. */ static bitset_bindex ebitset_list (bitset bset, bitset_bindex *list, bitset_bindex num, bitset_bindex *next) { bitset_bindex bitno; bitset_windex windex; bitset_windex eindex; bitset_bindex count; bitset_windex size; ebitset_elt *elt; bitset_word word; ebitset_elts *elts; if (EBITSET_ZERO_P (bset)) return 0; bitno = *next; count = 0; elts = EBITSET_ELTS (bset); size = EBITSET_SIZE (bset); eindex = bitno / EBITSET_ELT_BITS; if (bitno % EBITSET_ELT_BITS) { /* We need to start within an element. This is not very common. */ elt = elts[eindex]; if (elt) { bitset_windex woffset; bitset_word *srcp = EBITSET_WORDS (elt); windex = bitno / BITSET_WORD_BITS; woffset = eindex * EBITSET_ELT_WORDS; for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++) { word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS); for (; word; bitno++) { if (word & 1) { list[count++] = bitno; if (count >= num) { *next = bitno + 1; return count; } } word >>= 1; } bitno = (windex + 1) * BITSET_WORD_BITS; } } /* Skip to next element. */ eindex++; }
/* Copy bits from bitset SRC to bitset DST. Return true if bitsets different. */ static inline bool tbitset_copy_cmp (bitset dst, bitset src) { if (src == dst) return false; if (EBITSET_ZERO_P (dst)) { tbitset_copy_ (dst, src); return !EBITSET_ZERO_P (src); } if (tbitset_equal_p (dst, src)) return false; tbitset_copy_ (dst, src); return true; }
/* Set all bits in the bitset to zero. */ static inline void tbitset_zero (bitset bset) { if (EBITSET_ZERO_P (bset)) return; tbitset_elts *elts = EBITSET_ELTS (bset); for (bitset_windex j = 0; j < EBITSET_SIZE (bset); j++) { tbitset_elt *elt = elts[j]; if (elt) tbitset_elt_remove (bset, j); } /* All the bits are zero. We could shrink the elts. For now just mark BSET as known to be zero. */ EBITSET_ZERO_SET (bset); }
/* Weed out the zero elements from the elts. */ static inline bitset_windex ebitset_weed (bitset bset) { ebitset_elts *elts; bitset_windex j; bitset_windex count; if (EBITSET_ZERO_P (bset)) return 0; elts = EBITSET_ELTS (bset); count = 0; for (j = 0; j < EBITSET_SIZE (bset); j++) { ebitset_elt *elt = elts[j]; if (elt) { if (ebitset_elt_zero_p (elt)) { ebitset_elt_remove (bset, j); count++; } } else count++; } count = j - count; if (!count) { /* All the bits are zero. We could shrink the elts. For now just mark BSET as known to be zero. */ EBITSET_ZERO_SET (bset); } else EBITSET_NONZERO_SET (bset); return count; }
/* Find list of up to NUM bits set in BSET starting from and including *NEXT and store in array LIST. Return with actual number of bits found and with *NEXT indicating where search stopped. */ static bitset_bindex tbitset_list_reverse (bitset bset, bitset_bindex *list, bitset_bindex num, bitset_bindex *next) { if (EBITSET_ZERO_P (bset)) return 0; bitset_windex size = EBITSET_SIZE (bset); bitset_bindex n_bits = size * EBITSET_ELT_BITS; bitset_bindex rbitno = *next; if (rbitno >= n_bits) return 0; tbitset_elts *elts = EBITSET_ELTS (bset); bitset_bindex bitno = n_bits - (rbitno + 1); bitset_windex windex = bitno / BITSET_WORD_BITS; bitset_windex eindex = bitno / EBITSET_ELT_BITS; bitset_windex woffset = windex - eindex * EBITSET_ELT_WORDS; /* If num is 1, we could speed things up with a binary search of the word of interest. */ bitset_bindex count = 0; unsigned bcount = bitno % BITSET_WORD_BITS; bitset_bindex boffset = windex * BITSET_WORD_BITS; do { tbitset_elt *elt = elts[eindex]; if (elt) { bitset_word *srcp = EBITSET_WORDS (elt); do { for (bitset_word word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount); word; bcount--) { if (word & BITSET_MSB) { list[count++] = boffset + bcount; if (count >= num) { *next = n_bits - (boffset + bcount); return count; } } word <<= 1; } boffset -= BITSET_WORD_BITS; bcount = BITSET_WORD_BITS - 1; } while (woffset--); } woffset = EBITSET_ELT_WORDS - 1; boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS; } while (eindex--); *next = n_bits - (boffset + 1); return count; }