/* Copy bits from bitset SRC to bitset DST. */ static inline void tbitset_copy_ (bitset dst, bitset src) { if (src == dst) return; tbitset_zero (dst); if (BITSET_NBITS_ (dst) != BITSET_NBITS_ (src)) tbitset_resize (dst, BITSET_NBITS_ (src)); tbitset_elts *selts = EBITSET_ELTS (src); tbitset_elts *delts = EBITSET_ELTS (dst); for (bitset_windex j = 0; j < EBITSET_SIZE (src); j++) { tbitset_elt *selt = selts[j]; if (selt) { tbitset_elt *tmp = tbitset_elt_alloc (); delts[j] = tmp; memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt), sizeof (EBITSET_WORDS (selt))); } } EBITSET_NONZERO_SET (dst); }
static inline bool tbitset_equal_p (bitset dst, bitset src) { if (src == dst) return true; tbitset_weed (dst); tbitset_weed (src); if (EBITSET_SIZE (src) != EBITSET_SIZE (dst)) return false; tbitset_elts *selts = EBITSET_ELTS (src); tbitset_elts *delts = EBITSET_ELTS (dst); for (bitset_windex j = 0; j < EBITSET_SIZE (src); j++) { tbitset_elt *selt = selts[j]; tbitset_elt *delt = delts[j]; if (!selt && !delt) continue; if ((selt && !delt) || (!selt && delt)) return false; for (unsigned i = 0; i < EBITSET_ELT_WORDS; i++) if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i]) return false; } return true; }
/* Allocate a tbitset element. The bits are cleared. */ static inline tbitset_elt * tbitset_elt_calloc (void) { tbitset_elt *elt = tbitset_elt_alloc (); memset (EBITSET_WORDS (elt), 0, sizeof (EBITSET_WORDS (elt))); return elt; }
/* 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++; }
/* Are all bits in an element zero? */ static inline bool tbitset_elt_zero_p (tbitset_elt *elt) { for (int i = 0; i < EBITSET_ELT_WORDS; i++) if (EBITSET_WORDS (elt)[i]) return false; return true; }
static ebitset_elt * ebitset_elt_find (bitset bset, bitset_bindex bindex, enum ebitset_find_mode mode) { ebitset_elt *elt; bitset_windex size; bitset_windex eindex; ebitset_elts *elts; eindex = bindex / EBITSET_ELT_BITS; elts = EBITSET_ELTS (bset); size = EBITSET_SIZE (bset); if (eindex < size) { if ((elt = elts[eindex])) { if (EBITSET_WORDS (elt) == bset->b.cdata) return elt; EBITSET_CACHE_SET (bset, eindex); return elt; } } /* The element could not be found. */ switch (mode) { default: abort (); case EBITSET_FIND: return 0; case EBITSET_CREATE: if (eindex >= size) ebitset_resize (bset, bindex); /* Create a new element. */ elt = ebitset_elt_calloc (); ebitset_elt_add (bset, elt, eindex); EBITSET_CACHE_SET (bset, eindex); return elt; case EBITSET_SUBST: return &ebitset_zero_elts[0]; } }
/* 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; }