Skip to content

Commit dff5ce6

Browse files
committed
Move some BitSet code blocks to a better place.
These blocks are currently interleaved with `ChunkedBitSet` blocks. It makes things hard to find and has annoyed me for a while.
1 parent acabb52 commit dff5ce6

File tree

1 file changed

+105
-105
lines changed

1 file changed

+105
-105
lines changed

Diff for: compiler/rustc_index/src/bit_set.rs

+105-105
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,111 @@ impl<T: Idx> From<GrowableBitSet<T>> for BitSet<T> {
296296
}
297297
}
298298

299+
impl<T> Clone for BitSet<T> {
300+
fn clone(&self) -> Self {
301+
BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData }
302+
}
303+
304+
fn clone_from(&mut self, from: &Self) {
305+
self.domain_size = from.domain_size;
306+
self.words.clone_from(&from.words);
307+
}
308+
}
309+
310+
impl<T: Idx> fmt::Debug for BitSet<T> {
311+
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
312+
w.debug_list().entries(self.iter()).finish()
313+
}
314+
}
315+
316+
impl<T: Idx> ToString for BitSet<T> {
317+
fn to_string(&self) -> String {
318+
let mut result = String::new();
319+
let mut sep = '[';
320+
321+
// Note: this is a little endian printout of bytes.
322+
323+
// i tracks how many bits we have printed so far.
324+
let mut i = 0;
325+
for word in &self.words {
326+
let mut word = *word;
327+
for _ in 0..WORD_BYTES {
328+
// for each byte in `word`:
329+
let remain = self.domain_size - i;
330+
// If less than a byte remains, then mask just that many bits.
331+
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
332+
assert!(mask <= 0xFF);
333+
let byte = word & mask;
334+
335+
result.push_str(&format!("{sep}{byte:02x}"));
336+
337+
if remain <= 8 {
338+
break;
339+
}
340+
word >>= 8;
341+
i += 8;
342+
sep = '-';
343+
}
344+
sep = '|';
345+
}
346+
result.push(']');
347+
348+
result
349+
}
350+
}
351+
352+
pub struct BitIter<'a, T: Idx> {
353+
/// A copy of the current word, but with any already-visited bits cleared.
354+
/// (This lets us use `trailing_zeros()` to find the next set bit.) When it
355+
/// is reduced to 0, we move onto the next word.
356+
word: Word,
357+
358+
/// The offset (measured in bits) of the current word.
359+
offset: usize,
360+
361+
/// Underlying iterator over the words.
362+
iter: slice::Iter<'a, Word>,
363+
364+
marker: PhantomData<T>,
365+
}
366+
367+
impl<'a, T: Idx> BitIter<'a, T> {
368+
#[inline]
369+
fn new(words: &'a [Word]) -> BitIter<'a, T> {
370+
// We initialize `word` and `offset` to degenerate values. On the first
371+
// call to `next()` we will fall through to getting the first word from
372+
// `iter`, which sets `word` to the first word (if there is one) and
373+
// `offset` to 0. Doing it this way saves us from having to maintain
374+
// additional state about whether we have started.
375+
BitIter {
376+
word: 0,
377+
offset: usize::MAX - (WORD_BITS - 1),
378+
iter: words.iter(),
379+
marker: PhantomData,
380+
}
381+
}
382+
}
383+
384+
impl<'a, T: Idx> Iterator for BitIter<'a, T> {
385+
type Item = T;
386+
fn next(&mut self) -> Option<T> {
387+
loop {
388+
if self.word != 0 {
389+
// Get the position of the next set bit in the current word,
390+
// then clear the bit.
391+
let bit_pos = self.word.trailing_zeros() as usize;
392+
self.word ^= 1 << bit_pos;
393+
return Some(T::new(bit_pos + self.offset));
394+
}
395+
396+
// Move onto the next word. `wrapping_add()` is needed to handle
397+
// the degenerate initial value given to `offset` in `new()`.
398+
self.word = *self.iter.next()?;
399+
self.offset = self.offset.wrapping_add(WORD_BITS);
400+
}
401+
}
402+
}
403+
299404
/// A fixed-size bitset type with a partially dense, partially sparse
300405
/// representation. The bitset is broken into chunks, and chunks that are all
301406
/// zeros or all ones are represented and handled very efficiently.
@@ -958,117 +1063,12 @@ fn sequential_update<T: Idx>(
9581063
it.fold(false, |changed, elem| self_update(elem) | changed)
9591064
}
9601065

961-
impl<T> Clone for BitSet<T> {
962-
fn clone(&self) -> Self {
963-
BitSet { domain_size: self.domain_size, words: self.words.clone(), marker: PhantomData }
964-
}
965-
966-
fn clone_from(&mut self, from: &Self) {
967-
self.domain_size = from.domain_size;
968-
self.words.clone_from(&from.words);
969-
}
970-
}
971-
972-
impl<T: Idx> fmt::Debug for BitSet<T> {
973-
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
974-
w.debug_list().entries(self.iter()).finish()
975-
}
976-
}
977-
9781066
impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
9791067
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
9801068
w.debug_list().entries(self.iter()).finish()
9811069
}
9821070
}
9831071

