]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_index/src/bit_set.rs
Rollup merge of #96492 - joshtriplett:revert-std-ffi-re-export, r=yaahc
[rust.git] / compiler / rustc_index / src / bit_set.rs
1 use crate::vec::{Idx, IndexVec};
2 use arrayvec::ArrayVec;
3 use std::fmt;
4 use std::iter;
5 use std::marker::PhantomData;
6 use std::mem;
7 use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Bound, Not, Range, RangeBounds, Shl};
8 use std::rc::Rc;
9 use std::slice;
10
11 use rustc_macros::{Decodable, Encodable};
12
13 use Chunk::*;
14
15 #[cfg(test)]
16 mod tests;
17
18 type Word = u64;
19 const WORD_BYTES: usize = mem::size_of::<Word>();
20 const WORD_BITS: usize = WORD_BYTES * 8;
21
22 // The choice of chunk size has some trade-offs.
23 //
24 // A big chunk size tends to favour cases where many large `ChunkedBitSet`s are
25 // present, because they require fewer `Chunk`s, reducing the number of
26 // allocations and reducing peak memory usage. Also, fewer chunk operations are
27 // required, though more of them might be `Mixed`.
28 //
29 // A small chunk size tends to favour cases where many small `ChunkedBitSet`s
30 // are present, because less space is wasted at the end of the final chunk (if
31 // it's not full).
32 const CHUNK_WORDS: usize = 32;
33 const CHUNK_BITS: usize = CHUNK_WORDS * WORD_BITS; // 2048 bits
34
35 /// ChunkSize is small to keep `Chunk` small. The static assertion ensures it's
36 /// not too small.
37 type ChunkSize = u16;
38 const _: () = assert!(CHUNK_BITS <= ChunkSize::MAX as usize);
39
40 pub trait BitRelations<Rhs> {
41     fn union(&mut self, other: &Rhs) -> bool;
42     fn subtract(&mut self, other: &Rhs) -> bool;
43     fn intersect(&mut self, other: &Rhs) -> bool;
44 }
45
46 #[inline]
47 fn inclusive_start_end<T: Idx>(
48     range: impl RangeBounds<T>,
49     domain: usize,
50 ) -> Option<(usize, usize)> {
51     // Both start and end are inclusive.
52     let start = match range.start_bound().cloned() {
53         Bound::Included(start) => start.index(),
54         Bound::Excluded(start) => start.index() + 1,
55         Bound::Unbounded => 0,
56     };
57     let end = match range.end_bound().cloned() {
58         Bound::Included(end) => end.index(),
59         Bound::Excluded(end) => end.index().checked_sub(1)?,
60         Bound::Unbounded => domain - 1,
61     };
62     assert!(end < domain);
63     if start > end {
64         return None;
65     }
66     Some((start, end))
67 }
68
69 macro_rules! bit_relations_inherent_impls {
70     () => {
71         /// Sets `self = self | other` and returns `true` if `self` changed
72         /// (i.e., if new bits were added).
73         pub fn union<Rhs>(&mut self, other: &Rhs) -> bool
74         where
75             Self: BitRelations<Rhs>,
76         {
77             <Self as BitRelations<Rhs>>::union(self, other)
78         }
79
80         /// Sets `self = self - other` and returns `true` if `self` changed.
81         /// (i.e., if any bits were removed).
82         pub fn subtract<Rhs>(&mut self, other: &Rhs) -> bool
83         where
84             Self: BitRelations<Rhs>,
85         {
86             <Self as BitRelations<Rhs>>::subtract(self, other)
87         }
88
89         /// Sets `self = self & other` and return `true` if `self` changed.
90         /// (i.e., if any bits were removed).
91         pub fn intersect<Rhs>(&mut self, other: &Rhs) -> bool
92         where
93             Self: BitRelations<Rhs>,
94         {
95             <Self as BitRelations<Rhs>>::intersect(self, other)
96         }
97     };
98 }
99
100 /// A fixed-size bitset type with a dense representation.
101 ///
102 /// NOTE: Use [`GrowableBitSet`] if you need support for resizing after creation.
103 ///
104 /// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
105 /// just be `usize`.
106 ///
107 /// All operations that involve an element will panic if the element is equal
108 /// to or greater than the domain size. All operations that involve two bitsets
109 /// will panic if the bitsets have differing domain sizes.
110 ///
111 #[derive(Eq, PartialEq, Hash, Decodable, Encodable)]
112 pub struct BitSet<T> {
113     domain_size: usize,
114     words: Vec<Word>,
115     marker: PhantomData<T>,
116 }
117
118 impl<T> BitSet<T> {
119     /// Gets the domain size.
120     pub fn domain_size(&self) -> usize {
121         self.domain_size
122     }
123 }
124
125 impl<T: Idx> BitSet<T> {
126     /// Creates a new, empty bitset with a given `domain_size`.
127     #[inline]
128     pub fn new_empty(domain_size: usize) -> BitSet<T> {
129         let num_words = num_words(domain_size);
130         BitSet { domain_size, words: vec![0; num_words], marker: PhantomData }
131     }
132
133     /// Creates a new, filled bitset with a given `domain_size`.
134     #[inline]
135     pub fn new_filled(domain_size: usize) -> BitSet<T> {
136         let num_words = num_words(domain_size);
137         let mut result = BitSet { domain_size, words: vec![!0; num_words], marker: PhantomData };
138         result.clear_excess_bits();
139         result
140     }
141
142     /// Clear all elements.
143     #[inline]
144     pub fn clear(&mut self) {
145         self.words.fill(0);
146     }
147
148     /// Clear excess bits in the final word.
149     fn clear_excess_bits(&mut self) {
150         clear_excess_bits_in_final_word(self.domain_size, &mut self.words);
151     }
152
153     /// Count the number of set bits in the set.
154     pub fn count(&self) -> usize {
155         self.words.iter().map(|e| e.count_ones() as usize).sum()
156     }
157
158     /// Returns `true` if `self` contains `elem`.
159     #[inline]
160     pub fn contains(&self, elem: T) -> bool {
161         assert!(elem.index() < self.domain_size);
162         let (word_index, mask) = word_index_and_mask(elem);
163         (self.words[word_index] & mask) != 0
164     }
165
166     /// Is `self` is a (non-strict) superset of `other`?
167     #[inline]
168     pub fn superset(&self, other: &BitSet<T>) -> bool {
169         assert_eq!(self.domain_size, other.domain_size);
170         self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b)
171     }
172
173     /// Is the set empty?
174     #[inline]
175     pub fn is_empty(&self) -> bool {
176         self.words.iter().all(|a| *a == 0)
177     }
178
179     /// Insert `elem`. Returns whether the set has changed.
180     #[inline]
181     pub fn insert(&mut self, elem: T) -> bool {
182         assert!(elem.index() < self.domain_size);
183         let (word_index, mask) = word_index_and_mask(elem);
184         let word_ref = &mut self.words[word_index];
185         let word = *word_ref;
186         let new_word = word | mask;
187         *word_ref = new_word;
188         new_word != word
189     }
190
191     #[inline]
192     pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
193         let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
194             return;
195         };
196
197         let (start_word_index, start_mask) = word_index_and_mask(start);
198         let (end_word_index, end_mask) = word_index_and_mask(end);
199
200         // Set all words in between start and end (exclusively of both).
201         for word_index in (start_word_index + 1)..end_word_index {
202             self.words[word_index] = !0;
203         }
204
205         if start_word_index != end_word_index {
206             // Start and end are in different words, so we handle each in turn.
207             //
208             // We set all leading bits. This includes the start_mask bit.
209             self.words[start_word_index] |= !(start_mask - 1);
210             // And all trailing bits (i.e. from 0..=end) in the end word,
211             // including the end.
212             self.words[end_word_index] |= end_mask | end_mask - 1;
213         } else {
214             self.words[start_word_index] |= end_mask | (end_mask - start_mask);
215         }
216     }
217
218     /// Sets all bits to true.
219     pub fn insert_all(&mut self) {
220         self.words.fill(!0);
221         self.clear_excess_bits();
222     }
223
224     /// Returns `true` if the set has changed.
225     #[inline]
226     pub fn remove(&mut self, elem: T) -> bool {
227         assert!(elem.index() < self.domain_size);
228         let (word_index, mask) = word_index_and_mask(elem);
229         let word_ref = &mut self.words[word_index];
230         let word = *word_ref;
231         let new_word = word & !mask;
232         *word_ref = new_word;
233         new_word != word
234     }
235
236     /// Gets a slice of the underlying words.
237     pub fn words(&self) -> &[Word] {
238         &self.words
239     }
240
241     /// Iterates over the indices of set bits in a sorted order.
242     #[inline]
243     pub fn iter(&self) -> BitIter<'_, T> {
244         BitIter::new(&self.words)
245     }
246
247     /// Duplicates the set as a hybrid set.
248     pub fn to_hybrid(&self) -> HybridBitSet<T> {
249         // Note: we currently don't bother trying to make a Sparse set.
250         HybridBitSet::Dense(self.to_owned())
251     }
252
253     /// Set `self = self | other`. In contrast to `union` returns `true` if the set contains at
254     /// least one bit that is not in `other` (i.e. `other` is not a superset of `self`).
255     ///
256     /// This is an optimization for union of a hybrid bitset.
257     fn reverse_union_sparse(&mut self, sparse: &SparseBitSet<T>) -> bool {
258         assert!(sparse.domain_size == self.domain_size);
259         self.clear_excess_bits();
260
261         let mut not_already = false;
262         // Index of the current word not yet merged.
263         let mut current_index = 0;
264         // Mask of bits that came from the sparse set in the current word.
265         let mut new_bit_mask = 0;
266         for (word_index, mask) in sparse.iter().map(|x| word_index_and_mask(*x)) {
267             // Next bit is in a word not inspected yet.
268             if word_index > current_index {
269                 self.words[current_index] |= new_bit_mask;
270                 // Were there any bits in the old word that did not occur in the sparse set?
271                 not_already |= (self.words[current_index] ^ new_bit_mask) != 0;
272                 // Check all words we skipped for any set bit.
273                 not_already |= self.words[current_index + 1..word_index].iter().any(|&x| x != 0);
274                 // Update next word.
275                 current_index = word_index;
276                 // Reset bit mask, no bits have been merged yet.
277                 new_bit_mask = 0;
278             }
279             // Add bit and mark it as coming from the sparse set.
280             // self.words[word_index] |= mask;
281             new_bit_mask |= mask;
282         }
283         self.words[current_index] |= new_bit_mask;
284         // Any bits in the last inspected word that were not in the sparse set?
285         not_already |= (self.words[current_index] ^ new_bit_mask) != 0;
286         // Any bits in the tail? Note `clear_excess_bits` before.
287         not_already |= self.words[current_index + 1..].iter().any(|&x| x != 0);
288
289         not_already
290     }
291
292     fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
293         let (start, end) = inclusive_start_end(range, self.domain_size)?;
294         let (start_word_index, _) = word_index_and_mask(start);
295         let (end_word_index, end_mask) = word_index_and_mask(end);
296
297         let end_word = self.words[end_word_index] & (end_mask | (end_mask - 1));
298         if end_word != 0 {
299             let pos = max_bit(end_word) + WORD_BITS * end_word_index;
300             if start <= pos {
301                 return Some(T::new(pos));
302             }
303         }
304
305         // We exclude end_word_index from the range here, because we don't want
306         // to limit ourselves to *just* the last word: the bits set it in may be
307         // after `end`, so it may not work out.
308         if let Some(offset) =
309             self.words[start_word_index..end_word_index].iter().rposition(|&w| w != 0)
310         {
311             let word_idx = start_word_index + offset;
312             let start_word = self.words[word_idx];
313             let pos = max_bit(start_word) + WORD_BITS * word_idx;
314             if start <= pos {
315                 return Some(T::new(pos));
316             }
317         }
318
319         None
320     }
321
322     bit_relations_inherent_impls! {}
323 }
324
325 // dense REL dense
326 impl<T: Idx> BitRelations<BitSet<T>> for BitSet<T> {
327     fn union(&mut self, other: &BitSet<T>) -> bool {
328         assert_eq!(self.domain_size, other.domain_size);
329         bitwise(&mut self.words, &other.words, |a, b| a | b)
330     }
331
332     fn subtract(&mut self, other: &BitSet<T>) -> bool {
333         assert_eq!(self.domain_size, other.domain_size);
334         bitwise(&mut self.words, &other.words, |a, b| a & !b)
335     }
336
337     fn intersect(&mut self, other: &BitSet<T>) -> bool {
338         assert_eq!(self.domain_size, other.domain_size);
339         bitwise(&mut self.words, &other.words, |a, b| a & b)
340     }
341 }
342
343 /// A fixed-size bitset type with a partially dense, partially sparse
344 /// representation. The bitset is broken into chunks, and chunks that are all
345 /// zeros or all ones are represented and handled very efficiently.
346 ///
347 /// This type is especially efficient for sets that typically have a large
348 /// `domain_size` with significant stretches of all zeros or all ones, and also
349 /// some stretches with lots of 0s and 1s mixed in a way that causes trouble
350 /// for `IntervalSet`.
351 ///
352 /// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
353 /// just be `usize`.
354 ///
355 /// All operations that involve an element will panic if the element is equal
356 /// to or greater than the domain size. All operations that involve two bitsets
357 /// will panic if the bitsets have differing domain sizes.
358 #[derive(Debug, PartialEq, Eq)]
359 pub struct ChunkedBitSet<T> {
360     domain_size: usize,
361
362     /// The chunks. Each one contains exactly CHUNK_BITS values, except the
363     /// last one which contains 1..=CHUNK_BITS values.
364     chunks: Box<[Chunk]>,
365
366     marker: PhantomData<T>,
367 }
368
369 // Note: the chunk domain size is duplicated in each variant. This is a bit
370 // inconvenient, but it allows the type size to be smaller than if we had an
371 // outer struct containing a chunk domain size plus the `Chunk`, because the
372 // compiler can place the chunk domain size after the tag.
373 #[derive(Clone, Debug, PartialEq, Eq)]
374 enum Chunk {
375     /// A chunk that is all zeros; we don't represent the zeros explicitly.
376     Zeros(ChunkSize),
377
378     /// A chunk that is all ones; we don't represent the ones explicitly.
379     Ones(ChunkSize),
380
381     /// A chunk that has a mix of zeros and ones, which are represented
382     /// explicitly and densely. It never has all zeros or all ones.
383     ///
384     /// If this is the final chunk there may be excess, unused words. This
385     /// turns out to be both simpler and have better performance than
386     /// allocating the minimum number of words, largely because we avoid having
387     /// to store the length, which would make this type larger. These excess
388     /// words are always be zero, as are any excess bits in the final in-use
389     /// word.
390     ///
391     /// The second field is the count of 1s set in the chunk, and must satisfy
392     /// `0 < count < chunk_domain_size`.
393     ///
394     /// The words are within an `Rc` because it's surprisingly common to
395     /// duplicate an entire chunk, e.g. in `ChunkedBitSet::clone_from()`, or
396     /// when a `Mixed` chunk is union'd into a `Zeros` chunk. When we do need
397     /// to modify a chunk we use `Rc::make_mut`.
398     Mixed(ChunkSize, ChunkSize, Rc<[Word; CHUNK_WORDS]>),
399 }
400
401 // This type is used a lot. Make sure it doesn't unintentionally get bigger.
402 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
403 crate::static_assert_size!(Chunk, 16);
404
405 impl<T> ChunkedBitSet<T> {
406     pub fn domain_size(&self) -> usize {
407         self.domain_size
408     }
409
410     #[cfg(test)]
411     fn assert_valid(&self) {
412         if self.domain_size == 0 {
413             assert!(self.chunks.is_empty());
414             return;
415         }
416
417         assert!((self.chunks.len() - 1) * CHUNK_BITS <= self.domain_size);
418         assert!(self.chunks.len() * CHUNK_BITS >= self.domain_size);
419         for chunk in self.chunks.iter() {
420             chunk.assert_valid();
421         }
422     }
423 }
424
425 impl<T: Idx> ChunkedBitSet<T> {
426     /// Creates a new bitset with a given `domain_size` and chunk kind.
427     fn new(domain_size: usize, is_empty: bool) -> Self {
428         let chunks = if domain_size == 0 {
429             Box::new([])
430         } else {
431             // All the chunks have a chunk_domain_size of `CHUNK_BITS` except
432             // the final one.
433             let final_chunk_domain_size = {
434                 let n = domain_size % CHUNK_BITS;
435                 if n == 0 { CHUNK_BITS } else { n }
436             };
437             let mut chunks =
438                 vec![Chunk::new(CHUNK_BITS, is_empty); num_chunks(domain_size)].into_boxed_slice();
439             *chunks.last_mut().unwrap() = Chunk::new(final_chunk_domain_size, is_empty);
440             chunks
441         };
442         ChunkedBitSet { domain_size, chunks, marker: PhantomData }
443     }
444
445     /// Creates a new, empty bitset with a given `domain_size`.
446     #[inline]
447     pub fn new_empty(domain_size: usize) -> Self {
448         ChunkedBitSet::new(domain_size, /* is_empty */ true)
449     }
450
451     /// Creates a new, filled bitset with a given `domain_size`.
452     #[inline]
453     pub fn new_filled(domain_size: usize) -> Self {
454         ChunkedBitSet::new(domain_size, /* is_empty */ false)
455     }
456
457     #[cfg(test)]
458     fn chunks(&self) -> &[Chunk] {
459         &self.chunks
460     }
461
462     /// Count the number of bits in the set.
463     pub fn count(&self) -> usize {
464         self.chunks.iter().map(|chunk| chunk.count()).sum()
465     }
466
467     /// Returns `true` if `self` contains `elem`.
468     #[inline]
469     pub fn contains(&self, elem: T) -> bool {
470         assert!(elem.index() < self.domain_size);
471         let chunk = &self.chunks[chunk_index(elem)];
472         match &chunk {
473             Zeros(_) => false,
474             Ones(_) => true,
475             Mixed(_, _, words) => {
476                 let (word_index, mask) = chunk_word_index_and_mask(elem);
477                 (words[word_index] & mask) != 0
478             }
479         }
480     }
481
482     /// Insert `elem`. Returns whether the set has changed.
483     pub fn insert(&mut self, elem: T) -> bool {
484         assert!(elem.index() < self.domain_size);
485         let chunk_index = chunk_index(elem);
486         let chunk = &mut self.chunks[chunk_index];
487         match *chunk {
488             Zeros(chunk_domain_size) => {
489                 if chunk_domain_size > 1 {
490                     // We take some effort to avoid copying the words.
491                     let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
492                     // SAFETY: `words` can safely be all zeroes.
493                     let mut words = unsafe { words.assume_init() };
494                     let words_ref = Rc::get_mut(&mut words).unwrap();
495
496                     let (word_index, mask) = chunk_word_index_and_mask(elem);
497                     words_ref[word_index] |= mask;
498                     *chunk = Mixed(chunk_domain_size, 1, words);
499                 } else {
500                     *chunk = Ones(chunk_domain_size);
501                 }
502                 true
503             }
504             Ones(_) => false,
505             Mixed(chunk_domain_size, ref mut count, ref mut words) => {
506                 // We skip all the work if the bit is already set.
507                 let (word_index, mask) = chunk_word_index_and_mask(elem);
508                 if (words[word_index] & mask) == 0 {
509                     *count += 1;
510                     if *count < chunk_domain_size {
511                         let words = Rc::make_mut(words);
512                         words[word_index] |= mask;
513                     } else {
514                         *chunk = Ones(chunk_domain_size);
515                     }
516                     true
517                 } else {
518                     false
519                 }
520             }
521         }
522     }
523
524     /// Sets all bits to true.
525     pub fn insert_all(&mut self) {
526         for chunk in self.chunks.iter_mut() {
527             *chunk = match *chunk {
528                 Zeros(chunk_domain_size)
529                 | Ones(chunk_domain_size)
530                 | Mixed(chunk_domain_size, ..) => Ones(chunk_domain_size),
531             }
532         }
533     }
534
535     /// Returns `true` if the set has changed.
536     pub fn remove(&mut self, elem: T) -> bool {
537         assert!(elem.index() < self.domain_size);
538         let chunk_index = chunk_index(elem);
539         let chunk = &mut self.chunks[chunk_index];
540         match *chunk {
541             Zeros(_) => false,
542             Ones(chunk_domain_size) => {
543                 if chunk_domain_size > 1 {
544                     // We take some effort to avoid copying the words.
545                     let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
546                     // SAFETY: `words` can safely be all zeroes.
547                     let mut words = unsafe { words.assume_init() };
548                     let words_ref = Rc::get_mut(&mut words).unwrap();
549
550                     // Set only the bits in use.
551                     let num_words = num_words(chunk_domain_size as usize);
552                     words_ref[..num_words].fill(!0);
553                     clear_excess_bits_in_final_word(
554                         chunk_domain_size as usize,
555                         &mut words_ref[..num_words],
556                     );
557                     let (word_index, mask) = chunk_word_index_and_mask(elem);
558                     words_ref[word_index] &= !mask;
559                     *chunk = Mixed(chunk_domain_size, chunk_domain_size - 1, words);
560                 } else {
561                     *chunk = Zeros(chunk_domain_size);
562                 }
563                 true
564             }
565             Mixed(chunk_domain_size, ref mut count, ref mut words) => {
566                 // We skip all the work if the bit is already clear.
567                 let (word_index, mask) = chunk_word_index_and_mask(elem);
568                 if (words[word_index] & mask) != 0 {
569                     *count -= 1;
570                     if *count > 0 {
571                         let words = Rc::make_mut(words);
572                         words[word_index] &= !mask;
573                     } else {
574                         *chunk = Zeros(chunk_domain_size);
575                     }
576                     true
577                 } else {
578                     false
579                 }
580             }
581         }
582     }
583
584     bit_relations_inherent_impls! {}
585 }
586
587 impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
588     fn union(&mut self, other: &ChunkedBitSet<T>) -> bool {
589         assert_eq!(self.domain_size, other.domain_size);
590         debug_assert_eq!(self.chunks.len(), other.chunks.len());
591
592         let mut changed = false;
593         for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
594             match (&mut self_chunk, &other_chunk) {
595                 (_, Zeros(_)) | (Ones(_), _) => {}
596                 (Zeros(self_chunk_domain_size), Ones(other_chunk_domain_size))
597                 | (Mixed(self_chunk_domain_size, ..), Ones(other_chunk_domain_size))
598                 | (Zeros(self_chunk_domain_size), Mixed(other_chunk_domain_size, ..)) => {
599                     // `other_chunk` fully overwrites `self_chunk`
600                     debug_assert_eq!(self_chunk_domain_size, other_chunk_domain_size);
601                     *self_chunk = other_chunk.clone();
602                     changed = true;
603                 }
604                 (
605                     Mixed(
606                         self_chunk_domain_size,
607                         ref mut self_chunk_count,
608                         ref mut self_chunk_words,
609                     ),
610                     Mixed(_other_chunk_domain_size, _other_chunk_count, other_chunk_words),
611                 ) => {
612                     // First check if the operation would change
613                     // `self_chunk.words`. If not, we can avoid allocating some
614                     // words, and this happens often enough that it's a
615                     // performance win. Also, we only need to operate on the
616                     // in-use words, hence the slicing.
617                     let op = |a, b| a | b;
618                     let num_words = num_words(*self_chunk_domain_size as usize);
619                     if bitwise_changes(
620                         &self_chunk_words[0..num_words],
621                         &other_chunk_words[0..num_words],
622                         op,
623                     ) {
624                         let self_chunk_words = Rc::make_mut(self_chunk_words);
625                         let has_changed = bitwise(
626                             &mut self_chunk_words[0..num_words],
627                             &other_chunk_words[0..num_words],
628                             op,
629                         );
630                         debug_assert!(has_changed);
631                         *self_chunk_count = self_chunk_words[0..num_words]
632                             .iter()
633                             .map(|w| w.count_ones() as ChunkSize)
634                             .sum();
635                         if *self_chunk_count == *self_chunk_domain_size {
636                             *self_chunk = Ones(*self_chunk_domain_size);
637                         }
638                         changed = true;
639                     }
640                 }
641             }
642         }
643         changed
644     }
645
646     fn subtract(&mut self, _other: &ChunkedBitSet<T>) -> bool {
647         unimplemented!("implement if/when necessary");
648     }
649
650     fn intersect(&mut self, _other: &ChunkedBitSet<T>) -> bool {
651         unimplemented!("implement if/when necessary");
652     }
653 }
654
655 impl<T: Idx> BitRelations<HybridBitSet<T>> for ChunkedBitSet<T> {
656     fn union(&mut self, other: &HybridBitSet<T>) -> bool {
657         // FIXME: This is slow if `other` is dense, but it hasn't been a problem
658         // in practice so far.
659         // If a faster implementation of this operation is required, consider
660         // reopening https://github.com/rust-lang/rust/pull/94625
661         assert_eq!(self.domain_size, other.domain_size());
662         sequential_update(|elem| self.insert(elem), other.iter())
663     }
664
665     fn subtract(&mut self, other: &HybridBitSet<T>) -> bool {
666         // FIXME: This is slow if `other` is dense, but it hasn't been a problem
667         // in practice so far.
668         // If a faster implementation of this operation is required, consider
669         // reopening https://github.com/rust-lang/rust/pull/94625
670         assert_eq!(self.domain_size, other.domain_size());
671         sequential_update(|elem| self.remove(elem), other.iter())
672     }
673
674     fn intersect(&mut self, _other: &HybridBitSet<T>) -> bool {
675         unimplemented!("implement if/when necessary");
676     }
677 }
678
679 impl<T> Clone for ChunkedBitSet<T> {
680     fn clone(&self) -> Self {
681         ChunkedBitSet {
682             domain_size: self.domain_size,
683             chunks: self.chunks.clone(),
684             marker: PhantomData,
685         }
686     }
687
688     /// WARNING: this implementation of clone_from will panic if the two
689     /// bitsets have different domain sizes. This constraint is not inherent to
690     /// `clone_from`, but it works with the existing call sites and allows a
691     /// faster implementation, which is important because this function is hot.
692     fn clone_from(&mut self, from: &Self) {
693         assert_eq!(self.domain_size, from.domain_size);
694         debug_assert_eq!(self.chunks.len(), from.chunks.len());
695
696         self.chunks.clone_from(&from.chunks)
697     }
698 }
699
700 impl Chunk {
701     #[cfg(test)]
702     fn assert_valid(&self) {
703         match *self {
704             Zeros(chunk_domain_size) | Ones(chunk_domain_size) => {
705                 assert!(chunk_domain_size as usize <= CHUNK_BITS);
706             }
707             Mixed(chunk_domain_size, count, ref words) => {
708                 assert!(chunk_domain_size as usize <= CHUNK_BITS);
709                 assert!(0 < count && count < chunk_domain_size);
710
711                 // Check the number of set bits matches `count`.
712                 assert_eq!(
713                     words.iter().map(|w| w.count_ones() as ChunkSize).sum::<ChunkSize>(),
714                     count
715                 );
716
717                 // Check the not-in-use words are all zeroed.
718                 let num_words = num_words(chunk_domain_size as usize);
719                 if num_words < CHUNK_WORDS {
720                     assert_eq!(
721                         words[num_words..]
722                             .iter()
723                             .map(|w| w.count_ones() as ChunkSize)
724                             .sum::<ChunkSize>(),
725                         0
726                     );
727                 }
728             }
729         }
730     }
731
732     fn new(chunk_domain_size: usize, is_empty: bool) -> Self {
733         debug_assert!(chunk_domain_size <= CHUNK_BITS);
734         let chunk_domain_size = chunk_domain_size as ChunkSize;
735         if is_empty { Zeros(chunk_domain_size) } else { Ones(chunk_domain_size) }
736     }
737
738     /// Count the number of 1s in the chunk.
739     fn count(&self) -> usize {
740         match *self {
741             Zeros(_) => 0,
742             Ones(chunk_domain_size) => chunk_domain_size as usize,
743             Mixed(_, count, _) => count as usize,
744         }
745     }
746 }
747
748 // Applies a function to mutate a bitset, and returns true if any
749 // of the applications return true
750 fn sequential_update<T: Idx>(
751     mut self_update: impl FnMut(T) -> bool,
752     it: impl Iterator<Item = T>,
753 ) -> bool {
754     let mut changed = false;
755     for elem in it {
756         changed |= self_update(elem);
757     }
758     changed
759 }
760
761 // Optimization of intersection for SparseBitSet that's generic
762 // over the RHS
763 fn sparse_intersect<T: Idx>(
764     set: &mut SparseBitSet<T>,
765     other_contains: impl Fn(&T) -> bool,
766 ) -> bool {
767     let size = set.elems.len();
768     set.elems.retain(|elem| other_contains(elem));
769     set.elems.len() != size
770 }
771
772 // Optimization of dense/sparse intersection. The resulting set is
773 // guaranteed to be at most the size of the sparse set, and hence can be
774 // represented as a sparse set. Therefore the sparse set is copied and filtered,
775 // then returned as the new set.
776 fn dense_sparse_intersect<T: Idx>(
777     dense: &BitSet<T>,
778     sparse: &SparseBitSet<T>,
779 ) -> (SparseBitSet<T>, bool) {
780     let mut sparse_copy = sparse.clone();
781     sparse_intersect(&mut sparse_copy, |el| dense.contains(*el));
782     let n = sparse_copy.len();
783     (sparse_copy, n != dense.count())
784 }
785
786 // hybrid REL dense
787 impl<T: Idx> BitRelations<BitSet<T>> for HybridBitSet<T> {
788     fn union(&mut self, other: &BitSet<T>) -> bool {
789         assert_eq!(self.domain_size(), other.domain_size);
790         match self {
791             HybridBitSet::Sparse(sparse) => {
792                 // `self` is sparse and `other` is dense. To
793                 // merge them, we have two available strategies:
794                 // * Densify `self` then merge other
795                 // * Clone other then integrate bits from `self`
796                 // The second strategy requires dedicated method
797                 // since the usual `union` returns the wrong
798                 // result. In the dedicated case the computation
799                 // is slightly faster if the bits of the sparse
800                 // bitset map to only few words of the dense
801                 // representation, i.e. indices are near each
802                 // other.
803                 //
804                 // Benchmarking seems to suggest that the second
805                 // option is worth it.
806                 let mut new_dense = other.clone();
807                 let changed = new_dense.reverse_union_sparse(sparse);
808                 *self = HybridBitSet::Dense(new_dense);
809                 changed
810             }
811
812             HybridBitSet::Dense(dense) => dense.union(other),
813         }
814     }
815
816     fn subtract(&mut self, other: &BitSet<T>) -> bool {
817         assert_eq!(self.domain_size(), other.domain_size);
818         match self {
819             HybridBitSet::Sparse(sparse) => {
820                 sequential_update(|elem| sparse.remove(elem), other.iter())
821             }
822             HybridBitSet::Dense(dense) => dense.subtract(other),
823         }
824     }
825
826     fn intersect(&mut self, other: &BitSet<T>) -> bool {
827         assert_eq!(self.domain_size(), other.domain_size);
828         match self {
829             HybridBitSet::Sparse(sparse) => sparse_intersect(sparse, |elem| other.contains(*elem)),
830             HybridBitSet::Dense(dense) => dense.intersect(other),
831         }
832     }
833 }
834
835 // dense REL hybrid
836 impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> {
837     fn union(&mut self, other: &HybridBitSet<T>) -> bool {
838         assert_eq!(self.domain_size, other.domain_size());
839         match other {
840             HybridBitSet::Sparse(sparse) => {
841                 sequential_update(|elem| self.insert(elem), sparse.iter().cloned())
842             }
843             HybridBitSet::Dense(dense) => self.union(dense),
844         }
845     }
846
847     fn subtract(&mut self, other: &HybridBitSet<T>) -> bool {
848         assert_eq!(self.domain_size, other.domain_size());
849         match other {
850             HybridBitSet::Sparse(sparse) => {
851                 sequential_update(|elem| self.remove(elem), sparse.iter().cloned())
852             }
853             HybridBitSet::Dense(dense) => self.subtract(dense),
854         }
855     }
856
857     fn intersect(&mut self, other: &HybridBitSet<T>) -> bool {
858         assert_eq!(self.domain_size, other.domain_size());
859         match other {
860             HybridBitSet::Sparse(sparse) => {
861                 let (updated, changed) = dense_sparse_intersect(self, sparse);
862
863                 // We can't directly assign the SparseBitSet to the BitSet, and
864                 // doing `*self = updated.to_dense()` would cause a drop / reallocation. Instead,
865                 // the BitSet is cleared and `updated` is copied into `self`.
866                 self.clear();
867                 for elem in updated.iter() {
868                     self.insert(*elem);
869                 }
870                 changed
871             }
872             HybridBitSet::Dense(dense) => self.intersect(dense),
873         }
874     }
875 }
876
877 // hybrid REL hybrid
878 impl<T: Idx> BitRelations<HybridBitSet<T>> for HybridBitSet<T> {
879     fn union(&mut self, other: &HybridBitSet<T>) -> bool {
880         assert_eq!(self.domain_size(), other.domain_size());
881         match self {
882             HybridBitSet::Sparse(_) => {
883                 match other {
884                     HybridBitSet::Sparse(other_sparse) => {
885                         // Both sets are sparse. Add the elements in
886                         // `other_sparse` to `self` one at a time. This
887                         // may or may not cause `self` to be densified.
888                         let mut changed = false;
889                         for elem in other_sparse.iter() {
890                             changed |= self.insert(*elem);
891                         }
892                         changed
893                     }
894
895                     HybridBitSet::Dense(other_dense) => self.union(other_dense),
896                 }
897             }
898
899             HybridBitSet::Dense(self_dense) => self_dense.union(other),
900         }
901     }
902
903     fn subtract(&mut self, other: &HybridBitSet<T>) -> bool {
904         assert_eq!(self.domain_size(), other.domain_size());
905         match self {
906             HybridBitSet::Sparse(self_sparse) => {
907                 sequential_update(|elem| self_sparse.remove(elem), other.iter())
908             }
909             HybridBitSet::Dense(self_dense) => self_dense.subtract(other),
910         }
911     }
912
913     fn intersect(&mut self, other: &HybridBitSet<T>) -> bool {
914         assert_eq!(self.domain_size(), other.domain_size());
915         match self {
916             HybridBitSet::Sparse(self_sparse) => {
917                 sparse_intersect(self_sparse, |elem| other.contains(*elem))
918             }
919             HybridBitSet::Dense(self_dense) => match other {
920                 HybridBitSet::Sparse(other_sparse) => {
921                     let (updated, changed) = dense_sparse_intersect(self_dense, other_sparse);
922                     *self = HybridBitSet::Sparse(updated);
923                     changed
924                 }
925                 HybridBitSet::Dense(other_dense) => self_dense.intersect(other_dense),
926             },
927         }
928     }
929 }
930
931 impl<T> Clone for BitSet<T> {
932     fn clone(&self) -> Self {
933         BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData }
934     }
935
936     fn clone_from(&mut self, from: &Self) {
937         if self.domain_size != from.domain_size {
938             self.words.resize(from.domain_size, 0);
939             self.domain_size = from.domain_size;
940         }
941
942         self.words.copy_from_slice(&from.words);
943     }
944 }
945
946 impl<T: Idx> fmt::Debug for BitSet<T> {
947     fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
948         w.debug_list().entries(self.iter()).finish()
949     }
950 }
951
952 impl<T: Idx> ToString for BitSet<T> {
953     fn to_string(&self) -> String {
954         let mut result = String::new();
955         let mut sep = '[';
956
957         // Note: this is a little endian printout of bytes.
958
959         // i tracks how many bits we have printed so far.
960         let mut i = 0;
961         for word in &self.words {
962             let mut word = *word;
963             for _ in 0..WORD_BYTES {
964                 // for each byte in `word`:
965                 let remain = self.domain_size - i;
966                 // If less than a byte remains, then mask just that many bits.
967                 let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
968                 assert!(mask <= 0xFF);
969                 let byte = word & mask;
970
971                 result.push_str(&format!("{}{:02x}", sep, byte));
972
973                 if remain <= 8 {
974                     break;
975                 }
976                 word >>= 8;
977                 i += 8;
978                 sep = '-';
979             }
980             sep = '|';
981         }
982         result.push(']');
983
984         result
985     }
986 }
987
988 pub struct BitIter<'a, T: Idx> {
989     /// A copy of the current word, but with any already-visited bits cleared.
990     /// (This lets us use `trailing_zeros()` to find the next set bit.) When it
991     /// is reduced to 0, we move onto the next word.
992     word: Word,
993
994     /// The offset (measured in bits) of the current word.
995     offset: usize,
996
997     /// Underlying iterator over the words.
998     iter: slice::Iter<'a, Word>,
999
1000     marker: PhantomData<T>,
1001 }
1002
1003 impl<'a, T: Idx> BitIter<'a, T> {
1004     #[inline]
1005     fn new(words: &'a [Word]) -> BitIter<'a, T> {
1006         // We initialize `word` and `offset` to degenerate values. On the first
1007         // call to `next()` we will fall through to getting the first word from
1008         // `iter`, which sets `word` to the first word (if there is one) and
1009         // `offset` to 0. Doing it this way saves us from having to maintain
1010         // additional state about whether we have started.
1011         BitIter {
1012             word: 0,
1013             offset: usize::MAX - (WORD_BITS - 1),
1014             iter: words.iter(),
1015             marker: PhantomData,
1016         }
1017     }
1018 }
1019
1020 impl<'a, T: Idx> Iterator for BitIter<'a, T> {
1021     type Item = T;
1022     fn next(&mut self) -> Option<T> {
1023         loop {
1024             if self.word != 0 {
1025                 // Get the position of the next set bit in the current word,
1026                 // then clear the bit.
1027                 let bit_pos = self.word.trailing_zeros() as usize;
1028                 let bit = 1 << bit_pos;
1029                 self.word ^= bit;
1030                 return Some(T::new(bit_pos + self.offset));
1031             }
1032
1033             // Move onto the next word. `wrapping_add()` is needed to handle
1034             // the degenerate initial value given to `offset` in `new()`.
1035             let word = self.iter.next()?;
1036             self.word = *word;
1037             self.offset = self.offset.wrapping_add(WORD_BITS);
1038         }
1039     }
1040 }
1041
1042 #[inline]
1043 fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
1044 where
1045     Op: Fn(Word, Word) -> Word,
1046 {
1047     assert_eq!(out_vec.len(), in_vec.len());
1048     let mut changed = 0;
1049     for (out_elem, in_elem) in iter::zip(out_vec, in_vec) {
1050         let old_val = *out_elem;
1051         let new_val = op(old_val, *in_elem);
1052         *out_elem = new_val;
1053         // This is essentially equivalent to a != with changed being a bool, but
1054         // in practice this code gets auto-vectorized by the compiler for most
1055         // operators. Using != here causes us to generate quite poor code as the
1056         // compiler tries to go back to a boolean on each loop iteration.
1057         changed |= old_val ^ new_val;
1058     }
1059     changed != 0
1060 }
1061
1062 /// Does this bitwise operation change `out_vec`?
1063 #[inline]
1064 fn bitwise_changes<Op>(out_vec: &[Word], in_vec: &[Word], op: Op) -> bool
1065 where
1066     Op: Fn(Word, Word) -> Word,
1067 {
1068     assert_eq!(out_vec.len(), in_vec.len());
1069     for (out_elem, in_elem) in iter::zip(out_vec, in_vec) {
1070         let old_val = *out_elem;
1071         let new_val = op(old_val, *in_elem);
1072         if old_val != new_val {
1073             return true;
1074         }
1075     }
1076     false
1077 }
1078
1079 const SPARSE_MAX: usize = 8;
1080
1081 /// A fixed-size bitset type with a sparse representation and a maximum of
1082 /// `SPARSE_MAX` elements. The elements are stored as a sorted `ArrayVec` with
1083 /// no duplicates.
1084 ///
1085 /// This type is used by `HybridBitSet`; do not use directly.
1086 #[derive(Clone, Debug)]
1087 pub struct SparseBitSet<T> {
1088     domain_size: usize,
1089     elems: ArrayVec<T, SPARSE_MAX>,
1090 }
1091
1092 impl<T: Idx> SparseBitSet<T> {
1093     fn new_empty(domain_size: usize) -> Self {
1094         SparseBitSet { domain_size, elems: ArrayVec::new() }
1095     }
1096
1097     fn len(&self) -> usize {
1098         self.elems.len()
1099     }
1100
1101     fn is_empty(&self) -> bool {
1102         self.elems.len() == 0
1103     }
1104
1105     fn contains(&self, elem: T) -> bool {
1106         assert!(elem.index() < self.domain_size);
1107         self.elems.contains(&elem)
1108     }
1109
1110     fn insert(&mut self, elem: T) -> bool {
1111         assert!(elem.index() < self.domain_size);
1112         let changed = if let Some(i) = self.elems.iter().position(|&e| e.index() >= elem.index()) {
1113             if self.elems[i] == elem {
1114                 // `elem` is already in the set.
1115                 false
1116             } else {
1117                 // `elem` is smaller than one or more existing elements.
1118                 self.elems.insert(i, elem);
1119                 true
1120             }
1121         } else {
1122             // `elem` is larger than all existing elements.
1123             self.elems.push(elem);
1124             true
1125         };
1126         assert!(self.len() <= SPARSE_MAX);
1127         changed
1128     }
1129
1130     fn remove(&mut self, elem: T) -> bool {
1131         assert!(elem.index() < self.domain_size);
1132         if let Some(i) = self.elems.iter().position(|&e| e == elem) {
1133             self.elems.remove(i);
1134             true
1135         } else {
1136             false
1137         }
1138     }
1139
1140     fn to_dense(&self) -> BitSet<T> {
1141         let mut dense = BitSet::new_empty(self.domain_size);
1142         for elem in self.elems.iter() {
1143             dense.insert(*elem);
1144         }
1145         dense
1146     }
1147
1148     fn iter(&self) -> slice::Iter<'_, T> {
1149         self.elems.iter()
1150     }
1151
1152     bit_relations_inherent_impls! {}
1153 }
1154
1155 impl<T: Idx + Ord> SparseBitSet<T> {
1156     fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
1157         let mut last_leq = None;
1158         for e in self.iter() {
1159             if range.contains(e) {
1160                 last_leq = Some(*e);
1161             }
1162         }
1163         last_leq
1164     }
1165 }
1166
1167 /// A fixed-size bitset type with a hybrid representation: sparse when there
1168 /// are up to a `SPARSE_MAX` elements in the set, but dense when there are more
1169 /// than `SPARSE_MAX`.
1170 ///
1171 /// This type is especially efficient for sets that typically have a small
1172 /// number of elements, but a large `domain_size`, and are cleared frequently.
1173 ///
1174 /// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
1175 /// just be `usize`.
1176 ///
1177 /// All operations that involve an element will panic if the element is equal
1178 /// to or greater than the domain size. All operations that involve two bitsets
1179 /// will panic if the bitsets have differing domain sizes.
1180 #[derive(Clone)]
1181 pub enum HybridBitSet<T> {
1182     Sparse(SparseBitSet<T>),
1183     Dense(BitSet<T>),
1184 }
1185
1186 impl<T: Idx> fmt::Debug for HybridBitSet<T> {
1187     fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
1188         match self {
1189             Self::Sparse(b) => b.fmt(w),
1190             Self::Dense(b) => b.fmt(w),
1191         }
1192     }
1193 }
1194
1195 impl<T: Idx> HybridBitSet<T> {
1196     pub fn new_empty(domain_size: usize) -> Self {
1197         HybridBitSet::Sparse(SparseBitSet::new_empty(domain_size))
1198     }
1199
1200     pub fn domain_size(&self) -> usize {
1201         match self {
1202             HybridBitSet::Sparse(sparse) => sparse.domain_size,
1203             HybridBitSet::Dense(dense) => dense.domain_size,
1204         }
1205     }
1206
1207     pub fn clear(&mut self) {
1208         let domain_size = self.domain_size();
1209         *self = HybridBitSet::new_empty(domain_size);
1210     }
1211
1212     pub fn contains(&self, elem: T) -> bool {
1213         match self {
1214             HybridBitSet::Sparse(sparse) => sparse.contains(elem),
1215             HybridBitSet::Dense(dense) => dense.contains(elem),
1216         }
1217     }
1218
1219     pub fn superset(&self, other: &HybridBitSet<T>) -> bool {
1220         match (self, other) {
1221             (HybridBitSet::Dense(self_dense), HybridBitSet::Dense(other_dense)) => {
1222                 self_dense.superset(other_dense)
1223             }
1224             _ => {
1225                 assert!(self.domain_size() == other.domain_size());
1226                 other.iter().all(|elem| self.contains(elem))
1227             }
1228         }
1229     }
1230
1231     pub fn is_empty(&self) -> bool {
1232         match self {
1233             HybridBitSet::Sparse(sparse) => sparse.is_empty(),
1234             HybridBitSet::Dense(dense) => dense.is_empty(),
1235         }
1236     }
1237
1238     /// Returns the previous element present in the bitset from `elem`,
1239     /// inclusively of elem. That is, will return `Some(elem)` if elem is in the
1240     /// bitset.
1241     pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T>
1242     where
1243         T: Ord,
1244     {
1245         match self {
1246             HybridBitSet::Sparse(sparse) => sparse.last_set_in(range),
1247             HybridBitSet::Dense(dense) => dense.last_set_in(range),
1248         }
1249     }
1250
1251     pub fn insert(&mut self, elem: T) -> bool {
1252         // No need to check `elem` against `self.domain_size` here because all
1253         // the match cases check it, one way or another.
1254         match self {
1255             HybridBitSet::Sparse(sparse) if sparse.len() < SPARSE_MAX => {
1256                 // The set is sparse and has space for `elem`.
1257                 sparse.insert(elem)
1258             }
1259             HybridBitSet::Sparse(sparse) if sparse.contains(elem) => {
1260                 // The set is sparse and does not have space for `elem`, but
1261                 // that doesn't matter because `elem` is already present.
1262                 false
1263             }
1264             HybridBitSet::Sparse(sparse) => {
1265                 // The set is sparse and full. Convert to a dense set.
1266                 let mut dense = sparse.to_dense();
1267                 let changed = dense.insert(elem);
1268                 assert!(changed);
1269                 *self = HybridBitSet::Dense(dense);
1270                 changed
1271             }
1272             HybridBitSet::Dense(dense) => dense.insert(elem),
1273         }
1274     }
1275
1276     pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
1277         // No need to check `elem` against `self.domain_size` here because all
1278         // the match cases check it, one way or another.
1279         let start = match elems.start_bound().cloned() {
1280             Bound::Included(start) => start.index(),
1281             Bound::Excluded(start) => start.index() + 1,
1282             Bound::Unbounded => 0,
1283         };
1284         let end = match elems.end_bound().cloned() {
1285             Bound::Included(end) => end.index() + 1,
1286             Bound::Excluded(end) => end.index(),
1287             Bound::Unbounded => self.domain_size() - 1,
1288         };
1289         let Some(len) = end.checked_sub(start) else { return };
1290         match self {
1291             HybridBitSet::Sparse(sparse) if sparse.len() + len < SPARSE_MAX => {
1292                 // The set is sparse and has space for `elems`.
1293                 for elem in start..end {
1294                     sparse.insert(T::new(elem));
1295                 }
1296             }
1297             HybridBitSet::Sparse(sparse) => {
1298                 // The set is sparse and full. Convert to a dense set.
1299                 let mut dense = sparse.to_dense();
1300                 dense.insert_range(elems);
1301                 *self = HybridBitSet::Dense(dense);
1302             }
1303             HybridBitSet::Dense(dense) => dense.insert_range(elems),
1304         }
1305     }
1306
1307     pub fn insert_all(&mut self) {
1308         let domain_size = self.domain_size();
1309         match self {
1310             HybridBitSet::Sparse(_) => {
1311                 *self = HybridBitSet::Dense(BitSet::new_filled(domain_size));
1312             }
1313             HybridBitSet::Dense(dense) => dense.insert_all(),
1314         }
1315     }
1316
1317     pub fn remove(&mut self, elem: T) -> bool {
1318         // Note: we currently don't bother going from Dense back to Sparse.
1319         match self {
1320             HybridBitSet::Sparse(sparse) => sparse.remove(elem),
1321             HybridBitSet::Dense(dense) => dense.remove(elem),
1322         }
1323     }
1324
1325     /// Converts to a dense set, consuming itself in the process.
1326     pub fn to_dense(self) -> BitSet<T> {
1327         match self {
1328             HybridBitSet::Sparse(sparse) => sparse.to_dense(),
1329             HybridBitSet::Dense(dense) => dense,
1330         }
1331     }
1332
1333     pub fn iter(&self) -> HybridIter<'_, T> {
1334         match self {
1335             HybridBitSet::Sparse(sparse) => HybridIter::Sparse(sparse.iter()),
1336             HybridBitSet::Dense(dense) => HybridIter::Dense(dense.iter()),
1337         }
1338     }
1339
1340     bit_relations_inherent_impls! {}
1341 }
1342
1343 pub enum HybridIter<'a, T: Idx> {
1344     Sparse(slice::Iter<'a, T>),
1345     Dense(BitIter<'a, T>),
1346 }
1347
1348 impl<'a, T: Idx> Iterator for HybridIter<'a, T> {
1349     type Item = T;
1350
1351     fn next(&mut self) -> Option<T> {
1352         match self {
1353             HybridIter::Sparse(sparse) => sparse.next().copied(),
1354             HybridIter::Dense(dense) => dense.next(),
1355         }
1356     }
1357 }
1358
1359 /// A resizable bitset type with a dense representation.
1360 ///
1361 /// `T` is an index type, typically a newtyped `usize` wrapper, but it can also
1362 /// just be `usize`.
1363 ///
1364 /// All operations that involve an element will panic if the element is equal
1365 /// to or greater than the domain size.
1366 #[derive(Clone, Debug, PartialEq)]
1367 pub struct GrowableBitSet<T: Idx> {
1368     bit_set: BitSet<T>,
1369 }
1370
1371 impl<T: Idx> Default for GrowableBitSet<T> {
1372     fn default() -> Self {
1373         GrowableBitSet::new_empty()
1374     }
1375 }
1376
1377 impl<T: Idx> GrowableBitSet<T> {
1378     /// Ensure that the set can hold at least `min_domain_size` elements.
1379     pub fn ensure(&mut self, min_domain_size: usize) {
1380         if self.bit_set.domain_size < min_domain_size {
1381             self.bit_set.domain_size = min_domain_size;
1382         }
1383
1384         let min_num_words = num_words(min_domain_size);
1385         if self.bit_set.words.len() < min_num_words {
1386             self.bit_set.words.resize(min_num_words, 0)
1387         }
1388     }
1389
1390     pub fn new_empty() -> GrowableBitSet<T> {
1391         GrowableBitSet { bit_set: BitSet::new_empty(0) }
1392     }
1393
1394     pub fn with_capacity(capacity: usize) -> GrowableBitSet<T> {
1395         GrowableBitSet { bit_set: BitSet::new_empty(capacity) }
1396     }
1397
1398     /// Returns `true` if the set has changed.
1399     #[inline]
1400     pub fn insert(&mut self, elem: T) -> bool {
1401         self.ensure(elem.index() + 1);
1402         self.bit_set.insert(elem)
1403     }
1404
1405     /// Returns `true` if the set has changed.
1406     #[inline]
1407     pub fn remove(&mut self, elem: T) -> bool {
1408         self.ensure(elem.index() + 1);
1409         self.bit_set.remove(elem)
1410     }
1411
1412     #[inline]
1413     pub fn is_empty(&self) -> bool {
1414         self.bit_set.is_empty()
1415     }
1416
1417     #[inline]
1418     pub fn contains(&self, elem: T) -> bool {
1419         let (word_index, mask) = word_index_and_mask(elem);
1420         self.bit_set.words.get(word_index).map_or(false, |word| (word & mask) != 0)
1421     }
1422 }
1423
1424 /// A fixed-size 2D bit matrix type with a dense representation.
1425 ///
1426 /// `R` and `C` are index types used to identify rows and columns respectively;
1427 /// typically newtyped `usize` wrappers, but they can also just be `usize`.
1428 ///
1429 /// All operations that involve a row and/or column index will panic if the
1430 /// index exceeds the relevant bound.
1431 #[derive(Clone, Eq, PartialEq, Hash, Decodable, Encodable)]
1432 pub struct BitMatrix<R: Idx, C: Idx> {
1433     num_rows: usize,
1434     num_columns: usize,
1435     words: Vec<Word>,
1436     marker: PhantomData<(R, C)>,
1437 }
1438
1439 impl<R: Idx, C: Idx> BitMatrix<R, C> {
1440     /// Creates a new `rows x columns` matrix, initially empty.
1441     pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix<R, C> {
1442         // For every element, we need one bit for every other
1443         // element. Round up to an even number of words.
1444         let words_per_row = num_words(num_columns);
1445         BitMatrix {
1446             num_rows,
1447             num_columns,
1448             words: vec![0; num_rows * words_per_row],
1449             marker: PhantomData,
1450         }
1451     }
1452
1453     /// Creates a new matrix, with `row` used as the value for every row.
1454     pub fn from_row_n(row: &BitSet<C>, num_rows: usize) -> BitMatrix<R, C> {
1455         let num_columns = row.domain_size();
1456         let words_per_row = num_words(num_columns);
1457         assert_eq!(words_per_row, row.words().len());
1458         BitMatrix {
1459             num_rows,
1460             num_columns,
1461             words: iter::repeat(row.words()).take(num_rows).flatten().cloned().collect(),
1462             marker: PhantomData,
1463         }
1464     }
1465
1466     pub fn rows(&self) -> impl Iterator<Item = R> {
1467         (0..self.num_rows).map(R::new)
1468     }
1469
1470     /// The range of bits for a given row.
1471     fn range(&self, row: R) -> (usize, usize) {
1472         let words_per_row = num_words(self.num_columns);
1473         let start = row.index() * words_per_row;
1474         (start, start + words_per_row)
1475     }
1476
1477     /// Sets the cell at `(row, column)` to true. Put another way, insert
1478     /// `column` to the bitset for `row`.
1479     ///
1480     /// Returns `true` if this changed the matrix.
1481     pub fn insert(&mut self, row: R, column: C) -> bool {
1482         assert!(row.index() < self.num_rows && column.index() < self.num_columns);
1483         let (start, _) = self.range(row);
1484         let (word_index, mask) = word_index_and_mask(column);
1485         let words = &mut self.words[..];
1486         let word = words[start + word_index];
1487         let new_word = word | mask;
1488         words[start + word_index] = new_word;
1489         word != new_word
1490     }
1491
1492     /// Do the bits from `row` contain `column`? Put another way, is
1493     /// the matrix cell at `(row, column)` true?  Put yet another way,
1494     /// if the matrix represents (transitive) reachability, can
1495     /// `row` reach `column`?
1496     pub fn contains(&self, row: R, column: C) -> bool {
1497         assert!(row.index() < self.num_rows && column.index() < self.num_columns);
1498         let (start, _) = self.range(row);
1499         let (word_index, mask) = word_index_and_mask(column);
1500         (self.words[start + word_index] & mask) != 0
1501     }
1502
1503     /// Returns those indices that are true in rows `a` and `b`. This
1504     /// is an *O*(*n*) operation where *n* is the number of elements
1505     /// (somewhat independent from the actual size of the
1506     /// intersection, in particular).
1507     pub fn intersect_rows(&self, row1: R, row2: R) -> Vec<C> {
1508         assert!(row1.index() < self.num_rows && row2.index() < self.num_rows);
1509         let (row1_start, row1_end) = self.range(row1);
1510         let (row2_start, row2_end) = self.range(row2);
1511         let mut result = Vec::with_capacity(self.num_columns);
1512         for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() {
1513             let mut v = self.words[i] & self.words[j];
1514             for bit in 0..WORD_BITS {
1515                 if v == 0 {
1516                     break;
1517                 }
1518                 if v & 0x1 != 0 {
1519                     result.push(C::new(base * WORD_BITS + bit));
1520                 }
1521                 v >>= 1;
1522             }
1523         }
1524         result
1525     }
1526
1527     /// Adds the bits from row `read` to the bits from row `write`, and
1528     /// returns `true` if anything changed.
1529     ///
1530     /// This is used when computing transitive reachability because if
1531     /// you have an edge `write -> read`, because in that case
1532     /// `write` can reach everything that `read` can (and
1533     /// potentially more).
1534     pub fn union_rows(&mut self, read: R, write: R) -> bool {
1535         assert!(read.index() < self.num_rows && write.index() < self.num_rows);
1536         let (read_start, read_end) = self.range(read);
1537         let (write_start, write_end) = self.range(write);
1538         let words = &mut self.words[..];
1539         let mut changed = false;
1540         for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) {
1541             let word = words[write_index];
1542             let new_word = word | words[read_index];
1543             words[write_index] = new_word;
1544             changed |= word != new_word;
1545         }
1546         changed
1547     }
1548
1549     /// Adds the bits from `with` to the bits from row `write`, and
1550     /// returns `true` if anything changed.
1551     pub fn union_row_with(&mut self, with: &BitSet<C>, write: R) -> bool {
1552         assert!(write.index() < self.num_rows);
1553         assert_eq!(with.domain_size(), self.num_columns);
1554         let (write_start, write_end) = self.range(write);
1555         let mut changed = false;
1556         for (read_index, write_index) in iter::zip(0..with.words().len(), write_start..write_end) {
1557             let word = self.words[write_index];
1558             let new_word = word | with.words()[read_index];
1559             self.words[write_index] = new_word;
1560             changed |= word != new_word;
1561         }
1562         changed
1563     }
1564
1565     /// Sets every cell in `row` to true.
1566     pub fn insert_all_into_row(&mut self, row: R) {
1567         assert!(row.index() < self.num_rows);
1568         let (start, end) = self.range(row);
1569         let words = &mut self.words[..];
1570         for index in start..end {
1571             words[index] = !0;
1572         }
1573         clear_excess_bits_in_final_word(self.num_columns, &mut self.words[..end]);
1574     }
1575
1576     /// Gets a slice of the underlying words.
1577     pub fn words(&self) -> &[Word] {
1578         &self.words
1579     }
1580
1581     /// Iterates through all the columns set to true in a given row of
1582     /// the matrix.
1583     pub fn iter(&self, row: R) -> BitIter<'_, C> {
1584         assert!(row.index() < self.num_rows);
1585         let (start, end) = self.range(row);
1586         BitIter::new(&self.words[start..end])
1587     }
1588
1589     /// Returns the number of elements in `row`.
1590     pub fn count(&self, row: R) -> usize {
1591         let (start, end) = self.range(row);
1592         self.words[start..end].iter().map(|e| e.count_ones() as usize).sum()
1593     }
1594 }
1595
1596 impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
1597     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1598         /// Forces its contents to print in regular mode instead of alternate mode.
1599         struct OneLinePrinter<T>(T);
1600         impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
1601             fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1602                 write!(fmt, "{:?}", self.0)
1603             }
1604         }
1605
1606         write!(fmt, "BitMatrix({}x{}) ", self.num_rows, self.num_columns)?;
1607         let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
1608         fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
1609     }
1610 }
1611
1612 /// A fixed-column-size, variable-row-size 2D bit matrix with a moderately
1613 /// sparse representation.
1614 ///
1615 /// Initially, every row has no explicit representation. If any bit within a
1616 /// row is set, the entire row is instantiated as `Some(<HybridBitSet>)`.
1617 /// Furthermore, any previously uninstantiated rows prior to it will be
1618 /// instantiated as `None`. Those prior rows may themselves become fully
1619 /// instantiated later on if any of their bits are set.
1620 ///
1621 /// `R` and `C` are index types used to identify rows and columns respectively;
1622 /// typically newtyped `usize` wrappers, but they can also just be `usize`.
1623 #[derive(Clone, Debug)]
1624 pub struct SparseBitMatrix<R, C>
1625 where
1626     R: Idx,
1627     C: Idx,
1628 {
1629     num_columns: usize,
1630     rows: IndexVec<R, Option<HybridBitSet<C>>>,
1631 }
1632
1633 impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
1634     /// Creates a new empty sparse bit matrix with no rows or columns.
1635     pub fn new(num_columns: usize) -> Self {
1636         Self { num_columns, rows: IndexVec::new() }
1637     }
1638
1639     fn ensure_row(&mut self, row: R) -> &mut HybridBitSet<C> {
1640         // Instantiate any missing rows up to and including row `row` with an empty HybridBitSet.
1641         // Then replace row `row` with a full HybridBitSet if necessary.
1642         self.rows.get_or_insert_with(row, || HybridBitSet::new_empty(self.num_columns))
1643     }
1644
1645     /// Sets the cell at `(row, column)` to true. Put another way, insert
1646     /// `column` to the bitset for `row`.
1647     ///
1648     /// Returns `true` if this changed the matrix.
1649     pub fn insert(&mut self, row: R, column: C) -> bool {
1650         self.ensure_row(row).insert(column)
1651     }
1652
1653     /// Sets the cell at `(row, column)` to false. Put another way, delete
1654     /// `column` from the bitset for `row`. Has no effect if `row` does not
1655     /// exist.
1656     ///
1657     /// Returns `true` if this changed the matrix.
1658     pub fn remove(&mut self, row: R, column: C) -> bool {
1659         match self.rows.get_mut(row) {
1660             Some(Some(row)) => row.remove(column),
1661             _ => false,
1662         }
1663     }
1664
1665     /// Sets all columns at `row` to false. Has no effect if `row` does
1666     /// not exist.
1667     pub fn clear(&mut self, row: R) {
1668         if let Some(Some(row)) = self.rows.get_mut(row) {
1669             row.clear();
1670         }
1671     }
1672
1673     /// Do the bits from `row` contain `column`? Put another way, is
1674     /// the matrix cell at `(row, column)` true?  Put yet another way,
1675     /// if the matrix represents (transitive) reachability, can
1676     /// `row` reach `column`?
1677     pub fn contains(&self, row: R, column: C) -> bool {
1678         self.row(row).map_or(false, |r| r.contains(column))
1679     }
1680
1681     /// Adds the bits from row `read` to the bits from row `write`, and
1682     /// returns `true` if anything changed.
1683     ///
1684     /// This is used when computing transitive reachability because if
1685     /// you have an edge `write -> read`, because in that case
1686     /// `write` can reach everything that `read` can (and
1687     /// potentially more).
1688     pub fn union_rows(&mut self, read: R, write: R) -> bool {
1689         if read == write || self.row(read).is_none() {
1690             return false;
1691         }
1692
1693         self.ensure_row(write);
1694         if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) {
1695             write_row.union(read_row)
1696         } else {
1697             unreachable!()
1698         }
1699     }
1700
1701     /// Insert all bits in the given row.
1702     pub fn insert_all_into_row(&mut self, row: R) {
1703         self.ensure_row(row).insert_all();
1704     }
1705
1706     pub fn rows(&self) -> impl Iterator<Item = R> {
1707         self.rows.indices()
1708     }
1709
1710     /// Iterates through all the columns set to true in a given row of
1711     /// the matrix.
1712     pub fn iter<'a>(&'a self, row: R) -> impl Iterator<Item = C> + 'a {
1713         self.row(row).into_iter().flat_map(|r| r.iter())
1714     }
1715
1716     pub fn row(&self, row: R) -> Option<&HybridBitSet<C>> {
1717         self.rows.get(row)?.as_ref()
1718     }
1719
1720     /// Intersects `row` with `set`. `set` can be either `BitSet` or
1721     /// `HybridBitSet`. Has no effect if `row` does not exist.
1722     ///
1723     /// Returns true if the row was changed.
1724     pub fn intersect_row<Set>(&mut self, row: R, set: &Set) -> bool
1725     where
1726         HybridBitSet<C>: BitRelations<Set>,
1727     {
1728         match self.rows.get_mut(row) {
1729             Some(Some(row)) => row.intersect(set),
1730             _ => false,
1731         }
1732     }
1733
1734     /// Subtracts `set from `row`. `set` can be either `BitSet` or
1735     /// `HybridBitSet`. Has no effect if `row` does not exist.
1736     ///
1737     /// Returns true if the row was changed.
1738     pub fn subtract_row<Set>(&mut self, row: R, set: &Set) -> bool
1739     where
1740         HybridBitSet<C>: BitRelations<Set>,
1741     {
1742         match self.rows.get_mut(row) {
1743             Some(Some(row)) => row.subtract(set),
1744             _ => false,
1745         }
1746     }
1747
1748     /// Unions `row` with `set`. `set` can be either `BitSet` or
1749     /// `HybridBitSet`.
1750     ///
1751     /// Returns true if the row was changed.
1752     pub fn union_row<Set>(&mut self, row: R, set: &Set) -> bool
1753     where
1754         HybridBitSet<C>: BitRelations<Set>,
1755     {
1756         self.ensure_row(row).union(set)
1757     }
1758 }
1759
1760 #[inline]
1761 fn num_words<T: Idx>(domain_size: T) -> usize {
1762     (domain_size.index() + WORD_BITS - 1) / WORD_BITS
1763 }
1764
1765 #[inline]
1766 fn num_chunks<T: Idx>(domain_size: T) -> usize {
1767     assert!(domain_size.index() > 0);
1768     (domain_size.index() + CHUNK_BITS - 1) / CHUNK_BITS
1769 }
1770
1771 #[inline]
1772 fn word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1773     let elem = elem.index();
1774     let word_index = elem / WORD_BITS;
1775     let mask = 1 << (elem % WORD_BITS);
1776     (word_index, mask)
1777 }
1778
1779 #[inline]
1780 fn chunk_index<T: Idx>(elem: T) -> usize {
1781     elem.index() / CHUNK_BITS
1782 }
1783
1784 #[inline]
1785 fn chunk_word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1786     let chunk_elem = elem.index() % CHUNK_BITS;
1787     word_index_and_mask(chunk_elem)
1788 }
1789
1790 fn clear_excess_bits_in_final_word(domain_size: usize, words: &mut [Word]) {
1791     let num_bits_in_final_word = domain_size % WORD_BITS;
1792     if num_bits_in_final_word > 0 {
1793         let mask = (1 << num_bits_in_final_word) - 1;
1794         words[words.len() - 1] &= mask;
1795     }
1796 }
1797
1798 #[inline]
1799 fn max_bit(word: Word) -> usize {
1800     WORD_BITS - 1 - word.leading_zeros() as usize
1801 }
1802
1803 /// Integral type used to represent the bit set.
1804 pub trait FiniteBitSetTy:
1805     BitAnd<Output = Self>
1806     + BitAndAssign
1807     + BitOrAssign
1808     + Clone
1809     + Copy
1810     + Shl
1811     + Not<Output = Self>
1812     + PartialEq
1813     + Sized
1814 {
1815     /// Size of the domain representable by this type, e.g. 64 for `u64`.
1816     const DOMAIN_SIZE: u32;
1817
1818     /// Value which represents the `FiniteBitSet` having every bit set.
1819     const FILLED: Self;
1820     /// Value which represents the `FiniteBitSet` having no bits set.
1821     const EMPTY: Self;
1822
1823     /// Value for one as the integral type.
1824     const ONE: Self;
1825     /// Value for zero as the integral type.
1826     const ZERO: Self;
1827
1828     /// Perform a checked left shift on the integral type.
1829     fn checked_shl(self, rhs: u32) -> Option<Self>;
1830     /// Perform a checked right shift on the integral type.
1831     fn checked_shr(self, rhs: u32) -> Option<Self>;
1832 }
1833
1834 impl FiniteBitSetTy for u32 {
1835     const DOMAIN_SIZE: u32 = 32;
1836
1837     const FILLED: Self = Self::MAX;
1838     const EMPTY: Self = Self::MIN;
1839
1840     const ONE: Self = 1u32;
1841     const ZERO: Self = 0u32;
1842
1843     fn checked_shl(self, rhs: u32) -> Option<Self> {
1844         self.checked_shl(rhs)
1845     }
1846
1847     fn checked_shr(self, rhs: u32) -> Option<Self> {
1848         self.checked_shr(rhs)
1849     }
1850 }
1851
1852 impl std::fmt::Debug for FiniteBitSet<u32> {
1853     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1854         write!(f, "{:032b}", self.0)
1855     }
1856 }
1857
1858 impl FiniteBitSetTy for u64 {
1859     const DOMAIN_SIZE: u32 = 64;
1860
1861     const FILLED: Self = Self::MAX;
1862     const EMPTY: Self = Self::MIN;
1863
1864     const ONE: Self = 1u64;
1865     const ZERO: Self = 0u64;
1866
1867     fn checked_shl(self, rhs: u32) -> Option<Self> {
1868         self.checked_shl(rhs)
1869     }
1870
1871     fn checked_shr(self, rhs: u32) -> Option<Self> {
1872         self.checked_shr(rhs)
1873     }
1874 }
1875
1876 impl std::fmt::Debug for FiniteBitSet<u64> {
1877     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1878         write!(f, "{:064b}", self.0)
1879     }
1880 }
1881
1882 impl FiniteBitSetTy for u128 {
1883     const DOMAIN_SIZE: u32 = 128;
1884
1885     const FILLED: Self = Self::MAX;
1886     const EMPTY: Self = Self::MIN;
1887
1888     const ONE: Self = 1u128;
1889     const ZERO: Self = 0u128;
1890
1891     fn checked_shl(self, rhs: u32) -> Option<Self> {
1892         self.checked_shl(rhs)
1893     }
1894
1895     fn checked_shr(self, rhs: u32) -> Option<Self> {
1896         self.checked_shr(rhs)
1897     }
1898 }
1899
1900 impl std::fmt::Debug for FiniteBitSet<u128> {
1901     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1902         write!(f, "{:0128b}", self.0)
1903     }
1904 }
1905
1906 /// A fixed-sized bitset type represented by an integer type. Indices outwith than the range
1907 /// representable by `T` are considered set.
1908 #[derive(Copy, Clone, Eq, PartialEq, Decodable, Encodable)]
1909 pub struct FiniteBitSet<T: FiniteBitSetTy>(pub T);
1910
1911 impl<T: FiniteBitSetTy> FiniteBitSet<T> {
1912     /// Creates a new, empty bitset.
1913     pub fn new_empty() -> Self {
1914         Self(T::EMPTY)
1915     }
1916
1917     /// Sets the `index`th bit.
1918     pub fn set(&mut self, index: u32) {
1919         self.0 |= T::ONE.checked_shl(index).unwrap_or(T::ZERO);
1920     }
1921
1922     /// Unsets the `index`th bit.
1923     pub fn clear(&mut self, index: u32) {
1924         self.0 &= !T::ONE.checked_shl(index).unwrap_or(T::ZERO);
1925     }
1926
1927     /// Sets the `i`th to `j`th bits.
1928     pub fn set_range(&mut self, range: Range<u32>) {
1929         let bits = T::FILLED
1930             .checked_shl(range.end - range.start)
1931             .unwrap_or(T::ZERO)
1932             .not()
1933             .checked_shl(range.start)
1934             .unwrap_or(T::ZERO);
1935         self.0 |= bits;
1936     }
1937
1938     /// Is the set empty?
1939     pub fn is_empty(&self) -> bool {
1940         self.0 == T::EMPTY
1941     }
1942
1943     /// Returns the domain size of the bitset.
1944     pub fn within_domain(&self, index: u32) -> bool {
1945         index < T::DOMAIN_SIZE
1946     }
1947
1948     /// Returns if the `index`th bit is set.
1949     pub fn contains(&self, index: u32) -> Option<bool> {
1950         self.within_domain(index)
1951             .then(|| ((self.0.checked_shr(index).unwrap_or(T::ONE)) & T::ONE) == T::ONE)
1952     }
1953 }
1954
1955 impl<T: FiniteBitSetTy> Default for FiniteBitSet<T> {
1956     fn default() -> Self {
1957         Self::new_empty()
1958     }
1959 }