root/maint/gnulib/lib/bitset/vector.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vbitset_resize
  2. vbitset_set
  3. vbitset_reset
  4. vbitset_test
  5. vbitset_list_reverse
  6. vbitset_list
  7. vbitset_unused_clear
  8. vbitset_ones
  9. vbitset_zero
  10. vbitset_empty_p
  11. vbitset_copy1
  12. vbitset_not
  13. vbitset_equal_p
  14. vbitset_subset_p
  15. vbitset_disjoint_p
  16. vbitset_and
  17. vbitset_and_cmp
  18. vbitset_andn
  19. vbitset_andn_cmp
  20. vbitset_or
  21. vbitset_or_cmp
  22. vbitset_xor
  23. vbitset_xor_cmp
  24. vbitset_and_or
  25. vbitset_and_or_cmp
  26. vbitset_andn_or
  27. vbitset_andn_or_cmp
  28. vbitset_or_and
  29. vbitset_or_and_cmp
  30. vbitset_copy
  31. vbitset_free
  32. vbitset_bytes
  33. vbitset_init

   1 /* Variable array bitsets.
   2 
   3    Copyright (C) 2002-2006, 2009-2015, 2018-2021 Free Software Foundation, Inc.
   4 
   5    Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
   6 
   7    This program is free software: you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation, either version 3 of the License, or
  10    (at your option) any later version.
  11 
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16 
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
  19 
  20 #include <config.h>
  21 
  22 #include "bitset/vector.h"
  23 
  24 #include <stdlib.h>
  25 #include <string.h>
  26 
  27 #include "xalloc.h"
  28 
  29 /* This file implements variable size bitsets stored as a variable
  30    length array of words.  Any unused bits in the last word must be
  31    zero.
  32 
  33    Note that binary or ternary operations assume that each bitset operand
  34    has the same size.
  35 */
  36 
  37 static void vbitset_unused_clear (bitset);
  38 
  39 static void vbitset_set (bitset, bitset_bindex);
  40 static void vbitset_reset (bitset, bitset_bindex);
  41 static bool vbitset_test (bitset, bitset_bindex);
  42 static bitset_bindex vbitset_list (bitset, bitset_bindex *,
  43                                    bitset_bindex, bitset_bindex *);
  44 static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
  45                                            bitset_bindex, bitset_bindex *);
  46 
  47 #define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
  48 #define VBITSET_WORDS(X) ((X)->b.cdata)
  49 #define VBITSET_SIZE(X) ((X)->b.csize)
  50 #define VBITSET_ASIZE(X) ((X)->v.size)
  51 
  52 #undef min
  53 #undef max
  54 #define min(a, b) ((a) > (b) ? (b) : (a))
  55 #define max(a, b) ((a) > (b) ? (a) : (b))
  56 
  57 static bitset_bindex
  58 vbitset_resize (bitset src, bitset_bindex n_bits)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60   if (n_bits == BITSET_NBITS_ (src))
  61     return n_bits;
  62 
  63   bitset_windex oldsize = VBITSET_SIZE (src);
  64   bitset_windex newsize = VBITSET_N_WORDS (n_bits);
  65 
  66   if (oldsize < newsize)
  67     {
  68       /* The bitset needs to grow.  If we already have enough memory
  69          allocated, then just zero what we need.  */
  70       if (newsize > VBITSET_ASIZE (src))
  71         {
  72           /* We need to allocate more memory.  When oldsize is
  73              non-zero this means that we are changing the size, so
  74              grow the bitset 25% larger than requested to reduce
  75              number of reallocations.  */
  76 
  77           bitset_windex size = oldsize == 0 ? newsize : newsize + newsize / 4;
  78           VBITSET_WORDS (src)
  79             = xrealloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
  80           VBITSET_ASIZE (src) = size;
  81         }
  82 
  83       memset (VBITSET_WORDS (src) + oldsize, 0,
  84               (newsize - oldsize) * sizeof (bitset_word));
  85     }
  86   else
  87     {
  88       /* The bitset needs to shrink.  There's no point deallocating
  89          the memory unless it is shrinking by a reasonable amount.  */
  90       if ((oldsize - newsize) >= oldsize / 2)
  91         {
  92           void *p
  93             = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
  94           if (p)
  95             {
  96               VBITSET_WORDS (src) = p;
  97               VBITSET_ASIZE (src) = newsize;
  98             }
  99         }
 100 
 101       /* Need to prune any excess bits.  FIXME.  */
 102     }
 103 
 104   VBITSET_SIZE (src) = newsize;
 105   BITSET_NBITS_ (src) = n_bits;
 106   return n_bits;
 107 }
 108 
 109 
 110 /* Set bit BITNO in bitset DST.  */
 111 static void
 112 vbitset_set (bitset dst, bitset_bindex bitno)
     /* [previous][next][first][last][top][bottom][index][help] */
 113 {
 114   bitset_windex windex = bitno / BITSET_WORD_BITS;
 115 
 116   /* Perhaps we should abort.  The user should explicitly call
 117      bitset_resize since this will not catch the case when we set a
 118      bit larger than the current size but smaller than the allocated
 119      size.  */
 120   vbitset_resize (dst, bitno);
 121 
 122   dst->b.cdata[windex - dst->b.cindex] |=
 123     (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
 124 }
 125 
 126 
 127 /* Reset bit BITNO in bitset DST.  */
 128 static void
 129 vbitset_reset (MAYBE_UNUSED bitset dst, MAYBE_UNUSED bitset_bindex bitno)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131   /* We must be accessing outside the cache so the bit is
 132      zero anyway.  */
 133 }
 134 
 135 
 136 /* Test bit BITNO in bitset SRC.  */
 137 static bool
 138 vbitset_test (MAYBE_UNUSED bitset src,
     /* [previous][next][first][last][top][bottom][index][help] */
 139               MAYBE_UNUSED bitset_bindex bitno)
 140 {
 141   /* We must be accessing outside the cache so the bit is
 142      zero anyway.  */
 143   return false;
 144 }
 145 
 146 
 147 /* Find list of up to NUM bits set in BSET in reverse order, starting
 148    from and including NEXT and store in array LIST.  Return with
 149    actual number of bits found and with *NEXT indicating where search
 150    stopped.  */
 151 static bitset_bindex
 152 vbitset_list_reverse (bitset src, bitset_bindex *list,
     /* [previous][next][first][last][top][bottom][index][help] */
 153                       bitset_bindex num, bitset_bindex *next)
 154 {
 155   /* FIXME: almost a duplicate of abitset_list_reverse.  Factor?  */
 156   bitset_bindex rbitno = *next;
 157   bitset_word *srcp = VBITSET_WORDS (src);
 158   bitset_bindex n_bits = BITSET_SIZE_ (src);
 159 
 160   /* If num is 1, we could speed things up with a binary search
 161      of the word of interest.  */
 162 
 163   if (rbitno >= n_bits)
 164     return 0;
 165 
 166   bitset_bindex count = 0;
 167 
 168   bitset_bindex bitno = n_bits - (rbitno + 1);
 169 
 170   bitset_windex windex = bitno / BITSET_WORD_BITS;
 171   unsigned bitcnt = bitno % BITSET_WORD_BITS;
 172   bitset_bindex bitoff = windex * BITSET_WORD_BITS;
 173 
 174   do
 175     {
 176       bitset_word word = srcp[windex];
 177       if (bitcnt + 1 < BITSET_WORD_BITS)
 178         /* We're starting in the middle of a word: smash bits to ignore.  */
 179         word &= ((bitset_word) 1 << (bitcnt + 1)) - 1;
 180       BITSET_FOR_EACH_BIT_REVERSE(pos, word)
 181         {
 182           list[count++] = bitoff + pos;
 183           if (count >= num)
 184             {
 185               *next = n_bits - (bitoff + pos);
 186               return count;
 187             }
 188         }
 189       bitoff -= BITSET_WORD_BITS;
 190       bitcnt = BITSET_WORD_BITS - 1;
 191     }
 192   while (windex--);
 193 
 194   *next = n_bits - (bitoff + 1);
 195   return count;
 196 }
 197 
 198 
 199 /* Find list of up to NUM bits set in BSET starting from and including
 200    *NEXT and store in array LIST.  Return with actual number of bits
 201    found and with *NEXT indicating where search stopped.  */
 202 static bitset_bindex
 203 vbitset_list (bitset src, bitset_bindex *list,
     /* [previous][next][first][last][top][bottom][index][help] */
 204               bitset_bindex num, bitset_bindex *next)
 205 {
 206   /* FIXME: almost a duplicate of abitset_list.  Factor?  */
 207   bitset_windex size = VBITSET_SIZE (src);
 208   bitset_word *srcp = VBITSET_WORDS (src);
 209   bitset_bindex bitno = *next;
 210   bitset_bindex count = 0;
 211 
 212   bitset_windex windex;
 213   bitset_bindex bitoff;
 214 
 215   if (!bitno)
 216     {
 217       /* Many bitsets are zero, so make this common case fast.  */
 218       for (windex = 0; windex < size && !srcp[windex]; windex++)
 219         continue;
 220       if (windex >= size)
 221         return 0;
 222 
 223       /* If num is 1, we could speed things up with a binary search
 224          of the current word.  */
 225 
 226       bitoff = windex * BITSET_WORD_BITS;
 227     }
 228   else
 229     {
 230       if (bitno >= BITSET_SIZE_ (src))
 231         return 0;
 232 
 233       windex = bitno / BITSET_WORD_BITS;
 234       bitno = bitno % BITSET_WORD_BITS;
 235 
 236       if (bitno)
 237         {
 238           /* Handle the case where we start within a word.
 239              Most often, this is executed with large bitsets
 240              with many set bits where we filled the array
 241              on the previous call to this function.  */
 242 
 243           bitoff = windex * BITSET_WORD_BITS;
 244           bitset_word word = srcp[windex] >> bitno;
 245           bitno = bitoff + bitno;
 246           BITSET_FOR_EACH_BIT (pos, word)
 247             {
 248               list[count++] = bitno + pos;
 249               if (count >= num)
 250                 {
 251                   *next = bitno + pos + 1;
 252                   return count;
 253                 }
 254             }
 255           windex++;
 256         }
 257       bitoff = windex * BITSET_WORD_BITS;
 258     }
 259 
 260   for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
 261     {
 262       bitset_word word = srcp[windex];
 263       if (!word)
 264         continue;
 265 
 266       /* Is there enough room to avoid checking in each iteration? */
 267       if ((count + BITSET_WORD_BITS) < num)
 268         BITSET_FOR_EACH_BIT (pos, word)
 269           list[count++] = bitoff + pos;
 270       else
 271         BITSET_FOR_EACH_BIT (pos, word)
 272           {
 273             list[count++] = bitoff + pos;
 274             if (count >= num)
 275               {
 276                 *next = bitoff + pos + 1;
 277                 return count;
 278               }
 279           }
 280     }
 281 
 282   *next = bitoff;
 283   return count;
 284 }
 285 
 286 
 287 /* Ensure that any unused bits within the last word are clear.  */
 288 static inline void
 289 vbitset_unused_clear (bitset dst)
     /* [previous][next][first][last][top][bottom][index][help] */
 290 {
 291   unsigned last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
 292   if (last_bit)
 293     VBITSET_WORDS (dst)[VBITSET_SIZE (dst) - 1] &=
 294       ((bitset_word) 1 << last_bit) - 1;
 295 }
 296 
 297 
 298 static void
 299 vbitset_ones (bitset dst)
     /* [previous][next][first][last][top][bottom][index][help] */
 300 {
 301   bitset_word *dstp = VBITSET_WORDS (dst);
 302   unsigned bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
 303 
 304   memset (dstp, -1, bytes);
 305   vbitset_unused_clear (dst);
 306 }
 307 
 308 
 309 static void
 310 vbitset_zero (bitset dst)
     /* [previous][next][first][last][top][bottom][index][help] */
 311 {
 312   bitset_word *dstp = VBITSET_WORDS (dst);
 313   unsigned bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
 314 
 315   memset (dstp, 0, bytes);
 316 }
 317 
 318 
 319 static bool
 320 vbitset_empty_p (bitset dst)
     /* [previous][next][first][last][top][bottom][index][help] */
 321 {
 322   bitset_word *dstp = VBITSET_WORDS (dst);
 323 
 324   for (unsigned i = 0; i < VBITSET_SIZE (dst); i++)
 325     if (dstp[i])
 326       return false;
 327   return true;
 328 }
 329 
 330 
 331 static void
 332 vbitset_copy1 (bitset dst, bitset src)
     /* [previous][next][first][last][top][bottom][index][help] */
 333 {
 334   if (src == dst)
 335     return;
 336 
 337   vbitset_resize (dst, BITSET_SIZE_ (src));
 338 
 339   bitset_word *srcp = VBITSET_WORDS (src);
 340   bitset_word *dstp = VBITSET_WORDS (dst);
 341   bitset_windex ssize = VBITSET_SIZE (src);
 342   bitset_windex dsize = VBITSET_SIZE (dst);
 343 
 344   memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
 345 
 346   memset (dstp + sizeof (bitset_word) * ssize, 0,
 347           sizeof (bitset_word) * (dsize - ssize));
 348 }
 349 
 350 
 351 static void
 352 vbitset_not (bitset dst, bitset src)
     /* [previous][next][first][last][top][bottom][index][help] */
 353 {
 354   vbitset_resize (dst, BITSET_SIZE_ (src));
 355 
 356   bitset_word *srcp = VBITSET_WORDS (src);
 357   bitset_word *dstp = VBITSET_WORDS (dst);
 358   bitset_windex ssize = VBITSET_SIZE (src);
 359   bitset_windex dsize = VBITSET_SIZE (dst);
 360 
 361   for (unsigned i = 0; i < ssize; i++)
 362     *dstp++ = ~(*srcp++);
 363 
 364   vbitset_unused_clear (dst);
 365   memset (dstp + sizeof (bitset_word) * ssize, 0,
 366           sizeof (bitset_word) * (dsize - ssize));
 367 }
 368 
 369 
 370 static bool
 371 vbitset_equal_p (bitset dst, bitset src)
     /* [previous][next][first][last][top][bottom][index][help] */
 372 {
 373   bitset_word *srcp = VBITSET_WORDS (src);
 374   bitset_word *dstp = VBITSET_WORDS (dst);
 375   bitset_windex ssize = VBITSET_SIZE (src);
 376   bitset_windex dsize = VBITSET_SIZE (dst);
 377 
 378   unsigned i;
 379   for (i = 0; i < min (ssize, dsize); i++)
 380     if (*srcp++ != *dstp++)
 381       return false;
 382 
 383   if (ssize > dsize)
 384     {
 385       for (; i < ssize; i++)
 386         if (*srcp++)
 387           return false;
 388     }
 389   else
 390     {
 391       for (; i < dsize; i++)
 392         if (*dstp++)
 393           return false;
 394     }
 395 
 396   return true;
 397 }
 398 
 399 
 400 static bool
 401 vbitset_subset_p (bitset dst, bitset src)
     /* [previous][next][first][last][top][bottom][index][help] */
 402 {
 403   bitset_word *srcp = VBITSET_WORDS (src);
 404   bitset_word *dstp = VBITSET_WORDS (dst);
 405   bitset_windex ssize = VBITSET_SIZE (src);
 406   bitset_windex dsize = VBITSET_SIZE (dst);
 407 
 408   unsigned i;
 409   for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
 410     if (*dstp != (*srcp | *dstp))
 411       return false;
 412 
 413   if (ssize > dsize)
 414     for (; i < ssize; i++)
 415       if (*srcp++)
 416         return false;
 417 
 418   return true;
 419 }
 420 
 421 
 422 static bool
 423 vbitset_disjoint_p (bitset dst, bitset src)
     /* [previous][next][first][last][top][bottom][index][help] */
 424 {
 425   bitset_word *srcp = VBITSET_WORDS (src);
 426   bitset_word *dstp = VBITSET_WORDS (dst);
 427   bitset_windex ssize = VBITSET_SIZE (src);
 428   bitset_windex dsize = VBITSET_SIZE (dst);
 429 
 430   for (unsigned i = 0; i < min (ssize, dsize); i++)
 431     if (*srcp++ & *dstp++)
 432       return false;
 433 
 434   return true;
 435 }
 436 
 437 
 438 static void
 439 vbitset_and (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 440 {
 441   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 442 
 443   bitset_windex dsize = VBITSET_SIZE (dst);
 444   bitset_windex ssize1 = VBITSET_SIZE (src1);
 445   bitset_windex ssize2 = VBITSET_SIZE (src2);
 446   bitset_word *dstp = VBITSET_WORDS (dst);
 447   bitset_word *src1p = VBITSET_WORDS (src1);
 448   bitset_word *src2p = VBITSET_WORDS (src2);
 449 
 450   for (unsigned i = 0; i < min (ssize1, ssize2); i++)
 451     *dstp++ = *src1p++ & *src2p++;
 452 
 453   memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
 454 }
 455 
 456 
 457 static bool
 458 vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 459 {
 460   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 461 
 462   bitset_windex dsize = VBITSET_SIZE (dst);
 463   bitset_windex ssize1 = VBITSET_SIZE (src1);
 464   bitset_windex ssize2 = VBITSET_SIZE (src2);
 465   bitset_word *dstp = VBITSET_WORDS (dst);
 466   bitset_word *src1p = VBITSET_WORDS (src1);
 467   bitset_word *src2p = VBITSET_WORDS (src2);
 468 
 469   bool changed = false;
 470   unsigned i;
 471   for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
 472     {
 473       bitset_word tmp = *src1p++ & *src2p++;
 474 
 475       if (*dstp != tmp)
 476         {
 477           changed = true;
 478           *dstp = tmp;
 479         }
 480     }
 481 
 482   if (ssize2 > ssize1)
 483     {
 484       src1p = src2p;
 485       ssize1 = ssize2;
 486     }
 487 
 488   for (; i < ssize1; i++, dstp++)
 489     {
 490       if (*dstp != 0)
 491         {
 492           changed = true;
 493           *dstp = 0;
 494         }
 495     }
 496 
 497   memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 498 
 499   return changed;
 500 }
 501 
 502 
 503 static void
 504 vbitset_andn (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 505 {
 506   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 507 
 508   bitset_windex dsize = VBITSET_SIZE (dst);
 509   bitset_windex ssize1 = VBITSET_SIZE (src1);
 510   bitset_windex ssize2 = VBITSET_SIZE (src2);
 511   bitset_word *dstp = VBITSET_WORDS (dst);
 512   bitset_word *src1p = VBITSET_WORDS (src1);
 513   bitset_word *src2p = VBITSET_WORDS (src2);
 514 
 515   unsigned i;
 516   for (i = 0; i < min (ssize1, ssize2); i++)
 517     *dstp++ = *src1p++ & ~(*src2p++);
 518 
 519   if (ssize2 > ssize1)
 520     {
 521       for (; i < ssize2; i++)
 522         *dstp++ = 0;
 523 
 524       memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
 525     }
 526   else
 527     {
 528       for (; i < ssize1; i++)
 529         *dstp++ = *src1p++;
 530 
 531       memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 532     }
 533 }
 534 
 535 
 536 static bool
 537 vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 540 
 541   bitset_windex dsize = VBITSET_SIZE (dst);
 542   bitset_windex ssize1 = VBITSET_SIZE (src1);
 543   bitset_windex ssize2 = VBITSET_SIZE (src2);
 544   bitset_word *dstp = VBITSET_WORDS (dst);
 545   bitset_word *src1p = VBITSET_WORDS (src1);
 546   bitset_word *src2p = VBITSET_WORDS (src2);
 547 
 548   bool changed = false;
 549   unsigned i;
 550   for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
 551     {
 552       bitset_word tmp = *src1p++ & ~(*src2p++);
 553 
 554       if (*dstp != tmp)
 555         {
 556           changed = true;
 557           *dstp = tmp;
 558         }
 559     }
 560 
 561   if (ssize2 > ssize1)
 562     {
 563       for (; i < ssize2; i++, dstp++)
 564         {
 565           if (*dstp != 0)
 566             {
 567               changed = true;
 568               *dstp = 0;
 569             }
 570         }
 571 
 572       memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
 573     }
 574   else
 575     {
 576       for (; i < ssize1; i++, dstp++)
 577         {
 578           bitset_word tmp = *src1p++;
 579 
 580           if (*dstp != tmp)
 581             {
 582               changed = true;
 583               *dstp = tmp;
 584             }
 585         }
 586 
 587       memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 588     }
 589 
 590   return changed;
 591 }
 592 
 593 
 594 static void
 595 vbitset_or (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 596 {
 597   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 598 
 599   bitset_windex dsize = VBITSET_SIZE (dst);
 600   bitset_windex ssize1 = VBITSET_SIZE (src1);
 601   bitset_windex ssize2 = VBITSET_SIZE (src2);
 602   bitset_word *dstp = VBITSET_WORDS (dst);
 603   bitset_word *src1p = VBITSET_WORDS (src1);
 604   bitset_word *src2p = VBITSET_WORDS (src2);
 605 
 606   unsigned i;
 607   for (i = 0; i < min (ssize1, ssize2); i++)
 608     *dstp++ = *src1p++ | *src2p++;
 609 
 610   if (ssize2 > ssize1)
 611     {
 612       src1p = src2p;
 613       ssize1 = ssize2;
 614     }
 615 
 616   for (; i < ssize1; i++)
 617     *dstp++ = *src1p++;
 618 
 619   memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 620 }
 621 
 622 
 623 static bool
 624 vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 625 {
 626   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 627 
 628   bitset_windex dsize = VBITSET_SIZE (dst);
 629   bitset_windex ssize1 = VBITSET_SIZE (src1);
 630   bitset_windex ssize2 = VBITSET_SIZE (src2);
 631   bitset_word *dstp = VBITSET_WORDS (dst);
 632   bitset_word *src1p = VBITSET_WORDS (src1);
 633   bitset_word *src2p = VBITSET_WORDS (src2);
 634 
 635   bool changed = false;
 636   unsigned i;
 637   for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
 638     {
 639       bitset_word tmp = *src1p++ | *src2p++;
 640 
 641       if (*dstp != tmp)
 642         {
 643           changed = true;
 644           *dstp = tmp;
 645         }
 646     }
 647 
 648   if (ssize2 > ssize1)
 649     {
 650       src1p = src2p;
 651       ssize1 = ssize2;
 652     }
 653 
 654   for (; i < ssize1; i++, dstp++)
 655     {
 656       bitset_word tmp = *src1p++;
 657 
 658       if (*dstp != tmp)
 659         {
 660           changed = true;
 661           *dstp = tmp;
 662         }
 663     }
 664 
 665   memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 666 
 667   return changed;
 668 }
 669 
 670 
 671 static void
 672 vbitset_xor (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 673 {
 674   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 675 
 676   bitset_windex dsize = VBITSET_SIZE (dst);
 677   bitset_windex ssize1 = VBITSET_SIZE (src1);
 678   bitset_windex ssize2 = VBITSET_SIZE (src2);
 679   bitset_word *dstp = VBITSET_WORDS (dst);
 680   bitset_word *src1p = VBITSET_WORDS (src1);
 681   bitset_word *src2p = VBITSET_WORDS (src2);
 682 
 683   unsigned i;
 684   for (i = 0; i < min (ssize1, ssize2); i++)
 685     *dstp++ = *src1p++ ^ *src2p++;
 686 
 687   if (ssize2 > ssize1)
 688     {
 689       src1p = src2p;
 690       ssize1 = ssize2;
 691     }
 692 
 693   for (; i < ssize1; i++)
 694     *dstp++ = *src1p++;
 695 
 696   memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 697 }
 698 
 699 
 700 static bool
 701 vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
     /* [previous][next][first][last][top][bottom][index][help] */
 702 {
 703   vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
 704 
 705   bitset_windex dsize = VBITSET_SIZE (dst);
 706   bitset_windex ssize1 = VBITSET_SIZE (src1);
 707   bitset_windex ssize2 = VBITSET_SIZE (src2);
 708   bitset_word *dstp = VBITSET_WORDS (dst);
 709   bitset_word *src1p = VBITSET_WORDS (src1);
 710   bitset_word *src2p = VBITSET_WORDS (src2);
 711 
 712   bool changed = false;
 713   unsigned i;
 714   for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
 715     {
 716       bitset_word tmp = *src1p++ ^ *src2p++;
 717 
 718       if (*dstp != tmp)
 719         {
 720           changed = true;
 721           *dstp = tmp;
 722         }
 723     }
 724 
 725   if (ssize2 > ssize1)
 726     {
 727       src1p = src2p;
 728       ssize1 = ssize2;
 729     }
 730 
 731   for (; i < ssize1; i++, dstp++)
 732     {
 733       bitset_word tmp = *src1p++;
 734 
 735       if (*dstp != tmp)
 736         {
 737           changed = true;
 738           *dstp = tmp;
 739         }
 740     }
 741 
 742   memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
 743 
 744   return changed;
 745 }
 746 
 747 
 748 /* FIXME, these operations need fixing for different size
 749    bitsets.  */
 750 
 751 static void
 752 vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
     /* [previous][next][first][last][top][bottom][index][help] */
 753 {
 754   if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
 755       || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
 756     {
 757       bitset_and_or_ (dst, src1, src2, src3);
 758       return;
 759     }
 760 
 761   vbitset_resize (dst, BITSET_NBITS_ (src1));
 762 
 763   bitset_word *src1p = VBITSET_WORDS (src1);
 764   bitset_word *src2p = VBITSET_WORDS (src2);
 765   bitset_word *src3p = VBITSET_WORDS (src3);
 766   bitset_word *dstp = VBITSET_WORDS (dst);
 767   bitset_windex size = VBITSET_SIZE (dst);
 768 
 769   for (unsigned i = 0; i < size; i++)
 770     *dstp++ = (*src1p++ & *src2p++) | *src3p++;
 771 }
 772 
 773 
 774 static bool
 775 vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
     /* [previous][next][first][last][top][bottom][index][help] */
 776 {
 777   if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
 778       || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
 779     return bitset_and_or_cmp_ (dst, src1, src2, src3);
 780 
 781   vbitset_resize (dst, BITSET_NBITS_ (src1));
 782 
 783   bitset_word *src1p = VBITSET_WORDS (src1);
 784   bitset_word *src2p = VBITSET_WORDS (src2);
 785   bitset_word *src3p = VBITSET_WORDS (src3);
 786   bitset_word *dstp = VBITSET_WORDS (dst);
 787   bitset_windex size = VBITSET_SIZE (dst);
 788 
 789   bool changed = false;
 790   for (unsigned i = 0; i < size; i++, dstp++)
 791     {
 792       bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
 793 
 794       if (*dstp != tmp)
 795         {
 796           changed = true;
 797           *dstp = tmp;
 798         }
 799     }
 800   return changed;
 801 }
 802 
 803 
 804 static void
 805 vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
     /* [previous][next][first][last][top][bottom][index][help] */
 806 {
 807   if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
 808       || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
 809     {
 810       bitset_andn_or_ (dst, src1, src2, src3);
 811       return;
 812     }
 813 
 814   vbitset_resize (dst, BITSET_NBITS_ (src1));
 815 
 816   bitset_word *src1p = VBITSET_WORDS (src1);
 817   bitset_word *src2p = VBITSET_WORDS (src2);
 818   bitset_word *src3p = VBITSET_WORDS (src3);
 819   bitset_word *dstp = VBITSET_WORDS (dst);
 820   bitset_windex size = VBITSET_SIZE (dst);
 821 
 822   for (unsigned i = 0; i < size; i++)
 823     *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
 824 }
 825 
 826 
 827 static bool
 828 vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
     /* [previous][next][first][last][top][bottom][index][help] */
 829 {
 830   if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
 831       || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
 832     return bitset_andn_or_cmp_ (dst, src1, src2, src3);
 833 
 834   vbitset_resize (dst, BITSET_NBITS_ (src1));
 835 
 836   bitset_word *src1p = VBITSET_WORDS (src1);
 837   bitset_word *src2p = VBITSET_WORDS (src2);
 838   bitset_word *src3p = VBITSET_WORDS (src3);
 839   bitset_word *dstp = VBITSET_WORDS (dst);
 840   bitset_windex size = VBITSET_SIZE (dst);
 841 
 842   bool changed = false;
 843   for (unsigned i = 0; i < size; i++, dstp++)
 844     {
 845       bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
 846 
 847       if (*dstp != tmp)
 848         {
 849           changed = true;
 850           *dstp = tmp;
 851         }
 852     }
 853   return changed;
 854 }
 855 
 856 
 857 static void
 858 vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
     /* [previous][next][first][last][top][bottom][index][help] */
 859 {
 860   if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
 861       || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
 862     {
 863       bitset_or_and_ (dst, src1, src2, src3);
 864       return;
 865     }
 866 
 867   vbitset_resize (dst, BITSET_NBITS_ (src1));
 868 
 869   bitset_word *src1p = VBITSET_WORDS (src1);
 870   bitset_word *src2p = VBITSET_WORDS (src2);
 871   bitset_word *src3p = VBITSET_WORDS (src3);
 872   bitset_word *dstp = VBITSET_WORDS (dst);
 873   bitset_windex size = VBITSET_SIZE (dst);
 874 
 875   for (unsigned i = 0; i < size; i++)
 876     *dstp++ = (*src1p++ | *src2p++) & *src3p++;
 877 }
 878 
 879 
 880 static bool
 881 vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
     /* [previous][next][first][last][top][bottom][index][help] */
 882 {
 883   if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
 884       || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
 885     return bitset_or_and_cmp_ (dst, src1, src2, src3);
 886 
 887   vbitset_resize (dst, BITSET_NBITS_ (src1));
 888 
 889   bitset_word *src1p = VBITSET_WORDS (src1);
 890   bitset_word *src2p = VBITSET_WORDS (src2);
 891   bitset_word *src3p = VBITSET_WORDS (src3);
 892   bitset_word *dstp = VBITSET_WORDS (dst);
 893   bitset_windex size = VBITSET_SIZE (dst);
 894 
 895   bool changed = false;
 896   unsigned i;
 897   for (i = 0; i < size; i++, dstp++)
 898     {
 899       bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
 900 
 901       if (*dstp != tmp)
 902         {
 903           changed = true;
 904           *dstp = tmp;
 905         }
 906     }
 907   return changed;
 908 }
 909 
 910 
 911 static void
 912 vbitset_copy (bitset dst, bitset src)
     /* [previous][next][first][last][top][bottom][index][help] */
 913 {
 914   if (BITSET_COMPATIBLE_ (dst, src))
 915     vbitset_copy1 (dst, src);
 916   else
 917     bitset_copy_ (dst, src);
 918 }
 919 
 920 
 921 static void
 922 vbitset_free (bitset bset)
     /* [previous][next][first][last][top][bottom][index][help] */
 923 {
 924   free (VBITSET_WORDS (bset));
 925 }
 926 
 927 
 928 /* Vector of operations for multiple word bitsets.  */
 929 struct bitset_vtable vbitset_vtable = {
 930   vbitset_set,
 931   vbitset_reset,
 932   bitset_toggle_,
 933   vbitset_test,
 934   vbitset_resize,
 935   bitset_size_,
 936   bitset_count_,
 937   vbitset_empty_p,
 938   vbitset_ones,
 939   vbitset_zero,
 940   vbitset_copy,
 941   vbitset_disjoint_p,
 942   vbitset_equal_p,
 943   vbitset_not,
 944   vbitset_subset_p,
 945   vbitset_and,
 946   vbitset_and_cmp,
 947   vbitset_andn,
 948   vbitset_andn_cmp,
 949   vbitset_or,
 950   vbitset_or_cmp,
 951   vbitset_xor,
 952   vbitset_xor_cmp,
 953   vbitset_and_or,
 954   vbitset_and_or_cmp,
 955   vbitset_andn_or,
 956   vbitset_andn_or_cmp,
 957   vbitset_or_and,
 958   vbitset_or_and_cmp,
 959   vbitset_list,
 960   vbitset_list_reverse,
 961   vbitset_free,
 962   BITSET_VECTOR
 963 };
 964 
 965 
 966 size_t
 967 vbitset_bytes (MAYBE_UNUSED bitset_bindex n_bits)
     /* [previous][next][first][last][top][bottom][index][help] */
 968 {
 969   return sizeof (struct vbitset_struct);
 970 }
 971 
 972 
 973 bitset
 974 vbitset_init (bitset bset, bitset_bindex n_bits)
     /* [previous][next][first][last][top][bottom][index][help] */
 975 {
 976   bset->b.vtable = &vbitset_vtable;
 977   bset->b.cindex = 0;
 978   VBITSET_SIZE (bset) = 0;
 979   vbitset_resize (bset, n_bits);
 980   return bset;
 981 }

/* [previous][next][first][last][top][bottom][index][help] */