1use std::marker::PhantomData;
2use std::ops::{Bound, Range, RangeBounds};
3use std::rc::Rc;
4use std::{fmt, iter, slice};
5
6use Chunk::*;
7#[cfg(feature = "nightly")]
8use rustc_macros::{Decodable_NoContext, Encodable_NoContext};
9
10use crate::{Idx, IndexVec};
11
12#[cfg(test)]
13mod tests;
14
15type Word = u64;
16const WORD_BYTES: usize = size_of::<Word>();
17const WORD_BITS: usize = WORD_BYTES * 8;
18
19const CHUNK_WORDS: usize = 32;
30const CHUNK_BITS: usize = CHUNK_WORDS * WORD_BITS; type ChunkSize = u16;
35const _: () = 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);
36
37#[inline]
38fn inclusive_start_end<T: Idx>(
39 range: impl RangeBounds<T>,
40 domain: usize,
41) -> Option<(usize, usize)> {
42 let start = match range.start_bound().cloned() {
44 Bound::Included(start) => start.index(),
45 Bound::Excluded(start) => start.index() + 1,
46 Bound::Unbounded => 0,
47 };
48 let end = match range.end_bound().cloned() {
49 Bound::Included(end) => end.index(),
50 Bound::Excluded(end) => end.index().checked_sub(1)?,
51 Bound::Unbounded => domain - 1,
52 };
53 if !(end < domain) {
::core::panicking::panic("assertion failed: end < domain")
};assert!(end < domain);
54 if start > end {
55 return None;
56 }
57 Some((start, end))
58}
59
60#[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) {
let DenseBitSet {
domain_size: ref __binding_0,
words: ref __binding_1,
marker: ref __binding_2 } = *self;
::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))]
78#[derive(#[automatically_derived]
impl<T: ::core::cmp::Eq> ::core::cmp::Eq for DenseBitSet<T> {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_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::marker::StructuralPartialEq for
DenseBitSet<T> {
}
#[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)]
79pub struct DenseBitSet<T> {
80 domain_size: usize,
81 words: Vec<Word>,
82 marker: PhantomData<T>,
83}
84
85impl<T> DenseBitSet<T> {
86 pub fn domain_size(&self) -> usize {
88 self.domain_size
89 }
90}
91
92impl<T: Idx> DenseBitSet<T> {
93 #[inline]
95 pub fn new_empty(domain_size: usize) -> DenseBitSet<T> {
96 let num_words = num_words(domain_size);
97 DenseBitSet { domain_size, words: ::alloc::vec::from_elem(0, num_words)vec![0; num_words], marker: PhantomData }
98 }
99
100 #[inline]
102 pub fn new_filled(domain_size: usize) -> DenseBitSet<T> {
103 let num_words = num_words(domain_size);
104 let mut result =
105 DenseBitSet { domain_size, words: ::alloc::vec::from_elem(!0, num_words)vec![!0; num_words], marker: PhantomData };
106 result.clear_excess_bits();
107 result
108 }
109
110 #[inline]
112 pub fn clear(&mut self) {
113 self.words.fill(0);
114 }
115
116 fn clear_excess_bits(&mut self) {
118 clear_excess_bits_in_final_word(self.domain_size, &mut self.words);
119 }
120
121 pub fn count(&self) -> usize {
123 count_ones(&self.words)
124 }
125
126 #[inline]
128 pub fn contains(&self, elem: T) -> bool {
129 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
130 let (word_index, mask) = word_index_and_mask(elem);
131 (self.words[word_index] & mask) != 0
132 }
133
134 #[inline]
136 pub fn superset(&self, other: &DenseBitSet<T>) -> bool {
137 {
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);
138 self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b)
139 }
140
141 #[inline]
143 pub fn is_empty(&self) -> bool {
144 self.words.iter().all(|a| *a == 0)
145 }
146
147 #[inline]
149 pub fn insert(&mut self, elem: T) -> bool {
150 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!(
151 elem.index() < self.domain_size,
152 "inserting element at index {} but domain size is {}",
153 elem.index(),
154 self.domain_size,
155 );
156 let (word_index, mask) = word_index_and_mask(elem);
157 let word_ref = &mut self.words[word_index];
158 let word = *word_ref;
159 let new_word = word | mask;
160 *word_ref = new_word;
161 new_word != word
162 }
163
164 #[inline]
165 pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
166 let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
167 return;
168 };
169
170 let (start_word_index, start_mask) = word_index_and_mask(start);
171 let (end_word_index, end_mask) = word_index_and_mask(end);
172
173 for word_index in (start_word_index + 1)..end_word_index {
175 self.words[word_index] = !0;
176 }
177
178 if start_word_index != end_word_index {
179 self.words[start_word_index] |= !(start_mask - 1);
183 self.words[end_word_index] |= end_mask | (end_mask - 1);
186 } else {
187 self.words[start_word_index] |= end_mask | (end_mask - start_mask);
188 }
189 }
190
191 pub fn insert_all(&mut self) {
193 self.words.fill(!0);
194 self.clear_excess_bits();
195 }
196
197 #[inline]
199 pub fn contains_any(&self, elems: impl RangeBounds<T>) -> bool {
200 let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
201 return false;
202 };
203 let (start_word_index, start_mask) = word_index_and_mask(start);
204 let (end_word_index, end_mask) = word_index_and_mask(end);
205
206 if start_word_index == end_word_index {
207 self.words[start_word_index] & (end_mask | (end_mask - start_mask)) != 0
208 } else {
209 if self.words[start_word_index] & !(start_mask - 1) != 0 {
210 return true;
211 }
212
213 let remaining = start_word_index + 1..end_word_index;
214 if remaining.start <= remaining.end {
215 self.words[remaining].iter().any(|&w| w != 0)
216 || self.words[end_word_index] & (end_mask | (end_mask - 1)) != 0
217 } else {
218 false
219 }
220 }
221 }
222
223 #[inline]
225 pub fn remove(&mut self, elem: T) -> bool {
226 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
227 let (word_index, mask) = word_index_and_mask(elem);
228 let word_ref = &mut self.words[word_index];
229 let word = *word_ref;
230 let new_word = word & !mask;
231 *word_ref = new_word;
232 new_word != word
233 }
234
235 #[inline]
237 pub fn iter(&self) -> BitIter<'_, T> {
238 BitIter::new(&self.words)
239 }
240
241 pub fn first_set_at_or_after(&self, elem: T) -> Option<T> {
243 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
244 let (mut word_index, mask) = word_index_and_mask(elem);
245 let mut word = self.words[word_index] & !(mask - 1);
247 loop {
248 if word != 0 {
249 return Some(T::new(WORD_BITS * word_index + word.trailing_zeros() as usize));
250 }
251 word_index += 1;
252 word = *self.words.get(word_index)?;
253 }
254 }
255
256 pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
257 let (start, end) = inclusive_start_end(range, self.domain_size)?;
258 let (start_word_index, _) = word_index_and_mask(start);
259 let (end_word_index, end_mask) = word_index_and_mask(end);
260
261 let end_word = self.words[end_word_index] & (end_mask | (end_mask - 1));
262 if end_word != 0 {
263 let pos = max_bit(end_word) + WORD_BITS * end_word_index;
264 if start <= pos {
265 return Some(T::new(pos));
266 }
267 }
268
269 if let Some(offset) =
273 self.words[start_word_index..end_word_index].iter().rposition(|&w| w != 0)
274 {
275 let word_idx = start_word_index + offset;
276 let start_word = self.words[word_idx];
277 let pos = max_bit(start_word) + WORD_BITS * word_idx;
278 if start <= pos {
279 return Some(T::new(pos));
280 }
281 }
282
283 None
284 }
285
286 pub fn union_not(&mut self, other: &DenseBitSet<T>) {
288 {
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);
289
290 update_words(&mut self.words, &other.words, |a, b| a | !b);
296 self.clear_excess_bits();
299 }
300
301 pub fn union(&mut self, other: &DenseBitSet<T>) -> bool {
303 {
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);
304 update_words(&mut self.words, &other.words, |a, b| a | b)
305 }
306
307 pub fn subtract(&mut self, other: &DenseBitSet<T>) -> bool {
309 {
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);
310 update_words(&mut self.words, &other.words, |a, b| a & !b)
311 }
312
313 pub fn intersect(&mut self, other: &DenseBitSet<T>) -> bool {
315 {
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);
316 update_words(&mut self.words, &other.words, |a, b| a & b)
317 }
318}
319
320impl<T: Idx> From<GrowableBitSet<T>> for DenseBitSet<T> {
321 fn from(bit_set: GrowableBitSet<T>) -> Self {
322 bit_set.bit_set
323 }
324}
325
326impl<T> Clone for DenseBitSet<T> {
327 fn clone(&self) -> Self {
328 DenseBitSet {
329 domain_size: self.domain_size,
330 words: self.words.clone(),
331 marker: PhantomData,
332 }
333 }
334
335 fn clone_from(&mut self, from: &Self) {
336 self.domain_size = from.domain_size;
337 self.words.clone_from(&from.words);
338 }
339}
340
341impl<T: Idx> fmt::Debug for DenseBitSet<T> {
342 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
343 w.debug_list().entries(self.iter()).finish()
344 }
345}
346
347impl<T: Idx> ToString for DenseBitSet<T> {
348 fn to_string(&self) -> String {
349 let mut result = String::new();
350 let mut sep = '[';
351
352 let mut i = 0;
356 for word in &self.words {
357 let mut word = *word;
358 for _ in 0..WORD_BYTES {
359 let remain = self.domain_size - i;
361 let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
363 if !(mask <= 0xFF) {
::core::panicking::panic("assertion failed: mask <= 0xFF")
};assert!(mask <= 0xFF);
364 let byte = word & mask;
365
366 result.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1:02x}", sep, byte))
})format!("{sep}{byte:02x}"));
367
368 if remain <= 8 {
369 break;
370 }
371 word >>= 8;
372 i += 8;
373 sep = '-';
374 }
375 sep = '|';
376 }
377 result.push(']');
378
379 result
380 }
381}
382
383pub struct BitIter<'a, T: Idx> {
384 word: Word,
388
389 offset: usize,
391
392 iter: slice::Iter<'a, Word>,
394
395 marker: PhantomData<T>,
396}
397
398impl<'a, T: Idx> BitIter<'a, T> {
399 #[inline]
400 fn new(words: &'a [Word]) -> BitIter<'a, T> {
401 BitIter {
407 word: 0,
408 offset: usize::MAX - (WORD_BITS - 1),
409 iter: words.iter(),
410 marker: PhantomData,
411 }
412 }
413}
414
415impl<'a, T: Idx> Iterator for BitIter<'a, T> {
416 type Item = T;
417 fn next(&mut self) -> Option<T> {
418 loop {
419 if self.word != 0 {
420 let bit_pos = self.word.trailing_zeros() as usize;
423 self.word ^= 1 << bit_pos;
424 return Some(T::new(bit_pos + self.offset));
425 }
426
427 self.word = *self.iter.next()?;
430 self.offset = self.offset.wrapping_add(WORD_BITS);
431 }
432 }
433}
434
435#[derive(#[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
ChunkedBitSet<T> {
}
#[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_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<usize>;
let _: ::core::cmp::AssertParamIsEq<Box<[Chunk]>>;
let _: ::core::cmp::AssertParamIsEq<PhantomData<T>>;
}
}Eq)]
454pub struct ChunkedBitSet<T> {
455 domain_size: usize,
456
457 chunks: Box<[Chunk]>,
460
461 marker: PhantomData<T>,
462}
463
464#[derive(#[automatically_derived]
impl ::core::clone::Clone for Chunk {
#[inline]
fn clone(&self) -> Chunk {
match self {
Chunk::Zeros { chunk_domain_size: __self_0 } =>
Chunk::Zeros {
chunk_domain_size: ::core::clone::Clone::clone(__self_0),
},
Chunk::Ones { chunk_domain_size: __self_0 } =>
Chunk::Ones {
chunk_domain_size: ::core::clone::Clone::clone(__self_0),
},
Chunk::Mixed {
chunk_domain_size: __self_0,
ones_count: __self_1,
words: __self_2 } =>
Chunk::Mixed {
chunk_domain_size: ::core::clone::Clone::clone(__self_0),
ones_count: ::core::clone::Clone::clone(__self_1),
words: ::core::clone::Clone::clone(__self_2),
},
}
}
}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 { chunk_domain_size: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Zeros",
"chunk_domain_size", &__self_0),
Chunk::Ones { chunk_domain_size: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Ones",
"chunk_domain_size", &__self_0),
Chunk::Mixed {
chunk_domain_size: __self_0,
ones_count: __self_1,
words: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f, "Mixed",
"chunk_domain_size", __self_0, "ones_count", __self_1,
"words", &__self_2),
}
}
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Chunk { }
#[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::Zeros { chunk_domain_size: __self_0 }, Chunk::Zeros {
chunk_domain_size: __arg1_0 }) => __self_0 == __arg1_0,
(Chunk::Ones { chunk_domain_size: __self_0 }, Chunk::Ones {
chunk_domain_size: __arg1_0 }) => __self_0 == __arg1_0,
(Chunk::Mixed {
chunk_domain_size: __self_0,
ones_count: __self_1,
words: __self_2 }, Chunk::Mixed {
chunk_domain_size: __arg1_0,
ones_count: __arg1_1,
words: __arg1_2 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1 &&
__self_2 == __arg1_2,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Chunk {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<ChunkSize>;
let _: ::core::cmp::AssertParamIsEq<Rc<[Word; CHUNK_WORDS]>>;
}
}Eq)]
469enum Chunk {
470 Zeros { chunk_domain_size: ChunkSize },
472
473 Ones { chunk_domain_size: ChunkSize },
475
476 Mixed {
490 chunk_domain_size: ChunkSize,
491 ones_count: ChunkSize,
498 words: Rc<[Word; CHUNK_WORDS]>,
499 },
500}
501
502#[cfg(target_pointer_width = "64")]
504const _: [(); 16] = [(); ::std::mem::size_of::<Chunk>()];crate::static_assert_size!(Chunk, 16);
505
506impl<T> ChunkedBitSet<T> {
507 pub fn domain_size(&self) -> usize {
508 self.domain_size
509 }
510
511 #[cfg(test)]
512 fn assert_valid(&self) {
513 if self.domain_size == 0 {
514 assert!(self.chunks.is_empty());
515 return;
516 }
517
518 assert!((self.chunks.len() - 1) * CHUNK_BITS <= self.domain_size);
519 assert!(self.chunks.len() * CHUNK_BITS >= self.domain_size);
520 for chunk in self.chunks.iter() {
521 chunk.assert_valid();
522 }
523 }
524}
525
526impl<T: Idx> ChunkedBitSet<T> {
527 fn new(domain_size: usize, is_empty: bool) -> Self {
529 let chunks = if domain_size == 0 {
530 Box::new([])
531 } else {
532 let num_chunks = domain_size.index().div_ceil(CHUNK_BITS);
533 let mut last_chunk_domain_size = domain_size % CHUNK_BITS;
534 if last_chunk_domain_size == 0 {
535 last_chunk_domain_size = CHUNK_BITS;
536 };
537
538 let (normal_chunk, final_chunk) = if is_empty {
541 (
542 Zeros { chunk_domain_size: CHUNK_BITS as ChunkSize },
543 Zeros { chunk_domain_size: last_chunk_domain_size as ChunkSize },
544 )
545 } else {
546 (
547 Ones { chunk_domain_size: CHUNK_BITS as ChunkSize },
548 Ones { chunk_domain_size: last_chunk_domain_size as ChunkSize },
549 )
550 };
551 let mut chunks = ::alloc::vec::from_elem(normal_chunk, num_chunks)vec![normal_chunk; num_chunks].into_boxed_slice();
552 *chunks.as_mut().last_mut().unwrap() = final_chunk;
553 chunks
554 };
555 ChunkedBitSet { domain_size, chunks, marker: PhantomData }
556 }
557
558 #[inline]
560 pub fn new_empty(domain_size: usize) -> Self {
561 ChunkedBitSet::new(domain_size, true)
562 }
563
564 #[inline]
566 pub fn new_filled(domain_size: usize) -> Self {
567 ChunkedBitSet::new(domain_size, false)
568 }
569
570 pub fn clear(&mut self) {
571 *self = ChunkedBitSet::new_empty(self.domain_size);
573 }
574
575 #[cfg(test)]
576 fn chunks(&self) -> &[Chunk] {
577 &self.chunks
578 }
579
580 pub fn count(&self) -> usize {
582 self.chunks.iter().map(|chunk| chunk.count()).sum()
583 }
584
585 pub fn is_empty(&self) -> bool {
586 self.chunks.iter().all(|chunk| #[allow(non_exhaustive_omitted_patterns)] match chunk {
Zeros { .. } => true,
_ => false,
}matches!(chunk, Zeros { .. }))
587 }
588
589 #[inline]
591 pub fn contains(&self, elem: T) -> bool {
592 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
593 let chunk = &self.chunks[chunk_index(elem)];
594 match &chunk {
595 Zeros { .. } => false,
596 Ones { .. } => true,
597 Mixed { words, .. } => {
598 let (word_index, mask) = chunk_word_index_and_mask(elem);
599 (words[word_index] & mask) != 0
600 }
601 }
602 }
603
604 #[inline]
605 pub fn iter(&self) -> ChunkedBitIter<'_, T> {
606 ChunkedBitIter::new(self)
607 }
608
609 pub fn insert(&mut 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_index = chunk_index(elem);
613 let chunk = &mut self.chunks[chunk_index];
614 match *chunk {
615 Zeros { chunk_domain_size } => {
616 if chunk_domain_size > 1 {
617 let mut words = {
618 let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
620 unsafe { words.assume_init() }
622 };
623 let words_ref = Rc::get_mut(&mut words).unwrap();
624
625 let (word_index, mask) = chunk_word_index_and_mask(elem);
626 words_ref[word_index] |= mask;
627 *chunk = Mixed { chunk_domain_size, ones_count: 1, words };
628 } else {
629 *chunk = Ones { chunk_domain_size };
630 }
631 true
632 }
633 Ones { .. } => false,
634 Mixed { chunk_domain_size, ref mut ones_count, ref mut words } => {
635 let (word_index, mask) = chunk_word_index_and_mask(elem);
637 if (words[word_index] & mask) == 0 {
638 *ones_count += 1;
639 if *ones_count < chunk_domain_size {
640 let words = Rc::make_mut(words);
641 words[word_index] |= mask;
642 } else {
643 *chunk = Ones { chunk_domain_size };
644 }
645 true
646 } else {
647 false
648 }
649 }
650 }
651 }
652
653 pub fn insert_all(&mut self) {
655 *self = ChunkedBitSet::new_filled(self.domain_size);
657 }
658
659 pub fn remove(&mut self, elem: T) -> bool {
661 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
662 let chunk_index = chunk_index(elem);
663 let chunk = &mut self.chunks[chunk_index];
664 match *chunk {
665 Zeros { .. } => false,
666 Ones { chunk_domain_size } => {
667 if chunk_domain_size > 1 {
668 let mut words = {
669 let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
671 unsafe { words.assume_init() }
673 };
674 let words_ref = Rc::get_mut(&mut words).unwrap();
675
676 let num_words = num_words(chunk_domain_size as usize);
678 words_ref[..num_words].fill(!0);
679 clear_excess_bits_in_final_word(
680 chunk_domain_size as usize,
681 &mut words_ref[..num_words],
682 );
683 let (word_index, mask) = chunk_word_index_and_mask(elem);
684 words_ref[word_index] &= !mask;
685 *chunk = Mixed { chunk_domain_size, ones_count: chunk_domain_size - 1, words };
686 } else {
687 *chunk = Zeros { chunk_domain_size };
688 }
689 true
690 }
691 Mixed { chunk_domain_size, ref mut ones_count, ref mut words } => {
692 let (word_index, mask) = chunk_word_index_and_mask(elem);
694 if (words[word_index] & mask) != 0 {
695 *ones_count -= 1;
696 if *ones_count > 0 {
697 let words = Rc::make_mut(words);
698 words[word_index] &= !mask;
699 } else {
700 *chunk = Zeros { chunk_domain_size }
701 }
702 true
703 } else {
704 false
705 }
706 }
707 }
708 }
709
710 fn chunk_iter(&self, chunk_index: usize) -> ChunkIter<'_> {
711 match self.chunks.get(chunk_index) {
712 Some(Zeros { .. }) => ChunkIter::Zeros,
713 Some(Ones { chunk_domain_size }) => ChunkIter::Ones(0..*chunk_domain_size as usize),
714 Some(Mixed { chunk_domain_size, words, .. }) => {
715 let num_words = num_words(*chunk_domain_size as usize);
716 ChunkIter::Mixed(BitIter::new(&words[0..num_words]))
717 }
718 None => ChunkIter::Finished,
719 }
720 }
721
722 fn union(&mut self, other: &ChunkedBitSet<T>) -> bool {
724 {
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);
725
726 let mut changed = false;
727 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
728 match (&mut self_chunk, &other_chunk) {
729 (_, Zeros { .. }) | (Ones { .. }, _) => {}
730 (Zeros { .. }, _) | (Mixed { .. }, Ones { .. }) => {
731 *self_chunk = other_chunk.clone();
733 changed = true;
734 }
735 (
736 Mixed {
737 chunk_domain_size,
738 ones_count: self_chunk_ones_count,
739 words: self_chunk_words,
740 },
741 Mixed { words: other_chunk_words, .. },
742 ) => {
743 let num_words = num_words(*chunk_domain_size as usize);
749
750 if self_chunk_words[0..num_words] == other_chunk_words[0..num_words] {
754 continue;
755 }
756
757 let op = |a, b| a | b;
760 if !would_modify_words(
761 &self_chunk_words[0..num_words],
762 &other_chunk_words[0..num_words],
763 op,
764 ) {
765 continue;
766 }
767
768 let self_chunk_words = Rc::make_mut(self_chunk_words);
770 let has_changed = update_words(
771 &mut self_chunk_words[0..num_words],
772 &other_chunk_words[0..num_words],
773 op,
774 );
775 if true {
if !has_changed {
::core::panicking::panic("assertion failed: has_changed")
};
};debug_assert!(has_changed);
776 *self_chunk_ones_count =
777 count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
778 if *self_chunk_ones_count == *chunk_domain_size {
779 *self_chunk = Ones { chunk_domain_size: *chunk_domain_size };
780 }
781 changed = true;
782 }
783 }
784 }
785 changed
786 }
787
788 fn subtract(&mut self, other: &ChunkedBitSet<T>) -> bool {
790 {
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);
791
792 let mut changed = false;
793 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
794 match (&mut self_chunk, &other_chunk) {
795 (Zeros { .. }, _) | (_, Zeros { .. }) => {}
796 (Ones { chunk_domain_size } | Mixed { chunk_domain_size, .. }, Ones { .. }) => {
797 changed = true;
798 *self_chunk = Zeros { chunk_domain_size: *chunk_domain_size };
799 }
800 (
801 Ones { chunk_domain_size },
802 Mixed { ones_count: other_chunk_ones_count, words: other_chunk_words, .. },
803 ) => {
804 changed = true;
805 let num_words = num_words(*chunk_domain_size as usize);
806 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);
807 let mut self_chunk_words = **other_chunk_words;
810 for word in self_chunk_words[0..num_words].iter_mut() {
811 *word = !*word;
812 }
813 clear_excess_bits_in_final_word(
814 *chunk_domain_size as usize,
815 &mut self_chunk_words[..num_words],
816 );
817 let self_chunk_ones_count = *chunk_domain_size - *other_chunk_ones_count;
818 if true {
{
match (&self_chunk_ones_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!(
819 self_chunk_ones_count,
820 count_ones(&self_chunk_words[0..num_words]) as ChunkSize
821 );
822 *self_chunk = Mixed {
823 chunk_domain_size: *chunk_domain_size,
824 ones_count: self_chunk_ones_count,
825 words: Rc::new(self_chunk_words),
826 };
827 }
828 (
829 Mixed {
830 chunk_domain_size,
831 ones_count: self_chunk_ones_count,
832 words: self_chunk_words,
833 },
834 Mixed { words: other_chunk_words, .. },
835 ) => {
836 let num_words = num_words(*chunk_domain_size as usize);
838 let op = |a: Word, b: Word| a & !b;
839 if !would_modify_words(
840 &self_chunk_words[0..num_words],
841 &other_chunk_words[0..num_words],
842 op,
843 ) {
844 continue;
845 }
846
847 let self_chunk_words = Rc::make_mut(self_chunk_words);
848 let has_changed = update_words(
849 &mut self_chunk_words[0..num_words],
850 &other_chunk_words[0..num_words],
851 op,
852 );
853 if true {
if !has_changed {
::core::panicking::panic("assertion failed: has_changed")
};
};debug_assert!(has_changed);
854 *self_chunk_ones_count =
855 count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
856 if *self_chunk_ones_count == 0 {
857 *self_chunk = Zeros { chunk_domain_size: *chunk_domain_size };
858 }
859 changed = true;
860 }
861 }
862 }
863 changed
864 }
865}
866
867impl<T> Clone for ChunkedBitSet<T> {
868 fn clone(&self) -> Self {
869 ChunkedBitSet {
870 domain_size: self.domain_size,
871 chunks: self.chunks.clone(),
872 marker: PhantomData,
873 }
874 }
875
876 fn clone_from(&mut self, from: &Self) {
881 {
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);
882 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());
883
884 self.chunks.clone_from(&from.chunks)
885 }
886}
887
888pub struct ChunkedBitIter<'a, T: Idx> {
889 bit_set: &'a ChunkedBitSet<T>,
890
891 chunk_index: usize,
893
894 chunk_iter: ChunkIter<'a>,
896}
897
898impl<'a, T: Idx> ChunkedBitIter<'a, T> {
899 #[inline]
900 fn new(bit_set: &'a ChunkedBitSet<T>) -> ChunkedBitIter<'a, T> {
901 ChunkedBitIter { bit_set, chunk_index: 0, chunk_iter: bit_set.chunk_iter(0) }
902 }
903}
904
905impl<'a, T: Idx> Iterator for ChunkedBitIter<'a, T> {
906 type Item = T;
907
908 fn next(&mut self) -> Option<T> {
909 loop {
910 match &mut self.chunk_iter {
911 ChunkIter::Zeros => {}
912 ChunkIter::Ones(iter) => {
913 if let Some(next) = iter.next() {
914 return Some(T::new(next + self.chunk_index * CHUNK_BITS));
915 }
916 }
917 ChunkIter::Mixed(iter) => {
918 if let Some(next) = iter.next() {
919 return Some(T::new(next + self.chunk_index * CHUNK_BITS));
920 }
921 }
922 ChunkIter::Finished => return None,
923 }
924 self.chunk_index += 1;
925 self.chunk_iter = self.bit_set.chunk_iter(self.chunk_index);
926 }
927 }
928}
929
930impl Chunk {
931 #[cfg(test)]
932 fn assert_valid(&self) {
933 match *self {
934 Zeros { chunk_domain_size } | Ones { chunk_domain_size } => {
935 assert!(chunk_domain_size as usize <= CHUNK_BITS);
936 }
937 Mixed { chunk_domain_size, ones_count, ref words } => {
938 assert!(chunk_domain_size as usize <= CHUNK_BITS);
939 assert!(0 < ones_count && ones_count < chunk_domain_size);
940
941 assert_eq!(count_ones(words.as_slice()) as ChunkSize, ones_count);
943
944 let num_words = num_words(chunk_domain_size as usize);
946 if num_words < CHUNK_WORDS {
947 assert_eq!(count_ones(&words[num_words..]) as ChunkSize, 0);
948 }
949 }
950 }
951 }
952
953 fn count(&self) -> usize {
955 match *self {
956 Zeros { .. } => 0,
957 Ones { chunk_domain_size } => chunk_domain_size as usize,
958 Mixed { ones_count, .. } => usize::from(ones_count),
959 }
960 }
961}
962
963enum ChunkIter<'a> {
964 Zeros,
965 Ones(Range<usize>),
966 Mixed(BitIter<'a, usize>),
967 Finished,
968}
969
970impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
971 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
972 w.debug_list().entries(self.iter()).finish()
973 }
974}
975
976#[inline]
989fn update_words<Op>(lhs: &mut [Word], rhs: &[Word], op: Op) -> bool
990where
991 Op: Fn(Word, Word) -> Word,
992{
993 {
match (&lhs.len(), &rhs.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!(lhs.len(), rhs.len());
994 let mut changed = 0;
995 for (lhs_slot, &rhs_val) in iter::zip(lhs, rhs) {
996 let old_val = *lhs_slot;
997 let new_val = op(old_val, rhs_val);
998 *lhs_slot = new_val;
999 changed |= old_val ^ new_val;
1004 }
1005 changed != 0
1006}
1007
1008#[inline]
1011fn would_modify_words<Op>(lhs: &[Word], rhs: &[Word], op: Op) -> bool
1012where
1013 Op: Fn(Word, Word) -> Word,
1014{
1015 {
match (&lhs.len(), &rhs.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!(lhs.len(), rhs.len());
1016
1017 const SUBCHUNK_LEN: usize = 64 / size_of::<Word>();
1022 let (lhs_chunks, lhs_tail) = lhs.as_chunks::<SUBCHUNK_LEN>();
1023 let (rhs_chunks, rhs_tail) = rhs.as_chunks::<SUBCHUNK_LEN>();
1024
1025 let would_modify_subchunk = |lhs_chunk: &[Word], rhs_chunk: &[Word]| {
1026 let mut changed = 0;
1027 for (&old_val, &rhs_val) in iter::zip(lhs_chunk, rhs_chunk) {
1028 let new_val = op(old_val, rhs_val);
1029 changed |= old_val ^ new_val;
1032 }
1033 changed != 0
1034 };
1035
1036 for (lhs_chunk, rhs_chunk) in iter::zip(lhs_chunks, rhs_chunks) {
1037 if would_modify_subchunk(lhs_chunk, rhs_chunk) {
1038 return true;
1039 }
1040 }
1041 would_modify_subchunk(lhs_tail, rhs_tail)
1042}
1043
1044#[derive(#[automatically_derived]
impl<T: ::core::cmp::PartialEq> ::core::marker::StructuralPartialEq for
MixedBitSet<T> {
}
#[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_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<DenseBitSet<T>>;
let _: ::core::cmp::AssertParamIsEq<ChunkedBitSet<T>>;
}
}Eq)]
1056pub enum MixedBitSet<T> {
1057 Small(DenseBitSet<T>),
1058 Large(ChunkedBitSet<T>),
1059}
1060
1061impl<T> MixedBitSet<T> {
1062 pub fn domain_size(&self) -> usize {
1063 match self {
1064 MixedBitSet::Small(set) => set.domain_size(),
1065 MixedBitSet::Large(set) => set.domain_size(),
1066 }
1067 }
1068}
1069
1070impl<T: Idx> MixedBitSet<T> {
1071 #[inline]
1072 pub fn new_empty(domain_size: usize) -> MixedBitSet<T> {
1073 if domain_size <= CHUNK_BITS {
1074 MixedBitSet::Small(DenseBitSet::new_empty(domain_size))
1075 } else {
1076 MixedBitSet::Large(ChunkedBitSet::new_empty(domain_size))
1077 }
1078 }
1079
1080 #[inline]
1081 pub fn is_empty(&self) -> bool {
1082 match self {
1083 MixedBitSet::Small(set) => set.is_empty(),
1084 MixedBitSet::Large(set) => set.is_empty(),
1085 }
1086 }
1087
1088 #[inline]
1089 pub fn contains(&self, elem: T) -> bool {
1090 match self {
1091 MixedBitSet::Small(set) => set.contains(elem),
1092 MixedBitSet::Large(set) => set.contains(elem),
1093 }
1094 }
1095
1096 #[inline]
1097 pub fn insert(&mut self, elem: T) -> bool {
1098 match self {
1099 MixedBitSet::Small(set) => set.insert(elem),
1100 MixedBitSet::Large(set) => set.insert(elem),
1101 }
1102 }
1103
1104 pub fn insert_all(&mut self) {
1105 match self {
1106 MixedBitSet::Small(set) => set.insert_all(),
1107 MixedBitSet::Large(set) => set.insert_all(),
1108 }
1109 }
1110
1111 #[inline]
1112 pub fn remove(&mut self, elem: T) -> bool {
1113 match self {
1114 MixedBitSet::Small(set) => set.remove(elem),
1115 MixedBitSet::Large(set) => set.remove(elem),
1116 }
1117 }
1118
1119 pub fn iter(&self) -> MixedBitIter<'_, T> {
1120 match self {
1121 MixedBitSet::Small(set) => MixedBitIter::Small(set.iter()),
1122 MixedBitSet::Large(set) => MixedBitIter::Large(set.iter()),
1123 }
1124 }
1125
1126 #[inline]
1127 pub fn clear(&mut self) {
1128 match self {
1129 MixedBitSet::Small(set) => set.clear(),
1130 MixedBitSet::Large(set) => set.clear(),
1131 }
1132 }
1133
1134 pub fn union(&mut self, other: &MixedBitSet<T>) -> bool {
1136 match (self, other) {
1137 (MixedBitSet::Small(set), MixedBitSet::Small(other)) => set.union(other),
1138 (MixedBitSet::Large(set), MixedBitSet::Large(other)) => set.union(other),
1139 _ => { ::core::panicking::panic_fmt(format_args!("MixedBitSet size mismatch")); }panic!("MixedBitSet size mismatch"),
1140 }
1141 }
1142
1143 pub fn subtract(&mut self, other: &MixedBitSet<T>) -> bool {
1145 match (self, other) {
1146 (MixedBitSet::Small(set), MixedBitSet::Small(other)) => set.subtract(other),
1147 (MixedBitSet::Large(set), MixedBitSet::Large(other)) => set.subtract(other),
1148 _ => { ::core::panicking::panic_fmt(format_args!("MixedBitSet size mismatch")); }panic!("MixedBitSet size mismatch"),
1149 }
1150 }
1151}
1152
1153impl<T> Clone for MixedBitSet<T> {
1154 fn clone(&self) -> Self {
1155 match self {
1156 MixedBitSet::Small(set) => MixedBitSet::Small(set.clone()),
1157 MixedBitSet::Large(set) => MixedBitSet::Large(set.clone()),
1158 }
1159 }
1160
1161 fn clone_from(&mut self, from: &Self) {
1166 match (self, from) {
1167 (MixedBitSet::Small(set), MixedBitSet::Small(from)) => set.clone_from(from),
1168 (MixedBitSet::Large(set), MixedBitSet::Large(from)) => set.clone_from(from),
1169 _ => { ::core::panicking::panic_fmt(format_args!("MixedBitSet size mismatch")); }panic!("MixedBitSet size mismatch"),
1170 }
1171 }
1172}
1173
1174impl<T: Idx> fmt::Debug for MixedBitSet<T> {
1175 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
1176 match self {
1177 MixedBitSet::Small(set) => set.fmt(w),
1178 MixedBitSet::Large(set) => set.fmt(w),
1179 }
1180 }
1181}
1182
1183pub enum MixedBitIter<'a, T: Idx> {
1184 Small(BitIter<'a, T>),
1185 Large(ChunkedBitIter<'a, T>),
1186}
1187
1188impl<'a, T: Idx> Iterator for MixedBitIter<'a, T> {
1189 type Item = T;
1190 fn next(&mut self) -> Option<T> {
1191 match self {
1192 MixedBitIter::Small(iter) => iter.next(),
1193 MixedBitIter::Large(iter) => iter.next(),
1194 }
1195 }
1196}
1197
1198#[derive(#[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::marker::StructuralPartialEq for
GrowableBitSet<T> {
}
#[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)]
1206pub struct GrowableBitSet<T: Idx> {
1207 bit_set: DenseBitSet<T>,
1208}
1209
1210impl<T: Idx> Clone for GrowableBitSet<T> {
1212 fn clone(&self) -> Self {
1213 Self { bit_set: self.bit_set.clone() }
1214 }
1215
1216 fn clone_from(&mut self, source: &Self) {
1217 self.bit_set.clone_from(&source.bit_set);
1218 }
1219}
1220
1221impl<T: Idx> Default for GrowableBitSet<T> {
1222 fn default() -> Self {
1223 GrowableBitSet::new_empty()
1224 }
1225}
1226
1227impl<T: Idx> GrowableBitSet<T> {
1228 pub fn ensure(&mut self, min_domain_size: usize) {
1230 if self.bit_set.domain_size < min_domain_size {
1231 self.bit_set.domain_size = min_domain_size;
1232 }
1233
1234 let min_num_words = num_words(min_domain_size);
1235 if self.bit_set.words.len() < min_num_words {
1236 self.bit_set.words.resize(min_num_words, 0)
1237 }
1238 }
1239
1240 pub fn new_empty() -> GrowableBitSet<T> {
1241 GrowableBitSet { bit_set: DenseBitSet::new_empty(0) }
1242 }
1243
1244 pub fn with_capacity(capacity: usize) -> GrowableBitSet<T> {
1245 GrowableBitSet { bit_set: DenseBitSet::new_empty(capacity) }
1246 }
1247
1248 #[inline]
1250 pub fn insert(&mut self, elem: T) -> bool {
1251 self.ensure(elem.index() + 1);
1252 self.bit_set.insert(elem)
1253 }
1254
1255 #[inline]
1256 pub fn insert_range(&mut self, elems: Range<T>) {
1257 self.ensure(elems.end.index());
1258 self.bit_set.insert_range(elems);
1259 }
1260
1261 #[inline]
1263 pub fn remove(&mut self, elem: T) -> bool {
1264 self.ensure(elem.index() + 1);
1265 self.bit_set.remove(elem)
1266 }
1267
1268 #[inline]
1269 pub fn clear(&mut self) {
1270 self.bit_set.clear();
1271 }
1272
1273 #[inline]
1274 pub fn count(&self) -> usize {
1275 self.bit_set.count()
1276 }
1277
1278 #[inline]
1279 pub fn is_empty(&self) -> bool {
1280 self.bit_set.is_empty()
1281 }
1282
1283 #[inline]
1284 pub fn contains(&self, elem: T) -> bool {
1285 let (word_index, mask) = word_index_and_mask(elem);
1286 self.bit_set.words.get(word_index).is_some_and(|word| (word & mask) != 0)
1287 }
1288
1289 #[inline]
1290 pub fn contains_any(&self, elems: Range<T>) -> bool {
1291 elems.start.index() < self.bit_set.domain_size
1292 && self
1293 .bit_set
1294 .contains_any(elems.start..T::new(elems.end.index().min(self.bit_set.domain_size)))
1295 }
1296
1297 #[inline]
1298 pub fn iter(&self) -> BitIter<'_, T> {
1299 self.bit_set.iter()
1300 }
1301
1302 #[inline]
1303 pub fn len(&self) -> usize {
1304 self.bit_set.count()
1305 }
1306}
1307
1308impl<T: Idx> From<DenseBitSet<T>> for GrowableBitSet<T> {
1309 fn from(bit_set: DenseBitSet<T>) -> Self {
1310 Self { bit_set }
1311 }
1312}
1313
1314#[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) {
let BitMatrix {
num_rows: ref __binding_0,
num_columns: ref __binding_1,
words: ref __binding_2,
marker: ref __binding_3 } = *self;
::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))]
1322#[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_fields_are_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::marker::StructuralPartialEq for BitMatrix<R, C> {
}
#[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)]
1323pub struct BitMatrix<R: Idx, C: Idx> {
1324 num_rows: usize,
1325 num_columns: usize,
1326 words: Vec<Word>,
1327 marker: PhantomData<(R, C)>,
1328}
1329
1330impl<R: Idx, C: Idx> BitMatrix<R, C> {
1331 pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix<R, C> {
1333 let words_per_row = num_words(num_columns);
1336 BitMatrix {
1337 num_rows,
1338 num_columns,
1339 words: ::alloc::vec::from_elem(0, num_rows * words_per_row)vec![0; num_rows * words_per_row],
1340 marker: PhantomData,
1341 }
1342 }
1343
1344 pub fn from_row_n(row: &DenseBitSet<C>, num_rows: usize) -> BitMatrix<R, C> {
1346 let num_columns = row.domain_size();
1347 let words_per_row = num_words(num_columns);
1348 {
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());
1349 BitMatrix {
1350 num_rows,
1351 num_columns,
1352 words: iter::repeat_n(&row.words, num_rows).flatten().cloned().collect(),
1353 marker: PhantomData,
1354 }
1355 }
1356
1357 pub fn rows(&self) -> impl Iterator<Item = R> {
1358 (0..self.num_rows).map(R::new)
1359 }
1360
1361 fn range(&self, row: R) -> (usize, usize) {
1363 let words_per_row = num_words(self.num_columns);
1364 let start = row.index() * words_per_row;
1365 (start, start + words_per_row)
1366 }
1367
1368 pub fn insert(&mut self, row: R, column: C) -> bool {
1373 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);
1374 let (start, _) = self.range(row);
1375 let (word_index, mask) = word_index_and_mask(column);
1376 let words = &mut self.words[..];
1377 let word = words[start + word_index];
1378 let new_word = word | mask;
1379 words[start + word_index] = new_word;
1380 word != new_word
1381 }
1382
1383 pub fn contains(&self, row: R, column: C) -> bool {
1388 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);
1389 let (start, _) = self.range(row);
1390 let (word_index, mask) = word_index_and_mask(column);
1391 (self.words[start + word_index] & mask) != 0
1392 }
1393
1394 pub fn intersect_rows(&self, row1: R, row2: R) -> Vec<C> {
1399 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);
1400 let (row1_start, row1_end) = self.range(row1);
1401 let (row2_start, row2_end) = self.range(row2);
1402 let mut result = Vec::with_capacity(self.num_columns);
1403 for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() {
1404 let mut v = self.words[i] & self.words[j];
1405 for bit in 0..WORD_BITS {
1406 if v == 0 {
1407 break;
1408 }
1409 if v & 0x1 != 0 {
1410 result.push(C::new(base * WORD_BITS + bit));
1411 }
1412 v >>= 1;
1413 }
1414 }
1415 result
1416 }
1417
1418 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1426 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);
1427 let (read_start, read_end) = self.range(read);
1428 let (write_start, write_end) = self.range(write);
1429 let words = &mut self.words[..];
1430 let mut changed = 0;
1431 for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) {
1432 let word = words[write_index];
1433 let new_word = word | words[read_index];
1434 words[write_index] = new_word;
1435 changed |= word ^ new_word;
1437 }
1438 changed != 0
1439 }
1440
1441 pub fn union_row_with(&mut self, with: &DenseBitSet<C>, write: R) -> bool {
1444 if !(write.index() < self.num_rows) {
::core::panicking::panic("assertion failed: write.index() < self.num_rows")
};assert!(write.index() < self.num_rows);
1445 {
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);
1446 let (write_start, write_end) = self.range(write);
1447 update_words(&mut self.words[write_start..write_end], &with.words, |a, b| a | b)
1448 }
1449
1450 pub fn insert_all_into_row(&mut self, row: R) {
1452 if !(row.index() < self.num_rows) {
::core::panicking::panic("assertion failed: row.index() < self.num_rows")
};assert!(row.index() < self.num_rows);
1453 let (start, end) = self.range(row);
1454 let words = &mut self.words[..];
1455 for index in start..end {
1456 words[index] = !0;
1457 }
1458 clear_excess_bits_in_final_word(self.num_columns, &mut self.words[..end]);
1459 }
1460
1461 pub fn words(&self) -> &[Word] {
1463 &self.words
1464 }
1465
1466 pub fn iter(&self, row: R) -> BitIter<'_, C> {
1469 if !(row.index() < self.num_rows) {
::core::panicking::panic("assertion failed: row.index() < self.num_rows")
};assert!(row.index() < self.num_rows);
1470 let (start, end) = self.range(row);
1471 BitIter::new(&self.words[start..end])
1472 }
1473
1474 pub fn count(&self, row: R) -> usize {
1476 let (start, end) = self.range(row);
1477 count_ones(&self.words[start..end])
1478 }
1479}
1480
1481impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
1482 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1483 struct OneLinePrinter<T>(T);
1485 impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
1486 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1487 fmt.write_fmt(format_args!("{0:?}", self.0))write!(fmt, "{:?}", self.0)
1488 }
1489 }
1490
1491 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)?;
1492 let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
1493 fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
1494 }
1495}
1496
1497#[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)]
1509pub struct SparseBitMatrix<R, C>
1510where
1511 R: Idx,
1512 C: Idx,
1513{
1514 num_columns: usize,
1515 rows: IndexVec<R, Option<DenseBitSet<C>>>,
1516}
1517
1518impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
1519 pub fn new(num_columns: usize) -> Self {
1521 Self { num_columns, rows: IndexVec::new() }
1522 }
1523
1524 fn ensure_row(&mut self, row: R) -> &mut DenseBitSet<C> {
1525 self.rows.get_or_insert_with(row, || DenseBitSet::new_empty(self.num_columns))
1528 }
1529
1530 pub fn insert(&mut self, row: R, column: C) -> bool {
1535 self.ensure_row(row).insert(column)
1536 }
1537
1538 pub fn remove(&mut self, row: R, column: C) -> bool {
1544 match self.rows.get_mut(row) {
1545 Some(Some(row)) => row.remove(column),
1546 _ => false,
1547 }
1548 }
1549
1550 pub fn clear(&mut self, row: R) {
1553 if let Some(Some(row)) = self.rows.get_mut(row) {
1554 row.clear();
1555 }
1556 }
1557
1558 pub fn contains(&self, row: R, column: C) -> bool {
1563 self.row(row).is_some_and(|r| r.contains(column))
1564 }
1565
1566 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1574 if read == write || self.row(read).is_none() {
1575 return false;
1576 }
1577
1578 self.ensure_row(write);
1579 if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) {
1580 write_row.union(read_row)
1581 } else {
1582 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1583 }
1584 }
1585
1586 pub fn insert_all_into_row(&mut self, row: R) {
1588 self.ensure_row(row).insert_all();
1589 }
1590
1591 pub fn rows(&self) -> impl Iterator<Item = R> {
1592 self.rows.indices()
1593 }
1594
1595 pub fn iter(&self, row: R) -> impl Iterator<Item = C> {
1598 self.row(row).into_iter().flat_map(|r| r.iter())
1599 }
1600
1601 pub fn row(&self, row: R) -> Option<&DenseBitSet<C>> {
1602 self.rows.get(row)?.as_ref()
1603 }
1604}
1605
1606#[inline]
1607fn num_words<T: Idx>(domain_size: T) -> usize {
1608 domain_size.index().div_ceil(WORD_BITS)
1609}
1610
1611#[inline]
1612fn word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1613 let elem = elem.index();
1614 let word_index = elem / WORD_BITS;
1615 let mask = 1 << (elem % WORD_BITS);
1616 (word_index, mask)
1617}
1618
1619#[inline]
1620fn chunk_index<T: Idx>(elem: T) -> usize {
1621 elem.index() / CHUNK_BITS
1622}
1623
1624#[inline]
1625fn chunk_word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1626 let chunk_elem = elem.index() % CHUNK_BITS;
1627 word_index_and_mask(chunk_elem)
1628}
1629
1630fn clear_excess_bits_in_final_word(domain_size: usize, words: &mut [Word]) {
1631 let num_bits_in_final_word = domain_size % WORD_BITS;
1632 if num_bits_in_final_word > 0 {
1633 let mask = (1 << num_bits_in_final_word) - 1;
1634 words[words.len() - 1] &= mask;
1635 }
1636}
1637
1638#[inline]
1639fn max_bit(word: Word) -> usize {
1640 WORD_BITS - 1 - word.leading_zeros() as usize
1641}
1642
1643#[inline]
1644fn count_ones(words: &[Word]) -> usize {
1645 words.iter().map(|word| word.count_ones() as usize).sum()
1646}