#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#[cfg(all(test, feature = "nightly"))] extern crate test;
#[cfg(all(test, feature = "nightly"))] extern crate rand;
extern crate bit_vec;
extern crate bit_array;
extern crate typenum;
extern crate generic_array;
use bit_vec::BitBlock;
use bit_array::{BitsIn, BitArray, Blocks};
use std::cmp::Ordering;
use std::cmp;
use std::fmt;
use std::hash;
use std::ops::*;
use std::iter::{self, Chain, Enumerate, FromIterator, Repeat, Skip, Take};
use typenum::{Unsigned, NonZero};
type MatchWords<'a, B> = Chain<Enumerate<Blocks<'a, B>>, Skip<Take<Enumerate<Repeat<B>>>>>;
fn match_words<'a, 'b, B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero>(a: &'a BitArray<B, NBits>, b: &'b BitArray<B, NBits>)
-> (MatchWords<'a, B>, MatchWords<'b, B>)
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
let a_len = a.len();
let b_len = b.len();
if a_len < b_len {
(a.blocks().enumerate().chain(iter::repeat(B::zero()).enumerate().take(b_len).skip(a_len)),
b.blocks().enumerate().chain(iter::repeat(B::zero()).enumerate().take(0).skip(0)))
} else {
(a.blocks().enumerate().chain(iter::repeat(B::zero()).enumerate().take(0).skip(0)),
b.blocks().enumerate().chain(iter::repeat(B::zero()).enumerate().take(a_len).skip(b_len)))
}
}
pub struct BitArraySet<B: BitsIn, NBits: Unsigned + NonZero>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
bit_array: BitArray<B, NBits>,
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> Clone for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn clone(&self) -> Self {
BitArraySet {
bit_array: self.bit_array.clone(),
}
}
fn clone_from(&mut self, other: &Self) {
self.bit_array.clone_from(&other.bit_array);
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> Default for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
#[inline]
fn default() -> Self { BitArraySet { bit_array: Default::default() } }
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> FromIterator<usize> for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn from_iter<I: IntoIterator<Item = usize>>(iter: I) -> Self {
let mut ret = Self::default();
ret.extend(iter);
ret
}
}
impl<B: BitsIn + BitBlock + Default + BitAnd + BitOr, NBits: Unsigned + NonZero> Extend<usize> for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
#[inline]
fn extend<I: IntoIterator<Item = usize>>(&mut self, iter: I) {
for i in iter {
self.insert(i);
}
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> PartialOrd for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.iter().partial_cmp(other)
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> Ord for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other)
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> PartialEq for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.iter().eq(other)
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> Eq for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn from_bit_array(bit_array: BitArray<B, NBits>) -> Self {
BitArraySet { bit_array: bit_array }
}
pub fn from_bytes(bytes: &[u8]) -> Self {
BitArraySet { bit_array: BitArray::from_bytes(bytes) }
}
#[inline]
pub fn into_bit_array(self) -> BitArray<B, NBits> {
self.bit_array
}
#[inline]
pub fn get_ref(&self) -> &BitArray<B, NBits> {
&self.bit_array
}
#[inline]
fn other_op<F>(&mut self, other: &Self, mut f: F) where F: FnMut(B, B) -> B {
let self_bit_array = &mut self.bit_array;
let other_bit_array = &other.bit_array;
let other_words = {
let (_, result) = match_words(self_bit_array, other_bit_array);
result
};
for (i, w) in other_words {
let old = self_bit_array.storage()[i];
let new = f(old, w);
unsafe {
self_bit_array.storage_mut()[i] = new;
}
}
}
#[inline]
pub fn iter(&self) -> Iter<B> {
Iter(BlockIter::from_blocks(self.bit_array.blocks()))
}
#[inline]
pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, B> {
fn or<B: BitBlock>(w1: B, w2: B) -> B { w1 | w2 }
Union(BlockIter::from_blocks(TwoBitPositions {
set: self.bit_array.blocks(),
other: other.bit_array.blocks(),
merge: or,
}))
}
#[inline]
pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, B> {
fn bitand<B: BitBlock>(w1: B, w2: B) -> B { w1 & w2 }
let min = cmp::min(self.bit_array.len(), other.bit_array.len());
Intersection(BlockIter::from_blocks(TwoBitPositions {
set: self.bit_array.blocks(),
other: other.bit_array.blocks(),
merge: bitand,
}).take(min))
}
#[inline]
pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, B> {
fn diff<B: BitBlock>(w1: B, w2: B) -> <B as std::ops::BitAnd>::Output { w1 & !w2 }
Difference(BlockIter::from_blocks(TwoBitPositions {
set: self.bit_array.blocks(),
other: other.bit_array.blocks(),
merge: diff,
}))
}
#[inline]
pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, B> {
fn bitxor<B: BitBlock>(w1: B, w2: B) -> B { w1 ^ w2 }
SymmetricDifference(BlockIter::from_blocks(TwoBitPositions {
set: self.bit_array.blocks(),
other: other.bit_array.blocks(),
merge: bitxor,
}))
}
#[inline]
pub fn union_with(&mut self, other: &Self) {
self.other_op(other, |w1, w2| w1 | w2);
}
#[inline]
pub fn intersect_with(&mut self, other: &Self) {
self.other_op(other, |w1, w2| w1 & w2);
}
#[inline]
pub fn difference_with(&mut self, other: &Self) {
self.other_op(other, |w1, w2| w1 & !w2);
}
#[inline]
pub fn symmetric_difference_with(&mut self, other: &Self) {
self.other_op(other, |w1, w2| w1 ^ w2);
}
#[inline]
pub fn len(&self) -> usize {
self.bit_array.blocks().fold(0, |acc, n| acc + n.count_ones() as usize)
}
#[inline]
pub fn is_empty(&self) -> bool {
self.bit_array.none()
}
#[inline]
pub fn clear(&mut self) {
self.bit_array.clear();
}
#[inline]
pub fn contains(&self, value: usize) -> bool {
let bit_array = &self.bit_array;
value < bit_array.len() && bit_array[value]
}
#[inline]
pub fn is_disjoint(&self, other: &Self) -> bool {
self.intersection(other).next().is_none()
}
#[inline]
pub fn is_subset(&self, other: &Self) -> bool {
let self_bit_array = &self.bit_array;
let other_bit_array = &other.bit_array;
self_bit_array.blocks().zip(other_bit_array.blocks()).all(|(w1, w2)| w1 & w2 == w1)
}
#[inline]
pub fn is_superset(&self, other: &Self) -> bool {
other.is_subset(self)
}
pub fn insert(&mut self, value: usize) -> bool {
assert!(value <= NBits::to_usize(), "BitArraySet can only handle {:?} entries. Insert to {:?} requested.", NBits::to_usize(), value);
if self.contains(value) {
return false;
}
self.bit_array.set(value, true);
return true;
}
pub fn remove(&mut self, value: usize) -> bool {
if !self.contains(value) {
return false;
}
self.bit_array.set(value, false);
return true;
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> fmt::Debug for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_set().entries(self).finish()
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> hash::Hash for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn hash<H: hash::Hasher>(&self, state: &mut H) {
for pos in self {
pos.hash(state);
}
}
}
#[derive(Clone)]
struct BlockIter<T, B> {
head: B,
head_offset: usize,
tail: T,
}
impl<T, B: BitBlock> BlockIter<T, B> where T: Iterator<Item=B> {
fn from_blocks(mut blocks: T) -> BlockIter<T, B> {
let h = blocks.next().unwrap_or(B::zero());
BlockIter {tail: blocks, head: h, head_offset: 0}
}
}
#[derive(Clone)]
struct TwoBitPositions<'a, B: 'a> {
set: Blocks<'a, B>,
other: Blocks<'a, B>,
merge: fn(B, B) -> B,
}
#[derive(Clone)]
pub struct Iter<'a, B: 'a>(BlockIter<Blocks<'a, B>, B>);
#[derive(Clone)]
pub struct Union<'a, B: 'a>(BlockIter<TwoBitPositions<'a, B>, B>);
#[derive(Clone)]
pub struct Intersection<'a, B: 'a>(Take<BlockIter<TwoBitPositions<'a, B>, B>>);
#[derive(Clone)]
pub struct Difference<'a, B: 'a>(BlockIter<TwoBitPositions<'a, B>, B>);
#[derive(Clone)]
pub struct SymmetricDifference<'a, B: 'a>(BlockIter<TwoBitPositions<'a, B>, B>);
impl<'a, T, B: BitBlock> Iterator for BlockIter<T, B> where T: Iterator<Item=B> {
type Item = usize;
fn next(&mut self) -> Option<usize> {
while self.head == B::zero() {
match self.tail.next() {
Some(w) => self.head = w,
None => return None
}
self.head_offset += B::bits();
}
let k = (self.head & (!self.head + B::one())) - B::one();
self.head = self.head & (self.head - B::one());
Some(self.head_offset + (B::count_ones(k) as usize))
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
match self.tail.size_hint() {
(_, Some(h)) => (0, Some(1 + h * B::bits())),
_ => (0, None)
}
}
}
impl<'a, B: BitBlock> Iterator for TwoBitPositions<'a, B> {
type Item = B;
fn next(&mut self) -> Option<B> {
match (self.set.next(), self.other.next()) {
(Some(a), Some(b)) => Some((self.merge)(a, b)),
(Some(a), None) => Some((self.merge)(a, B::zero())),
(None, Some(b)) => Some((self.merge)(B::zero(), b)),
_ => return None
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (a, au) = self.set.size_hint();
let (b, bu) = self.other.size_hint();
let upper = match (au, bu) {
(Some(au), Some(bu)) => Some(cmp::max(au, bu)),
_ => None
};
(cmp::max(a, b), upper)
}
}
impl<'a, B: BitBlock> Iterator for Iter<'a, B> {
type Item = usize;
#[inline] fn next(&mut self) -> Option<usize> { self.0.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
}
impl<'a, B: BitBlock> Iterator for Union<'a, B> {
type Item = usize;
#[inline] fn next(&mut self) -> Option<usize> { self.0.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
}
impl<'a, B: BitBlock> Iterator for Intersection<'a, B> {
type Item = usize;
#[inline] fn next(&mut self) -> Option<usize> { self.0.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
}
impl<'a, B: BitBlock> Iterator for Difference<'a, B> {
type Item = usize;
#[inline] fn next(&mut self) -> Option<usize> { self.0.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
}
impl<'a, B: BitBlock> Iterator for SymmetricDifference<'a, B> {
type Item = usize;
#[inline] fn next(&mut self) -> Option<usize> { self.0.next() }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.0.size_hint() }
}
impl<'a, B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> IntoIterator for &'a BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
type Item = usize;
type IntoIter = Iter<'a, B>;
fn into_iter(self) -> Iter<'a, B> {
self.iter()
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> Not for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
type Output = BitArraySet<B, NBits>;
fn not(self) -> Self::Output {
let mut not = self.clone();
not.bit_array.negate();
not
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitAnd for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
type Output = BitArraySet<B, NBits>;
fn bitand(self, rhs: Self) -> Self::Output {
let mut and = self.clone();
and.intersect_with(&rhs);
and
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitAndAssign for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn bitand_assign(&mut self, rhs: Self) {
self.intersect_with(&rhs);
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitOr for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
type Output = BitArraySet<B, NBits>;
fn bitor(self, rhs: Self) -> Self::Output {
let mut or = self.clone();
or.union_with(&rhs);
or
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitOrAssign for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn bitor_assign(&mut self, rhs: Self) {
self.union_with(&rhs);
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitXor for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
type Output = BitArraySet<B, NBits>;
fn bitxor(self, rhs: Self) -> Self::Output {
let mut xor = self.clone();
xor.symmetric_difference_with(&rhs);
xor
}
}
impl<B: BitsIn + BitBlock + Default, NBits: Unsigned + NonZero> BitXorAssign for BitArraySet<B, NBits>
where NBits: Add<<B as BitsIn>::Output>,
<NBits as Add<<B as BitsIn>::Output>>::Output: Sub<typenum::B1>,
<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output: Div<<B as BitsIn>::Output>,
<<<NBits as Add<<B as BitsIn>::Output>>::Output as Sub<typenum::B1>>::Output as Div<<B as BitsIn>::Output>>::Output: generic_array::ArrayLength<B>
{
fn bitxor_assign(&mut self, rhs: Self) {
self.symmetric_difference_with(&rhs);
}
}
#[cfg(test)]
mod tests {
use std::cmp::Ordering::{Equal, Greater, Less};
use super::BitArraySet;
use bit_array::BitArray;
use typenum::{U4, U8, U10, U51, U64, U100, U104, U152, U201, U221, U401, U501, U1001};
#[test]
fn test_bit_set_show() {
let mut s = BitArraySet::<u32, U51>::new();
s.insert(1);
s.insert(10);
s.insert(50);
s.insert(2);
assert_eq!("{1, 2, 10, 50}", format!("{:?}", s));
}
#[test]
fn test_bit_set_from_usizes() {
let usizes = vec![0, 2, 2, 3];
let a: BitArraySet<u32, U4> = usizes.into_iter().collect();
let mut b = BitArraySet::new();
b.insert(0);
b.insert(2);
b.insert(3);
assert_eq!(a, b);
}
#[test]
fn test_bit_set_iterator() {
let usizes = vec![0, 2, 2, 3];
let bit_array: BitArraySet<u32, U4> = usizes.into_iter().collect();
let idxs: Vec<_> = bit_array.iter().collect();
assert_eq!(idxs, [0, 2, 3]);
let long: BitArraySet<u32, U1001> = (0..1000).filter(|&n| n % 2 == 0).collect();
let real: Vec<_> = (0..1000/2).map(|x| x*2).collect();
let idxs: Vec<_> = long.iter().collect();
assert_eq!(idxs, real);
}
#[test]
fn test_bit_set_frombit_array_init() {
let bools = [true, false];
for &b in &bools {
let bitset_10 = BitArraySet::from_bit_array(BitArray::<u32, U10>::from_elem(b));
let bitset_64 = BitArraySet::from_bit_array(BitArray::<u32, U64>::from_elem(b));
let bitset_100 = BitArraySet::from_bit_array(BitArray::<u32, U100>::from_elem(b));
assert_eq!(bitset_10.contains(1), b);
assert_eq!(bitset_10.contains((9)), b);
assert!(!bitset_10.contains(10));
assert_eq!(bitset_64.contains(1), b);
assert_eq!(bitset_64.contains((63)), b);
assert!(!bitset_64.contains(64));
assert_eq!(bitset_100.contains(1), b);
assert_eq!(bitset_100.contains((99)), b);
assert!(!bitset_100.contains(100));
}
}
#[test]
fn test_bit_array_masking() {
let b: BitArray<u32, U152> = BitArray::from_elem(true);
let mut bs = BitArraySet::from_bit_array(b);
bs.remove(140);
bs.remove(149);
bs.remove(150);
bs.remove(151);
assert!(bs.contains(139));
assert!(!bs.contains(140));
assert!(bs.insert(150));
assert!(!bs.contains(140));
assert!(!bs.contains(149));
assert!(bs.contains(150));
assert!(!bs.contains(151));
}
#[test]
fn test_bit_set_basic() {
let mut b = BitArraySet::<u32, U401>::new();
assert!(b.insert(3));
assert!(!b.insert(3));
assert!(b.contains(3));
assert!(b.insert(4));
assert!(!b.insert(4));
assert!(b.contains(3));
assert!(b.insert(400));
assert!(!b.insert(400));
assert!(b.contains(400));
assert_eq!(b.len(), 3);
}
#[test]
fn test_bit_set_intersection() {
let mut a = BitArraySet::<u32, U104>::new();
let mut b = BitArraySet::<u32, U104>::new();
assert!(a.insert(11));
assert!(a.insert(1));
assert!(a.insert(3));
assert!(a.insert(77));
assert!(a.insert(103));
assert!(a.insert(5));
assert!(b.insert(2));
assert!(b.insert(11));
assert!(b.insert(77));
assert!(b.insert(5));
assert!(b.insert(3));
let expected = [3, 5, 11, 77];
let actual: Vec<_> = a.intersection(&b).collect();
assert_eq!(actual, expected);
}
#[test]
fn test_bit_set_difference() {
let mut a = BitArraySet::<u32, U501>::new();
let mut b = BitArraySet::<u32, U501>::new();
assert!(a.insert(1));
assert!(a.insert(3));
assert!(a.insert(5));
assert!(a.insert(200));
assert!(a.insert(500));
assert!(b.insert(3));
assert!(b.insert(200));
let expected = [1, 5, 500];
let actual: Vec<_> = a.difference(&b).collect();
assert_eq!(actual, expected);
}
#[test]
fn test_bit_set_symmetric_difference() {
let mut a = BitArraySet::<u32, U221>::new();
let mut b = BitArraySet::<u32, U221>::new();
assert!(a.insert(1));
assert!(a.insert(3));
assert!(a.insert(5));
assert!(a.insert(9));
assert!(a.insert(11));
assert!(b.insert(3));
assert!(b.insert(9));
assert!(b.insert(14));
assert!(b.insert(220));
let expected = [1, 5, 11, 14, 220];
let actual: Vec<_> = a.symmetric_difference(&b).collect();
assert_eq!(actual, expected);
}
#[test]
fn test_bit_set_union() {
let mut a = BitArraySet::<u32, U201>::new();
let mut b = BitArraySet::<u32, U201>::new();
assert!(a.insert(1));
assert!(a.insert(3));
assert!(a.insert(5));
assert!(a.insert(9));
assert!(a.insert(11));
assert!(a.insert(160));
assert!(a.insert(19));
assert!(a.insert(24));
assert!(a.insert(200));
assert!(b.insert(1));
assert!(b.insert(5));
assert!(b.insert(9));
assert!(b.insert(13));
assert!(b.insert(19));
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200];
let actual: Vec<_> = a.union(&b).collect();
assert_eq!(actual, expected);
}
#[test]
fn test_bit_set_subset() {
let mut set1 = BitArraySet::<u32, U401>::new();
let mut set2 = BitArraySet::<u32, U401>::new();
assert!(set1.is_subset(&set2)); set2.insert(100);
assert!(set1.is_subset(&set2)); set2.insert(200);
assert!(set1.is_subset(&set2)); set1.insert(200);
assert!(set1.is_subset(&set2)); set1.insert(300);
assert!(!set1.is_subset(&set2)); set2.insert(300);
assert!(set1.is_subset(&set2)); set2.insert(400);
assert!(set1.is_subset(&set2)); set2.remove(100);
assert!(set1.is_subset(&set2)); set2.remove(300);
assert!(!set1.is_subset(&set2)); set1.remove(300);
assert!(set1.is_subset(&set2)); }
#[test]
fn test_bit_set_is_disjoint() {
let a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let b = BitArraySet::<u32, U8>::from_bytes(&[0b01000000]);
let c = BitArraySet::<u32, U8>::new();
let d = BitArraySet::<u32, U8>::from_bytes(&[0b00110000]);
assert!(!a.is_disjoint(&d));
assert!(!d.is_disjoint(&a));
assert!(a.is_disjoint(&b));
assert!(a.is_disjoint(&c));
assert!(b.is_disjoint(&a));
assert!(b.is_disjoint(&c));
assert!(c.is_disjoint(&a));
assert!(c.is_disjoint(&b));
}
#[test]
fn test_bit_set_union_with() {
let mut a = BitArraySet::<u32, U8>::new();
a.insert(0);
let mut b = BitArraySet::<u32, U8>::new();
b.insert(5);
let expected = BitArraySet::<u32, U8>::from_bytes(&[0b10000100]);
a.union_with(&b);
assert_eq!(a, expected);
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let mut b = BitArraySet::<u32, U8>::from_bytes(&[0b01100010]);
let c = a.clone();
a.union_with(&b);
b.union_with(&c);
assert_eq!(a.len(), 4);
assert_eq!(b.len(), 4);
}
#[test]
fn test_bit_set_intersect_with() {
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let mut b = BitArraySet::<u32, U8>::from_bytes(&[0b00000000]);
let c = a.clone();
a.intersect_with(&b);
b.intersect_with(&c);
assert!(a.is_empty());
assert!(b.is_empty());
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let mut b = BitArraySet::<u32, U8>::new();
let c = a.clone();
a.intersect_with(&b);
b.intersect_with(&c);
assert!(a.is_empty());
assert!(b.is_empty());
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let mut b = BitArraySet::<u32, U8>::from_bytes(&[0b01100010]);
let c = a.clone();
a.intersect_with(&b);
b.intersect_with(&c);
assert_eq!(a.len(), 2);
assert_eq!(b.len(), 2);
}
#[test]
fn test_bit_set_difference_with() {
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b00000000]);
let b = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
a.difference_with(&b);
assert!(a.is_empty());
let mut a = BitArraySet::<u32, U8>::new();
let b = BitArraySet::<u32, U8>::from_bytes(&[0b11111111]);
a.difference_with(&b);
assert!(a.is_empty());
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let mut b = BitArraySet::<u32, U8>::from_bytes(&[0b01100010]);
let c = a.clone();
a.difference_with(&b);
b.difference_with(&c);
assert_eq!(a.len(), 1);
assert_eq!(b.len(), 1);
}
#[test]
fn test_bit_set_symmetric_difference_with() {
let mut a = BitArraySet::<u32, U8>::new();
a.insert(0);
a.insert(1);
let mut b = BitArraySet::<u32, U8>::new();
b.insert(1);
b.insert(5);
let expected = BitArraySet::<u32, U8>::from_bytes(&[0b10000100]);
a.symmetric_difference_with(&b);
assert_eq!(a, expected);
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let b = BitArraySet::<u32, U8>::new();
let c = a.clone();
a.symmetric_difference_with(&b);
assert_eq!(a, c);
let mut a = BitArraySet::<u32, U8>::from_bytes(&[0b11100010]);
let mut b = BitArraySet::<u32, U8>::from_bytes(&[0b01101010]);
let c = a.clone();
a.symmetric_difference_with(&b);
b.symmetric_difference_with(&c);
assert_eq!(a.len(), 2);
assert_eq!(b.len(), 2);
}
#[test]
fn test_bit_set_eq() {
let a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let b = BitArraySet::<u32, U8>::from_bytes(&[0b00000000]);
let c = BitArraySet::<u32, U8>::new();
assert!(a == a);
assert!(a != b);
assert!(a != c);
assert!(b == b);
assert!(b == c);
assert!(c == c);
}
#[test]
fn test_bit_set_cmp() {
let a = BitArraySet::<u32, U8>::from_bytes(&[0b10100010]);
let b = BitArraySet::<u32, U8>::from_bytes(&[0b00000000]);
let c = BitArraySet::<u32, U8>::new();
assert_eq!(a.cmp(&b), Greater);
assert_eq!(a.cmp(&c), Greater);
assert_eq!(b.cmp(&a), Less);
assert_eq!(b.cmp(&c), Equal);
assert_eq!(c.cmp(&a), Less);
assert_eq!(c.cmp(&b), Equal);
}
#[test]
fn test_bit_array_remove() {
let mut a = BitArraySet::<u32, U1001>::new();
assert!(a.insert(1));
assert!(a.remove(1));
assert!(a.insert(100));
assert!(a.remove(100));
assert!(a.insert(1000));
assert!(a.remove(1000));
}
#[test]
fn test_bit_array_clone() {
let mut a = BitArraySet::<u32, U1001>::new();
assert!(a.insert(1));
assert!(a.insert(100));
assert!(a.insert(1000));
let mut b = a.clone();
assert!(a == b);
assert!(b.remove(1));
assert!(a.contains(1));
assert!(a.remove(1000));
assert!(b.contains(1000));
}
}
#[cfg(all(test, feature = "nightly"))]
mod bench {
use super::BitArraySet;
use bit_array::BitArray;
use rand::{Rng, thread_rng, ThreadRng};
use typenum::*;
use test::{Bencher, black_box};
const BITS: usize = 32;
fn rng() -> ThreadRng {
thread_rng()
}
#[bench]
fn bench_bit_arrayset_small(b: &mut Bencher) {
let mut r = rng();
let mut bit_arrayset = BitArraySet::<u32, U32>::new();
b.iter(|| {
for _ in 0..100 {
bit_arrayset.insert((r.next_u32() as usize) % BITS);
}
black_box(&bit_arrayset);
});
}
#[bench]
fn bench_bit_arrayset_big(b: &mut Bencher) {
let mut r = rng();
let mut bit_arrayset = BitArraySet::<u32, U16384>::new();
b.iter(|| {
for _ in 0..100 {
bit_arrayset.insert((r.next_u32() as usize) % U16384::to_usize());
}
black_box(&bit_arrayset);
});
}
#[bench]
fn bench_bit_arrayset_iter(b: &mut Bencher) {
let bit_arrayset = BitArraySet::from_bit_array(BitArray::<u32, U32>::from_fn(
|idx| {idx % 3 == 0}));
b.iter(|| {
let mut sum = 0;
for idx in &bit_arrayset {
sum += idx as usize;
}
sum
})
}
}