1use std::marker::PhantomData;
2use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl};
3use std::rc::Rc;
4use std::{fmt, iter, mem, slice};
5
6use Chunk::*;
7#[cfg(feature = "nightly")]
8use rustc_macros::{Decodable_Generic, Encodable_Generic};
9use smallvec::{SmallVec, smallvec};
10
11use crate::{Idx, IndexVec};
12
13#[cfg(test)]
14mod tests;
15
16type Word = u64;
17const WORD_BYTES: usize = mem::size_of::<Word>();
18const WORD_BITS: usize = WORD_BYTES * 8;
19
20const CHUNK_WORDS: usize = 32;
31const CHUNK_BITS: usize = CHUNK_WORDS * WORD_BITS; type ChunkSize = u16;
36const _: () = assert!(CHUNK_BITS <= ChunkSize::MAX as usize);
37
38pub trait BitRelations<Rhs> {
39 fn union(&mut self, other: &Rhs) -> bool;
40 fn subtract(&mut self, other: &Rhs) -> bool;
41 fn intersect(&mut self, other: &Rhs) -> bool;
42}
43
44#[inline]
45fn inclusive_start_end<T: Idx>(
46 range: impl RangeBounds<T>,
47 domain: usize,
48) -> Option<(usize, usize)> {
49 let start = match range.start_bound().cloned() {
51 Bound::Included(start) => start.index(),
52 Bound::Excluded(start) => start.index() + 1,
53 Bound::Unbounded => 0,
54 };
55 let end = match range.end_bound().cloned() {
56 Bound::Included(end) => end.index(),
57 Bound::Excluded(end) => end.index().checked_sub(1)?,
58 Bound::Unbounded => domain - 1,
59 };
60 assert!(end < domain);
61 if start > end {
62 return None;
63 }
64 Some((start, end))
65}
66
67macro_rules! bit_relations_inherent_impls {
68 () => {
69 pub fn union<Rhs>(&mut self, other: &Rhs) -> bool
72 where
73 Self: BitRelations<Rhs>,
74 {
75 <Self as BitRelations<Rhs>>::union(self, other)
76 }
77
78 pub fn subtract<Rhs>(&mut self, other: &Rhs) -> bool
81 where
82 Self: BitRelations<Rhs>,
83 {
84 <Self as BitRelations<Rhs>>::subtract(self, other)
85 }
86
87 pub fn intersect<Rhs>(&mut self, other: &Rhs) -> bool
90 where
91 Self: BitRelations<Rhs>,
92 {
93 <Self as BitRelations<Rhs>>::intersect(self, other)
94 }
95 };
96}
97
98#[cfg_attr(feature = "nightly", derive(Decodable_Generic, Encodable_Generic))]
116#[derive(Eq, PartialEq, Hash)]
117pub struct DenseBitSet<T> {
118 domain_size: usize,
119 words: SmallVec<[Word; 2]>,
120 marker: PhantomData<T>,
121}
122
123impl<T> DenseBitSet<T> {
124 pub fn domain_size(&self) -> usize {
126 self.domain_size
127 }
128}
129
130impl<T: Idx> DenseBitSet<T> {
131 #[inline]
133 pub fn new_empty(domain_size: usize) -> DenseBitSet<T> {
134 let num_words = num_words(domain_size);
135 DenseBitSet { domain_size, words: smallvec![0; num_words], marker: PhantomData }
136 }
137
138 #[inline]
140 pub fn new_filled(domain_size: usize) -> DenseBitSet<T> {
141 let num_words = num_words(domain_size);
142 let mut result =
143 DenseBitSet { domain_size, words: smallvec![!0; num_words], marker: PhantomData };
144 result.clear_excess_bits();
145 result
146 }
147
148 #[inline]
150 pub fn clear(&mut self) {
151 self.words.fill(0);
152 }
153
154 fn clear_excess_bits(&mut self) {
156 clear_excess_bits_in_final_word(self.domain_size, &mut self.words);
157 }
158
159 pub fn count(&self) -> usize {
161 self.words.iter().map(|e| e.count_ones() as usize).sum()
162 }
163
164 #[inline]
166 pub fn contains(&self, elem: T) -> bool {
167 assert!(elem.index() < self.domain_size);
168 let (word_index, mask) = word_index_and_mask(elem);
169 (self.words[word_index] & mask) != 0
170 }
171
172 #[inline]
174 pub fn superset(&self, other: &DenseBitSet<T>) -> bool {
175 assert_eq!(self.domain_size, other.domain_size);
176 self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b)
177 }
178
179 #[inline]
181 pub fn is_empty(&self) -> bool {
182 self.words.iter().all(|a| *a == 0)
183 }
184
185 #[inline]
187 pub fn insert(&mut self, elem: T) -> bool {
188 assert!(
189 elem.index() < self.domain_size,
190 "inserting element at index {} but domain size is {}",
191 elem.index(),
192 self.domain_size,
193 );
194 let (word_index, mask) = word_index_and_mask(elem);
195 let word_ref = &mut self.words[word_index];
196 let word = *word_ref;
197 let new_word = word | mask;
198 *word_ref = new_word;
199 new_word != word
200 }
201
202 #[inline]
203 pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
204 let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
205 return;
206 };
207
208 let (start_word_index, start_mask) = word_index_and_mask(start);
209 let (end_word_index, end_mask) = word_index_and_mask(end);
210
211 for word_index in (start_word_index + 1)..end_word_index {
213 self.words[word_index] = !0;
214 }
215
216 if start_word_index != end_word_index {
217 self.words[start_word_index] |= !(start_mask - 1);
221 self.words[end_word_index] |= end_mask | (end_mask - 1);
224 } else {
225 self.words[start_word_index] |= end_mask | (end_mask - start_mask);
226 }
227 }
228
229 pub fn insert_all(&mut self) {
231 self.words.fill(!0);
232 self.clear_excess_bits();
233 }
234
235 #[inline]
237 pub fn remove(&mut self, elem: T) -> bool {
238 assert!(elem.index() < self.domain_size);
239 let (word_index, mask) = word_index_and_mask(elem);
240 let word_ref = &mut self.words[word_index];
241 let word = *word_ref;
242 let new_word = word & !mask;
243 *word_ref = new_word;
244 new_word != word
245 }
246
247 #[inline]
249 pub fn iter(&self) -> BitIter<'_, T> {
250 BitIter::new(&self.words)
251 }
252
253 pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
254 let (start, end) = inclusive_start_end(range, self.domain_size)?;
255 let (start_word_index, _) = word_index_and_mask(start);
256 let (end_word_index, end_mask) = word_index_and_mask(end);
257
258 let end_word = self.words[end_word_index] & (end_mask | (end_mask - 1));
259 if end_word != 0 {
260 let pos = max_bit(end_word) + WORD_BITS * end_word_index;
261 if start <= pos {
262 return Some(T::new(pos));
263 }
264 }
265
266 if let Some(offset) =
270 self.words[start_word_index..end_word_index].iter().rposition(|&w| w != 0)
271 {
272 let word_idx = start_word_index + offset;
273 let start_word = self.words[word_idx];
274 let pos = max_bit(start_word) + WORD_BITS * word_idx;
275 if start <= pos {
276 return Some(T::new(pos));
277 }
278 }
279
280 None
281 }
282
283 bit_relations_inherent_impls! {}
284
285 pub fn union_not(&mut self, other: &DenseBitSet<T>) {
290 assert_eq!(self.domain_size, other.domain_size);
291
292 bitwise(&mut self.words, &other.words, |a, b| a | !b);
298 self.clear_excess_bits();
301 }
302}
303
304impl<T: Idx> BitRelations<DenseBitSet<T>> for DenseBitSet<T> {
306 fn union(&mut self, other: &DenseBitSet<T>) -> bool {
307 assert_eq!(self.domain_size, other.domain_size);
308 bitwise(&mut self.words, &other.words, |a, b| a | b)
309 }
310
311 fn subtract(&mut self, other: &DenseBitSet<T>) -> bool {
312 assert_eq!(self.domain_size, other.domain_size);
313 bitwise(&mut self.words, &other.words, |a, b| a & !b)
314 }
315
316 fn intersect(&mut self, other: &DenseBitSet<T>) -> bool {
317 assert_eq!(self.domain_size, other.domain_size);
318 bitwise(&mut self.words, &other.words, |a, b| a & b)
319 }
320}
321
322impl<T: Idx> From<GrowableBitSet<T>> for DenseBitSet<T> {
323 fn from(bit_set: GrowableBitSet<T>) -> Self {
324 bit_set.bit_set
325 }
326}
327
328impl<T> Clone for DenseBitSet<T> {
329 fn clone(&self) -> Self {
330 DenseBitSet {
331 domain_size: self.domain_size,
332 words: self.words.clone(),
333 marker: PhantomData,
334 }
335 }
336
337 fn clone_from(&mut self, from: &Self) {
338 self.domain_size = from.domain_size;
339 self.words.clone_from(&from.words);
340 }
341}
342
343impl<T: Idx> fmt::Debug for DenseBitSet<T> {
344 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
345 w.debug_list().entries(self.iter()).finish()
346 }
347}
348
349impl<T: Idx> ToString for DenseBitSet<T> {
350 fn to_string(&self) -> String {
351 let mut result = String::new();
352 let mut sep = '[';
353
354 let mut i = 0;
358 for word in &self.words {
359 let mut word = *word;
360 for _ in 0..WORD_BYTES {
361 let remain = self.domain_size - i;
363 let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
365 assert!(mask <= 0xFF);
366 let byte = word & mask;
367
368 result.push_str(&format!("{sep}{byte:02x}"));
369
370 if remain <= 8 {
371 break;
372 }
373 word >>= 8;
374 i += 8;
375 sep = '-';
376 }
377 sep = '|';
378 }
379 result.push(']');
380
381 result
382 }
383}
384
385pub struct BitIter<'a, T: Idx> {
386 word: Word,
390
391 offset: usize,
393
394 iter: slice::Iter<'a, Word>,
396
397 marker: PhantomData<T>,
398}
399
400impl<'a, T: Idx> BitIter<'a, T> {
401 #[inline]
402 fn new(words: &'a [Word]) -> BitIter<'a, T> {
403 BitIter {
409 word: 0,
410 offset: usize::MAX - (WORD_BITS - 1),
411 iter: words.iter(),
412 marker: PhantomData,
413 }
414 }
415}
416
417impl<'a, T: Idx> Iterator for BitIter<'a, T> {
418 type Item = T;
419 fn next(&mut self) -> Option<T> {
420 loop {
421 if self.word != 0 {
422 let bit_pos = self.word.trailing_zeros() as usize;
425 self.word ^= 1 << bit_pos;
426 return Some(T::new(bit_pos + self.offset));
427 }
428
429 self.word = *self.iter.next()?;
432 self.offset = self.offset.wrapping_add(WORD_BITS);
433 }
434 }
435}
436
437#[derive(PartialEq, Eq)]
456pub struct ChunkedBitSet<T> {
457 domain_size: usize,
458
459 chunks: Box<[Chunk]>,
462
463 marker: PhantomData<T>,
464}
465
466#[derive(Clone, Debug, PartialEq, Eq)]
471enum Chunk {
472 Zeros(ChunkSize),
475
476 Ones(ChunkSize),
479
480 Mixed(ChunkSize, ChunkSize, Rc<[Word; CHUNK_WORDS]>),
499}
500
501#[cfg(target_pointer_width = "64")]
503crate::static_assert_size!(Chunk, 16);
504
505impl<T> ChunkedBitSet<T> {
506 pub fn domain_size(&self) -> usize {
507 self.domain_size
508 }
509
510 #[cfg(test)]
511 fn assert_valid(&self) {
512 if self.domain_size == 0 {
513 assert!(self.chunks.is_empty());
514 return;
515 }
516
517 assert!((self.chunks.len() - 1) * CHUNK_BITS <= self.domain_size);
518 assert!(self.chunks.len() * CHUNK_BITS >= self.domain_size);
519 for chunk in self.chunks.iter() {
520 chunk.assert_valid();
521 }
522 }
523}
524
525impl<T: Idx> ChunkedBitSet<T> {
526 fn new(domain_size: usize, is_empty: bool) -> Self {
528 let chunks = if domain_size == 0 {
529 Box::new([])
530 } else {
531 let final_chunk_domain_size = {
534 let n = domain_size % CHUNK_BITS;
535 if n == 0 { CHUNK_BITS } else { n }
536 };
537 let mut chunks =
538 vec![Chunk::new(CHUNK_BITS, is_empty); num_chunks(domain_size)].into_boxed_slice();
539 *chunks.last_mut().unwrap() = Chunk::new(final_chunk_domain_size, is_empty);
540 chunks
541 };
542 ChunkedBitSet { domain_size, chunks, marker: PhantomData }
543 }
544
545 #[inline]
547 pub fn new_empty(domain_size: usize) -> Self {
548 ChunkedBitSet::new(domain_size, true)
549 }
550
551 #[inline]
553 pub fn new_filled(domain_size: usize) -> Self {
554 ChunkedBitSet::new(domain_size, false)
555 }
556
557 pub fn clear(&mut self) {
558 let domain_size = self.domain_size();
559 *self = ChunkedBitSet::new_empty(domain_size);
560 }
561
562 #[cfg(test)]
563 fn chunks(&self) -> &[Chunk] {
564 &self.chunks
565 }
566
567 pub fn count(&self) -> usize {
569 self.chunks.iter().map(|chunk| chunk.count()).sum()
570 }
571
572 pub fn is_empty(&self) -> bool {
573 self.chunks.iter().all(|chunk| matches!(chunk, Zeros(..)))
574 }
575
576 #[inline]
578 pub fn contains(&self, elem: T) -> bool {
579 assert!(elem.index() < self.domain_size);
580 let chunk = &self.chunks[chunk_index(elem)];
581 match &chunk {
582 Zeros(_) => false,
583 Ones(_) => true,
584 Mixed(_, _, words) => {
585 let (word_index, mask) = chunk_word_index_and_mask(elem);
586 (words[word_index] & mask) != 0
587 }
588 }
589 }
590
591 #[inline]
592 pub fn iter(&self) -> ChunkedBitIter<'_, T> {
593 ChunkedBitIter::new(self)
594 }
595
596 pub fn insert(&mut self, elem: T) -> bool {
598 assert!(elem.index() < self.domain_size);
599 let chunk_index = chunk_index(elem);
600 let chunk = &mut self.chunks[chunk_index];
601 match *chunk {
602 Zeros(chunk_domain_size) => {
603 if chunk_domain_size > 1 {
604 #[cfg(feature = "nightly")]
605 let mut words = {
606 let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
608 unsafe { words.assume_init() }
610 };
611 #[cfg(not(feature = "nightly"))]
612 let mut words = {
613 let words = mem::MaybeUninit::<[Word; CHUNK_WORDS]>::zeroed();
615 let words = unsafe { words.assume_init() };
617 Rc::new(words)
619 };
620 let words_ref = Rc::get_mut(&mut words).unwrap();
621
622 let (word_index, mask) = chunk_word_index_and_mask(elem);
623 words_ref[word_index] |= mask;
624 *chunk = Mixed(chunk_domain_size, 1, words);
625 } else {
626 *chunk = Ones(chunk_domain_size);
627 }
628 true
629 }
630 Ones(_) => false,
631 Mixed(chunk_domain_size, ref mut count, ref mut words) => {
632 let (word_index, mask) = chunk_word_index_and_mask(elem);
634 if (words[word_index] & mask) == 0 {
635 *count += 1;
636 if *count < chunk_domain_size {
637 let words = Rc::make_mut(words);
638 words[word_index] |= mask;
639 } else {
640 *chunk = Ones(chunk_domain_size);
641 }
642 true
643 } else {
644 false
645 }
646 }
647 }
648 }
649
650 pub fn insert_all(&mut self) {
652 for chunk in self.chunks.iter_mut() {
653 *chunk = match *chunk {
654 Zeros(chunk_domain_size)
655 | Ones(chunk_domain_size)
656 | Mixed(chunk_domain_size, ..) => Ones(chunk_domain_size),
657 }
658 }
659 }
660
661 pub fn remove(&mut self, elem: T) -> bool {
663 assert!(elem.index() < self.domain_size);
664 let chunk_index = chunk_index(elem);
665 let chunk = &mut self.chunks[chunk_index];
666 match *chunk {
667 Zeros(_) => false,
668 Ones(chunk_domain_size) => {
669 if chunk_domain_size > 1 {
670 #[cfg(feature = "nightly")]
671 let mut words = {
672 let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
674 unsafe { words.assume_init() }
676 };
677 #[cfg(not(feature = "nightly"))]
678 let mut words = {
679 let words = mem::MaybeUninit::<[Word; CHUNK_WORDS]>::zeroed();
681 let words = unsafe { words.assume_init() };
683 Rc::new(words)
685 };
686 let words_ref = Rc::get_mut(&mut words).unwrap();
687
688 let num_words = num_words(chunk_domain_size as usize);
690 words_ref[..num_words].fill(!0);
691 clear_excess_bits_in_final_word(
692 chunk_domain_size as usize,
693 &mut words_ref[..num_words],
694 );
695 let (word_index, mask) = chunk_word_index_and_mask(elem);
696 words_ref[word_index] &= !mask;
697 *chunk = Mixed(chunk_domain_size, chunk_domain_size - 1, words);
698 } else {
699 *chunk = Zeros(chunk_domain_size);
700 }
701 true
702 }
703 Mixed(chunk_domain_size, ref mut count, ref mut words) => {
704 let (word_index, mask) = chunk_word_index_and_mask(elem);
706 if (words[word_index] & mask) != 0 {
707 *count -= 1;
708 if *count > 0 {
709 let words = Rc::make_mut(words);
710 words[word_index] &= !mask;
711 } else {
712 *chunk = Zeros(chunk_domain_size);
713 }
714 true
715 } else {
716 false
717 }
718 }
719 }
720 }
721
722 fn chunk_iter(&self, chunk_index: usize) -> ChunkIter<'_> {
723 match self.chunks.get(chunk_index) {
724 Some(Zeros(_chunk_domain_size)) => ChunkIter::Zeros,
725 Some(Ones(chunk_domain_size)) => ChunkIter::Ones(0..*chunk_domain_size as usize),
726 Some(Mixed(chunk_domain_size, _, words)) => {
727 let num_words = num_words(*chunk_domain_size as usize);
728 ChunkIter::Mixed(BitIter::new(&words[0..num_words]))
729 }
730 None => ChunkIter::Finished,
731 }
732 }
733
734 bit_relations_inherent_impls! {}
735}
736
737impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
738 fn union(&mut self, other: &ChunkedBitSet<T>) -> bool {
739 assert_eq!(self.domain_size, other.domain_size);
740 debug_assert_eq!(self.chunks.len(), other.chunks.len());
741
742 let mut changed = false;
743 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
744 match (&mut self_chunk, &other_chunk) {
745 (_, Zeros(_)) | (Ones(_), _) => {}
746 (Zeros(self_chunk_domain_size), Ones(other_chunk_domain_size))
747 | (Mixed(self_chunk_domain_size, ..), Ones(other_chunk_domain_size))
748 | (Zeros(self_chunk_domain_size), Mixed(other_chunk_domain_size, ..)) => {
749 debug_assert_eq!(self_chunk_domain_size, other_chunk_domain_size);
751 *self_chunk = other_chunk.clone();
752 changed = true;
753 }
754 (
755 Mixed(self_chunk_domain_size, self_chunk_count, self_chunk_words),
756 Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words),
757 ) => {
758 let op = |a, b| a | b;
764 let num_words = num_words(*self_chunk_domain_size as usize);
765 if bitwise_changes(
766 &self_chunk_words[0..num_words],
767 &other_chunk_words[0..num_words],
768 op,
769 ) {
770 let self_chunk_words = Rc::make_mut(self_chunk_words);
771 let has_changed = bitwise(
772 &mut self_chunk_words[0..num_words],
773 &other_chunk_words[0..num_words],
774 op,
775 );
776 debug_assert!(has_changed);
777 *self_chunk_count = self_chunk_words[0..num_words]
778 .iter()
779 .map(|w| w.count_ones() as ChunkSize)
780 .sum();
781 if *self_chunk_count == *self_chunk_domain_size {
782 *self_chunk = Ones(*self_chunk_domain_size);
783 }
784 changed = true;
785 }
786 }
787 }
788 }
789 changed
790 }
791
792 fn subtract(&mut self, other: &ChunkedBitSet<T>) -> bool {
793 assert_eq!(self.domain_size, other.domain_size);
794 debug_assert_eq!(self.chunks.len(), other.chunks.len());
795
796 let mut changed = false;
797 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
798 match (&mut self_chunk, &other_chunk) {
799 (Zeros(..), _) | (_, Zeros(..)) => {}
800 (
801 Ones(self_chunk_domain_size) | Mixed(self_chunk_domain_size, _, _),
802 Ones(other_chunk_domain_size),
803 ) => {
804 debug_assert_eq!(self_chunk_domain_size, other_chunk_domain_size);
805 changed = true;
806 *self_chunk = Zeros(*self_chunk_domain_size);
807 }
808 (
809 Ones(self_chunk_domain_size),
810 Mixed(other_chunk_domain_size, other_chunk_count, other_chunk_words),
811 ) => {
812 debug_assert_eq!(self_chunk_domain_size, other_chunk_domain_size);
813 changed = true;
814 let num_words = num_words(*self_chunk_domain_size as usize);
815 debug_assert!(num_words > 0 && num_words <= CHUNK_WORDS);
816 let mut tail_mask =
817 1 << (*other_chunk_domain_size - ((num_words - 1) * WORD_BITS) as u16) - 1;
818 let mut self_chunk_words = **other_chunk_words;
819 for word in self_chunk_words[0..num_words].iter_mut().rev() {
820 *word = !*word & tail_mask;
821 tail_mask = u64::MAX;
822 }
823 let self_chunk_count = *self_chunk_domain_size - *other_chunk_count;
824 debug_assert_eq!(
825 self_chunk_count,
826 self_chunk_words[0..num_words]
827 .iter()
828 .map(|w| w.count_ones() as ChunkSize)
829 .sum()
830 );
831 *self_chunk =
832 Mixed(*self_chunk_domain_size, self_chunk_count, Rc::new(self_chunk_words));
833 }
834 (
835 Mixed(self_chunk_domain_size, self_chunk_count, self_chunk_words),
836 Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words),
837 ) => {
838 let op = |a: u64, b: u64| a & !b;
840 let num_words = num_words(*self_chunk_domain_size as usize);
841 if bitwise_changes(
842 &self_chunk_words[0..num_words],
843 &other_chunk_words[0..num_words],
844 op,
845 ) {
846 let self_chunk_words = Rc::make_mut(self_chunk_words);
847 let has_changed = bitwise(
848 &mut self_chunk_words[0..num_words],
849 &other_chunk_words[0..num_words],
850 op,
851 );
852 debug_assert!(has_changed);
853 *self_chunk_count = self_chunk_words[0..num_words]
854 .iter()
855 .map(|w| w.count_ones() as ChunkSize)
856 .sum();
857 if *self_chunk_count == 0 {
858 *self_chunk = Zeros(*self_chunk_domain_size);
859 }
860 changed = true;
861 }
862 }
863 }
864 }
865 changed
866 }
867
868 fn intersect(&mut self, other: &ChunkedBitSet<T>) -> bool {
869 assert_eq!(self.domain_size, other.domain_size);
870 debug_assert_eq!(self.chunks.len(), other.chunks.len());
871
872 let mut changed = false;
873 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
874 match (&mut self_chunk, &other_chunk) {
875 (Zeros(..), _) | (_, Ones(..)) => {}
876 (
877 Ones(self_chunk_domain_size),
878 Zeros(other_chunk_domain_size) | Mixed(other_chunk_domain_size, ..),
879 )
880 | (Mixed(self_chunk_domain_size, ..), Zeros(other_chunk_domain_size)) => {
881 debug_assert_eq!(self_chunk_domain_size, other_chunk_domain_size);
882 changed = true;
883 *self_chunk = other_chunk.clone();
884 }
885 (
886 Mixed(self_chunk_domain_size, self_chunk_count, self_chunk_words),
887 Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words),
888 ) => {
889 let op = |a, b| a & b;
891 let num_words = num_words(*self_chunk_domain_size as usize);
892 if bitwise_changes(
893 &self_chunk_words[0..num_words],
894 &other_chunk_words[0..num_words],
895 op,
896 ) {
897 let self_chunk_words = Rc::make_mut(self_chunk_words);
898 let has_changed = bitwise(
899 &mut self_chunk_words[0..num_words],
900 &other_chunk_words[0..num_words],
901 op,
902 );
903 debug_assert!(has_changed);
904 *self_chunk_count = self_chunk_words[0..num_words]
905 .iter()
906 .map(|w| w.count_ones() as ChunkSize)
907 .sum();
908 if *self_chunk_count == 0 {
909 *self_chunk = Zeros(*self_chunk_domain_size);
910 }
911 changed = true;
912 }
913 }
914 }
915 }
916
917 changed
918 }
919}
920
921impl<T: Idx> BitRelations<ChunkedBitSet<T>> for DenseBitSet<T> {
922 fn union(&mut self, other: &ChunkedBitSet<T>) -> bool {
923 sequential_update(|elem| self.insert(elem), other.iter())
924 }
925
926 fn subtract(&mut self, _other: &ChunkedBitSet<T>) -> bool {
927 unimplemented!("implement if/when necessary");
928 }
929
930 fn intersect(&mut self, other: &ChunkedBitSet<T>) -> bool {
931 assert_eq!(self.domain_size(), other.domain_size);
932 let mut changed = false;
933 for (i, chunk) in other.chunks.iter().enumerate() {
934 let mut words = &mut self.words[i * CHUNK_WORDS..];
935 if words.len() > CHUNK_WORDS {
936 words = &mut words[..CHUNK_WORDS];
937 }
938 match chunk {
939 Zeros(..) => {
940 for word in words {
941 if *word != 0 {
942 changed = true;
943 *word = 0;
944 }
945 }
946 }
947 Ones(..) => (),
948 Mixed(_, _, data) => {
949 for (i, word) in words.iter_mut().enumerate() {
950 let new_val = *word & data[i];
951 if new_val != *word {
952 changed = true;
953 *word = new_val;
954 }
955 }
956 }
957 }
958 }
959 changed
960 }
961}
962
963impl<T> Clone for ChunkedBitSet<T> {
964 fn clone(&self) -> Self {
965 ChunkedBitSet {
966 domain_size: self.domain_size,
967 chunks: self.chunks.clone(),
968 marker: PhantomData,
969 }
970 }
971
972 fn clone_from(&mut self, from: &Self) {
977 assert_eq!(self.domain_size, from.domain_size);
978 debug_assert_eq!(self.chunks.len(), from.chunks.len());
979
980 self.chunks.clone_from(&from.chunks)
981 }
982}
983
984pub struct ChunkedBitIter<'a, T: Idx> {
985 bit_set: &'a ChunkedBitSet<T>,
986
987 chunk_index: usize,
989
990 chunk_iter: ChunkIter<'a>,
992}
993
994impl<'a, T: Idx> ChunkedBitIter<'a, T> {
995 #[inline]
996 fn new(bit_set: &'a ChunkedBitSet<T>) -> ChunkedBitIter<'a, T> {
997 ChunkedBitIter { bit_set, chunk_index: 0, chunk_iter: bit_set.chunk_iter(0) }
998 }
999}
1000
1001impl<'a, T: Idx> Iterator for ChunkedBitIter<'a, T> {
1002 type Item = T;
1003
1004 fn next(&mut self) -> Option<T> {
1005 loop {
1006 match &mut self.chunk_iter {
1007 ChunkIter::Zeros => {}
1008 ChunkIter::Ones(iter) => {
1009 if let Some(next) = iter.next() {
1010 return Some(T::new(next + self.chunk_index * CHUNK_BITS));
1011 }
1012 }
1013 ChunkIter::Mixed(iter) => {
1014 if let Some(next) = iter.next() {
1015 return Some(T::new(next + self.chunk_index * CHUNK_BITS));
1016 }
1017 }
1018 ChunkIter::Finished => return None,
1019 }
1020 self.chunk_index += 1;
1021 self.chunk_iter = self.bit_set.chunk_iter(self.chunk_index);
1022 }
1023 }
1024}
1025
1026impl Chunk {
1027 #[cfg(test)]
1028 fn assert_valid(&self) {
1029 match *self {
1030 Zeros(chunk_domain_size) | Ones(chunk_domain_size) => {
1031 assert!(chunk_domain_size as usize <= CHUNK_BITS);
1032 }
1033 Mixed(chunk_domain_size, count, ref words) => {
1034 assert!(chunk_domain_size as usize <= CHUNK_BITS);
1035 assert!(0 < count && count < chunk_domain_size);
1036
1037 assert_eq!(
1039 words.iter().map(|w| w.count_ones() as ChunkSize).sum::<ChunkSize>(),
1040 count
1041 );
1042
1043 let num_words = num_words(chunk_domain_size as usize);
1045 if num_words < CHUNK_WORDS {
1046 assert_eq!(
1047 words[num_words..]
1048 .iter()
1049 .map(|w| w.count_ones() as ChunkSize)
1050 .sum::<ChunkSize>(),
1051 0
1052 );
1053 }
1054 }
1055 }
1056 }
1057
1058 fn new(chunk_domain_size: usize, is_empty: bool) -> Self {
1059 debug_assert!(0 < chunk_domain_size && chunk_domain_size <= CHUNK_BITS);
1060 let chunk_domain_size = chunk_domain_size as ChunkSize;
1061 if is_empty { Zeros(chunk_domain_size) } else { Ones(chunk_domain_size) }
1062 }
1063
1064 fn count(&self) -> usize {
1066 match *self {
1067 Zeros(_) => 0,
1068 Ones(chunk_domain_size) => chunk_domain_size as usize,
1069 Mixed(_, count, _) => count as usize,
1070 }
1071 }
1072}
1073
1074enum ChunkIter<'a> {
1075 Zeros,
1076 Ones(Range<usize>),
1077 Mixed(BitIter<'a, usize>),
1078 Finished,
1079}
1080
1081fn sequential_update<T: Idx>(
1084 mut self_update: impl FnMut(T) -> bool,
1085 it: impl Iterator<Item = T>,
1086) -> bool {
1087 it.fold(false, |changed, elem| self_update(elem) | changed)
1088}
1089
1090impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
1091 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
1092 w.debug_list().entries(self.iter()).finish()
1093 }
1094}
1095
1096#[inline]
1109fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
1110where
1111 Op: Fn(Word, Word) -> Word,
1112{
1113 assert_eq!(out_vec.len(), in_vec.len());
1114 let mut changed = 0;
1115 for (out_elem, in_elem) in iter::zip(out_vec, in_vec) {
1116 let old_val = *out_elem;
1117 let new_val = op(old_val, *in_elem);
1118 *out_elem = new_val;
1119 changed |= old_val ^ new_val;
1124 }
1125 changed != 0
1126}
1127
1128#[inline]
1130fn bitwise_changes<Op>(out_vec: &[Word], in_vec: &[Word], op: Op) -> bool
1131where
1132 Op: Fn(Word, Word) -> Word,
1133{
1134 assert_eq!(out_vec.len(), in_vec.len());
1135 for (out_elem, in_elem) in iter::zip(out_vec, in_vec) {
1136 let old_val = *out_elem;
1137 let new_val = op(old_val, *in_elem);
1138 if old_val != new_val {
1139 return true;
1140 }
1141 }
1142 false
1143}
1144
1145#[derive(PartialEq, Eq)]
1157pub enum MixedBitSet<T> {
1158 Small(DenseBitSet<T>),
1159 Large(ChunkedBitSet<T>),
1160}
1161
1162impl<T> MixedBitSet<T> {
1163 pub fn domain_size(&self) -> usize {
1164 match self {
1165 MixedBitSet::Small(set) => set.domain_size(),
1166 MixedBitSet::Large(set) => set.domain_size(),
1167 }
1168 }
1169}
1170
1171impl<T: Idx> MixedBitSet<T> {
1172 #[inline]
1173 pub fn new_empty(domain_size: usize) -> MixedBitSet<T> {
1174 if domain_size <= CHUNK_BITS {
1175 MixedBitSet::Small(DenseBitSet::new_empty(domain_size))
1176 } else {
1177 MixedBitSet::Large(ChunkedBitSet::new_empty(domain_size))
1178 }
1179 }
1180
1181 #[inline]
1182 pub fn is_empty(&self) -> bool {
1183 match self {
1184 MixedBitSet::Small(set) => set.is_empty(),
1185 MixedBitSet::Large(set) => set.is_empty(),
1186 }
1187 }
1188
1189 #[inline]
1190 pub fn contains(&self, elem: T) -> bool {
1191 match self {
1192 MixedBitSet::Small(set) => set.contains(elem),
1193 MixedBitSet::Large(set) => set.contains(elem),
1194 }
1195 }
1196
1197 #[inline]
1198 pub fn insert(&mut self, elem: T) -> bool {
1199 match self {
1200 MixedBitSet::Small(set) => set.insert(elem),
1201 MixedBitSet::Large(set) => set.insert(elem),
1202 }
1203 }
1204
1205 pub fn insert_all(&mut self) {
1206 match self {
1207 MixedBitSet::Small(set) => set.insert_all(),
1208 MixedBitSet::Large(set) => set.insert_all(),
1209 }
1210 }
1211
1212 #[inline]
1213 pub fn remove(&mut self, elem: T) -> bool {
1214 match self {
1215 MixedBitSet::Small(set) => set.remove(elem),
1216 MixedBitSet::Large(set) => set.remove(elem),
1217 }
1218 }
1219
1220 pub fn iter(&self) -> MixedBitIter<'_, T> {
1221 match self {
1222 MixedBitSet::Small(set) => MixedBitIter::Small(set.iter()),
1223 MixedBitSet::Large(set) => MixedBitIter::Large(set.iter()),
1224 }
1225 }
1226
1227 #[inline]
1228 pub fn clear(&mut self) {
1229 match self {
1230 MixedBitSet::Small(set) => set.clear(),
1231 MixedBitSet::Large(set) => set.clear(),
1232 }
1233 }
1234
1235 bit_relations_inherent_impls! {}
1236}
1237
1238impl<T> Clone for MixedBitSet<T> {
1239 fn clone(&self) -> Self {
1240 match self {
1241 MixedBitSet::Small(set) => MixedBitSet::Small(set.clone()),
1242 MixedBitSet::Large(set) => MixedBitSet::Large(set.clone()),
1243 }
1244 }
1245
1246 fn clone_from(&mut self, from: &Self) {
1251 match (self, from) {
1252 (MixedBitSet::Small(set), MixedBitSet::Small(from)) => set.clone_from(from),
1253 (MixedBitSet::Large(set), MixedBitSet::Large(from)) => set.clone_from(from),
1254 _ => panic!("MixedBitSet size mismatch"),
1255 }
1256 }
1257}
1258
1259impl<T: Idx> BitRelations<MixedBitSet<T>> for MixedBitSet<T> {
1260 fn union(&mut self, other: &MixedBitSet<T>) -> bool {
1261 match (self, other) {
1262 (MixedBitSet::Small(set), MixedBitSet::Small(other)) => set.union(other),
1263 (MixedBitSet::Large(set), MixedBitSet::Large(other)) => set.union(other),
1264 _ => panic!("MixedBitSet size mismatch"),
1265 }
1266 }
1267
1268 fn subtract(&mut self, other: &MixedBitSet<T>) -> bool {
1269 match (self, other) {
1270 (MixedBitSet::Small(set), MixedBitSet::Small(other)) => set.subtract(other),
1271 (MixedBitSet::Large(set), MixedBitSet::Large(other)) => set.subtract(other),
1272 _ => panic!("MixedBitSet size mismatch"),
1273 }
1274 }
1275
1276 fn intersect(&mut self, _other: &MixedBitSet<T>) -> bool {
1277 unimplemented!("implement if/when necessary");
1278 }
1279}
1280
1281impl<T: Idx> fmt::Debug for MixedBitSet<T> {
1282 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
1283 match self {
1284 MixedBitSet::Small(set) => set.fmt(w),
1285 MixedBitSet::Large(set) => set.fmt(w),
1286 }
1287 }
1288}
1289
1290pub enum MixedBitIter<'a, T: Idx> {
1291 Small(BitIter<'a, T>),
1292 Large(ChunkedBitIter<'a, T>),
1293}
1294
1295impl<'a, T: Idx> Iterator for MixedBitIter<'a, T> {
1296 type Item = T;
1297 fn next(&mut self) -> Option<T> {
1298 match self {
1299 MixedBitIter::Small(iter) => iter.next(),
1300 MixedBitIter::Large(iter) => iter.next(),
1301 }
1302 }
1303}
1304
1305#[derive(Clone, Debug, PartialEq)]
1313pub struct GrowableBitSet<T: Idx> {
1314 bit_set: DenseBitSet<T>,
1315}
1316
1317impl<T: Idx> Default for GrowableBitSet<T> {
1318 fn default() -> Self {
1319 GrowableBitSet::new_empty()
1320 }
1321}
1322
1323impl<T: Idx> GrowableBitSet<T> {
1324 pub fn ensure(&mut self, min_domain_size: usize) {
1326 if self.bit_set.domain_size < min_domain_size {
1327 self.bit_set.domain_size = min_domain_size;
1328 }
1329
1330 let min_num_words = num_words(min_domain_size);
1331 if self.bit_set.words.len() < min_num_words {
1332 self.bit_set.words.resize(min_num_words, 0)
1333 }
1334 }
1335
1336 pub fn new_empty() -> GrowableBitSet<T> {
1337 GrowableBitSet { bit_set: DenseBitSet::new_empty(0) }
1338 }
1339
1340 pub fn with_capacity(capacity: usize) -> GrowableBitSet<T> {
1341 GrowableBitSet { bit_set: DenseBitSet::new_empty(capacity) }
1342 }
1343
1344 #[inline]
1346 pub fn insert(&mut self, elem: T) -> bool {
1347 self.ensure(elem.index() + 1);
1348 self.bit_set.insert(elem)
1349 }
1350
1351 #[inline]
1353 pub fn remove(&mut self, elem: T) -> bool {
1354 self.ensure(elem.index() + 1);
1355 self.bit_set.remove(elem)
1356 }
1357
1358 #[inline]
1359 pub fn is_empty(&self) -> bool {
1360 self.bit_set.is_empty()
1361 }
1362
1363 #[inline]
1364 pub fn contains(&self, elem: T) -> bool {
1365 let (word_index, mask) = word_index_and_mask(elem);
1366 self.bit_set.words.get(word_index).is_some_and(|word| (word & mask) != 0)
1367 }
1368
1369 #[inline]
1370 pub fn iter(&self) -> BitIter<'_, T> {
1371 self.bit_set.iter()
1372 }
1373
1374 #[inline]
1375 pub fn len(&self) -> usize {
1376 self.bit_set.count()
1377 }
1378}
1379
1380impl<T: Idx> From<DenseBitSet<T>> for GrowableBitSet<T> {
1381 fn from(bit_set: DenseBitSet<T>) -> Self {
1382 Self { bit_set }
1383 }
1384}
1385
1386#[cfg_attr(feature = "nightly", derive(Decodable_Generic, Encodable_Generic))]
1394#[derive(Clone, Eq, PartialEq, Hash)]
1395pub struct BitMatrix<R: Idx, C: Idx> {
1396 num_rows: usize,
1397 num_columns: usize,
1398 words: SmallVec<[Word; 2]>,
1399 marker: PhantomData<(R, C)>,
1400}
1401
1402impl<R: Idx, C: Idx> BitMatrix<R, C> {
1403 pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix<R, C> {
1405 let words_per_row = num_words(num_columns);
1408 BitMatrix {
1409 num_rows,
1410 num_columns,
1411 words: smallvec![0; num_rows * words_per_row],
1412 marker: PhantomData,
1413 }
1414 }
1415
1416 pub fn from_row_n(row: &DenseBitSet<C>, num_rows: usize) -> BitMatrix<R, C> {
1418 let num_columns = row.domain_size();
1419 let words_per_row = num_words(num_columns);
1420 assert_eq!(words_per_row, row.words.len());
1421 BitMatrix {
1422 num_rows,
1423 num_columns,
1424 words: iter::repeat(&row.words).take(num_rows).flatten().cloned().collect(),
1425 marker: PhantomData,
1426 }
1427 }
1428
1429 pub fn rows(&self) -> impl Iterator<Item = R> {
1430 (0..self.num_rows).map(R::new)
1431 }
1432
1433 fn range(&self, row: R) -> (usize, usize) {
1435 let words_per_row = num_words(self.num_columns);
1436 let start = row.index() * words_per_row;
1437 (start, start + words_per_row)
1438 }
1439
1440 pub fn insert(&mut self, row: R, column: C) -> bool {
1445 assert!(row.index() < self.num_rows && column.index() < self.num_columns);
1446 let (start, _) = self.range(row);
1447 let (word_index, mask) = word_index_and_mask(column);
1448 let words = &mut self.words[..];
1449 let word = words[start + word_index];
1450 let new_word = word | mask;
1451 words[start + word_index] = new_word;
1452 word != new_word
1453 }
1454
1455 pub fn contains(&self, row: R, column: C) -> bool {
1460 assert!(row.index() < self.num_rows && column.index() < self.num_columns);
1461 let (start, _) = self.range(row);
1462 let (word_index, mask) = word_index_and_mask(column);
1463 (self.words[start + word_index] & mask) != 0
1464 }
1465
1466 pub fn intersect_rows(&self, row1: R, row2: R) -> Vec<C> {
1471 assert!(row1.index() < self.num_rows && row2.index() < self.num_rows);
1472 let (row1_start, row1_end) = self.range(row1);
1473 let (row2_start, row2_end) = self.range(row2);
1474 let mut result = Vec::with_capacity(self.num_columns);
1475 for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() {
1476 let mut v = self.words[i] & self.words[j];
1477 for bit in 0..WORD_BITS {
1478 if v == 0 {
1479 break;
1480 }
1481 if v & 0x1 != 0 {
1482 result.push(C::new(base * WORD_BITS + bit));
1483 }
1484 v >>= 1;
1485 }
1486 }
1487 result
1488 }
1489
1490 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1498 assert!(read.index() < self.num_rows && write.index() < self.num_rows);
1499 let (read_start, read_end) = self.range(read);
1500 let (write_start, write_end) = self.range(write);
1501 let words = &mut self.words[..];
1502 let mut changed = 0;
1503 for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) {
1504 let word = words[write_index];
1505 let new_word = word | words[read_index];
1506 words[write_index] = new_word;
1507 changed |= word ^ new_word;
1509 }
1510 changed != 0
1511 }
1512
1513 pub fn union_row_with(&mut self, with: &DenseBitSet<C>, write: R) -> bool {
1516 assert!(write.index() < self.num_rows);
1517 assert_eq!(with.domain_size(), self.num_columns);
1518 let (write_start, write_end) = self.range(write);
1519 bitwise(&mut self.words[write_start..write_end], &with.words, |a, b| a | b)
1520 }
1521
1522 pub fn insert_all_into_row(&mut self, row: R) {
1524 assert!(row.index() < self.num_rows);
1525 let (start, end) = self.range(row);
1526 let words = &mut self.words[..];
1527 for index in start..end {
1528 words[index] = !0;
1529 }
1530 clear_excess_bits_in_final_word(self.num_columns, &mut self.words[..end]);
1531 }
1532
1533 pub fn words(&self) -> &[Word] {
1535 &self.words
1536 }
1537
1538 pub fn iter(&self, row: R) -> BitIter<'_, C> {
1541 assert!(row.index() < self.num_rows);
1542 let (start, end) = self.range(row);
1543 BitIter::new(&self.words[start..end])
1544 }
1545
1546 pub fn count(&self, row: R) -> usize {
1548 let (start, end) = self.range(row);
1549 self.words[start..end].iter().map(|e| e.count_ones() as usize).sum()
1550 }
1551}
1552
1553impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
1554 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1555 struct OneLinePrinter<T>(T);
1557 impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
1558 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1559 write!(fmt, "{:?}", self.0)
1560 }
1561 }
1562
1563 write!(fmt, "BitMatrix({}x{}) ", self.num_rows, self.num_columns)?;
1564 let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
1565 fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
1566 }
1567}
1568
1569#[derive(Clone, Debug)]
1581pub struct SparseBitMatrix<R, C>
1582where
1583 R: Idx,
1584 C: Idx,
1585{
1586 num_columns: usize,
1587 rows: IndexVec<R, Option<DenseBitSet<C>>>,
1588}
1589
1590impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
1591 pub fn new(num_columns: usize) -> Self {
1593 Self { num_columns, rows: IndexVec::new() }
1594 }
1595
1596 fn ensure_row(&mut self, row: R) -> &mut DenseBitSet<C> {
1597 self.rows.get_or_insert_with(row, || DenseBitSet::new_empty(self.num_columns))
1600 }
1601
1602 pub fn insert(&mut self, row: R, column: C) -> bool {
1607 self.ensure_row(row).insert(column)
1608 }
1609
1610 pub fn remove(&mut self, row: R, column: C) -> bool {
1616 match self.rows.get_mut(row) {
1617 Some(Some(row)) => row.remove(column),
1618 _ => false,
1619 }
1620 }
1621
1622 pub fn clear(&mut self, row: R) {
1625 if let Some(Some(row)) = self.rows.get_mut(row) {
1626 row.clear();
1627 }
1628 }
1629
1630 pub fn contains(&self, row: R, column: C) -> bool {
1635 self.row(row).is_some_and(|r| r.contains(column))
1636 }
1637
1638 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1646 if read == write || self.row(read).is_none() {
1647 return false;
1648 }
1649
1650 self.ensure_row(write);
1651 if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) {
1652 write_row.union(read_row)
1653 } else {
1654 unreachable!()
1655 }
1656 }
1657
1658 pub fn insert_all_into_row(&mut self, row: R) {
1660 self.ensure_row(row).insert_all();
1661 }
1662
1663 pub fn rows(&self) -> impl Iterator<Item = R> {
1664 self.rows.indices()
1665 }
1666
1667 pub fn iter(&self, row: R) -> impl Iterator<Item = C> + '_ {
1670 self.row(row).into_iter().flat_map(|r| r.iter())
1671 }
1672
1673 pub fn row(&self, row: R) -> Option<&DenseBitSet<C>> {
1674 self.rows.get(row)?.as_ref()
1675 }
1676
1677 pub fn intersect_row<Set>(&mut self, row: R, set: &Set) -> bool
1682 where
1683 DenseBitSet<C>: BitRelations<Set>,
1684 {
1685 match self.rows.get_mut(row) {
1686 Some(Some(row)) => row.intersect(set),
1687 _ => false,
1688 }
1689 }
1690
1691 pub fn subtract_row<Set>(&mut self, row: R, set: &Set) -> bool
1696 where
1697 DenseBitSet<C>: BitRelations<Set>,
1698 {
1699 match self.rows.get_mut(row) {
1700 Some(Some(row)) => row.subtract(set),
1701 _ => false,
1702 }
1703 }
1704
1705 pub fn union_row<Set>(&mut self, row: R, set: &Set) -> bool
1710 where
1711 DenseBitSet<C>: BitRelations<Set>,
1712 {
1713 self.ensure_row(row).union(set)
1714 }
1715}
1716
1717#[inline]
1718fn num_words<T: Idx>(domain_size: T) -> usize {
1719 (domain_size.index() + WORD_BITS - 1) / WORD_BITS
1720}
1721
1722#[inline]
1723fn num_chunks<T: Idx>(domain_size: T) -> usize {
1724 assert!(domain_size.index() > 0);
1725 (domain_size.index() + CHUNK_BITS - 1) / CHUNK_BITS
1726}
1727
1728#[inline]
1729fn word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1730 let elem = elem.index();
1731 let word_index = elem / WORD_BITS;
1732 let mask = 1 << (elem % WORD_BITS);
1733 (word_index, mask)
1734}
1735
1736#[inline]
1737fn chunk_index<T: Idx>(elem: T) -> usize {
1738 elem.index() / CHUNK_BITS
1739}
1740
1741#[inline]
1742fn chunk_word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1743 let chunk_elem = elem.index() % CHUNK_BITS;
1744 word_index_and_mask(chunk_elem)
1745}
1746
1747fn clear_excess_bits_in_final_word(domain_size: usize, words: &mut [Word]) {
1748 let num_bits_in_final_word = domain_size % WORD_BITS;
1749 if num_bits_in_final_word > 0 {
1750 let mask = (1 << num_bits_in_final_word) - 1;
1751 words[words.len() - 1] &= mask;
1752 }
1753}
1754
1755#[inline]
1756fn max_bit(word: Word) -> usize {
1757 WORD_BITS - 1 - word.leading_zeros() as usize
1758}
1759
1760pub trait FiniteBitSetTy:
1762 BitAnd<Output = Self>
1763 + BitAndAssign
1764 + BitOrAssign
1765 + Clone
1766 + Copy
1767 + Shl
1768 + Not<Output = Self>
1769 + PartialEq
1770 + Sized
1771{
1772 const DOMAIN_SIZE: u32;
1774
1775 const FILLED: Self;
1777 const EMPTY: Self;
1779
1780 const ONE: Self;
1782 const ZERO: Self;
1784
1785 fn checked_shl(self, rhs: u32) -> Option<Self>;
1787 fn checked_shr(self, rhs: u32) -> Option<Self>;
1789}
1790
1791impl FiniteBitSetTy for u32 {
1792 const DOMAIN_SIZE: u32 = 32;
1793
1794 const FILLED: Self = Self::MAX;
1795 const EMPTY: Self = Self::MIN;
1796
1797 const ONE: Self = 1u32;
1798 const ZERO: Self = 0u32;
1799
1800 fn checked_shl(self, rhs: u32) -> Option<Self> {
1801 self.checked_shl(rhs)
1802 }
1803
1804 fn checked_shr(self, rhs: u32) -> Option<Self> {
1805 self.checked_shr(rhs)
1806 }
1807}
1808
1809impl std::fmt::Debug for FiniteBitSet<u32> {
1810 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1811 write!(f, "{:032b}", self.0)
1812 }
1813}
1814
1815#[cfg_attr(feature = "nightly", derive(Decodable_Generic, Encodable_Generic))]
1818#[derive(Copy, Clone, Eq, PartialEq)]
1819pub struct FiniteBitSet<T: FiniteBitSetTy>(pub T);
1820
1821impl<T: FiniteBitSetTy> FiniteBitSet<T> {
1822 pub fn new_empty() -> Self {
1824 Self(T::EMPTY)
1825 }
1826
1827 pub fn set(&mut self, index: u32) {
1829 self.0 |= T::ONE.checked_shl(index).unwrap_or(T::ZERO);
1830 }
1831
1832 pub fn clear(&mut self, index: u32) {
1834 self.0 &= !T::ONE.checked_shl(index).unwrap_or(T::ZERO);
1835 }
1836
1837 pub fn set_range(&mut self, range: Range<u32>) {
1839 let bits = T::FILLED
1840 .checked_shl(range.end - range.start)
1841 .unwrap_or(T::ZERO)
1842 .not()
1843 .checked_shl(range.start)
1844 .unwrap_or(T::ZERO);
1845 self.0 |= bits;
1846 }
1847
1848 pub fn is_empty(&self) -> bool {
1850 self.0 == T::EMPTY
1851 }
1852
1853 pub fn within_domain(&self, index: u32) -> bool {
1855 index < T::DOMAIN_SIZE
1856 }
1857
1858 pub fn contains(&self, index: u32) -> Option<bool> {
1860 self.within_domain(index)
1861 .then(|| ((self.0.checked_shr(index).unwrap_or(T::ONE)) & T::ONE) == T::ONE)
1862 }
1863}
1864
1865impl<T: FiniteBitSetTy> Default for FiniteBitSet<T> {
1866 fn default() -> Self {
1867 Self::new_empty()
1868 }
1869}