提交 7896af95 编写于 作者: B bors

Auto merge of #54177 - nnethercote:streamline-bit-stuff, r=Mark-Simulacrum

Remove bitslice.rs

As the comment in `bitslice.rs` says:

> FIXME: merge with `bitvec`
// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// FIXME: merge with `bitvec`
use std::mem;
pub type Word = usize;
/// `BitSlice` provides helper methods for treating a `[Word]`
/// as a bitvector.
pub trait BitSlice {
fn clear_bit(&mut self, idx: usize) -> bool;
fn set_bit(&mut self, idx: usize) -> bool;
fn get_bit(&self, idx: usize) -> bool;
}
impl BitSlice for [Word] {
/// Clears bit at `idx` to 0; returns true iff this changed `self.`
#[inline]
fn clear_bit(&mut self, idx: usize) -> bool {
let words = self;
debug!("clear_bit: words={} idx={}",
bits_to_string(words, words.len() * mem::size_of::<Word>() * 8), idx);
let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
debug!("word={} bit_in_word={} bit_mask=0x{:x}", word, bit_in_word, bit_mask);
let oldv = words[word];
let newv = oldv & !bit_mask;
words[word] = newv;
oldv != newv
}
/// Sets bit at `idx` to 1; returns true iff this changed `self.`
#[inline]
fn set_bit(&mut self, idx: usize) -> bool {
let words = self;
debug!("set_bit: words={} idx={}",
bits_to_string(words, words.len() * mem::size_of::<Word>() * 8), idx);
let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
let oldv = words[word];
let newv = oldv | bit_mask;
words[word] = newv;
oldv != newv
}
/// Extracts value of bit at `idx` in `self`.
#[inline]
fn get_bit(&self, idx: usize) -> bool {
let words = self;
let BitLookup { word, bit_mask, .. } = bit_lookup(idx);
(words[word] & bit_mask) != 0
}
}
struct BitLookup {
/// An index of the word holding the bit in original `[Word]` of query.
word: usize,
/// Index of the particular bit within the word holding the bit.
bit_in_word: usize,
/// Word with single 1-bit set corresponding to where the bit is located.
bit_mask: Word,
}
#[inline]
fn bit_lookup(bit: usize) -> BitLookup {
let word_bits = mem::size_of::<Word>() * 8;
let word = bit / word_bits;
let bit_in_word = bit % word_bits;
let bit_mask = 1 << bit_in_word;
BitLookup { word, bit_in_word, bit_mask }
}
pub fn bits_to_string(words: &[Word], bits: usize) -> String {
let mut result = String::new();
let mut sep = '[';
// Note: this is a little endian printout of bytes.
// i tracks how many bits we have printed so far.
let mut i = 0;
for &word in words.iter() {
let mut v = word;
for _ in 0..mem::size_of::<Word>() { // for each byte in `v`:
let remain = bits - i;
// If less than a byte remains, then mask just that many bits.
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
assert!(mask <= 0xFF);
let byte = v & mask;
result.push_str(&format!("{}{:02x}", sep, byte));
if remain <= 8 { break; }
v >>= 8;
i += 8;
sep = '-';
}
sep = '|';
}
result.push(']');
result
}
#[inline]
pub fn bitwise<Op:BitwiseOperator>(out_vec: &mut [Word],
in_vec: &[Word],
op: &Op) -> bool {
assert_eq!(out_vec.len(), in_vec.len());
let mut changed = false;
for (out_elt, in_elt) in out_vec.iter_mut().zip(in_vec) {
let old_val = *out_elt;
let new_val = op.join(old_val, *in_elt);
*out_elt = new_val;
changed |= old_val != new_val;
}
changed
}
pub trait BitwiseOperator {
/// Applies some bit-operation pointwise to each of the bits in the two inputs.
fn join(&self, pred1: Word, pred2: Word) -> Word;
}
pub struct Intersect;
impl BitwiseOperator for Intersect {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & b }
}
pub struct Union;
impl BitwiseOperator for Union {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & !b }
}
......@@ -9,65 +9,29 @@
// except according to those terms.
use indexed_vec::{Idx, IndexVec};
use rustc_serialize;
use std::iter;
use std::marker::PhantomData;
use std::slice;
type Word = u128;
const WORD_BITS: usize = 128;
pub type Word = u64;
pub const WORD_BYTES: usize = ::std::mem::size_of::<Word>();
pub const WORD_BITS: usize = WORD_BYTES * 8;
/// A very simple BitArray type.
///
/// It does not support resizing after creation; use `BitVector` for that.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct BitArray<C: Idx> {
data: Vec<Word>,
marker: PhantomData<C>,
}
#[derive(Clone, Debug, PartialEq)]
pub struct BitVector<C: Idx> {
data: BitArray<C>,
}
impl<C: Idx> BitVector<C> {
pub fn grow(&mut self, num_bits: C) {
self.data.grow(num_bits)
}
pub fn new() -> BitVector<C> {
BitVector {
data: BitArray::new(0),
}
}
pub fn with_capacity(bits: usize) -> BitVector<C> {
BitVector {
data: BitArray::new(bits),
}
}
/// Returns true if the bit has changed.
#[inline]
pub fn insert(&mut self, bit: C) -> bool {
self.grow(bit);
self.data.insert(bit)
}
#[inline]
pub fn contains(&self, bit: C) -> bool {
let (word, mask) = word_mask(bit);
if let Some(word) = self.data.data.get(word) {
(word & mask) != 0
} else {
false
}
}
}
impl<C: Idx> BitArray<C> {
// Do not make this method public, instead switch your use case to BitVector.
#[inline]
fn grow(&mut self, num_bits: C) {
let num_words = words(num_bits);
let num_words = num_words(num_bits);
if self.data.len() <= num_words {
self.data.resize(num_words + 1, 0)
}
......@@ -75,13 +39,29 @@ fn grow(&mut self, num_bits: C) {
#[inline]
pub fn new(num_bits: usize) -> BitArray<C> {
let num_words = words(num_bits);
BitArray::new_empty(num_bits)
}
#[inline]
pub fn new_empty(num_bits: usize) -> BitArray<C> {
let num_words = num_words(num_bits);
BitArray {
data: vec![0; num_words],
marker: PhantomData,
}
}
#[inline]
pub fn new_filled(num_bits: usize) -> BitArray<C> {
let num_words = num_words(num_bits);
let mut result = BitArray {
data: vec![!0; num_words],
marker: PhantomData,
};
result.clear_above(num_bits);
result
}
#[inline]
pub fn clear(&mut self) {
for p in &mut self.data {
......@@ -89,6 +69,31 @@ pub fn clear(&mut self) {
}
}
/// Sets all elements up to `num_bits`.
pub fn set_up_to(&mut self, num_bits: usize) {
for p in &mut self.data {
*p = !0;
}
self.clear_above(num_bits);
}
/// Clear all elements above `num_bits`.
fn clear_above(&mut self, num_bits: usize) {
let first_clear_block = num_bits / WORD_BITS;
if first_clear_block < self.data.len() {
// Within `first_clear_block`, the `num_bits % WORD_BITS` LSBs
// should remain.
let mask = (1 << (num_bits % WORD_BITS)) - 1;
self.data[first_clear_block] &= mask;
// All the blocks above `first_clear_block` are fully cleared.
for b in &mut self.data[first_clear_block + 1..] {
*b = 0;
}
}
}
pub fn count(&self) -> usize {
self.data.iter().map(|e| e.count_ones() as usize).sum()
}
......@@ -128,7 +133,7 @@ pub fn insert(&mut self, bit: C) -> bool {
/// Sets all bits to true.
pub fn insert_all(&mut self) {
for data in &mut self.data {
*data = u128::max_value();
*data = !0;
}
}
......@@ -157,52 +162,168 @@ pub fn merge(&mut self, all: &BitArray<C>) -> bool {
changed
}
pub fn words(&self) -> &[Word] {
&self.data
}
pub fn words_mut(&mut self) -> &mut [Word] {
&mut self.data
}
/// Iterates over indexes of set bits in a sorted order
#[inline]
pub fn iter<'a>(&'a self) -> BitIter<'a, C> {
BitIter {
iter: self.data.iter(),
current: 0,
idx: 0,
cur: None,
iter: self.data.iter().enumerate(),
marker: PhantomData,
}
}
}
impl<T: Idx> rustc_serialize::Encodable for BitArray<T> {
fn encode<E: rustc_serialize::Encoder>(&self, encoder: &mut E) -> Result<(), E::Error> {
self.data.encode(encoder)
}
}
impl<T: Idx> rustc_serialize::Decodable for BitArray<T> {
fn decode<D: rustc_serialize::Decoder>(d: &mut D) -> Result<BitArray<T>, D::Error> {
let words: Vec<Word> = rustc_serialize::Decodable::decode(d)?;
Ok(BitArray {
data: words,
marker: PhantomData,
})
}
}
pub struct BitIter<'a, C: Idx> {
iter: ::std::slice::Iter<'a, Word>,
current: Word,
idx: usize,
cur: Option<(Word, usize)>,
iter: iter::Enumerate<slice::Iter<'a, Word>>,
marker: PhantomData<C>
}
impl<'a, C: Idx> Iterator for BitIter<'a, C> {
type Item = C;
fn next(&mut self) -> Option<C> {
while self.current == 0 {
self.current = if let Some(&i) = self.iter.next() {
if i == 0 {
self.idx += WORD_BITS;
continue;
} else {
self.idx = words(self.idx) * WORD_BITS;
i
loop {
if let Some((ref mut word, offset)) = self.cur {
let bit_pos = word.trailing_zeros() as usize;
if bit_pos != WORD_BITS {
let bit = 1 << bit_pos;
*word ^= bit;
return Some(C::new(bit_pos + offset))
}
} else {
return None;
}
let (i, word) = self.iter.next()?;
self.cur = Some((*word, WORD_BITS * i));
}
let offset = self.current.trailing_zeros() as usize;
self.current >>= offset;
self.current >>= 1; // shift otherwise overflows for 0b1000_0000_…_0000
self.idx += offset + 1;
}
}
pub trait BitwiseOperator {
/// Applies some bit-operation pointwise to each of the bits in the two inputs.
fn join(&self, pred1: Word, pred2: Word) -> Word;
}
#[inline]
pub fn bitwise<Op: BitwiseOperator>(out_vec: &mut [Word], in_vec: &[Word], op: &Op) -> bool
{
assert_eq!(out_vec.len(), in_vec.len());
let mut changed = false;
for (out_elem, in_elem) in out_vec.iter_mut().zip(in_vec.iter()) {
let old_val = *out_elem;
let new_val = op.join(old_val, *in_elem);
*out_elem = new_val;
changed |= old_val != new_val;
}
changed
}
pub struct Intersect;
impl BitwiseOperator for Intersect {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & b }
}
pub struct Union;
impl BitwiseOperator for Union {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
#[inline]
fn join(&self, a: Word, b: Word) -> Word { a & !b }
}
pub fn bits_to_string(words: &[Word], bits: usize) -> String {
let mut result = String::new();
let mut sep = '[';
// Note: this is a little endian printout of bytes.
// i tracks how many bits we have printed so far.
let mut i = 0;
for &word in words.iter() {
let mut v = word;
for _ in 0..WORD_BYTES { // for each byte in `v`:
let remain = bits - i;
// If less than a byte remains, then mask just that many bits.
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
assert!(mask <= 0xFF);
let byte = v & mask;
result.push_str(&format!("{}{:02x}", sep, byte));
if remain <= 8 { break; }
v >>= 8;
i += 8;
sep = '-';
}
sep = '|';
}
result.push(']');
result
}
/// A resizable BitVector type.
#[derive(Clone, Debug, PartialEq)]
pub struct BitVector<C: Idx> {
data: BitArray<C>,
}
impl<C: Idx> BitVector<C> {
pub fn grow(&mut self, num_bits: C) {
self.data.grow(num_bits)
}
pub fn new() -> BitVector<C> {
BitVector { data: BitArray::new(0) }
}
Some(C::new(self.idx - 1))
pub fn with_capacity(bits: usize) -> BitVector<C> {
BitVector { data: BitArray::new(bits) }
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
/// Returns true if the bit has changed.
#[inline]
pub fn insert(&mut self, bit: C) -> bool {
self.grow(bit);
self.data.insert(bit)
}
#[inline]
pub fn contains(&self, bit: C) -> bool {
let (word, mask) = word_mask(bit);
if let Some(word) = self.data.data.get(word) {
(word & mask) != 0
} else {
false
}
}
}
......@@ -221,7 +342,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
pub fn new(rows: usize, columns: usize) -> BitMatrix<R, C> {
// For every element, we need one bit for every other
// element. Round up to an even number of words.
let words_per_row = words(columns);
let words_per_row = num_words(columns);
BitMatrix {
columns,
vector: vec![0; rows * words_per_row],
......@@ -232,7 +353,7 @@ pub fn new(rows: usize, columns: usize) -> BitMatrix<R, C> {
/// The range of bits for a given row.
fn range(&self, row: R) -> (usize, usize) {
let row = row.index();
let words_per_row = words(self.columns);
let words_per_row = num_words(self.columns);
let start = row * words_per_row;
(start, start + words_per_row)
}
......@@ -310,9 +431,8 @@ pub fn merge(&mut self, read: R, write: R) -> bool {
pub fn iter<'a>(&'a self, row: R) -> BitIter<'a, C> {
let (start, end) = self.range(row);
BitIter {
iter: self.vector[start..end].iter(),
current: 0,
idx: 0,
cur: None,
iter: self.vector[start..end].iter().enumerate(),
marker: PhantomData,
}
}
......@@ -421,7 +541,7 @@ pub fn row(&self, row: R) -> Option<&BitArray<C>> {
}
#[inline]
fn words<C: Idx>(elements: C) -> usize {
fn num_words<C: Idx>(elements: C) -> usize {
(elements.index() + WORD_BITS - 1) / WORD_BITS
}
......@@ -433,6 +553,46 @@ fn word_mask<C: Idx>(index: C) -> (usize, Word) {
(word, mask)
}
#[test]
fn test_clear_above() {
use std::cmp;
for i in 0..256 {
let mut idx_buf: BitArray<usize> = BitArray::new_filled(128);
idx_buf.clear_above(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![BitArray::new_empty(128), BitArray::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 = BitArray::new_filled(i);
let elems: Vec<usize> = idx_buf.iter().collect();
let expected: Vec<usize> = (0..i).collect();
assert_eq!(elems, expected);
}
}
#[test]
fn bitvec_iter_works() {
let mut bitvec: BitArray<usize> = BitArray::new(100);
......
......@@ -10,12 +10,9 @@
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`
......@@ -194,12 +138,8 @@ pub fn intersect(&mut self, other: &IdxSet<T>) -> bool {
bitwise(self.words_mut(), other.words(), &Intersect)
}
pub fn iter(&self) -> Iter<T> {
Iter {
cur: None,
iter: self.words().iter().enumerate(),
_pd: PhantomData,
}
pub fn iter(&self) -> BitIter<T> {
self.0.iter()
}
}
......@@ -215,32 +155,6 @@ 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)>,
}
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));
}
}
}
const SPARSE_MAX: usize = 8;
/// A sparse index set with a maximum of SPARSE_MAX elements. Used by
......@@ -293,10 +207,8 @@ fn to_dense(&self, domain_size: usize) -> IdxSet<T> {
dense
}
fn iter(&self) -> SparseIter<T> {
SparseIter {
iter: self.0.iter(),
}
fn iter(&self) -> slice::Iter<T> {
self.0.iter()
}
}
......@@ -320,18 +232,6 @@ fn subtract_from(&self, other: &mut IdxSet<T>) -> bool {
}
}
pub struct SparseIter<'a, T: Idx> {
iter: slice::Iter<'a, T>,
}
impl<'a, T: Idx> Iterator for SparseIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<T> {
self.iter.next().map(|e| *e)
}
}
/// Like IdxSet, but with a hybrid representation: sparse when there are few
/// elements in the set, but dense when there are many. It's especially
/// efficient for sets that typically have a small number of elements, but a
......@@ -442,8 +342,8 @@ fn subtract_from(&self, other: &mut IdxSet<T>) -> bool {
}
pub enum HybridIter<'a, T: Idx> {
Sparse(SparseIter<'a, T>),
Dense(Iter<'a, T>),
Sparse(slice::Iter<'a, T>),
Dense(BitIter<'a, T>),
}
impl<'a, T: Idx> Iterator for HybridIter<'a, T> {
......@@ -451,48 +351,8 @@ impl<'a, T: Idx> Iterator for HybridIter<'a, T> {
fn next(&mut self) -> Option<T> {
match self {
HybridIter::Sparse(sparse) => sparse.next(),
HybridIter::Sparse(sparse) => sparse.next().map(|e| *e),
HybridIter::Dense(dense) => dense.next(),
}
}
}
#[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);
}
}
......@@ -62,7 +62,6 @@
pub mod svh;
pub mod array_vec;
pub mod base_n;
pub mod bitslice;
pub mod bitvec;
pub mod const_cstr;
pub mod flock;
......
......@@ -15,7 +15,7 @@
use rustc::mir::{BasicBlock, Location};
use rustc::ty::RegionVid;
use rustc_data_structures::indexed_set::Iter;
use rustc_data_structures::bitvec::BitIter;
use borrow_check::location::LocationIndex;
......@@ -67,7 +67,7 @@ impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
}
}
crate fn with_outgoing_borrows(&self, op: impl FnOnce(Iter<BorrowIndex>)) {
crate fn with_outgoing_borrows(&self, op: impl FnOnce(BitIter<BorrowIndex>)) {
self.borrows.with_iter_outgoing(op)
}
}
......
......@@ -12,7 +12,8 @@
//! locations.
use rustc::mir::{BasicBlock, Location};
use rustc_data_structures::indexed_set::{HybridIdxSet, IdxSet, Iter};
use rustc_data_structures::bitvec::BitIter;
use rustc_data_structures::indexed_set::{HybridIdxSet, IdxSet};
use dataflow::{BitDenotation, BlockSets, DataflowResults};
use dataflow::move_paths::{HasMoveData, MovePathIndex};
......@@ -125,7 +126,7 @@ pub fn contains(&self, x: &BD::Idx) -> bool {
}
/// Returns an iterator over the elements present in the current state.
pub fn iter_incoming(&self) -> iter::Peekable<Iter<BD::Idx>> {
pub fn iter_incoming(&self) -> iter::Peekable<BitIter<BD::Idx>> {
self.curr_state.iter().peekable()
}
......@@ -134,7 +135,7 @@ pub fn iter_incoming(&self) -> iter::Peekable<Iter<BD::Idx>> {
/// Invokes `f` with an iterator over the resulting state.
pub fn with_iter_outgoing<F>(&self, f: F)
where
F: FnOnce(Iter<BD::Idx>),
F: FnOnce(BitIter<BD::Idx>),
{
let mut curr_state = self.curr_state.clone();
curr_state.union(&self.stmt_gen);
......
......@@ -12,7 +12,7 @@
use syntax::ast::NodeId;
use rustc::mir::{BasicBlock, Mir};
use rustc_data_structures::bitslice::bits_to_string;
use rustc_data_structures::bitvec::bits_to_string;
use dot;
use dot::IntoCow;
......
......@@ -20,7 +20,7 @@
use rustc::ty::{RegionKind, RegionVid};
use rustc::ty::RegionKind::ReScope;
use rustc_data_structures::bitslice::{BitwiseOperator, Word};
use rustc_data_structures::bitvec::{BitwiseOperator, Word};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_set::IdxSet;
use rustc_data_structures::indexed_vec::IndexVec;
......
......@@ -14,7 +14,7 @@
use rustc::ty::TyCtxt;
use rustc::mir::{self, Mir, Location};
use rustc_data_structures::bitslice::{BitwiseOperator, Word};
use rustc_data_structures::bitvec::{BitwiseOperator, Word};
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::Idx;
......
......@@ -10,7 +10,7 @@
use syntax::ast::{self, MetaItem};
use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
use rustc_data_structures::bitvec::{bitwise, BitwiseOperator};
use rustc_data_structures::indexed_set::{HybridIdxSet, IdxSet};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::work_queue::WorkQueue;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册