findprog-in: Relicense under LGPLv2+.
[gnulib.git] / lib / bitset / vector.c
blob9f1c08e7745edac7d243a17110278c93aa8d2585
1 /* Variable array bitsets.
3 Copyright (C) 2002-2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
5 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
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.
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.
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/>. */
20 #include <config.h>
22 #include "bitset/vector.h"
24 #include <stdlib.h>
25 #include <string.h>
27 #include "xalloc.h"
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.
33 Note that binary or ternary operations assume that each bitset operand
34 has the same size.
37 static void vbitset_unused_clear (bitset);
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 *);
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)
52 #undef min
53 #undef max
54 #define min(a, b) ((a) > (b) ? (b) : (a))
55 #define max(a, b) ((a) > (b) ? (a) : (b))
57 static bitset_bindex
58 vbitset_resize (bitset src, bitset_bindex n_bits)
60 if (n_bits == BITSET_NBITS_ (src))
61 return n_bits;
63 bitset_windex oldsize = VBITSET_SIZE (src);
64 bitset_windex newsize = VBITSET_N_WORDS (n_bits);
66 if (oldsize < newsize)
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))
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. */
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;
83 memset (VBITSET_WORDS (src) + oldsize, 0,
84 (newsize - oldsize) * sizeof (bitset_word));
86 else
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)
92 void *p
93 = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
94 if (p)
96 VBITSET_WORDS (src) = p;
97 VBITSET_ASIZE (src) = newsize;
101 /* Need to prune any excess bits. FIXME. */
104 VBITSET_SIZE (src) = newsize;
105 BITSET_NBITS_ (src) = n_bits;
106 return n_bits;
110 /* Set bit BITNO in bitset DST. */
111 static void
112 vbitset_set (bitset dst, bitset_bindex bitno)
114 bitset_windex windex = bitno / BITSET_WORD_BITS;
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);
122 dst->b.cdata[windex - dst->b.cindex] |=
123 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
127 /* Reset bit BITNO in bitset DST. */
128 static void
129 vbitset_reset (bitset dst MAYBE_UNUSED, bitset_bindex bitno MAYBE_UNUSED)
131 /* We must be accessing outside the cache so the bit is
132 zero anyway. */
136 /* Test bit BITNO in bitset SRC. */
137 static bool
138 vbitset_test (bitset src MAYBE_UNUSED,
139 bitset_bindex bitno MAYBE_UNUSED)
141 /* We must be accessing outside the cache so the bit is
142 zero anyway. */
143 return false;
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,
153 bitset_bindex num, bitset_bindex *next)
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);
160 /* If num is 1, we could speed things up with a binary search
161 of the word of interest. */
163 if (rbitno >= n_bits)
164 return 0;
166 bitset_bindex count = 0;
168 bitset_bindex bitno = n_bits - (rbitno + 1);
170 bitset_windex windex = bitno / BITSET_WORD_BITS;
171 unsigned bitcnt = bitno % BITSET_WORD_BITS;
172 bitset_bindex bitoff = windex * BITSET_WORD_BITS;
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)
182 list[count++] = bitoff + pos;
183 if (count >= num)
185 *next = n_bits - (bitoff + pos);
186 return count;
189 bitoff -= BITSET_WORD_BITS;
190 bitcnt = BITSET_WORD_BITS - 1;
192 while (windex--);
194 *next = n_bits - (bitoff + 1);
195 return count;
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,
204 bitset_bindex num, bitset_bindex *next)
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;
212 bitset_windex windex;
213 bitset_bindex bitoff;
215 if (!bitno)
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;
223 /* If num is 1, we could speed things up with a binary search
224 of the current word. */
226 bitoff = windex * BITSET_WORD_BITS;
228 else
230 if (bitno >= BITSET_SIZE_ (src))
231 return 0;
233 windex = bitno / BITSET_WORD_BITS;
234 bitno = bitno % BITSET_WORD_BITS;
236 if (bitno)
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. */
243 bitoff = windex * BITSET_WORD_BITS;
244 bitset_word word = srcp[windex] >> bitno;
245 bitno = bitoff + bitno;
246 BITSET_FOR_EACH_BIT (pos, word)
248 list[count++] = bitno + pos;
249 if (count >= num)
251 *next = bitno + pos + 1;
252 return count;
255 windex++;
257 bitoff = windex * BITSET_WORD_BITS;
260 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
262 bitset_word word = srcp[windex];
263 if (!word)
264 continue;
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)
273 list[count++] = bitoff + pos;
274 if (count >= num)
276 *next = bitoff + pos + 1;
277 return count;
282 *next = bitoff;
283 return count;
287 /* Ensure that any unused bits within the last word are clear. */
288 static inline void
289 vbitset_unused_clear (bitset dst)
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;
298 static void
299 vbitset_ones (bitset dst)
301 bitset_word *dstp = VBITSET_WORDS (dst);
302 unsigned bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
304 memset (dstp, -1, bytes);
305 vbitset_unused_clear (dst);
309 static void
310 vbitset_zero (bitset dst)
312 bitset_word *dstp = VBITSET_WORDS (dst);
313 unsigned bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
315 memset (dstp, 0, bytes);
319 static bool
320 vbitset_empty_p (bitset dst)
322 bitset_word *dstp = VBITSET_WORDS (dst);
324 for (unsigned i = 0; i < VBITSET_SIZE (dst); i++)
325 if (dstp[i])
326 return false;
327 return true;
331 static void
332 vbitset_copy1 (bitset dst, bitset src)
334 if (src == dst)
335 return;
337 vbitset_resize (dst, BITSET_SIZE_ (src));
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);
344 memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
346 memset (dstp + sizeof (bitset_word) * ssize, 0,
347 sizeof (bitset_word) * (dsize - ssize));
351 static void
352 vbitset_not (bitset dst, bitset src)
354 vbitset_resize (dst, BITSET_SIZE_ (src));
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);
361 for (unsigned i = 0; i < ssize; i++)
362 *dstp++ = ~(*srcp++);
364 vbitset_unused_clear (dst);
365 memset (dstp + sizeof (bitset_word) * ssize, 0,
366 sizeof (bitset_word) * (dsize - ssize));
370 static bool
371 vbitset_equal_p (bitset dst, bitset src)
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);
378 unsigned i;
379 for (i = 0; i < min (ssize, dsize); i++)
380 if (*srcp++ != *dstp++)
381 return false;
383 if (ssize > dsize)
385 for (; i < ssize; i++)
386 if (*srcp++)
387 return false;
389 else
391 for (; i < dsize; i++)
392 if (*dstp++)
393 return false;
396 return true;
400 static bool
401 vbitset_subset_p (bitset dst, bitset src)
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);
408 unsigned i;
409 for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
410 if (*dstp != (*srcp | *dstp))
411 return false;
413 if (ssize > dsize)
414 for (; i < ssize; i++)
415 if (*srcp++)
416 return false;
418 return true;
422 static bool
423 vbitset_disjoint_p (bitset dst, bitset src)
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);
430 for (unsigned i = 0; i < min (ssize, dsize); i++)
431 if (*srcp++ & *dstp++)
432 return false;
434 return true;
438 static void
439 vbitset_and (bitset dst, bitset src1, bitset src2)
441 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
450 for (unsigned i = 0; i < min (ssize1, ssize2); i++)
451 *dstp++ = *src1p++ & *src2p++;
453 memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
457 static bool
458 vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
460 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
469 bool changed = false;
470 unsigned i;
471 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
473 bitset_word tmp = *src1p++ & *src2p++;
475 if (*dstp != tmp)
477 changed = true;
478 *dstp = tmp;
482 if (ssize2 > ssize1)
484 src1p = src2p;
485 ssize1 = ssize2;
488 for (; i < ssize1; i++, dstp++)
490 if (*dstp != 0)
492 changed = true;
493 *dstp = 0;
497 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
499 return changed;
503 static void
504 vbitset_andn (bitset dst, bitset src1, bitset src2)
506 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
515 unsigned i;
516 for (i = 0; i < min (ssize1, ssize2); i++)
517 *dstp++ = *src1p++ & ~(*src2p++);
519 if (ssize2 > ssize1)
521 for (; i < ssize2; i++)
522 *dstp++ = 0;
524 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
526 else
528 for (; i < ssize1; i++)
529 *dstp++ = *src1p++;
531 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
536 static bool
537 vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
539 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
548 bool changed = false;
549 unsigned i;
550 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
552 bitset_word tmp = *src1p++ & ~(*src2p++);
554 if (*dstp != tmp)
556 changed = true;
557 *dstp = tmp;
561 if (ssize2 > ssize1)
563 for (; i < ssize2; i++, dstp++)
565 if (*dstp != 0)
567 changed = true;
568 *dstp = 0;
572 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
574 else
576 for (; i < ssize1; i++, dstp++)
578 bitset_word tmp = *src1p++;
580 if (*dstp != tmp)
582 changed = true;
583 *dstp = tmp;
587 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
590 return changed;
594 static void
595 vbitset_or (bitset dst, bitset src1, bitset src2)
597 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
606 unsigned i;
607 for (i = 0; i < min (ssize1, ssize2); i++)
608 *dstp++ = *src1p++ | *src2p++;
610 if (ssize2 > ssize1)
612 src1p = src2p;
613 ssize1 = ssize2;
616 for (; i < ssize1; i++)
617 *dstp++ = *src1p++;
619 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
623 static bool
624 vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
626 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
635 bool changed = false;
636 unsigned i;
637 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
639 bitset_word tmp = *src1p++ | *src2p++;
641 if (*dstp != tmp)
643 changed = true;
644 *dstp = tmp;
648 if (ssize2 > ssize1)
650 src1p = src2p;
651 ssize1 = ssize2;
654 for (; i < ssize1; i++, dstp++)
656 bitset_word tmp = *src1p++;
658 if (*dstp != tmp)
660 changed = true;
661 *dstp = tmp;
665 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
667 return changed;
671 static void
672 vbitset_xor (bitset dst, bitset src1, bitset src2)
674 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
683 unsigned i;
684 for (i = 0; i < min (ssize1, ssize2); i++)
685 *dstp++ = *src1p++ ^ *src2p++;
687 if (ssize2 > ssize1)
689 src1p = src2p;
690 ssize1 = ssize2;
693 for (; i < ssize1; i++)
694 *dstp++ = *src1p++;
696 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
700 static bool
701 vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
703 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
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);
712 bool changed = false;
713 unsigned i;
714 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
716 bitset_word tmp = *src1p++ ^ *src2p++;
718 if (*dstp != tmp)
720 changed = true;
721 *dstp = tmp;
725 if (ssize2 > ssize1)
727 src1p = src2p;
728 ssize1 = ssize2;
731 for (; i < ssize1; i++, dstp++)
733 bitset_word tmp = *src1p++;
735 if (*dstp != tmp)
737 changed = true;
738 *dstp = tmp;
742 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
744 return changed;
748 /* FIXME, these operations need fixing for different size
749 bitsets. */
751 static void
752 vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
754 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
755 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
757 bitset_and_or_ (dst, src1, src2, src3);
758 return;
761 vbitset_resize (dst, BITSET_NBITS_ (src1));
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);
769 for (unsigned i = 0; i < size; i++)
770 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
774 static bool
775 vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
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);
781 vbitset_resize (dst, BITSET_NBITS_ (src1));
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);
789 bool changed = false;
790 for (unsigned i = 0; i < size; i++, dstp++)
792 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
794 if (*dstp != tmp)
796 changed = true;
797 *dstp = tmp;
800 return changed;
804 static void
805 vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
807 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
808 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
810 bitset_andn_or_ (dst, src1, src2, src3);
811 return;
814 vbitset_resize (dst, BITSET_NBITS_ (src1));
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);
822 for (unsigned i = 0; i < size; i++)
823 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
827 static bool
828 vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
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);
834 vbitset_resize (dst, BITSET_NBITS_ (src1));
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);
842 bool changed = false;
843 for (unsigned i = 0; i < size; i++, dstp++)
845 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
847 if (*dstp != tmp)
849 changed = true;
850 *dstp = tmp;
853 return changed;
857 static void
858 vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
860 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
861 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
863 bitset_or_and_ (dst, src1, src2, src3);
864 return;
867 vbitset_resize (dst, BITSET_NBITS_ (src1));
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);
875 for (unsigned i = 0; i < size; i++)
876 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
880 static bool
881 vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
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);
887 vbitset_resize (dst, BITSET_NBITS_ (src1));
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);
895 bool changed = false;
896 unsigned i;
897 for (i = 0; i < size; i++, dstp++)
899 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
901 if (*dstp != tmp)
903 changed = true;
904 *dstp = tmp;
907 return changed;
911 static void
912 vbitset_copy (bitset dst, bitset src)
914 if (BITSET_COMPATIBLE_ (dst, src))
915 vbitset_copy1 (dst, src);
916 else
917 bitset_copy_ (dst, src);
921 static void
922 vbitset_free (bitset bset)
924 free (VBITSET_WORDS (bset));
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
966 size_t
967 vbitset_bytes (bitset_bindex n_bits MAYBE_UNUSED)
969 return sizeof (struct vbitset_struct);
973 bitset
974 vbitset_init (bitset bset, bitset_bindex n_bits)
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;