984-
impl<T: Idx> ToString for BitSet<T> {
985-
fn to_string(&self) -> String {
986-
let mut result = String::new();
987-
let mut sep = '[';
988-
989-
// Note: this is a little endian printout of bytes.
990-
991-
// i tracks how many bits we have printed so far.
992-
let mut i = 0;
993-
for word in &self.words {
994-
let mut word = *word;
995-
for _ in 0..WORD_BYTES {
996-
// for each byte in `word`:
997-
let remain = self.domain_size - i;
998-
// If less than a byte remains, then mask just that many bits.
999-
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
1000-
assert!(mask <= 0xFF);
1001-
let byte = word & mask;
1002-
1003-
result.push_str(&format!("{sep}{byte:02x}"));
1004-
1005-
if remain <= 8 {
1006-
break;
1007-
}
1008-
word >>= 8;
1009-
i += 8;
1010-
sep = '-';
1011-
}
1012-
sep = '|';
1013-
}
1014-
result.push(']');
1015-
1016-
result
1017-
}
1018-
}
1019-
1020-
pub struct BitIter<'a, T: Idx> {
1021-
/// A copy of the current word, but with any already-visited bits cleared.
1022-
/// (This lets us use `trailing_zeros()` to find the next set bit.) When it
1023-
/// is reduced to 0, we move onto the next word.
1024-
word: Word,
1025-
1026-
/// The offset (measured in bits) of the current word.
1027-
offset: usize,
1028-
1029-
/// Underlying iterator over the words.
1030-
iter: slice::Iter<'a, Word>,
1031-
1032-
marker: PhantomData<T>,
1033-
}
1034-
1035-
impl<'a, T: Idx> BitIter<'a, T> {
1036-
#[inline]
1037-
fn new(words: &'a [Word]) -> BitIter<'a, T> {
1038-
// We initialize `word` and `offset` to degenerate values. On the first
1039-
// call to `next()` we will fall through to getting the first word from
1040-
// `iter`, which sets `word` to the first word (if there is one) and
1041-
// `offset` to 0. Doing it this way saves us from having to maintain
1042-
// additional state about whether we have started.
1043-
BitIter {
1044-
word: 0,
1045-
offset: usize::MAX - (WORD_BITS - 1),
1046-
iter: words.iter(),
1047-
marker: PhantomData,
1048-
}
1049-
}
1050-
}
1051-
1052-
impl<'a, T: Idx> Iterator for BitIter<'a, T> {
1053-
type Item = T;
1054-
fn next(&mut self) -> Option<T> {
1055-
loop {
1056-
if self.word != 0 {
1057-
// Get the position of the next set bit in the current word,
1058-
// then clear the bit.
1059-
let bit_pos = self.word.trailing_zeros() as usize;
1060-
self.word ^= 1 << bit_pos;
1061-
return Some(T::new(bit_pos + self.offset));
1062-
}
1063-
1064-
// Move onto the next word. `wrapping_add()` is needed to handle
1065-
// the degenerate initial value given to `offset` in `new()`.
1066-
self.word = *self.iter.next()?;
1067-
self.offset = self.offset.wrapping_add(WORD_BITS);
1068-
}
1069-
}
1070-
}
1071-
10721072
#[inline]
10731073
fn bitwise<Op>(out_vec: &mut [Word], in_vec: &[Word], op: Op) -> bool
10741074
where

0 commit comments

Comments
 (0)