abitset.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. /* Array bitsets.
  2. Copyright (C) 2002-2003, 2006, 2009-2013 Free Software Foundation,
  3. Inc.
  4. Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include <config.h>
  16. #include "abitset.h"
  17. #include <stddef.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. /* This file implements fixed size bitsets stored as an array
  21. of words. Any unused bits in the last word must be zero. */
  22. #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
  23. #define ABITSET_WORDS(X) ((X)->a.words)
  24. static bitset_bindex
  25. abitset_resize (bitset src, bitset_bindex size)
  26. {
  27. /* These bitsets have a fixed size. */
  28. if (BITSET_SIZE_ (src) != size)
  29. abort ();
  30. return size;
  31. }
  32. /* Find list of up to NUM bits set in BSET starting from and including
  33. *NEXT and store in array LIST. Return with actual number of bits
  34. found and with *NEXT indicating where search stopped. */
  35. static bitset_bindex
  36. abitset_small_list (bitset src, bitset_bindex *list,
  37. bitset_bindex num, bitset_bindex *next)
  38. {
  39. bitset_bindex bitno;
  40. bitset_bindex count;
  41. bitset_windex size;
  42. bitset_word word;
  43. word = ABITSET_WORDS (src)[0];
  44. /* Short circuit common case. */
  45. if (!word)
  46. return 0;
  47. size = BITSET_SIZE_ (src);
  48. bitno = *next;
  49. if (bitno >= size)
  50. return 0;
  51. word >>= bitno;
  52. /* If num is 1, we could speed things up with a binary search
  53. of the word of interest. */
  54. if (num >= BITSET_WORD_BITS)
  55. {
  56. for (count = 0; word; bitno++)
  57. {
  58. if (word & 1)
  59. list[count++] = bitno;
  60. word >>= 1;
  61. }
  62. }
  63. else
  64. {
  65. for (count = 0; word; bitno++)
  66. {
  67. if (word & 1)
  68. {
  69. list[count++] = bitno;
  70. if (count >= num)
  71. {
  72. bitno++;
  73. break;
  74. }
  75. }
  76. word >>= 1;
  77. }
  78. }
  79. *next = bitno;
  80. return count;
  81. }
  82. /* Set bit BITNO in bitset DST. */
  83. static void
  84. abitset_set (bitset dst ATTRIBUTE_UNUSED, bitset_bindex bitno ATTRIBUTE_UNUSED)
  85. {
  86. /* This should never occur for abitsets since we should always hit
  87. the cache. It is likely someone is trying to access outside the
  88. bounds of the bitset. */
  89. abort ();
  90. }
  91. /* Reset bit BITNO in bitset DST. */
  92. static void
  93. abitset_reset (bitset dst ATTRIBUTE_UNUSED,
  94. bitset_bindex bitno ATTRIBUTE_UNUSED)
  95. {
  96. /* This should never occur for abitsets since we should always hit
  97. the cache. It is likely someone is trying to access outside the
  98. bounds of the bitset. Since the bit is zero anyway, let it pass. */
  99. }
  100. /* Test bit BITNO in bitset SRC. */
  101. static bool
  102. abitset_test (bitset src ATTRIBUTE_UNUSED,
  103. bitset_bindex bitno ATTRIBUTE_UNUSED)
  104. {
  105. /* This should never occur for abitsets since we should always
  106. hit the cache. */
  107. return false;
  108. }
  109. /* Find list of up to NUM bits set in BSET in reverse order, starting
  110. from and including NEXT and store in array LIST. Return with
  111. actual number of bits found and with *NEXT indicating where search
  112. stopped. */
  113. static bitset_bindex
  114. abitset_list_reverse (bitset src, bitset_bindex *list,
  115. bitset_bindex num, bitset_bindex *next)
  116. {
  117. bitset_bindex bitno;
  118. bitset_bindex rbitno;
  119. bitset_bindex count;
  120. bitset_windex windex;
  121. unsigned int bitcnt;
  122. bitset_bindex bitoff;
  123. bitset_word *srcp = ABITSET_WORDS (src);
  124. bitset_bindex n_bits = BITSET_SIZE_ (src);
  125. rbitno = *next;
  126. /* If num is 1, we could speed things up with a binary search
  127. of the word of interest. */
  128. if (rbitno >= n_bits)
  129. return 0;
  130. count = 0;
  131. bitno = n_bits - (rbitno + 1);
  132. windex = bitno / BITSET_WORD_BITS;
  133. bitcnt = bitno % BITSET_WORD_BITS;
  134. bitoff = windex * BITSET_WORD_BITS;
  135. do
  136. {
  137. bitset_word word;
  138. word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
  139. for (; word; bitcnt--)
  140. {
  141. if (word & BITSET_MSB)
  142. {
  143. list[count++] = bitoff + bitcnt;
  144. if (count >= num)
  145. {
  146. *next = n_bits - (bitoff + bitcnt);
  147. return count;
  148. }
  149. }
  150. word <<= 1;
  151. }
  152. bitoff -= BITSET_WORD_BITS;
  153. bitcnt = BITSET_WORD_BITS - 1;
  154. }
  155. while (windex--);
  156. *next = n_bits - (bitoff + 1);
  157. return count;
  158. }
  159. /* Find list of up to NUM bits set in BSET starting from and including
  160. *NEXT and store in array LIST. Return with actual number of bits
  161. found and with *NEXT indicating where search stopped. */
  162. static bitset_bindex
  163. abitset_list (bitset src, bitset_bindex *list,
  164. bitset_bindex num, bitset_bindex *next)
  165. {
  166. bitset_bindex bitno;
  167. bitset_bindex count;
  168. bitset_windex windex;
  169. bitset_bindex bitoff;
  170. bitset_windex size = src->b.csize;
  171. bitset_word *srcp = ABITSET_WORDS (src);
  172. bitset_word word;
  173. bitno = *next;
  174. count = 0;
  175. if (!bitno)
  176. {
  177. /* Many bitsets are zero, so make this common case fast. */
  178. for (windex = 0; windex < size && !srcp[windex]; windex++)
  179. continue;
  180. if (windex >= size)
  181. return 0;
  182. /* If num is 1, we could speed things up with a binary search
  183. of the current word. */
  184. bitoff = windex * BITSET_WORD_BITS;
  185. }
  186. else
  187. {
  188. if (bitno >= BITSET_SIZE_ (src))
  189. return 0;
  190. windex = bitno / BITSET_WORD_BITS;
  191. bitno = bitno % BITSET_WORD_BITS;
  192. if (bitno)
  193. {
  194. /* Handle the case where we start within a word.
  195. Most often, this is executed with large bitsets
  196. with many set bits where we filled the array
  197. on the previous call to this function. */
  198. bitoff = windex * BITSET_WORD_BITS;
  199. word = srcp[windex] >> bitno;
  200. for (bitno = bitoff + bitno; word; bitno++)
  201. {
  202. if (word & 1)
  203. {
  204. list[count++] = bitno;
  205. if (count >= num)
  206. {
  207. *next = bitno + 1;
  208. return count;
  209. }
  210. }
  211. word >>= 1;
  212. }
  213. windex++;
  214. }
  215. bitoff = windex * BITSET_WORD_BITS;
  216. }
  217. for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
  218. {
  219. if (!(word = srcp[windex]))
  220. continue;
  221. if ((count + BITSET_WORD_BITS) < num)
  222. {
  223. for (bitno = bitoff; word; bitno++)
  224. {
  225. if (word & 1)
  226. list[count++] = bitno;
  227. word >>= 1;
  228. }
  229. }
  230. else
  231. {
  232. for (bitno = bitoff; word; bitno++)
  233. {
  234. if (word & 1)
  235. {
  236. list[count++] = bitno;
  237. if (count >= num)
  238. {
  239. *next = bitno + 1;
  240. return count;
  241. }
  242. }
  243. word >>= 1;
  244. }
  245. }
  246. }
  247. *next = bitoff;
  248. return count;
  249. }
  250. /* Ensure that any unused bits within the last word are clear. */
  251. static inline void
  252. abitset_unused_clear (bitset dst)
  253. {
  254. unsigned int last_bit;
  255. last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
  256. if (last_bit)
  257. ABITSET_WORDS (dst)[dst->b.csize - 1] &=
  258. ((bitset_word) 1 << last_bit) - 1;
  259. }
  260. static void
  261. abitset_ones (bitset dst)
  262. {
  263. bitset_word *dstp = ABITSET_WORDS (dst);
  264. size_t bytes;
  265. bytes = sizeof (bitset_word) * dst->b.csize;
  266. memset (dstp, -1, bytes);
  267. abitset_unused_clear (dst);
  268. }
  269. static void
  270. abitset_zero (bitset dst)
  271. {
  272. bitset_word *dstp = ABITSET_WORDS (dst);
  273. size_t bytes;
  274. bytes = sizeof (bitset_word) * dst->b.csize;
  275. memset (dstp, 0, bytes);
  276. }
  277. static bool
  278. abitset_empty_p (bitset dst)
  279. {
  280. bitset_windex i;
  281. bitset_word *dstp = ABITSET_WORDS (dst);
  282. for (i = 0; i < dst->b.csize; i++)
  283. if (dstp[i])
  284. return false;
  285. return true;
  286. }
  287. static void
  288. abitset_copy1 (bitset dst, bitset src)
  289. {
  290. bitset_word *srcp = ABITSET_WORDS (src);
  291. bitset_word *dstp = ABITSET_WORDS (dst);
  292. bitset_windex size = dst->b.csize;
  293. if (srcp == dstp)
  294. return;
  295. memcpy (dstp, srcp, sizeof (bitset_word) * size);
  296. }
  297. static void
  298. abitset_not (bitset dst, bitset src)
  299. {
  300. bitset_windex i;
  301. bitset_word *srcp = ABITSET_WORDS (src);
  302. bitset_word *dstp = ABITSET_WORDS (dst);
  303. bitset_windex size = dst->b.csize;
  304. for (i = 0; i < size; i++)
  305. *dstp++ = ~(*srcp++);
  306. abitset_unused_clear (dst);
  307. }
  308. static bool
  309. abitset_equal_p (bitset dst, bitset src)
  310. {
  311. bitset_windex i;
  312. bitset_word *srcp = ABITSET_WORDS (src);
  313. bitset_word *dstp = ABITSET_WORDS (dst);
  314. bitset_windex size = dst->b.csize;
  315. for (i = 0; i < size; i++)
  316. if (*srcp++ != *dstp++)
  317. return false;
  318. return true;
  319. }
  320. static bool
  321. abitset_subset_p (bitset dst, bitset src)
  322. {
  323. bitset_windex i;
  324. bitset_word *srcp = ABITSET_WORDS (src);
  325. bitset_word *dstp = ABITSET_WORDS (dst);
  326. bitset_windex size = dst->b.csize;
  327. for (i = 0; i < size; i++, dstp++, srcp++)
  328. if (*dstp != (*srcp | *dstp))
  329. return false;
  330. return true;
  331. }
  332. static bool
  333. abitset_disjoint_p (bitset dst, bitset src)
  334. {
  335. bitset_windex i;
  336. bitset_word *srcp = ABITSET_WORDS (src);
  337. bitset_word *dstp = ABITSET_WORDS (dst);
  338. bitset_windex size = dst->b.csize;
  339. for (i = 0; i < size; i++)
  340. if (*srcp++ & *dstp++)
  341. return false;
  342. return true;
  343. }
  344. static void
  345. abitset_and (bitset dst, bitset src1, bitset src2)
  346. {
  347. bitset_windex i;
  348. bitset_word *src1p = ABITSET_WORDS (src1);
  349. bitset_word *src2p = ABITSET_WORDS (src2);
  350. bitset_word *dstp = ABITSET_WORDS (dst);
  351. bitset_windex size = dst->b.csize;
  352. for (i = 0; i < size; i++)
  353. *dstp++ = *src1p++ & *src2p++;
  354. }
  355. static bool
  356. abitset_and_cmp (bitset dst, bitset src1, bitset src2)
  357. {
  358. bitset_windex i;
  359. bool changed = false;
  360. bitset_word *src1p = ABITSET_WORDS (src1);
  361. bitset_word *src2p = ABITSET_WORDS (src2);
  362. bitset_word *dstp = ABITSET_WORDS (dst);
  363. bitset_windex size = dst->b.csize;
  364. for (i = 0; i < size; i++, dstp++)
  365. {
  366. bitset_word tmp = *src1p++ & *src2p++;
  367. if (*dstp != tmp)
  368. {
  369. changed = true;
  370. *dstp = tmp;
  371. }
  372. }
  373. return changed;
  374. }
  375. static void
  376. abitset_andn (bitset dst, bitset src1, bitset src2)
  377. {
  378. bitset_windex i;
  379. bitset_word *src1p = ABITSET_WORDS (src1);
  380. bitset_word *src2p = ABITSET_WORDS (src2);
  381. bitset_word *dstp = ABITSET_WORDS (dst);
  382. bitset_windex size = dst->b.csize;
  383. for (i = 0; i < size; i++)
  384. *dstp++ = *src1p++ & ~(*src2p++);
  385. }
  386. static bool
  387. abitset_andn_cmp (bitset dst, bitset src1, bitset src2)
  388. {
  389. bitset_windex i;
  390. bool changed = false;
  391. bitset_word *src1p = ABITSET_WORDS (src1);
  392. bitset_word *src2p = ABITSET_WORDS (src2);
  393. bitset_word *dstp = ABITSET_WORDS (dst);
  394. bitset_windex size = dst->b.csize;
  395. for (i = 0; i < size; i++, dstp++)
  396. {
  397. bitset_word tmp = *src1p++ & ~(*src2p++);
  398. if (*dstp != tmp)
  399. {
  400. changed = true;
  401. *dstp = tmp;
  402. }
  403. }
  404. return changed;
  405. }
  406. static void
  407. abitset_or (bitset dst, bitset src1, bitset src2)
  408. {
  409. bitset_windex i;
  410. bitset_word *src1p = ABITSET_WORDS (src1);
  411. bitset_word *src2p = ABITSET_WORDS (src2);
  412. bitset_word *dstp = ABITSET_WORDS (dst);
  413. bitset_windex size = dst->b.csize;
  414. for (i = 0; i < size; i++)
  415. *dstp++ = *src1p++ | *src2p++;
  416. }
  417. static bool
  418. abitset_or_cmp (bitset dst, bitset src1, bitset src2)
  419. {
  420. bitset_windex i;
  421. bool changed = false;
  422. bitset_word *src1p = ABITSET_WORDS (src1);
  423. bitset_word *src2p = ABITSET_WORDS (src2);
  424. bitset_word *dstp = ABITSET_WORDS (dst);
  425. bitset_windex size = dst->b.csize;
  426. for (i = 0; i < size; i++, dstp++)
  427. {
  428. bitset_word tmp = *src1p++ | *src2p++;
  429. if (*dstp != tmp)
  430. {
  431. changed = true;
  432. *dstp = tmp;
  433. }
  434. }
  435. return changed;
  436. }
  437. static void
  438. abitset_xor (bitset dst, bitset src1, bitset src2)
  439. {
  440. bitset_windex i;
  441. bitset_word *src1p = ABITSET_WORDS (src1);
  442. bitset_word *src2p = ABITSET_WORDS (src2);
  443. bitset_word *dstp = ABITSET_WORDS (dst);
  444. bitset_windex size = dst->b.csize;
  445. for (i = 0; i < size; i++)
  446. *dstp++ = *src1p++ ^ *src2p++;
  447. }
  448. static bool
  449. abitset_xor_cmp (bitset dst, bitset src1, bitset src2)
  450. {
  451. bitset_windex i;
  452. bool changed = false;
  453. bitset_word *src1p = ABITSET_WORDS (src1);
  454. bitset_word *src2p = ABITSET_WORDS (src2);
  455. bitset_word *dstp = ABITSET_WORDS (dst);
  456. bitset_windex size = dst->b.csize;
  457. for (i = 0; i < size; i++, dstp++)
  458. {
  459. bitset_word tmp = *src1p++ ^ *src2p++;
  460. if (*dstp != tmp)
  461. {
  462. changed = true;
  463. *dstp = tmp;
  464. }
  465. }
  466. return changed;
  467. }
  468. static void
  469. abitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
  470. {
  471. bitset_windex i;
  472. bitset_word *src1p = ABITSET_WORDS (src1);
  473. bitset_word *src2p = ABITSET_WORDS (src2);
  474. bitset_word *src3p = ABITSET_WORDS (src3);
  475. bitset_word *dstp = ABITSET_WORDS (dst);
  476. bitset_windex size = dst->b.csize;
  477. for (i = 0; i < size; i++)
  478. *dstp++ = (*src1p++ & *src2p++) | *src3p++;
  479. }
  480. static bool
  481. abitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
  482. {
  483. bitset_windex i;
  484. bool changed = false;
  485. bitset_word *src1p = ABITSET_WORDS (src1);
  486. bitset_word *src2p = ABITSET_WORDS (src2);
  487. bitset_word *src3p = ABITSET_WORDS (src3);
  488. bitset_word *dstp = ABITSET_WORDS (dst);
  489. bitset_windex size = dst->b.csize;
  490. for (i = 0; i < size; i++, dstp++)
  491. {
  492. bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
  493. if (*dstp != tmp)
  494. {
  495. changed = true;
  496. *dstp = tmp;
  497. }
  498. }
  499. return changed;
  500. }
  501. static void
  502. abitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
  503. {
  504. bitset_windex i;
  505. bitset_word *src1p = ABITSET_WORDS (src1);
  506. bitset_word *src2p = ABITSET_WORDS (src2);
  507. bitset_word *src3p = ABITSET_WORDS (src3);
  508. bitset_word *dstp = ABITSET_WORDS (dst);
  509. bitset_windex size = dst->b.csize;
  510. for (i = 0; i < size; i++)
  511. *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
  512. }
  513. static bool
  514. abitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
  515. {
  516. bitset_windex i;
  517. bool changed = false;
  518. bitset_word *src1p = ABITSET_WORDS (src1);
  519. bitset_word *src2p = ABITSET_WORDS (src2);
  520. bitset_word *src3p = ABITSET_WORDS (src3);
  521. bitset_word *dstp = ABITSET_WORDS (dst);
  522. bitset_windex size = dst->b.csize;
  523. for (i = 0; i < size; i++, dstp++)
  524. {
  525. bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
  526. if (*dstp != tmp)
  527. {
  528. changed = true;
  529. *dstp = tmp;
  530. }
  531. }
  532. return changed;
  533. }
  534. static void
  535. abitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
  536. {
  537. bitset_windex i;
  538. bitset_word *src1p = ABITSET_WORDS (src1);
  539. bitset_word *src2p = ABITSET_WORDS (src2);
  540. bitset_word *src3p = ABITSET_WORDS (src3);
  541. bitset_word *dstp = ABITSET_WORDS (dst);
  542. bitset_windex size = dst->b.csize;
  543. for (i = 0; i < size; i++)
  544. *dstp++ = (*src1p++ | *src2p++) & *src3p++;
  545. }
  546. static bool
  547. abitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
  548. {
  549. bitset_windex i;
  550. bool changed = false;
  551. bitset_word *src1p = ABITSET_WORDS (src1);
  552. bitset_word *src2p = ABITSET_WORDS (src2);
  553. bitset_word *src3p = ABITSET_WORDS (src3);
  554. bitset_word *dstp = ABITSET_WORDS (dst);
  555. bitset_windex size = dst->b.csize;
  556. for (i = 0; i < size; i++, dstp++)
  557. {
  558. bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
  559. if (*dstp != tmp)
  560. {
  561. changed = true;
  562. *dstp = tmp;
  563. }
  564. }
  565. return changed;
  566. }
  567. static void
  568. abitset_copy (bitset dst, bitset src)
  569. {
  570. if (BITSET_COMPATIBLE_ (dst, src))
  571. abitset_copy1 (dst, src);
  572. else
  573. bitset_copy_ (dst, src);
  574. }
  575. /* Vector of operations for single word bitsets. */
  576. struct bitset_vtable abitset_small_vtable = {
  577. abitset_set,
  578. abitset_reset,
  579. bitset_toggle_,
  580. abitset_test,
  581. abitset_resize,
  582. bitset_size_,
  583. bitset_count_,
  584. abitset_empty_p,
  585. abitset_ones,
  586. abitset_zero,
  587. abitset_copy,
  588. abitset_disjoint_p,
  589. abitset_equal_p,
  590. abitset_not,
  591. abitset_subset_p,
  592. abitset_and,
  593. abitset_and_cmp,
  594. abitset_andn,
  595. abitset_andn_cmp,
  596. abitset_or,
  597. abitset_or_cmp,
  598. abitset_xor,
  599. abitset_xor_cmp,
  600. abitset_and_or,
  601. abitset_and_or_cmp,
  602. abitset_andn_or,
  603. abitset_andn_or_cmp,
  604. abitset_or_and,
  605. abitset_or_and_cmp,
  606. abitset_small_list,
  607. abitset_list_reverse,
  608. NULL,
  609. BITSET_ARRAY
  610. };
  611. /* Vector of operations for multiple word bitsets. */
  612. struct bitset_vtable abitset_vtable = {
  613. abitset_set,
  614. abitset_reset,
  615. bitset_toggle_,
  616. abitset_test,
  617. abitset_resize,
  618. bitset_size_,
  619. bitset_count_,
  620. abitset_empty_p,
  621. abitset_ones,
  622. abitset_zero,
  623. abitset_copy,
  624. abitset_disjoint_p,
  625. abitset_equal_p,
  626. abitset_not,
  627. abitset_subset_p,
  628. abitset_and,
  629. abitset_and_cmp,
  630. abitset_andn,
  631. abitset_andn_cmp,
  632. abitset_or,
  633. abitset_or_cmp,
  634. abitset_xor,
  635. abitset_xor_cmp,
  636. abitset_and_or,
  637. abitset_and_or_cmp,
  638. abitset_andn_or,
  639. abitset_andn_or_cmp,
  640. abitset_or_and,
  641. abitset_or_and_cmp,
  642. abitset_list,
  643. abitset_list_reverse,
  644. NULL,
  645. BITSET_ARRAY
  646. };
  647. size_t
  648. abitset_bytes (bitset_bindex n_bits)
  649. {
  650. bitset_windex size;
  651. size_t bytes;
  652. size_t header_size = offsetof (union bitset_union, a.words);
  653. struct bitset_align_struct { char a; union bitset_union b; };
  654. size_t bitset_alignment = offsetof (struct bitset_align_struct, b);
  655. size = ABITSET_N_WORDS (n_bits);
  656. bytes = header_size + size * sizeof (bitset_word);
  657. /* Align the size properly for a vector of abitset objects. */
  658. if (header_size % bitset_alignment != 0
  659. || sizeof (bitset_word) % bitset_alignment != 0)
  660. {
  661. bytes += bitset_alignment - 1;
  662. bytes -= bytes % bitset_alignment;
  663. }
  664. return bytes;
  665. }
  666. bitset
  667. abitset_init (bitset bset, bitset_bindex n_bits)
  668. {
  669. bitset_windex size;
  670. size = ABITSET_N_WORDS (n_bits);
  671. BITSET_NBITS_ (bset) = n_bits;
  672. /* Use optimized routines if bitset fits within a single word.
  673. There is probably little merit if using caching since
  674. the small bitset will always fit in the cache. */
  675. if (size == 1)
  676. bset->b.vtable = &abitset_small_vtable;
  677. else
  678. bset->b.vtable = &abitset_vtable;
  679. bset->b.cindex = 0;
  680. bset->b.csize = size;
  681. bset->b.cdata = ABITSET_WORDS (bset);
  682. return bset;
  683. }