]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_data_structures/indexed_set.rs
Remove bitslice.rs.
[rust.git] / src / librustc_data_structures / indexed_set.rs
index 65fdf10a86d13f7d6fa1897a7bbe9a40f9adea62..be519e7bbdeb7485d53958596af007da5cbb3302 100644 (file)
 
 use array_vec::ArrayVec;
 use std::fmt;
-use std::iter;
-use std::marker::PhantomData;
 use std::mem;
 use std::slice;
-use bitslice::{BitSlice, Word};
-use bitslice::{bitwise, Union, Subtract, Intersect};
+use bitvec::{bitwise, BitArray, BitIter, Intersect, Subtract, Union, Word, WORD_BITS};
 use indexed_vec::Idx;
 use rustc_serialize;
 
@@ -40,39 +37,21 @@ pub trait SubtractFromIdxSet<T: Idx> {
 /// this type uses to represent the set of object it holds.
 ///
 /// The representation is dense, using one bit per possible element.
-#[derive(Eq, PartialEq)]
-pub struct IdxSet<T: Idx> {
-    _pd: PhantomData<fn(&T)>,
-    bits: Vec<Word>,
-}
-
-impl<T: Idx> Clone for IdxSet<T> {
-    fn clone(&self) -> Self {
-        IdxSet { _pd: PhantomData, bits: self.bits.clone() }
-    }
-}
+#[derive(Clone, Eq, PartialEq)]
+pub struct IdxSet<T: Idx>(BitArray<T>);
 
 impl<T: Idx> rustc_serialize::Encodable for IdxSet<T> {
-    fn encode<E: rustc_serialize::Encoder>(&self,
-                                     encoder: &mut E)
-                                     -> Result<(), E::Error> {
-        self.bits.encode(encoder)
+    fn encode<E: rustc_serialize::Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
+        self.0.encode(encoder)
     }
 }
 
 impl<T: Idx> rustc_serialize::Decodable for IdxSet<T> {
     fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<IdxSet<T>, D::Error> {
-        let words: Vec<Word> = rustc_serialize::Decodable::decode(d)?;
-
-        Ok(IdxSet {
-            _pd: PhantomData,
-            bits: words,
-        })
+        Ok(IdxSet(rustc_serialize::Decodable::decode(d)?))
     }
 }
 
-const BITS_PER_WORD: usize = mem::size_of::<Word>() * 8;
-
 impl<T: Idx> fmt::Debug for IdxSet<T> {
     fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
         w.debug_list()
@@ -82,31 +61,21 @@ fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
 }
 
 impl<T: Idx> IdxSet<T> {
-    fn new(init: Word, domain_size: usize) -> Self {
-        let num_words = (domain_size + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
-        IdxSet {
-            _pd: Default::default(),
-            bits: vec![init; num_words],
-        }
+    /// Creates set holding no elements.
+    pub fn new_empty(domain_size: usize) -> Self {
+        IdxSet(BitArray::new_empty(domain_size))
     }
 
     /// Creates set holding every element whose index falls in range 0..domain_size.
     pub fn new_filled(domain_size: usize) -> Self {
-        let mut result = Self::new(!0, domain_size);
-        result.trim_to(domain_size);
-        result
-    }
-
-    /// Creates set holding no elements.
-    pub fn new_empty(domain_size: usize) -> Self {
-        Self::new(0, domain_size)
+        IdxSet(BitArray::new_filled(domain_size))
     }
 
     /// Duplicates as a hybrid set.
     pub fn to_hybrid(&self) -> HybridIdxSet<T> {
         // This domain_size may be slightly larger than the one specified
         // upon creation, due to rounding up to a whole word. That's ok.
-        let domain_size = self.bits.len() * BITS_PER_WORD;
+        let domain_size = self.words().len() * WORD_BITS;
 
         // Note: we currently don't bother trying to make a Sparse set.
         HybridIdxSet::Dense(self.to_owned(), domain_size)
@@ -114,60 +83,35 @@ pub fn to_hybrid(&self) -> HybridIdxSet<T> {
 
     /// Removes all elements
     pub fn clear(&mut self) {
-        for b in &mut self.bits {
-            *b = 0;
-        }
+        self.0.clear();
     }
 
     /// Sets all elements up to `domain_size`
     pub fn set_up_to(&mut self, domain_size: usize) {
-        for b in &mut self.bits {
-            *b = !0;
-        }
-        self.trim_to(domain_size);
-    }
-
-    /// Clear all elements above `domain_size`.
-    fn trim_to(&mut self, domain_size: usize) {
-        // `trim_block` is the first block where some bits have
-        // to be cleared.
-        let trim_block = domain_size / BITS_PER_WORD;
-
-        // all the blocks above it have to be completely cleared.
-        if trim_block < self.bits.len() {
-            for b in &mut self.bits[trim_block+1..] {
-                *b = 0;
-            }
-
-            // at that block, the `domain_size % BITS_PER_WORD` LSBs
-            // should remain.
-            let remaining_bits = domain_size % BITS_PER_WORD;
-            let mask = (1<<remaining_bits)-1;
-            self.bits[trim_block] &= mask;
-        }
+        self.0.set_up_to(domain_size);
     }
 
     /// Removes `elem` from the set `self`; returns true iff this changed `self`.
     pub fn remove(&mut self, elem: &T) -> bool {
-        self.bits.clear_bit(elem.index())
+        self.0.remove(*elem)
     }
 
     /// Adds `elem` to the set `self`; returns true iff this changed `self`.
     pub fn add(&mut self, elem: &T) -> bool {
-        self.bits.set_bit(elem.index())
+        self.0.insert(*elem)
     }
 
     /// Returns true iff set `self` contains `elem`.
     pub fn contains(&self, elem: &T) -> bool {
-        self.bits.get_bit(elem.index())
+        self.0.contains(*elem)
     }
 
     pub fn words(&self) -> &[Word] {
-        &self.bits
+        self.0.words()
     }
 
     pub fn words_mut(&mut self) -> &mut [Word] {
-        &mut self.bits
+        self.0.words_mut()
     }
 
     /// Efficiently overwrite `self` with `other`. Panics if `self` and `other`
@@ -196,9 +140,7 @@ pub fn intersect(&mut self, other: &IdxSet<T>) -> bool {
 
     pub fn iter(&self) -> Iter<T> {
         Iter {
-            cur: None,
-            iter: self.words().iter().enumerate(),
-            _pd: PhantomData,
+            iter: self.0.iter()
         }
     }
 }
@@ -216,28 +158,14 @@ fn subtract_from(&self, other: &mut IdxSet<T>) -> bool {
 }
 
 pub struct Iter<'a, T: Idx> {
-    cur: Option<(Word, usize)>,
-    iter: iter::Enumerate<slice::Iter<'a, Word>>,
-    _pd: PhantomData<fn(&T)>,
+    iter: BitIter<'a, T>
 }
 
 impl<'a, T: Idx> Iterator for Iter<'a, T> {
     type Item = T;
 
     fn next(&mut self) -> Option<T> {
-        loop {
-            if let Some((ref mut word, offset)) = self.cur {
-                let bit_pos = word.trailing_zeros() as usize;
-                if bit_pos != BITS_PER_WORD {
-                    let bit = 1 << bit_pos;
-                    *word ^= bit;
-                    return Some(T::new(bit_pos + offset))
-                }
-            }
-
-            let (i, word) = self.iter.next()?;
-            self.cur = Some((*word, BITS_PER_WORD * i));
-        }
+        self.iter.next()
     }
 }
 
@@ -456,43 +384,3 @@ fn next(&mut self) -> Option<T> {
         }
     }
 }
-
-#[test]
-fn test_trim_to() {
-    use std::cmp;
-
-    for i in 0..256 {
-        let mut idx_buf: IdxSet<usize> = IdxSet::new_filled(128);
-        idx_buf.trim_to(i);
-
-        let elems: Vec<usize> = idx_buf.iter().collect();
-        let expected: Vec<usize> = (0..cmp::min(i, 128)).collect();
-        assert_eq!(elems, expected);
-    }
-}
-
-#[test]
-fn test_set_up_to() {
-    for i in 0..128 {
-        for mut idx_buf in
-            vec![IdxSet::new_empty(128), IdxSet::new_filled(128)]
-            .into_iter()
-        {
-            idx_buf.set_up_to(i);
-
-            let elems: Vec<usize> = idx_buf.iter().collect();
-            let expected: Vec<usize> = (0..i).collect();
-            assert_eq!(elems, expected);
-        }
-    }
-}
-
-#[test]
-fn test_new_filled() {
-    for i in 0..128 {
-        let idx_buf = IdxSet::new_filled(i);
-        let elems: Vec<usize> = idx_buf.iter().collect();
-        let expected: Vec<usize> = (0..i).collect();
-        assert_eq!(elems, expected);
-    }
-}