Пример #1
0
/* 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);
}
Пример #2
0
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;
}
Пример #3
0
/* 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;
}
Пример #4
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
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++;
    }
Пример #5
0
/* 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;
}
Пример #6
0
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];
    }
}
Пример #7
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;
}