rustc_index/
bit_set.rs

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