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<Box<[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: Box<[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 {
98 domain_size,
99 words: ::alloc::vec::from_elem(0, num_words)vec![0; num_words].into_boxed_slice(),
100 marker: PhantomData,
101 }
102 }
103
104 #[inline]
106 pub fn new_filled(domain_size: usize) -> DenseBitSet<T> {
107 let num_words = num_words(domain_size);
108 let mut result = DenseBitSet {
109 domain_size,
110 words: ::alloc::vec::from_elem(!0, num_words)vec![!0; num_words].into_boxed_slice(),
111 marker: PhantomData,
112 };
113 result.clear_excess_bits();
114 result
115 }
116
117 #[inline]
119 pub fn clear(&mut self) {
120 self.words.fill(0);
121 }
122
123 fn clear_excess_bits(&mut self) {
125 clear_excess_bits_in_final_word(self.domain_size, &mut self.words);
126 }
127
128 pub fn count(&self) -> usize {
130 count_ones(&self.words)
131 }
132
133 #[inline]
138 pub fn contains_loose(&self, value: T) -> bool {
139 (value.index() < self.domain_size) && self.contains(value)
140 }
141
142 #[inline]
151 pub fn contains(&self, value: T) -> bool {
152 if !(value.index() < self.domain_size) {
::core::panicking::panic("assertion failed: value.index() < self.domain_size")
};assert!(value.index() < self.domain_size);
153 let (word_index, mask) = word_index_and_mask(value);
154 (self.words[word_index] & mask) != 0
155 }
156
157 #[inline]
159 pub fn superset(&self, other: &DenseBitSet<T>) -> bool {
160 {
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);
161 self.words.iter().zip(&other.words).all(|(a, b)| (a & b) == *b)
162 }
163
164 #[inline]
166 pub fn is_empty(&self) -> bool {
167 self.words.iter().all(|a| *a == 0)
168 }
169
170 #[inline]
172 pub fn insert(&mut self, value: T) -> bool {
173 if !(value.index() < self.domain_size) {
{
::core::panicking::panic_fmt(format_args!("inserting element at index {0} but domain size is {1}",
value.index(), self.domain_size));
}
};assert!(
174 value.index() < self.domain_size,
175 "inserting element at index {} but domain size is {}",
176 value.index(),
177 self.domain_size,
178 );
179 insert(&mut self.words, value)
180 }
181
182 #[inline]
183 pub fn insert_range(&mut self, elems: impl RangeBounds<T>) {
184 let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
185 return;
186 };
187
188 let (start_word_index, start_mask) = word_index_and_mask(start);
189 let (end_word_index, end_mask) = word_index_and_mask(end);
190
191 for word_index in (start_word_index + 1)..end_word_index {
193 self.words[word_index] = !0;
194 }
195
196 if start_word_index != end_word_index {
197 self.words[start_word_index] |= !(start_mask - 1);
201 self.words[end_word_index] |= end_mask | (end_mask - 1);
204 } else {
205 self.words[start_word_index] |= end_mask | (end_mask - start_mask);
206 }
207 }
208
209 pub fn insert_all(&mut self) {
211 self.words.fill(!0);
212 self.clear_excess_bits();
213 }
214
215 #[inline]
217 pub fn contains_any(&self, elems: impl RangeBounds<T>) -> bool {
218 let Some((start, end)) = inclusive_start_end(elems, self.domain_size) else {
219 return false;
220 };
221 let (start_word_index, start_mask) = word_index_and_mask(start);
222 let (end_word_index, end_mask) = word_index_and_mask(end);
223
224 if start_word_index == end_word_index {
225 self.words[start_word_index] & (end_mask | (end_mask - start_mask)) != 0
226 } else {
227 if self.words[start_word_index] & !(start_mask - 1) != 0 {
228 return true;
229 }
230
231 let remaining = start_word_index + 1..end_word_index;
232 if remaining.start <= remaining.end {
233 self.words[remaining].iter().any(|&w| w != 0)
234 || self.words[end_word_index] & (end_mask | (end_mask - 1)) != 0
235 } else {
236 false
237 }
238 }
239 }
240
241 #[inline]
243 pub fn remove(&mut self, elem: T) -> bool {
244 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
245 let (word_index, mask) = word_index_and_mask(elem);
246 let word_ref = &mut self.words[word_index];
247 let word = *word_ref;
248 let new_word = word & !mask;
249 *word_ref = new_word;
250 new_word != word
251 }
252
253 #[inline]
255 pub fn iter(&self) -> BitIter<'_, T> {
256 BitIter::new(&self.words)
257 }
258
259 pub fn first_set_at_or_after(&self, elem: T) -> Option<T> {
261 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
262 let (mut word_index, mask) = word_index_and_mask(elem);
263 let mut word = self.words[word_index] & !(mask - 1);
265 loop {
266 if word != 0 {
267 return Some(T::new(WORD_BITS * word_index + word.trailing_zeros() as usize));
268 }
269 word_index += 1;
270 word = *self.words.get(word_index)?;
271 }
272 }
273
274 pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
275 let (start, end) = inclusive_start_end(range, self.domain_size)?;
276 let (start_word_index, _) = word_index_and_mask(start);
277 let (end_word_index, end_mask) = word_index_and_mask(end);
278
279 let end_word = self.words[end_word_index] & (end_mask | (end_mask - 1));
280 if end_word != 0 {
281 let pos = max_bit(end_word) + WORD_BITS * end_word_index;
282 if start <= pos {
283 return Some(T::new(pos));
284 }
285 }
286
287 if let Some(offset) =
291 self.words[start_word_index..end_word_index].iter().rposition(|&w| w != 0)
292 {
293 let word_idx = start_word_index + offset;
294 let start_word = self.words[word_idx];
295 let pos = max_bit(start_word) + WORD_BITS * word_idx;
296 if start <= pos {
297 return Some(T::new(pos));
298 }
299 }
300
301 None
302 }
303
304 pub fn union_not(&mut self, other: &DenseBitSet<T>) {
306 {
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);
307
308 update_words(&mut self.words, &other.words, |a, b| a | !b);
314 self.clear_excess_bits();
317 }
318
319 pub fn union(&mut self, other: &DenseBitSet<T>) -> bool {
321 {
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);
322 update_words(&mut self.words, &other.words, |a, b| a | b)
323 }
324
325 pub fn subtract(&mut self, other: &DenseBitSet<T>) -> bool {
327 {
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);
328 update_words(&mut self.words, &other.words, |a, b| a & !b)
329 }
330
331 pub fn intersect(&mut self, other: &DenseBitSet<T>) -> bool {
333 {
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);
334 update_words(&mut self.words, &other.words, |a, b| a & b)
335 }
336}
337
338impl<T> Clone for DenseBitSet<T> {
339 fn clone(&self) -> Self {
340 DenseBitSet {
341 domain_size: self.domain_size,
342 words: self.words.clone(),
343 marker: PhantomData,
344 }
345 }
346
347 fn clone_from(&mut self, from: &Self) {
348 self.domain_size = from.domain_size;
349 self.words.clone_from(&from.words);
350 }
351}
352
353impl<T: Idx> fmt::Debug for DenseBitSet<T> {
354 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
355 w.debug_list().entries(self.iter()).finish()
356 }
357}
358
359impl<T: Idx> ToString for DenseBitSet<T> {
360 fn to_string(&self) -> String {
361 let mut result = String::new();
362 let mut sep = '[';
363
364 let mut i = 0;
368 for word in &self.words {
369 let mut word = *word;
370 for _ in 0..WORD_BYTES {
371 let remain = self.domain_size - i;
373 let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
375 if !(mask <= 0xFF) {
::core::panicking::panic("assertion failed: mask <= 0xFF")
};assert!(mask <= 0xFF);
376 let byte = word & mask;
377
378 result.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1:02x}", sep, byte))
})format!("{sep}{byte:02x}"));
379
380 if remain <= 8 {
381 break;
382 }
383 word >>= 8;
384 i += 8;
385 sep = '-';
386 }
387 sep = '|';
388 }
389 result.push(']');
390
391 result
392 }
393}
394
395pub struct BitIter<'a, T: Idx> {
396 word: Word,
400
401 offset: usize,
403
404 iter: slice::Iter<'a, Word>,
406
407 marker: PhantomData<T>,
408}
409
410impl<'a, T: Idx> BitIter<'a, T> {
411 #[inline]
412 fn new(words: &'a [Word]) -> BitIter<'a, T> {
413 BitIter {
419 word: 0,
420 offset: usize::MAX - (WORD_BITS - 1),
421 iter: words.iter(),
422 marker: PhantomData,
423 }
424 }
425}
426
427impl<'a, T: Idx> Iterator for BitIter<'a, T> {
428 type Item = T;
429 fn next(&mut self) -> Option<T> {
430 loop {
431 if self.word != 0 {
432 let bit_pos = self.word.trailing_zeros() as usize;
435 self.word ^= 1 << bit_pos;
436 return Some(T::new(bit_pos + self.offset));
437 }
438
439 self.word = *self.iter.next()?;
442 self.offset = self.offset.wrapping_add(WORD_BITS);
443 }
444 }
445}
446
447#[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)]
466pub struct ChunkedBitSet<T> {
467 domain_size: usize,
468
469 chunks: Box<[Chunk]>,
472
473 marker: PhantomData<T>,
474}
475
476#[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)]
481enum Chunk {
482 Zeros { chunk_domain_size: ChunkSize },
484
485 Ones { chunk_domain_size: ChunkSize },
487
488 Mixed {
502 chunk_domain_size: ChunkSize,
503 ones_count: ChunkSize,
510 words: Rc<[Word; CHUNK_WORDS]>,
511 },
512}
513
514#[cfg(target_pointer_width = "64")]
516const _: [(); 16] = [(); ::std::mem::size_of::<Chunk>()];crate::static_assert_size!(Chunk, 16);
517
518impl<T> ChunkedBitSet<T> {
519 pub fn domain_size(&self) -> usize {
520 self.domain_size
521 }
522
523 #[cfg(test)]
524 fn assert_valid(&self) {
525 if self.domain_size == 0 {
526 assert!(self.chunks.is_empty());
527 return;
528 }
529
530 assert!((self.chunks.len() - 1) * CHUNK_BITS <= self.domain_size);
531 assert!(self.chunks.len() * CHUNK_BITS >= self.domain_size);
532 for chunk in self.chunks.iter() {
533 chunk.assert_valid();
534 }
535 }
536}
537
538impl<T: Idx> ChunkedBitSet<T> {
539 fn new(domain_size: usize, is_empty: bool) -> Self {
541 let chunks = if domain_size == 0 {
542 Box::new([])
543 } else {
544 let num_chunks = domain_size.index().div_ceil(CHUNK_BITS);
545 let mut last_chunk_domain_size = domain_size % CHUNK_BITS;
546 if last_chunk_domain_size == 0 {
547 last_chunk_domain_size = CHUNK_BITS;
548 };
549
550 let (normal_chunk, final_chunk) = if is_empty {
553 (
554 Zeros { chunk_domain_size: CHUNK_BITS as ChunkSize },
555 Zeros { chunk_domain_size: last_chunk_domain_size as ChunkSize },
556 )
557 } else {
558 (
559 Ones { chunk_domain_size: CHUNK_BITS as ChunkSize },
560 Ones { chunk_domain_size: last_chunk_domain_size as ChunkSize },
561 )
562 };
563 let mut chunks = ::alloc::vec::from_elem(normal_chunk, num_chunks)vec![normal_chunk; num_chunks].into_boxed_slice();
564 *chunks.as_mut().last_mut().unwrap() = final_chunk;
565 chunks
566 };
567 ChunkedBitSet { domain_size, chunks, marker: PhantomData }
568 }
569
570 #[inline]
572 pub fn new_empty(domain_size: usize) -> Self {
573 ChunkedBitSet::new(domain_size, true)
574 }
575
576 #[inline]
578 pub fn new_filled(domain_size: usize) -> Self {
579 ChunkedBitSet::new(domain_size, false)
580 }
581
582 pub fn clear(&mut self) {
583 *self = ChunkedBitSet::new_empty(self.domain_size);
585 }
586
587 #[cfg(test)]
588 fn chunks(&self) -> &[Chunk] {
589 &self.chunks
590 }
591
592 pub fn count(&self) -> usize {
594 self.chunks.iter().map(|chunk| chunk.count()).sum()
595 }
596
597 pub fn is_empty(&self) -> bool {
598 self.chunks.iter().all(|chunk| #[allow(non_exhaustive_omitted_patterns)] match chunk {
Zeros { .. } => true,
_ => false,
}matches!(chunk, Zeros { .. }))
599 }
600
601 #[inline]
603 pub fn contains(&self, elem: T) -> bool {
604 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
605 let chunk = &self.chunks[chunk_index(elem)];
606 match &chunk {
607 Zeros { .. } => false,
608 Ones { .. } => true,
609 Mixed { words, .. } => {
610 let (word_index, mask) = chunk_word_index_and_mask(elem);
611 (words[word_index] & mask) != 0
612 }
613 }
614 }
615
616 #[inline]
617 pub fn iter(&self) -> ChunkedBitIter<'_, T> {
618 ChunkedBitIter::new(self)
619 }
620
621 pub fn insert(&mut self, elem: T) -> bool {
623 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
624 let chunk_index = chunk_index(elem);
625 let chunk = &mut self.chunks[chunk_index];
626 match *chunk {
627 Zeros { chunk_domain_size } => {
628 if chunk_domain_size > 1 {
629 let mut words = {
630 let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
632 unsafe { words.assume_init() }
634 };
635 let words_ref = Rc::get_mut(&mut words).unwrap();
636
637 let (word_index, mask) = chunk_word_index_and_mask(elem);
638 words_ref[word_index] |= mask;
639 *chunk = Mixed { chunk_domain_size, ones_count: 1, words };
640 } else {
641 *chunk = Ones { chunk_domain_size };
642 }
643 true
644 }
645 Ones { .. } => false,
646 Mixed { chunk_domain_size, ref mut ones_count, ref mut words } => {
647 let (word_index, mask) = chunk_word_index_and_mask(elem);
649 if (words[word_index] & mask) == 0 {
650 *ones_count += 1;
651 if *ones_count < chunk_domain_size {
652 let words = Rc::make_mut(words);
653 words[word_index] |= mask;
654 } else {
655 *chunk = Ones { chunk_domain_size };
656 }
657 true
658 } else {
659 false
660 }
661 }
662 }
663 }
664
665 pub fn insert_all(&mut self) {
667 *self = ChunkedBitSet::new_filled(self.domain_size);
669 }
670
671 pub fn remove(&mut self, elem: T) -> bool {
673 if !(elem.index() < self.domain_size) {
::core::panicking::panic("assertion failed: elem.index() < self.domain_size")
};assert!(elem.index() < self.domain_size);
674 let chunk_index = chunk_index(elem);
675 let chunk = &mut self.chunks[chunk_index];
676 match *chunk {
677 Zeros { .. } => false,
678 Ones { chunk_domain_size } => {
679 if chunk_domain_size > 1 {
680 let mut words = {
681 let words = Rc::<[Word; CHUNK_WORDS]>::new_zeroed();
683 unsafe { words.assume_init() }
685 };
686 let words_ref = Rc::get_mut(&mut words).unwrap();
687
688 let num_words = num_words(chunk_domain_size as usize);
690 words_ref[..num_words].fill(!0);
691 clear_excess_bits_in_final_word(
692 chunk_domain_size as usize,
693 &mut words_ref[..num_words],
694 );
695 let (word_index, mask) = chunk_word_index_and_mask(elem);
696 words_ref[word_index] &= !mask;
697 *chunk = Mixed { chunk_domain_size, ones_count: chunk_domain_size - 1, words };
698 } else {
699 *chunk = Zeros { chunk_domain_size };
700 }
701 true
702 }
703 Mixed { chunk_domain_size, ref mut ones_count, ref mut words } => {
704 let (word_index, mask) = chunk_word_index_and_mask(elem);
706 if (words[word_index] & mask) != 0 {
707 *ones_count -= 1;
708 if *ones_count > 0 {
709 let words = Rc::make_mut(words);
710 words[word_index] &= !mask;
711 } else {
712 *chunk = Zeros { chunk_domain_size }
713 }
714 true
715 } else {
716 false
717 }
718 }
719 }
720 }
721
722 fn chunk_iter(&self, chunk_index: usize) -> ChunkIter<'_> {
723 match self.chunks.get(chunk_index) {
724 Some(Zeros { .. }) => ChunkIter::Zeros,
725 Some(Ones { chunk_domain_size }) => ChunkIter::Ones(0..*chunk_domain_size as usize),
726 Some(Mixed { chunk_domain_size, words, .. }) => {
727 let num_words = num_words(*chunk_domain_size as usize);
728 ChunkIter::Mixed(BitIter::new(&words[0..num_words]))
729 }
730 None => ChunkIter::Finished,
731 }
732 }
733
734 fn union(&mut self, other: &ChunkedBitSet<T>) -> bool {
736 {
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);
737
738 let mut changed = false;
739 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
740 match (&mut self_chunk, &other_chunk) {
741 (_, Zeros { .. }) | (Ones { .. }, _) => {}
742 (Zeros { .. }, _) | (Mixed { .. }, Ones { .. }) => {
743 *self_chunk = other_chunk.clone();
745 changed = true;
746 }
747 (
748 Mixed {
749 chunk_domain_size,
750 ones_count: self_chunk_ones_count,
751 words: self_chunk_words,
752 },
753 Mixed { words: other_chunk_words, .. },
754 ) => {
755 let num_words = num_words(*chunk_domain_size as usize);
761
762 if self_chunk_words[0..num_words] == other_chunk_words[0..num_words] {
766 continue;
767 }
768
769 let op = |a, b| a | b;
772 if !would_modify_words(
773 &self_chunk_words[0..num_words],
774 &other_chunk_words[0..num_words],
775 op,
776 ) {
777 continue;
778 }
779
780 let self_chunk_words = Rc::make_mut(self_chunk_words);
782 let has_changed = update_words(
783 &mut self_chunk_words[0..num_words],
784 &other_chunk_words[0..num_words],
785 op,
786 );
787 if true {
if !has_changed {
::core::panicking::panic("assertion failed: has_changed")
};
};debug_assert!(has_changed);
788 *self_chunk_ones_count =
789 count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
790 if *self_chunk_ones_count == *chunk_domain_size {
791 *self_chunk = Ones { chunk_domain_size: *chunk_domain_size };
792 }
793 changed = true;
794 }
795 }
796 }
797 changed
798 }
799
800 fn subtract(&mut self, other: &ChunkedBitSet<T>) -> bool {
802 {
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);
803
804 let mut changed = false;
805 for (mut self_chunk, other_chunk) in self.chunks.iter_mut().zip(other.chunks.iter()) {
806 match (&mut self_chunk, &other_chunk) {
807 (Zeros { .. }, _) | (_, Zeros { .. }) => {}
808 (Ones { chunk_domain_size } | Mixed { chunk_domain_size, .. }, Ones { .. }) => {
809 changed = true;
810 *self_chunk = Zeros { chunk_domain_size: *chunk_domain_size };
811 }
812 (
813 Ones { chunk_domain_size },
814 Mixed { ones_count: other_chunk_ones_count, words: other_chunk_words, .. },
815 ) => {
816 changed = true;
817 let num_words = num_words(*chunk_domain_size as usize);
818 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);
819 let mut self_chunk_words = **other_chunk_words;
822 for word in self_chunk_words[0..num_words].iter_mut() {
823 *word = !*word;
824 }
825 clear_excess_bits_in_final_word(
826 *chunk_domain_size as usize,
827 &mut self_chunk_words[..num_words],
828 );
829 let self_chunk_ones_count = *chunk_domain_size - *other_chunk_ones_count;
830 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!(
831 self_chunk_ones_count,
832 count_ones(&self_chunk_words[0..num_words]) as ChunkSize
833 );
834 *self_chunk = Mixed {
835 chunk_domain_size: *chunk_domain_size,
836 ones_count: self_chunk_ones_count,
837 words: Rc::new(self_chunk_words),
838 };
839 }
840 (
841 Mixed {
842 chunk_domain_size,
843 ones_count: self_chunk_ones_count,
844 words: self_chunk_words,
845 },
846 Mixed { words: other_chunk_words, .. },
847 ) => {
848 let num_words = num_words(*chunk_domain_size as usize);
850 let op = |a: Word, b: Word| a & !b;
851 if !would_modify_words(
852 &self_chunk_words[0..num_words],
853 &other_chunk_words[0..num_words],
854 op,
855 ) {
856 continue;
857 }
858
859 let self_chunk_words = Rc::make_mut(self_chunk_words);
860 let has_changed = update_words(
861 &mut self_chunk_words[0..num_words],
862 &other_chunk_words[0..num_words],
863 op,
864 );
865 if true {
if !has_changed {
::core::panicking::panic("assertion failed: has_changed")
};
};debug_assert!(has_changed);
866 *self_chunk_ones_count =
867 count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
868 if *self_chunk_ones_count == 0 {
869 *self_chunk = Zeros { chunk_domain_size: *chunk_domain_size };
870 }
871 changed = true;
872 }
873 }
874 }
875 changed
876 }
877}
878
879impl<T> Clone for ChunkedBitSet<T> {
880 fn clone(&self) -> Self {
881 ChunkedBitSet {
882 domain_size: self.domain_size,
883 chunks: self.chunks.clone(),
884 marker: PhantomData,
885 }
886 }
887
888 fn clone_from(&mut self, from: &Self) {
893 {
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);
894 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());
895
896 self.chunks.clone_from(&from.chunks)
897 }
898}
899
900pub struct ChunkedBitIter<'a, T: Idx> {
901 bit_set: &'a ChunkedBitSet<T>,
902
903 chunk_index: usize,
905
906 chunk_iter: ChunkIter<'a>,
908}
909
910impl<'a, T: Idx> ChunkedBitIter<'a, T> {
911 #[inline]
912 fn new(bit_set: &'a ChunkedBitSet<T>) -> ChunkedBitIter<'a, T> {
913 ChunkedBitIter { bit_set, chunk_index: 0, chunk_iter: bit_set.chunk_iter(0) }
914 }
915}
916
917impl<'a, T: Idx> Iterator for ChunkedBitIter<'a, T> {
918 type Item = T;
919
920 fn next(&mut self) -> Option<T> {
921 loop {
922 match &mut self.chunk_iter {
923 ChunkIter::Zeros => {}
924 ChunkIter::Ones(iter) => {
925 if let Some(next) = iter.next() {
926 return Some(T::new(next + self.chunk_index * CHUNK_BITS));
927 }
928 }
929 ChunkIter::Mixed(iter) => {
930 if let Some(next) = iter.next() {
931 return Some(T::new(next + self.chunk_index * CHUNK_BITS));
932 }
933 }
934 ChunkIter::Finished => return None,
935 }
936 self.chunk_index += 1;
937 self.chunk_iter = self.bit_set.chunk_iter(self.chunk_index);
938 }
939 }
940}
941
942impl Chunk {
943 #[cfg(test)]
944 fn assert_valid(&self) {
945 match *self {
946 Zeros { chunk_domain_size } | Ones { chunk_domain_size } => {
947 assert!(chunk_domain_size as usize <= CHUNK_BITS);
948 }
949 Mixed { chunk_domain_size, ones_count, ref words } => {
950 assert!(chunk_domain_size as usize <= CHUNK_BITS);
951 assert!(0 < ones_count && ones_count < chunk_domain_size);
952
953 assert_eq!(count_ones(words.as_slice()) as ChunkSize, ones_count);
955
956 let num_words = num_words(chunk_domain_size as usize);
958 if num_words < CHUNK_WORDS {
959 assert_eq!(count_ones(&words[num_words..]) as ChunkSize, 0);
960 }
961 }
962 }
963 }
964
965 fn count(&self) -> usize {
967 match *self {
968 Zeros { .. } => 0,
969 Ones { chunk_domain_size } => chunk_domain_size as usize,
970 Mixed { ones_count, .. } => usize::from(ones_count),
971 }
972 }
973}
974
975enum ChunkIter<'a> {
976 Zeros,
977 Ones(Range<usize>),
978 Mixed(BitIter<'a, usize>),
979 Finished,
980}
981
982impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
983 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
984 w.debug_list().entries(self.iter()).finish()
985 }
986}
987
988#[inline]
1001fn update_words<Op>(lhs: &mut [Word], rhs: &[Word], op: Op) -> bool
1002where
1003 Op: Fn(Word, Word) -> Word,
1004{
1005 {
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());
1006 let mut changed = 0;
1007 for (lhs_slot, &rhs_val) in iter::zip(lhs, rhs) {
1008 let old_val = *lhs_slot;
1009 let new_val = op(old_val, rhs_val);
1010 *lhs_slot = new_val;
1011 changed |= old_val ^ new_val;
1016 }
1017 changed != 0
1018}
1019
1020#[inline]
1023fn would_modify_words<Op>(lhs: &[Word], rhs: &[Word], op: Op) -> bool
1024where
1025 Op: Fn(Word, Word) -> Word,
1026{
1027 {
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());
1028
1029 const SUBCHUNK_LEN: usize = 64 / size_of::<Word>();
1034 let (lhs_chunks, lhs_tail) = lhs.as_chunks::<SUBCHUNK_LEN>();
1035 let (rhs_chunks, rhs_tail) = rhs.as_chunks::<SUBCHUNK_LEN>();
1036
1037 let would_modify_subchunk = |lhs_chunk: &[Word], rhs_chunk: &[Word]| {
1038 let mut changed = 0;
1039 for (&old_val, &rhs_val) in iter::zip(lhs_chunk, rhs_chunk) {
1040 let new_val = op(old_val, rhs_val);
1041 changed |= old_val ^ new_val;
1044 }
1045 changed != 0
1046 };
1047
1048 for (lhs_chunk, rhs_chunk) in iter::zip(lhs_chunks, rhs_chunks) {
1049 if would_modify_subchunk(lhs_chunk, rhs_chunk) {
1050 return true;
1051 }
1052 }
1053 would_modify_subchunk(lhs_tail, rhs_tail)
1054}
1055
1056#[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)]
1068pub enum MixedBitSet<T> {
1069 Small(DenseBitSet<T>),
1070 Large(ChunkedBitSet<T>),
1071}
1072
1073impl<T> MixedBitSet<T> {
1074 pub fn domain_size(&self) -> usize {
1075 match self {
1076 MixedBitSet::Small(set) => set.domain_size(),
1077 MixedBitSet::Large(set) => set.domain_size(),
1078 }
1079 }
1080}
1081
1082impl<T: Idx> MixedBitSet<T> {
1083 #[inline]
1084 pub fn new_empty(domain_size: usize) -> MixedBitSet<T> {
1085 if domain_size <= CHUNK_BITS {
1086 MixedBitSet::Small(DenseBitSet::new_empty(domain_size))
1087 } else {
1088 MixedBitSet::Large(ChunkedBitSet::new_empty(domain_size))
1089 }
1090 }
1091
1092 #[inline]
1093 pub fn is_empty(&self) -> bool {
1094 match self {
1095 MixedBitSet::Small(set) => set.is_empty(),
1096 MixedBitSet::Large(set) => set.is_empty(),
1097 }
1098 }
1099
1100 #[inline]
1101 pub fn contains(&self, elem: T) -> bool {
1102 match self {
1103 MixedBitSet::Small(set) => set.contains(elem),
1104 MixedBitSet::Large(set) => set.contains(elem),
1105 }
1106 }
1107
1108 #[inline]
1109 pub fn insert(&mut self, elem: T) -> bool {
1110 match self {
1111 MixedBitSet::Small(set) => set.insert(elem),
1112 MixedBitSet::Large(set) => set.insert(elem),
1113 }
1114 }
1115
1116 pub fn insert_all(&mut self) {
1117 match self {
1118 MixedBitSet::Small(set) => set.insert_all(),
1119 MixedBitSet::Large(set) => set.insert_all(),
1120 }
1121 }
1122
1123 #[inline]
1124 pub fn remove(&mut self, elem: T) -> bool {
1125 match self {
1126 MixedBitSet::Small(set) => set.remove(elem),
1127 MixedBitSet::Large(set) => set.remove(elem),
1128 }
1129 }
1130
1131 pub fn iter(&self) -> MixedBitIter<'_, T> {
1132 match self {
1133 MixedBitSet::Small(set) => MixedBitIter::Small(set.iter()),
1134 MixedBitSet::Large(set) => MixedBitIter::Large(set.iter()),
1135 }
1136 }
1137
1138 #[inline]
1139 pub fn clear(&mut self) {
1140 match self {
1141 MixedBitSet::Small(set) => set.clear(),
1142 MixedBitSet::Large(set) => set.clear(),
1143 }
1144 }
1145
1146 pub fn union(&mut self, other: &MixedBitSet<T>) -> bool {
1148 match (self, other) {
1149 (MixedBitSet::Small(set), MixedBitSet::Small(other)) => set.union(other),
1150 (MixedBitSet::Large(set), MixedBitSet::Large(other)) => set.union(other),
1151 _ => { ::core::panicking::panic_fmt(format_args!("MixedBitSet size mismatch")); }panic!("MixedBitSet size mismatch"),
1152 }
1153 }
1154
1155 pub fn subtract(&mut self, other: &MixedBitSet<T>) -> bool {
1157 match (self, other) {
1158 (MixedBitSet::Small(set), MixedBitSet::Small(other)) => set.subtract(other),
1159 (MixedBitSet::Large(set), MixedBitSet::Large(other)) => set.subtract(other),
1160 _ => { ::core::panicking::panic_fmt(format_args!("MixedBitSet size mismatch")); }panic!("MixedBitSet size mismatch"),
1161 }
1162 }
1163}
1164
1165impl<T> Clone for MixedBitSet<T> {
1166 fn clone(&self) -> Self {
1167 match self {
1168 MixedBitSet::Small(set) => MixedBitSet::Small(set.clone()),
1169 MixedBitSet::Large(set) => MixedBitSet::Large(set.clone()),
1170 }
1171 }
1172
1173 fn clone_from(&mut self, from: &Self) {
1178 match (self, from) {
1179 (MixedBitSet::Small(set), MixedBitSet::Small(from)) => set.clone_from(from),
1180 (MixedBitSet::Large(set), MixedBitSet::Large(from)) => set.clone_from(from),
1181 _ => { ::core::panicking::panic_fmt(format_args!("MixedBitSet size mismatch")); }panic!("MixedBitSet size mismatch"),
1182 }
1183 }
1184}
1185
1186impl<T: Idx> fmt::Debug for MixedBitSet<T> {
1187 fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
1188 match self {
1189 MixedBitSet::Small(set) => set.fmt(w),
1190 MixedBitSet::Large(set) => set.fmt(w),
1191 }
1192 }
1193}
1194
1195pub enum MixedBitIter<'a, T: Idx> {
1196 Small(BitIter<'a, T>),
1197 Large(ChunkedBitIter<'a, T>),
1198}
1199
1200impl<'a, T: Idx> Iterator for MixedBitIter<'a, T> {
1201 type Item = T;
1202 fn next(&mut self) -> Option<T> {
1203 match self {
1204 MixedBitIter::Small(iter) => iter.next(),
1205 MixedBitIter::Large(iter) => iter.next(),
1206 }
1207 }
1208}
1209
1210#[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_field2_finish(f,
"GrowableBitSet", "words", &self.words, "marker", &&self.marker)
}
}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.words == other.words && self.marker == other.marker
}
}PartialEq)]
1215pub struct GrowableBitSet<T: Idx> {
1216 words: Vec<Word>,
1217 marker: PhantomData<T>,
1218}
1219
1220impl<T: Idx> Clone for GrowableBitSet<T> {
1222 fn clone(&self) -> Self {
1223 let &GrowableBitSet { ref words, marker } = self;
1224 GrowableBitSet { words: words.clone(), marker }
1225 }
1226
1227 fn clone_from(&mut self, source: &Self) {
1228 let GrowableBitSet { words, marker } = source;
1229 self.words.clone_from(words);
1230 self.marker.clone_from(marker);
1231 }
1232}
1233
1234impl<T: Idx> Default for GrowableBitSet<T> {
1235 fn default() -> Self {
1236 GrowableBitSet::new_empty()
1237 }
1238}
1239
1240impl<T: Idx> GrowableBitSet<T> {
1241 fn ensure(&mut self, min_num_bits: usize) {
1243 let min_num_words = num_words(min_num_bits);
1244 self.ensure_words(min_num_words);
1245 }
1246
1247 fn ensure_words(&mut self, min_num_words: usize) {
1249 if self.words.len() < min_num_words {
1250 self.words.resize(min_num_words, 0)
1251 }
1252 }
1253
1254 pub fn new_empty() -> GrowableBitSet<T> {
1255 GrowableBitSet { words: ::alloc::vec::Vec::new()vec![], marker: PhantomData }
1256 }
1257
1258 pub fn with_capacity(capacity: usize) -> GrowableBitSet<T> {
1259 GrowableBitSet { words: Vec::with_capacity(num_words(capacity)), marker: PhantomData }
1260 }
1261
1262 #[inline]
1264 pub fn insert(&mut self, value: T) -> bool {
1265 self.ensure(value.index() + 1);
1266 insert(&mut self.words, value)
1267 }
1268
1269 #[inline]
1270 pub fn count(&self) -> usize {
1271 count_ones(&self.words)
1272 }
1273
1274 #[inline]
1275 pub fn is_empty(&self) -> bool {
1276 self.words.iter().all(|&w| w == 0)
1277 }
1278
1279 #[inline]
1280 pub fn contains(&self, elem: T) -> bool {
1281 let (word_index, mask) = word_index_and_mask(elem);
1282 self.words.get(word_index).is_some_and(|word| (word & mask) != 0)
1283 }
1284
1285 #[inline]
1286 pub fn iter(&self) -> BitIter<'_, T> {
1287 BitIter::new(&self.words)
1288 }
1289
1290 #[inline]
1292 pub fn union(&mut self, other: &GrowableBitSet<T>) {
1293 self.ensure_words(other.words.len());
1297 update_words(&mut self.words[..other.words.len()], &other.words, |a, b| a | b);
1298 }
1299}
1300
1301#[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))]
1309#[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)]
1310pub struct BitMatrix<R: Idx, C: Idx> {
1311 num_rows: usize,
1312 num_columns: usize,
1313 words: Vec<Word>,
1314 marker: PhantomData<(R, C)>,
1315}
1316
1317impl<R: Idx, C: Idx> BitMatrix<R, C> {
1318 pub fn new(num_rows: usize, num_columns: usize) -> BitMatrix<R, C> {
1320 let words_per_row = num_words(num_columns);
1323 BitMatrix {
1324 num_rows,
1325 num_columns,
1326 words: ::alloc::vec::from_elem(0, num_rows * words_per_row)vec![0; num_rows * words_per_row],
1327 marker: PhantomData,
1328 }
1329 }
1330
1331 pub fn from_row_n(row: &DenseBitSet<C>, num_rows: usize) -> BitMatrix<R, C> {
1333 let num_columns = row.domain_size();
1334 let words_per_row = num_words(num_columns);
1335 {
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());
1336 BitMatrix {
1337 num_rows,
1338 num_columns,
1339 words: iter::repeat_n(&row.words, num_rows).flatten().cloned().collect(),
1340 marker: PhantomData,
1341 }
1342 }
1343
1344 pub fn rows(&self) -> impl Iterator<Item = R> {
1345 (0..self.num_rows).map(R::new)
1346 }
1347
1348 fn range(&self, row: R) -> (usize, usize) {
1350 let words_per_row = num_words(self.num_columns);
1351 let start = row.index() * words_per_row;
1352 (start, start + words_per_row)
1353 }
1354
1355 pub fn insert(&mut self, row: R, column: C) -> bool {
1360 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);
1361 let (start, _) = self.range(row);
1362 let (word_index, mask) = word_index_and_mask(column);
1363 let words = &mut self.words[..];
1364 let word = words[start + word_index];
1365 let new_word = word | mask;
1366 words[start + word_index] = new_word;
1367 word != new_word
1368 }
1369
1370 pub fn contains(&self, row: R, column: C) -> bool {
1375 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);
1376 let (start, _) = self.range(row);
1377 let (word_index, mask) = word_index_and_mask(column);
1378 (self.words[start + word_index] & mask) != 0
1379 }
1380
1381 pub fn intersect_rows(&self, row1: R, row2: R) -> Vec<C> {
1386 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);
1387 let (row1_start, row1_end) = self.range(row1);
1388 let (row2_start, row2_end) = self.range(row2);
1389 let mut result = Vec::with_capacity(self.num_columns);
1390 for (base, (i, j)) in (row1_start..row1_end).zip(row2_start..row2_end).enumerate() {
1391 let mut v = self.words[i] & self.words[j];
1392 for bit in 0..WORD_BITS {
1393 if v == 0 {
1394 break;
1395 }
1396 if v & 0x1 != 0 {
1397 result.push(C::new(base * WORD_BITS + bit));
1398 }
1399 v >>= 1;
1400 }
1401 }
1402 result
1403 }
1404
1405 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1413 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);
1414 let (read_start, read_end) = self.range(read);
1415 let (write_start, write_end) = self.range(write);
1416 let words = &mut self.words[..];
1417 let mut changed = 0;
1418 for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) {
1419 let word = words[write_index];
1420 let new_word = word | words[read_index];
1421 words[write_index] = new_word;
1422 changed |= word ^ new_word;
1424 }
1425 changed != 0
1426 }
1427
1428 pub fn union_row_with(&mut self, with: &DenseBitSet<C>, write: R) -> bool {
1431 if !(write.index() < self.num_rows) {
::core::panicking::panic("assertion failed: write.index() < self.num_rows")
};assert!(write.index() < self.num_rows);
1432 {
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);
1433 let (write_start, write_end) = self.range(write);
1434 update_words(&mut self.words[write_start..write_end], &with.words, |a, b| a | b)
1435 }
1436
1437 pub fn insert_all_into_row(&mut self, row: R) {
1439 if !(row.index() < self.num_rows) {
::core::panicking::panic("assertion failed: row.index() < self.num_rows")
};assert!(row.index() < self.num_rows);
1440 let (start, end) = self.range(row);
1441 let words = &mut self.words[..];
1442 for index in start..end {
1443 words[index] = !0;
1444 }
1445 clear_excess_bits_in_final_word(self.num_columns, &mut self.words[..end]);
1446 }
1447
1448 pub fn words(&self) -> &[Word] {
1450 &self.words
1451 }
1452
1453 pub fn iter(&self, row: R) -> BitIter<'_, C> {
1456 if !(row.index() < self.num_rows) {
::core::panicking::panic("assertion failed: row.index() < self.num_rows")
};assert!(row.index() < self.num_rows);
1457 let (start, end) = self.range(row);
1458 BitIter::new(&self.words[start..end])
1459 }
1460
1461 pub fn count(&self, row: R) -> usize {
1463 let (start, end) = self.range(row);
1464 count_ones(&self.words[start..end])
1465 }
1466}
1467
1468impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
1469 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1470 struct OneLinePrinter<T>(T);
1472 impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
1473 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1474 fmt.write_fmt(format_args!("{0:?}", self.0))write!(fmt, "{:?}", self.0)
1475 }
1476 }
1477
1478 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)?;
1479 let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
1480 fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
1481 }
1482}
1483
1484#[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)]
1496pub struct SparseBitMatrix<R, C>
1497where
1498 R: Idx,
1499 C: Idx,
1500{
1501 num_columns: usize,
1502 rows: IndexVec<R, Option<DenseBitSet<C>>>,
1503}
1504
1505impl<R: Idx, C: Idx> SparseBitMatrix<R, C> {
1506 pub fn new(num_columns: usize) -> Self {
1508 Self { num_columns, rows: IndexVec::new() }
1509 }
1510
1511 fn ensure_row(&mut self, row: R) -> &mut DenseBitSet<C> {
1512 self.rows.get_or_insert_with(row, || DenseBitSet::new_empty(self.num_columns))
1515 }
1516
1517 pub fn insert(&mut self, row: R, column: C) -> bool {
1522 self.ensure_row(row).insert(column)
1523 }
1524
1525 pub fn remove(&mut self, row: R, column: C) -> bool {
1531 match self.rows.get_mut(row) {
1532 Some(Some(row)) => row.remove(column),
1533 _ => false,
1534 }
1535 }
1536
1537 pub fn clear(&mut self, row: R) {
1540 if let Some(Some(row)) = self.rows.get_mut(row) {
1541 row.clear();
1542 }
1543 }
1544
1545 pub fn contains(&self, row: R, column: C) -> bool {
1550 self.row(row).is_some_and(|r| r.contains(column))
1551 }
1552
1553 pub fn union_rows(&mut self, read: R, write: R) -> bool {
1561 if read == write || self.row(read).is_none() {
1562 return false;
1563 }
1564
1565 self.ensure_row(write);
1566 if let (Some(read_row), Some(write_row)) = self.rows.pick2_mut(read, write) {
1567 write_row.union(read_row)
1568 } else {
1569 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
1570 }
1571 }
1572
1573 pub fn insert_all_into_row(&mut self, row: R) {
1575 self.ensure_row(row).insert_all();
1576 }
1577
1578 pub fn rows(&self) -> impl Iterator<Item = R> {
1579 self.rows.indices()
1580 }
1581
1582 pub fn iter(&self, row: R) -> impl Iterator<Item = C> {
1585 self.row(row).into_iter().flat_map(|r| r.iter())
1586 }
1587
1588 pub fn row(&self, row: R) -> Option<&DenseBitSet<C>> {
1589 self.rows.get(row)?.as_ref()
1590 }
1591}
1592
1593#[inline]
1594fn num_words<T: Idx>(domain_size: T) -> usize {
1595 domain_size.index().div_ceil(WORD_BITS)
1596}
1597
1598#[inline]
1599fn word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1600 let elem = elem.index();
1601 let word_index = elem / WORD_BITS;
1602 let mask = 1 << (elem % WORD_BITS);
1603 (word_index, mask)
1604}
1605
1606#[inline]
1607fn chunk_index<T: Idx>(elem: T) -> usize {
1608 elem.index() / CHUNK_BITS
1609}
1610
1611#[inline]
1612fn chunk_word_index_and_mask<T: Idx>(elem: T) -> (usize, Word) {
1613 let chunk_elem = elem.index() % CHUNK_BITS;
1614 word_index_and_mask(chunk_elem)
1615}
1616
1617fn clear_excess_bits_in_final_word(domain_size: usize, words: &mut [Word]) {
1618 let num_bits_in_final_word = domain_size % WORD_BITS;
1619 if num_bits_in_final_word > 0 {
1620 let mask = (1 << num_bits_in_final_word) - 1;
1621 words[words.len() - 1] &= mask;
1622 }
1623}
1624
1625#[inline]
1626fn max_bit(word: Word) -> usize {
1627 WORD_BITS - 1 - word.leading_zeros() as usize
1628}
1629
1630#[inline]
1631fn count_ones(words: &[Word]) -> usize {
1632 words.iter().map(|word| word.count_ones() as usize).sum()
1633}
1634
1635#[inline]
1636fn insert<T: Idx>(words: &mut [Word], value: T) -> bool {
1637 let (word_index, mask) = word_index_and_mask(value);
1638 let word_ref = &mut words[word_index];
1639 let word = *word_ref;
1640 let new_word = word | mask;
1641 *word_ref = new_word;
1642 new_word != word
1643}