2013-05-30 03:16:33 -07:00
|
|
|
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 16:48:01 -08:00
|
|
|
// 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.
|
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
#[allow(missing_doc)];
|
|
|
|
|
2013-05-17 15:28:44 -07:00
|
|
|
|
2013-06-28 18:32:26 -04:00
|
|
|
use std::cmp;
|
2013-07-31 21:07:44 +02:00
|
|
|
use std::iterator::RandomAccessIterator;
|
|
|
|
use std::iterator::{Invert, Enumerate};
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 18:05:17 +02:00
|
|
|
use std::num;
|
2013-06-28 18:32:26 -04:00
|
|
|
use std::ops;
|
|
|
|
use std::uint;
|
|
|
|
use std::vec;
|
2013-05-24 19:35:29 -07:00
|
|
|
|
2013-07-10 01:57:07 -04:00
|
|
|
#[deriving(Clone)]
|
2012-09-02 18:04:38 +01:00
|
|
|
struct SmallBitv {
|
|
|
|
/// only the lowest nbits of this value are used. the rest is undefined.
|
2013-02-17 17:54:18 -05:00
|
|
|
bits: uint
|
2012-09-02 18:04:38 +01:00
|
|
|
}
|
|
|
|
|
2012-08-21 19:42:16 +01:00
|
|
|
/// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-02-17 17:54:18 -05:00
|
|
|
fn small_mask(nbits: uint) -> uint {
|
2012-08-21 19:42:16 +01:00
|
|
|
(1 << nbits) - 1
|
|
|
|
}
|
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
impl SmallBitv {
|
|
|
|
pub fn new(bits: uint) -> SmallBitv {
|
2013-02-17 17:07:51 -05:00
|
|
|
SmallBitv {bits: bits}
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn bits_op(&mut self,
|
|
|
|
right_bits: uint,
|
|
|
|
nbits: uint,
|
|
|
|
f: &fn(uint, uint) -> uint)
|
|
|
|
-> bool {
|
2012-09-02 18:04:38 +01:00
|
|
|
let mask = small_mask(nbits);
|
2013-02-17 17:54:18 -05:00
|
|
|
let old_b: uint = self.bits;
|
2012-09-02 18:04:38 +01:00
|
|
|
let new_b = f(old_b, right_bits);
|
|
|
|
self.bits = new_b;
|
|
|
|
mask & old_b != mask & new_b
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn union(&mut self, s: &SmallBitv, nbits: uint) -> bool {
|
2012-08-21 19:42:16 +01:00
|
|
|
self.bits_op(s.bits, nbits, |u1, u2| u1 | u2)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn intersect(&mut self, s: &SmallBitv, nbits: uint) -> bool {
|
2012-08-21 19:42:16 +01:00
|
|
|
self.bits_op(s.bits, nbits, |u1, u2| u1 & u2)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn become(&mut self, s: &SmallBitv, nbits: uint) -> bool {
|
2012-08-21 19:42:16 +01:00
|
|
|
self.bits_op(s.bits, nbits, |_u1, u2| u2)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn difference(&mut self, s: &SmallBitv, nbits: uint) -> bool {
|
2013-01-15 12:43:40 -05:00
|
|
|
self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn get(&self, i: uint) -> bool {
|
2012-07-29 16:00:55 -07:00
|
|
|
(self.bits & (1 << i)) != 0
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn set(&mut self, i: uint, x: bool) {
|
2012-07-29 16:00:55 -07:00
|
|
|
if x {
|
|
|
|
self.bits |= 1<<i;
|
|
|
|
}
|
|
|
|
else {
|
2013-02-17 17:54:18 -05:00
|
|
|
self.bits &= !(1<<i as uint);
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn equals(&self, b: &SmallBitv, nbits: uint) -> bool {
|
2012-08-21 19:42:16 +01:00
|
|
|
let mask = small_mask(nbits);
|
|
|
|
mask & self.bits == mask & b.bits
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn clear(&mut self) { self.bits = 0; }
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn set_all(&mut self) { self.bits = !0; }
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn is_true(&self, nbits: uint) -> bool {
|
2012-08-21 19:42:16 +01:00
|
|
|
small_mask(nbits) & !self.bits == 0
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn is_false(&self, nbits: uint) -> bool {
|
2012-08-21 19:42:16 +01:00
|
|
|
small_mask(nbits) & self.bits == 0
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-07-11 21:10:59 -04:00
|
|
|
pub fn negate(&mut self) { self.bits = !self.bits; }
|
2012-09-02 18:04:38 +01:00
|
|
|
}
|
|
|
|
|
2013-07-10 01:57:07 -04:00
|
|
|
#[deriving(Clone)]
|
2012-09-02 18:04:38 +01:00
|
|
|
struct BigBitv {
|
2013-02-17 17:07:51 -05:00
|
|
|
storage: ~[uint]
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2010-10-21 07:36:13 -07:00
|
|
|
|
2012-08-21 19:42:16 +01:00
|
|
|
/**
|
|
|
|
* a mask that has a 1 for each defined bit in the nth element of a big_bitv,
|
|
|
|
* assuming n bits.
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2012-08-21 19:42:16 +01:00
|
|
|
fn big_mask(nbits: uint, elem: uint) -> uint {
|
2013-02-17 17:56:07 -05:00
|
|
|
let rmd = nbits % uint::bits;
|
|
|
|
let nelems = nbits/uint::bits + if rmd == 0 {0} else {1};
|
2012-08-21 19:42:16 +01:00
|
|
|
|
|
|
|
if elem < nelems - 1 || rmd == 0 {
|
|
|
|
!0
|
|
|
|
} else {
|
|
|
|
(1 << rmd) - 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
impl BigBitv {
|
|
|
|
pub fn new(storage: ~[uint]) -> BigBitv {
|
2013-02-17 17:07:51 -05:00
|
|
|
BigBitv {storage: storage}
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn process(&mut self,
|
|
|
|
b: &BigBitv,
|
|
|
|
nbits: uint,
|
|
|
|
op: &fn(uint, uint) -> uint)
|
|
|
|
-> bool {
|
2012-09-02 18:04:38 +01:00
|
|
|
let len = b.storage.len();
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(self.storage.len(), len);
|
2012-09-02 18:04:38 +01:00
|
|
|
let mut changed = false;
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in range(0, len) {
|
2012-09-02 18:04:38 +01:00
|
|
|
let mask = big_mask(nbits, i);
|
|
|
|
let w0 = self.storage[i] & mask;
|
|
|
|
let w1 = b.storage[i] & mask;
|
|
|
|
let w = op(w0, w1) & mask;
|
2013-01-23 11:43:58 -08:00
|
|
|
if w0 != w {
|
2013-02-17 20:01:47 -05:00
|
|
|
changed = true;
|
|
|
|
self.storage[i] = w;
|
2012-08-21 19:42:16 +01:00
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
changed
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) -> bool {
|
2013-08-01 18:35:46 -04:00
|
|
|
range(0u, self.storage.len()).advance(|i| op(&mut self.storage[i]))
|
2013-05-02 18:33:27 -04:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-07-31 21:07:44 +02:00
|
|
|
pub fn negate(&mut self) { do self.each_storage |w| { *w = !*w; true }; }
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
|
2013-02-17 17:58:55 -05:00
|
|
|
self.process(b, nbits, |w1, w2| w1 | w2)
|
2012-08-21 19:42:16 +01:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn intersect(&mut self, b: &BigBitv, nbits: uint) -> bool {
|
2013-02-17 17:58:55 -05:00
|
|
|
self.process(b, nbits, |w1, w2| w1 & w2)
|
2012-08-21 19:42:16 +01:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn become(&mut self, b: &BigBitv, nbits: uint) -> bool {
|
2013-02-17 17:58:55 -05:00
|
|
|
self.process(b, nbits, |_, w| w)
|
2012-08-21 19:42:16 +01:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn difference(&mut self, b: &BigBitv, nbits: uint) -> bool {
|
2013-02-17 17:58:55 -05:00
|
|
|
self.process(b, nbits, |w1, w2| w1 & !w2)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn get(&self, i: uint) -> bool {
|
2013-02-17 17:56:07 -05:00
|
|
|
let w = i / uint::bits;
|
|
|
|
let b = i % uint::bits;
|
2012-07-29 16:00:55 -07:00
|
|
|
let x = 1 & self.storage[w] >> b;
|
|
|
|
x == 1
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn set(&mut self, i: uint, x: bool) {
|
2013-02-17 17:56:07 -05:00
|
|
|
let w = i / uint::bits;
|
|
|
|
let b = i % uint::bits;
|
2012-07-29 16:00:55 -07:00
|
|
|
let flag = 1 << b;
|
|
|
|
self.storage[w] = if x { self.storage[w] | flag }
|
2013-02-17 17:07:51 -05:00
|
|
|
else { self.storage[w] & !flag };
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn equals(&self, b: &BigBitv, nbits: uint) -> bool {
|
2013-05-02 18:33:27 -04:00
|
|
|
let len = b.storage.len();
|
2013-08-02 02:17:20 -04:00
|
|
|
do uint::iterate(0, len) |i| {
|
2013-05-02 18:33:27 -04:00
|
|
|
let mask = big_mask(nbits, i);
|
|
|
|
if mask & self.storage[i] != mask & b.storage[i] {
|
2013-08-02 02:17:20 -04:00
|
|
|
false
|
|
|
|
} else {
|
|
|
|
true
|
2013-05-02 18:33:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2013-07-10 01:57:07 -04:00
|
|
|
#[deriving(Clone)]
|
2013-07-10 03:29:24 -04:00
|
|
|
enum BitvVariant { Big(BigBitv), Small(SmallBitv) }
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2012-08-11 10:08:42 -04:00
|
|
|
enum Op {Union, Intersect, Assign, Difference}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2013-05-28 22:11:41 -05:00
|
|
|
/// The bitvector type
|
2013-07-10 01:57:07 -04:00
|
|
|
#[deriving(Clone)]
|
2012-09-28 14:55:31 -07:00
|
|
|
pub struct Bitv {
|
2013-05-28 22:11:41 -05:00
|
|
|
/// Internal representation of the bit vector (small or large)
|
2012-09-02 18:04:38 +01:00
|
|
|
rep: BitvVariant,
|
2013-05-28 22:11:41 -05:00
|
|
|
/// The number of valid bits in the internal representation
|
2012-09-02 18:04:38 +01:00
|
|
|
nbits: uint
|
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2013-03-15 15:24:24 -04:00
|
|
|
fn die() -> ! {
|
2013-05-06 00:18:51 +02:00
|
|
|
fail!("Tried to do operation on bit vectors with different sizes");
|
2013-03-15 15:24:24 -04:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
impl Bitv {
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-02-17 17:07:51 -05:00
|
|
|
fn do_op(&mut self, op: Op, other: &Bitv) -> bool {
|
2012-09-02 18:04:38 +01:00
|
|
|
if self.nbits != other.nbits {
|
2013-03-15 15:24:24 -04:00
|
|
|
die();
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
match self.rep {
|
2013-02-17 17:07:51 -05:00
|
|
|
Small(ref mut s) => match other.rep {
|
2012-09-28 00:22:18 -07:00
|
|
|
Small(ref s1) => match op {
|
2013-07-10 03:29:24 -04:00
|
|
|
Union => s.union(s1, self.nbits),
|
|
|
|
Intersect => s.intersect(s1, self.nbits),
|
|
|
|
Assign => s.become(s1, self.nbits),
|
|
|
|
Difference => s.difference(s1, self.nbits)
|
2012-09-02 18:04:38 +01:00
|
|
|
},
|
2013-03-15 15:24:24 -04:00
|
|
|
Big(_) => die()
|
2012-09-02 18:04:38 +01:00
|
|
|
},
|
2013-02-17 17:07:51 -05:00
|
|
|
Big(ref mut s) => match other.rep {
|
2013-03-15 15:24:24 -04:00
|
|
|
Small(_) => die(),
|
2012-09-28 00:22:18 -07:00
|
|
|
Big(ref s1) => match op {
|
2013-07-10 03:29:24 -04:00
|
|
|
Union => s.union(s1, self.nbits),
|
|
|
|
Intersect => s.intersect(s1, self.nbits),
|
|
|
|
Assign => s.become(s1, self.nbits),
|
|
|
|
Difference => s.difference(s1, self.nbits)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
|
|
|
}
|
2011-10-27 15:35:56 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
}
|
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
impl Bitv {
|
|
|
|
pub fn new(nbits: uint, init: bool) -> Bitv {
|
2013-02-17 17:54:18 -05:00
|
|
|
let rep = if nbits <= uint::bits {
|
2013-07-10 03:29:24 -04:00
|
|
|
Small(SmallBitv::new(if init {!0} else {0}))
|
2013-02-17 17:07:51 -05:00
|
|
|
}
|
|
|
|
else {
|
2013-02-17 17:56:07 -05:00
|
|
|
let nelems = nbits/uint::bits +
|
|
|
|
if nbits % uint::bits == 0 {0} else {1};
|
2013-07-02 12:47:32 -07:00
|
|
|
let elem = if init {!0u} else {0u};
|
2013-05-23 09:39:00 -07:00
|
|
|
let s = vec::from_elem(nelems, elem);
|
2013-07-10 03:29:24 -04:00
|
|
|
Big(BigBitv::new(s))
|
2013-02-17 17:07:51 -05:00
|
|
|
};
|
|
|
|
Bitv {rep: rep, nbits: nbits}
|
|
|
|
}
|
2012-09-02 18:04:38 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the union of two bitvectors
|
|
|
|
*
|
|
|
|
* Sets `self` to the union of `self` and `v1`. Both bitvectors must be
|
|
|
|
* the same length. Returns 'true' if `self` changed.
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn union(&mut self, v1: &Bitv) -> bool { self.do_op(Union, v1) }
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Calculates the intersection of two bitvectors
|
|
|
|
*
|
|
|
|
* Sets `self` to the intersection of `self` and `v1`. Both bitvectors
|
|
|
|
* must be the same length. Returns 'true' if `self` changed.
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn intersect(&mut self, v1: &Bitv) -> bool {
|
|
|
|
self.do_op(Intersect, v1)
|
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Assigns the value of `v1` to `self`
|
|
|
|
*
|
|
|
|
* Both bitvectors must be the same length. Returns `true` if `self` was
|
|
|
|
* changed
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn assign(&mut self, v: &Bitv) -> bool { self.do_op(Assign, v) }
|
2012-07-29 16:00:55 -07:00
|
|
|
|
|
|
|
/// Retrieve the value at index `i`
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn get(&self, i: uint) -> bool {
|
|
|
|
assert!((i < self.nbits));
|
|
|
|
match self.rep {
|
|
|
|
Big(ref b) => b.get(i),
|
|
|
|
Small(ref s) => s.get(i)
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2011-04-12 12:16:21 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Set the value of a bit at a given index
|
|
|
|
*
|
|
|
|
* `i` must be less than the length of the bitvector.
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn set(&mut self, i: uint, x: bool) {
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!((i < self.nbits));
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2013-02-17 17:07:51 -05:00
|
|
|
Big(ref mut b) => b.set(i, x),
|
|
|
|
Small(ref mut s) => s.set(i, x)
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Compares two bitvectors
|
|
|
|
*
|
|
|
|
* Both bitvectors must be the same length. Returns `true` if both
|
|
|
|
* bitvectors contain identical elements.
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn equal(&self, v1: &Bitv) -> bool {
|
2012-08-01 17:30:05 -07:00
|
|
|
if self.nbits != v1.nbits { return false; }
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2012-09-28 00:22:18 -07:00
|
|
|
Small(ref b) => match v1.rep {
|
2013-07-10 03:29:24 -04:00
|
|
|
Small(ref b1) => b.equals(b1, self.nbits),
|
2012-08-03 19:59:04 -07:00
|
|
|
_ => false
|
2012-08-06 17:14:32 -07:00
|
|
|
},
|
2012-09-28 00:22:18 -07:00
|
|
|
Big(ref s) => match v1.rep {
|
2013-07-10 03:29:24 -04:00
|
|
|
Big(ref s1) => s.equals(s1, self.nbits),
|
2012-08-11 10:08:42 -04:00
|
|
|
Small(_) => return false
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
}
|
|
|
|
|
2012-07-29 16:00:55 -07:00
|
|
|
/// Set all bits to 0
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn clear(&mut self) {
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2013-02-17 17:07:51 -05:00
|
|
|
Small(ref mut b) => b.clear(),
|
2013-08-02 02:17:20 -04:00
|
|
|
Big(ref mut s) => { do s.each_storage() |w| { *w = 0u; true }; }
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2012-07-29 16:00:55 -07:00
|
|
|
/// Set all bits to 1
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn set_all(&mut self) {
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2013-02-17 17:07:51 -05:00
|
|
|
Small(ref mut b) => b.set_all(),
|
2013-08-02 02:17:20 -04:00
|
|
|
Big(ref mut s) => { do s.each_storage() |w| { *w = !0u; true }; }
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2011-05-18 15:38:11 -07:00
|
|
|
|
2012-07-29 16:00:55 -07:00
|
|
|
/// Invert all bits
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-07-11 21:10:59 -04:00
|
|
|
pub fn negate(&mut self) {
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2013-07-11 21:10:59 -04:00
|
|
|
Small(ref mut b) => b.negate(),
|
2013-08-02 02:17:20 -04:00
|
|
|
Big(ref mut s) => { do s.each_storage() |w| { *w = !*w; true }; }
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Calculate the difference between two bitvectors
|
|
|
|
*
|
|
|
|
* Sets each element of `v0` to the value of that element minus the
|
|
|
|
* element of `v1` at the same index. Both bitvectors must be the same
|
|
|
|
* length.
|
|
|
|
*
|
|
|
|
* Returns `true` if `v0` was changed.
|
|
|
|
*/
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn difference(&mut self, v: &Bitv) -> bool {
|
|
|
|
self.do_op(Difference, v)
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/// Returns true if all bits are 1
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn is_true(&self) -> bool {
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2012-09-28 00:22:18 -07:00
|
|
|
Small(ref b) => b.is_true(self.nbits),
|
2012-08-03 19:59:04 -07:00
|
|
|
_ => {
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in self.iter() { if !i { return false; } }
|
2012-07-29 16:00:55 -07:00
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-10-20 17:04:15 -07:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-07-10 01:06:38 -04:00
|
|
|
pub fn iter<'a>(&'a self) -> BitvIterator<'a> {
|
2013-07-29 21:22:54 +02:00
|
|
|
BitvIterator {bitv: self, next_idx: 0, end_idx: self.nbits}
|
2013-05-02 18:33:27 -04:00
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2013-07-30 02:48:40 +02:00
|
|
|
#[inline]
|
|
|
|
pub fn rev_liter<'a>(&'a self) -> Invert<BitvIterator<'a>> {
|
|
|
|
self.iter().invert()
|
|
|
|
}
|
|
|
|
|
2012-07-29 16:00:55 -07:00
|
|
|
/// Returns true if all bits are 0
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn is_false(&self) -> bool {
|
2012-08-06 12:34:08 -07:00
|
|
|
match self.rep {
|
2012-09-28 00:22:18 -07:00
|
|
|
Small(ref b) => b.is_false(self.nbits),
|
2012-08-11 10:08:42 -04:00
|
|
|
Big(_) => {
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in self.iter() { if i { return false; } }
|
2012-07-29 16:00:55 -07:00
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-06-15 11:19:50 -07:00
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn init_to_vec(&self, i: uint) -> uint {
|
2012-08-01 17:30:05 -07:00
|
|
|
return if self.get(i) { 1 } else { 0 };
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
2011-04-06 17:56:44 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Converts `self` to a vector of uint with the same length.
|
|
|
|
*
|
|
|
|
* Each uint in the resulting vector has either value 0u or 1u.
|
|
|
|
*/
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn to_vec(&self) -> ~[uint] {
|
2012-08-02 15:42:56 -07:00
|
|
|
vec::from_fn(self.nbits, |x| self.init_to_vec(x))
|
2012-03-27 15:14:12 +02:00
|
|
|
}
|
2012-05-31 11:37:39 -07:00
|
|
|
|
2012-09-01 18:13:37 +01:00
|
|
|
/**
|
|
|
|
* Organise the bits into bytes, such that the first bit in the
|
|
|
|
* bitv becomes the high-order bit of the first byte. If the
|
|
|
|
* size of the bitv is not a multiple of 8 then trailing bits
|
|
|
|
* will be filled-in with false/0
|
|
|
|
*/
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn to_bytes(&self) -> ~[u8] {
|
2012-09-01 18:13:37 +01:00
|
|
|
fn bit (bitv: &Bitv, byte: uint, bit: uint) -> u8 {
|
|
|
|
let offset = byte * 8 + bit;
|
|
|
|
if offset >= bitv.nbits {
|
|
|
|
0
|
|
|
|
} else {
|
2013-04-10 13:14:06 -07:00
|
|
|
bitv[offset] as u8 << (7 - bit)
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let len = self.nbits/8 +
|
|
|
|
if self.nbits % 8 == 0 { 0 } else { 1 };
|
|
|
|
vec::from_fn(len, |i|
|
2013-02-17 17:07:51 -05:00
|
|
|
bit(self, i, 0) |
|
|
|
|
bit(self, i, 1) |
|
|
|
|
bit(self, i, 2) |
|
|
|
|
bit(self, i, 3) |
|
|
|
|
bit(self, i, 4) |
|
|
|
|
bit(self, i, 5) |
|
|
|
|
bit(self, i, 6) |
|
|
|
|
bit(self, i, 7)
|
2012-09-01 18:13:37 +01:00
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Transform self into a [bool] by turning each bit into a bool
|
|
|
|
*/
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn to_bools(&self) -> ~[bool] {
|
2013-04-10 13:14:06 -07:00
|
|
|
vec::from_fn(self.nbits, |i| self[i])
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
|
|
|
* Converts `self` to a string.
|
|
|
|
*
|
|
|
|
* The resulting string has the same length as `self`, and each
|
|
|
|
* character is either '0' or '1'.
|
|
|
|
*/
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn to_str(&self) -> ~str {
|
2013-06-11 19:13:42 -07:00
|
|
|
let mut rs = ~"";
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in self.iter() {
|
2013-06-11 19:13:42 -07:00
|
|
|
if i {
|
|
|
|
rs.push_char('1');
|
|
|
|
} else {
|
|
|
|
rs.push_char('0');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
rs
|
2012-07-29 16:00:55 -07:00
|
|
|
}
|
|
|
|
|
2011-04-07 18:15:56 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
/**
|
2013-07-12 09:52:49 +10:00
|
|
|
* Compare a bitvector to a vector of bool.
|
2012-09-02 18:04:38 +01:00
|
|
|
*
|
2013-07-12 09:52:49 +10:00
|
|
|
* Both the bitvector and vector must have the same length.
|
2012-09-02 18:04:38 +01:00
|
|
|
*/
|
2013-07-12 23:17:59 +10:00
|
|
|
pub fn eq_vec(&self, v: &[bool]) -> bool {
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(self.nbits, v.len());
|
2012-09-02 18:04:38 +01:00
|
|
|
let mut i = 0;
|
|
|
|
while i < self.nbits {
|
2013-07-12 09:52:49 +10:00
|
|
|
if self.get(i) != v[i] { return false; }
|
2012-09-02 18:04:38 +01:00
|
|
|
i = i + 1;
|
|
|
|
}
|
|
|
|
true
|
|
|
|
}
|
2012-07-17 17:03:27 -07:00
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn ones(&self, f: &fn(uint) -> bool) -> bool {
|
2013-08-01 18:35:46 -04:00
|
|
|
range(0u, self.nbits).advance(|i| !self.get(i) || f(i))
|
2013-05-02 18:33:27 -04:00
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
|
2012-09-02 18:04:38 +01:00
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
|
2012-09-01 18:13:37 +01:00
|
|
|
/**
|
|
|
|
* Transform a byte-vector into a bitv. Each byte becomes 8 bits,
|
|
|
|
* with the most significant bits of each byte coming first. Each
|
|
|
|
* bit becomes true if equal to 1 or false if equal to 0.
|
|
|
|
*/
|
2012-09-28 14:55:31 -07:00
|
|
|
pub fn from_bytes(bytes: &[u8]) -> Bitv {
|
2012-09-01 18:13:37 +01:00
|
|
|
from_fn(bytes.len() * 8, |i| {
|
|
|
|
let b = bytes[i / 8] as uint;
|
|
|
|
let offset = i % 8;
|
|
|
|
b >> (7 - offset) & 1 == 1
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Transform a [bool] into a bitv by converting each bool into a bit.
|
|
|
|
*/
|
2012-09-28 14:55:31 -07:00
|
|
|
pub fn from_bools(bools: &[bool]) -> Bitv {
|
2012-09-01 18:13:37 +01:00
|
|
|
from_fn(bools.len(), |i| bools[i])
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a bitv of the specified length where the value at each
|
|
|
|
* index is f(index).
|
|
|
|
*/
|
2013-03-07 14:38:38 -08:00
|
|
|
pub fn from_fn(len: uint, f: &fn(index: uint) -> bool) -> Bitv {
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut bitv = Bitv::new(len, false);
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in range(0u, len) {
|
2012-09-01 18:13:37 +01:00
|
|
|
bitv.set(i, f(i));
|
|
|
|
}
|
2013-02-15 02:30:30 -05:00
|
|
|
bitv
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
|
|
|
|
2013-02-17 20:01:47 -05:00
|
|
|
impl ops::Index<uint,bool> for Bitv {
|
2013-03-26 15:04:30 -04:00
|
|
|
fn index(&self, i: &uint) -> bool {
|
|
|
|
self.get(*i)
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-03-21 21:34:30 -07:00
|
|
|
fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool {
|
2013-02-17 20:01:47 -05:00
|
|
|
if bits == 0 {
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in range(0u, uint::bits) {
|
2013-02-17 20:01:47 -05:00
|
|
|
if bits & (1 << i) != 0 {
|
|
|
|
if !f(base + i) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2012-07-29 16:00:55 -07:00
|
|
|
|
2013-07-10 01:06:38 -04:00
|
|
|
/// An iterator for Bitv
|
|
|
|
pub struct BitvIterator<'self> {
|
|
|
|
priv bitv: &'self Bitv,
|
2013-07-29 21:22:54 +02:00
|
|
|
priv next_idx: uint,
|
|
|
|
priv end_idx: uint,
|
2013-07-10 01:06:38 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self> Iterator<bool> for BitvIterator<'self> {
|
2013-07-14 11:52:49 -07:00
|
|
|
#[inline]
|
2013-07-10 01:06:38 -04:00
|
|
|
fn next(&mut self) -> Option<bool> {
|
2013-07-29 21:22:54 +02:00
|
|
|
if self.next_idx != self.end_idx {
|
2013-07-10 01:06:38 -04:00
|
|
|
let idx = self.next_idx;
|
|
|
|
self.next_idx += 1;
|
|
|
|
Some(self.bitv.get(idx))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
2013-07-29 21:22:54 +02:00
|
|
|
let rem = self.end_idx - self.next_idx;
|
2013-07-10 01:06:38 -04:00
|
|
|
(rem, Some(rem))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-29 21:22:54 +02:00
|
|
|
impl<'self> DoubleEndedIterator<bool> for BitvIterator<'self> {
|
|
|
|
#[inline]
|
|
|
|
fn next_back(&mut self) -> Option<bool> {
|
|
|
|
if self.next_idx != self.end_idx {
|
|
|
|
self.end_idx -= 1;
|
|
|
|
Some(self.bitv.get(self.end_idx))
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self> RandomAccessIterator<bool> for BitvIterator<'self> {
|
|
|
|
#[inline]
|
|
|
|
fn indexable(&self) -> uint {
|
|
|
|
self.end_idx - self.next_idx
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn idx(&self, index: uint) -> Option<bool> {
|
|
|
|
if index >= self.indexable() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(self.bitv.get(index))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-17 20:01:47 -05:00
|
|
|
/// An implementation of a set using a bit vector as an underlying
|
|
|
|
/// representation for holding numerical elements.
|
|
|
|
///
|
|
|
|
/// It should also be noted that the amount of storage necessary for holding a
|
|
|
|
/// set of objects is proportional to the maximum of the objects when viewed
|
|
|
|
/// as a uint.
|
2013-07-10 01:57:07 -04:00
|
|
|
#[deriving(Clone)]
|
2013-02-17 20:01:47 -05:00
|
|
|
pub struct BitvSet {
|
|
|
|
priv size: uint,
|
|
|
|
|
|
|
|
// In theory this is a Bitv instead of always a BigBitv, but knowing that
|
|
|
|
// there's an array of storage makes our lives a whole lot easier when
|
|
|
|
// performing union/intersection/etc operations
|
|
|
|
priv bitv: BigBitv
|
|
|
|
}
|
2013-01-15 12:43:40 -05:00
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
impl BitvSet {
|
2013-02-17 20:01:47 -05:00
|
|
|
/// Creates a new bit vector set with initially no contents
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn new() -> BitvSet {
|
2013-02-17 20:01:47 -05:00
|
|
|
BitvSet{ size: 0, bitv: BigBitv::new(~[0]) }
|
|
|
|
}
|
2012-07-17 15:16:09 -07:00
|
|
|
|
2013-02-17 20:01:47 -05:00
|
|
|
/// Creates a new bit vector set from the given bit vector
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn from_bitv(bitv: Bitv) -> BitvSet {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut size = 0;
|
2013-07-31 21:07:44 +02:00
|
|
|
do bitv.ones |_| {
|
2013-02-17 20:01:47 -05:00
|
|
|
size += 1;
|
2013-07-31 21:07:44 +02:00
|
|
|
true
|
|
|
|
};
|
2013-02-17 20:01:47 -05:00
|
|
|
let Bitv{rep, _} = bitv;
|
|
|
|
match rep {
|
2013-07-10 03:29:24 -04:00
|
|
|
Big(b) => BitvSet{ size: size, bitv: b },
|
|
|
|
Small(SmallBitv{bits}) =>
|
2013-02-17 20:01:47 -05:00
|
|
|
BitvSet{ size: size, bitv: BigBitv{ storage: ~[bits] } },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns the capacity in bits for this bit vector. Inserting any
|
|
|
|
/// element less than this amount will not trigger a resizing.
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn capacity(&self) -> uint { self.bitv.storage.len() * uint::bits }
|
2013-02-17 20:01:47 -05:00
|
|
|
|
|
|
|
/// Consumes this set to return the underlying bit vector
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn unwrap(self) -> Bitv {
|
2013-02-17 20:01:47 -05:00
|
|
|
let cap = self.capacity();
|
|
|
|
let BitvSet{bitv, _} = self;
|
2013-07-10 03:29:24 -04:00
|
|
|
return Bitv{ nbits:cap, rep: Big(bitv) };
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
2013-06-18 14:45:18 -07:00
|
|
|
#[inline]
|
2013-05-31 15:17:22 -07:00
|
|
|
fn other_op(&mut self, other: &BitvSet, f: &fn(uint, uint) -> uint) {
|
2013-02-17 20:01:47 -05:00
|
|
|
fn nbits(mut w: uint) -> uint {
|
|
|
|
let mut bits = 0;
|
2013-08-03 12:45:23 -04:00
|
|
|
for _ in range(0u, uint::bits) {
|
2013-02-17 20:01:47 -05:00
|
|
|
if w == 0 {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bits += w & 1;
|
|
|
|
w >>= 1;
|
|
|
|
}
|
|
|
|
return bits;
|
|
|
|
}
|
|
|
|
if self.capacity() < other.capacity() {
|
|
|
|
self.bitv.storage.grow(other.capacity() / uint::bits, &0);
|
|
|
|
}
|
2013-08-03 12:45:23 -04:00
|
|
|
for (i, &w) in other.bitv.storage.iter().enumerate() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let old = self.bitv.storage[i];
|
|
|
|
let new = f(old, w);
|
|
|
|
self.bitv.storage[i] = new;
|
|
|
|
self.size += nbits(new) - nbits(old);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Union in-place with the specified other bit vector
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn union_with(&mut self, other: &BitvSet) {
|
2013-02-17 20:01:47 -05:00
|
|
|
self.other_op(other, |w1, w2| w1 | w2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Intersect in-place with the specified other bit vector
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn intersect_with(&mut self, other: &BitvSet) {
|
2013-02-17 20:01:47 -05:00
|
|
|
self.other_op(other, |w1, w2| w1 & w2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Difference in-place with the specified other bit vector
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn difference_with(&mut self, other: &BitvSet) {
|
2013-02-17 20:01:47 -05:00
|
|
|
self.other_op(other, |w1, w2| w1 & !w2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Symmetric difference in-place with the specified other bit vector
|
2013-05-31 15:17:22 -07:00
|
|
|
pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
|
2013-02-17 20:01:47 -05:00
|
|
|
self.other_op(other, |w1, w2| w1 ^ w2);
|
|
|
|
}
|
|
|
|
|
2013-07-10 01:06:38 -04:00
|
|
|
pub fn iter<'a>(&'a self) -> BitvSetIterator<'a> {
|
|
|
|
BitvSetIterator {set: self, next_idx: 0}
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
2013-07-31 21:07:45 +02:00
|
|
|
|
|
|
|
pub fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
|
2013-08-03 12:45:23 -04:00
|
|
|
for (i, w1, w2) in self.common_iter(other) {
|
2013-07-31 21:07:45 +02:00
|
|
|
if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
|
2013-08-02 02:17:20 -04:00
|
|
|
return false
|
2013-07-31 21:07:45 +02:00
|
|
|
}
|
2013-08-02 02:17:20 -04:00
|
|
|
};
|
2013-07-31 21:07:45 +02:00
|
|
|
/* everything we have that they don't also shows up */
|
|
|
|
self.outlier_iter(other).advance(|(mine, i, w)|
|
|
|
|
!mine || iterate_bits(i, w, |b| f(&b))
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn symmetric_difference(&self, other: &BitvSet,
|
|
|
|
f: &fn(&uint) -> bool) -> bool {
|
2013-08-03 12:45:23 -04:00
|
|
|
for (i, w1, w2) in self.common_iter(other) {
|
2013-07-31 21:07:45 +02:00
|
|
|
if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
|
2013-08-02 02:17:20 -04:00
|
|
|
return false
|
2013-07-31 21:07:45 +02:00
|
|
|
}
|
2013-08-02 02:17:20 -04:00
|
|
|
};
|
2013-07-31 21:07:45 +02:00
|
|
|
self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
|
|
|
|
self.common_iter(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b)))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
|
2013-08-03 12:45:23 -04:00
|
|
|
for (i, w1, w2) in self.common_iter(other) {
|
2013-07-31 21:07:45 +02:00
|
|
|
if !iterate_bits(i, w1 | w2, |b| f(&b)) {
|
2013-08-02 02:17:20 -04:00
|
|
|
return false
|
2013-07-31 21:07:45 +02:00
|
|
|
}
|
2013-08-02 02:17:20 -04:00
|
|
|
};
|
2013-07-31 21:07:45 +02:00
|
|
|
self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
|
|
|
|
}
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl cmp::Eq for BitvSet {
|
2013-03-21 21:34:30 -07:00
|
|
|
fn eq(&self, other: &BitvSet) -> bool {
|
2013-02-17 20:01:47 -05:00
|
|
|
if self.size != other.size {
|
|
|
|
return false;
|
|
|
|
}
|
2013-08-03 12:45:23 -04:00
|
|
|
for (_, w1, w2) in self.common_iter(other) {
|
2013-02-17 20:01:47 -05:00
|
|
|
if w1 != w2 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2013-08-03 12:45:23 -04:00
|
|
|
for (_, _, w) in self.outlier_iter(other) {
|
2013-02-17 20:01:47 -05:00
|
|
|
if w != 0 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-03-21 21:34:30 -07:00
|
|
|
fn ne(&self, other: &BitvSet) -> bool { !self.eq(other) }
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Container for BitvSet {
|
2013-07-25 04:02:08 -04:00
|
|
|
#[inline]
|
2013-06-23 20:44:11 -07:00
|
|
|
fn len(&self) -> uint { self.size }
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Mutable for BitvSet {
|
|
|
|
fn clear(&mut self) {
|
2013-07-31 21:07:44 +02:00
|
|
|
do self.bitv.each_storage |w| { *w = 0; true };
|
2013-02-17 20:01:47 -05:00
|
|
|
self.size = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Set<uint> for BitvSet {
|
2013-03-21 21:34:30 -07:00
|
|
|
fn contains(&self, value: &uint) -> bool {
|
2013-02-17 20:01:47 -05:00
|
|
|
*value < self.bitv.storage.len() * uint::bits && self.bitv.get(*value)
|
|
|
|
}
|
|
|
|
|
2013-03-21 21:34:30 -07:00
|
|
|
fn is_disjoint(&self, other: &BitvSet) -> bool {
|
2013-07-31 21:07:44 +02:00
|
|
|
do self.intersection(other) |_| {
|
|
|
|
false
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-21 21:34:30 -07:00
|
|
|
fn is_subset(&self, other: &BitvSet) -> bool {
|
2013-08-03 12:45:23 -04:00
|
|
|
for (_, w1, w2) in self.common_iter(other) {
|
2013-02-17 20:01:47 -05:00
|
|
|
if w1 & w2 != w1 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* If anything is not ours, then everything is not ours so we're
|
|
|
|
definitely a subset in that case. Otherwise if there's any stray
|
|
|
|
ones that 'other' doesn't have, we're not a subset. */
|
2013-08-03 12:45:23 -04:00
|
|
|
for (mine, _, w) in self.outlier_iter(other) {
|
2013-02-17 20:01:47 -05:00
|
|
|
if !mine {
|
|
|
|
return true;
|
|
|
|
} else if w != 0 {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-03-21 21:34:30 -07:00
|
|
|
fn is_superset(&self, other: &BitvSet) -> bool {
|
2013-02-17 20:01:47 -05:00
|
|
|
other.is_subset(self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-13 19:44:36 -07:00
|
|
|
impl MutableSet<uint> for BitvSet {
|
|
|
|
fn insert(&mut self, value: uint) -> bool {
|
|
|
|
if self.contains(&value) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
let nbits = self.capacity();
|
|
|
|
if value >= nbits {
|
|
|
|
let newsize = num::max(value, nbits * 2) / uint::bits + 1;
|
|
|
|
assert!(newsize > self.bitv.storage.len());
|
|
|
|
self.bitv.storage.grow(newsize, &0);
|
|
|
|
}
|
|
|
|
self.size += 1;
|
|
|
|
self.bitv.set(value, true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn remove(&mut self, value: &uint) -> bool {
|
|
|
|
if !self.contains(value) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
self.size -= 1;
|
|
|
|
self.bitv.set(*value, false);
|
|
|
|
|
|
|
|
// Attempt to truncate our storage
|
|
|
|
let mut i = self.bitv.storage.len();
|
|
|
|
while i > 1 && self.bitv.storage[i - 1] == 0 {
|
|
|
|
i -= 1;
|
|
|
|
}
|
|
|
|
self.bitv.storage.truncate(i);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-31 15:17:22 -07:00
|
|
|
impl BitvSet {
|
2013-02-17 20:01:47 -05:00
|
|
|
/// Visits each of the words that the two bit vectors (self and other)
|
|
|
|
/// both have in common. The three yielded arguments are (bit location,
|
|
|
|
/// w1, w2) where the bit location is the number of bits offset so far,
|
|
|
|
/// and w1/w2 are the words coming from the two vectors self, other.
|
2013-07-31 21:07:44 +02:00
|
|
|
fn common_iter<'a>(&'a self, other: &'a BitvSet)
|
|
|
|
-> MapE<(uint,&uint),(uint,uint,uint), &'a ~[uint],Enumerate<vec::VecIterator<'a,uint>>> {
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 18:05:17 +02:00
|
|
|
let min = num::min(self.bitv.storage.len(),
|
2013-02-17 20:01:47 -05:00
|
|
|
other.bitv.storage.len());
|
2013-07-31 21:07:44 +02:00
|
|
|
MapE{iter: self.bitv.storage.slice(0, min).iter().enumerate(),
|
|
|
|
env: &other.bitv.storage,
|
|
|
|
f: |(i, &w): (uint, &uint), o_store| (i * uint::bits, w, o_store[i])
|
|
|
|
}
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Visits each word in self or other that extends beyond the other. This
|
|
|
|
/// will only iterate through one of the vectors, and it only iterates
|
|
|
|
/// over the portion that doesn't overlap with the other one.
|
|
|
|
///
|
|
|
|
/// The yielded arguments are a bool, the bit offset, and a word. The bool
|
|
|
|
/// is true if the word comes from 'self', and false if it comes from
|
|
|
|
/// 'other'.
|
2013-07-31 21:07:44 +02:00
|
|
|
fn outlier_iter<'a>(&'a self, other: &'a BitvSet)
|
|
|
|
-> MapE<(uint, &uint),(bool, uint, uint), uint, Enumerate<vec::VecIterator<'a, uint>>> {
|
2013-02-17 20:01:47 -05:00
|
|
|
let len1 = self.bitv.storage.len();
|
|
|
|
let len2 = other.bitv.storage.len();
|
Replaces the free-standing functions in f32, &c.
The free-standing functions in f32, f64, i8, i16, i32, i64, u8, u16,
u32, u64, float, int, and uint are replaced with generic functions in
num instead.
If you were previously using any of those functions, just replace them
with the corresponding function with the same name in num.
Note: If you were using a function that corresponds to an operator, use
the operator instead.
2013-07-08 18:05:17 +02:00
|
|
|
let min = num::min(len1, len2);
|
2013-02-17 20:01:47 -05:00
|
|
|
|
2013-07-31 21:07:44 +02:00
|
|
|
if min < len1 {
|
|
|
|
MapE{iter: self.bitv.storage.slice(min, len1).iter().enumerate(),
|
|
|
|
env: min,
|
|
|
|
f: |(i, &w): (uint, &uint), min| (true, (i + min) * uint::bits, w)
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
2013-07-31 21:07:44 +02:00
|
|
|
} else {
|
|
|
|
MapE{iter: other.bitv.storage.slice(min, len2).iter().enumerate(),
|
|
|
|
env: min,
|
|
|
|
f: |(i, &w): (uint, &uint), min| (false, (i + min) * uint::bits, w)
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
}
|
2013-07-31 21:07:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Like iterator::Map with explicit env capture
|
|
|
|
struct MapE<A, B, Env, I> {
|
|
|
|
priv env: Env,
|
|
|
|
priv f: &'static fn(A, Env) -> B,
|
|
|
|
priv iter: I,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self, A, B, Env: Clone, I: Iterator<A>> Iterator<B> for MapE<A, B, Env, I> {
|
|
|
|
#[inline]
|
|
|
|
fn next(&mut self) -> Option<B> {
|
|
|
|
match self.iter.next() {
|
|
|
|
Some(elt) => Some((self.f)(elt, self.env.clone())),
|
|
|
|
None => None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
self.iter.size_hint()
|
2012-11-28 13:51:50 -08:00
|
|
|
}
|
2012-07-27 14:51:19 -07:00
|
|
|
}
|
|
|
|
|
2013-07-10 01:06:38 -04:00
|
|
|
pub struct BitvSetIterator<'self> {
|
|
|
|
priv set: &'self BitvSet,
|
|
|
|
priv next_idx: uint
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'self> Iterator<uint> for BitvSetIterator<'self> {
|
2013-07-14 11:52:49 -07:00
|
|
|
#[inline]
|
2013-07-10 01:06:38 -04:00
|
|
|
fn next(&mut self) -> Option<uint> {
|
|
|
|
while self.next_idx < self.set.capacity() {
|
|
|
|
let idx = self.next_idx;
|
|
|
|
self.next_idx += 1;
|
|
|
|
|
|
|
|
if self.set.contains(&idx) {
|
|
|
|
return Some(idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
(0, Some(self.set.capacity() - self.next_idx))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-17 19:05:07 -08:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
2013-06-29 11:01:25 -04:00
|
|
|
use extra::test::BenchHarness;
|
2013-01-08 19:37:25 -08:00
|
|
|
|
|
|
|
use bitv::*;
|
2012-12-27 18:24:18 -08:00
|
|
|
use bitv;
|
|
|
|
|
2013-06-28 18:32:26 -04:00
|
|
|
use std::uint;
|
|
|
|
use std::vec;
|
|
|
|
use std::rand;
|
|
|
|
use std::rand::Rng;
|
2013-02-18 01:24:14 -05:00
|
|
|
|
2013-07-01 13:51:13 +10:00
|
|
|
static BENCH_BITS : uint = 1 << 14;
|
2012-12-27 18:24:18 -08:00
|
|
|
|
2012-05-27 22:08:48 +02:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_to_str() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let zerolen = Bitv::new(0u, false);
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(zerolen.to_str(), ~"");
|
2012-05-27 22:08:48 +02:00
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
let eightbits = Bitv::new(8u, false);
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(eightbits.to_str(), ~"00000000");
|
2012-05-27 22:08:48 +02:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:05:07 -08:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_0_elements() {
|
2013-05-23 09:39:00 -07:00
|
|
|
let act = Bitv::new(0u, false);
|
2013-07-12 09:52:49 +10:00
|
|
|
let exp = vec::from_elem::<bool>(0u, false);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(exp));
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_1_element() {
|
2013-05-23 09:39:00 -07:00
|
|
|
let mut act = Bitv::new(1u, false);
|
2013-07-17 21:12:01 +02:00
|
|
|
assert!(act.eq_vec([false]));
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(1u, true);
|
2013-07-17 21:12:01 +02:00
|
|
|
assert!(act.eq_vec([true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|
|
|
|
|
2012-08-21 19:41:29 +01:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_2_elements() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut b = bitv::Bitv::new(2, false);
|
2012-08-21 19:41:29 +01:00
|
|
|
b.set(0, true);
|
|
|
|
b.set(1, false);
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(b.to_str(), ~"10");
|
2012-08-21 19:41:29 +01:00
|
|
|
}
|
|
|
|
|
2012-01-17 19:05:07 -08:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_10_elements() {
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut act;
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 0
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(10u, false);
|
2013-07-12 09:52:49 +10:00
|
|
|
assert!((act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false])));
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 1
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(10u, true);
|
2013-07-17 21:12:01 +02:00
|
|
|
assert!((act.eq_vec([true, true, true, true, true, true, true, true, true, true])));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(10u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(0u, true);
|
|
|
|
act.set(1u, true);
|
|
|
|
act.set(2u, true);
|
|
|
|
act.set(3u, true);
|
|
|
|
act.set(4u, true);
|
2013-07-17 21:12:01 +02:00
|
|
|
assert!((act.eq_vec([true, true, true, true, true, false, false, false, false, false])));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(10u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(5u, true);
|
|
|
|
act.set(6u, true);
|
|
|
|
act.set(7u, true);
|
|
|
|
act.set(8u, true);
|
|
|
|
act.set(9u, true);
|
2013-07-17 21:12:01 +02:00
|
|
|
assert!((act.eq_vec([false, false, false, false, false, true, true, true, true, true])));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(10u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(0u, true);
|
|
|
|
act.set(3u, true);
|
|
|
|
act.set(6u, true);
|
|
|
|
act.set(9u, true);
|
2013-07-17 21:12:01 +02:00
|
|
|
assert!((act.eq_vec([true, false, false, true, false, false, true, false, false, true])));
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_31_elements() {
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut act;
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 0
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(31u, false);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 1
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(31u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[true, true, true, true, true, true, true, true, true, true, true, true, true,
|
2013-07-12 09:52:49 +10:00
|
|
|
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(31u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(0u, true);
|
|
|
|
act.set(1u, true);
|
|
|
|
act.set(2u, true);
|
|
|
|
act.set(3u, true);
|
|
|
|
act.set(4u, true);
|
|
|
|
act.set(5u, true);
|
|
|
|
act.set(6u, true);
|
|
|
|
act.set(7u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[true, true, true, true, true, true, true, true, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(31u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(16u, true);
|
|
|
|
act.set(17u, true);
|
|
|
|
act.set(18u, true);
|
|
|
|
act.set(19u, true);
|
|
|
|
act.set(20u, true);
|
|
|
|
act.set(21u, true);
|
|
|
|
act.set(22u, true);
|
|
|
|
act.set(23u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, true, true, true, true, true, true, true, true,
|
|
|
|
false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(31u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(24u, true);
|
|
|
|
act.set(25u, true);
|
|
|
|
act.set(26u, true);
|
|
|
|
act.set(27u, true);
|
|
|
|
act.set(28u, true);
|
|
|
|
act.set(29u, true);
|
|
|
|
act.set(30u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, true, true, true, true, true, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(31u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(3u, true);
|
|
|
|
act.set(17u, true);
|
|
|
|
act.set(30u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, true, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, true, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_32_elements() {
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut act;
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 0
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(32u, false);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 1
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(32u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[true, true, true, true, true, true, true, true, true, true, true, true, true,
|
2013-07-12 09:52:49 +10:00
|
|
|
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(32u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(0u, true);
|
|
|
|
act.set(1u, true);
|
|
|
|
act.set(2u, true);
|
|
|
|
act.set(3u, true);
|
|
|
|
act.set(4u, true);
|
|
|
|
act.set(5u, true);
|
|
|
|
act.set(6u, true);
|
|
|
|
act.set(7u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[true, true, true, true, true, true, true, true, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(32u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(16u, true);
|
|
|
|
act.set(17u, true);
|
|
|
|
act.set(18u, true);
|
|
|
|
act.set(19u, true);
|
|
|
|
act.set(20u, true);
|
|
|
|
act.set(21u, true);
|
|
|
|
act.set(22u, true);
|
|
|
|
act.set(23u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, true, true, true, true, true, true, true, true,
|
|
|
|
false, false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(32u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(24u, true);
|
|
|
|
act.set(25u, true);
|
|
|
|
act.set(26u, true);
|
|
|
|
act.set(27u, true);
|
|
|
|
act.set(28u, true);
|
|
|
|
act.set(29u, true);
|
|
|
|
act.set(30u, true);
|
|
|
|
act.set(31u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, true, true, true, true, true, true, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(32u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(3u, true);
|
|
|
|
act.set(17u, true);
|
|
|
|
act.set(30u, true);
|
|
|
|
act.set(31u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, true, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, true, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_33_elements() {
|
2012-03-22 08:39:41 -07:00
|
|
|
let mut act;
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 0
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(33u, false);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// all 1
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(33u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[true, true, true, true, true, true, true, true, true, true, true, true, true,
|
2013-07-12 09:52:49 +10:00
|
|
|
true, true, true, true, true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(33u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(0u, true);
|
|
|
|
act.set(1u, true);
|
|
|
|
act.set(2u, true);
|
|
|
|
act.set(3u, true);
|
|
|
|
act.set(4u, true);
|
|
|
|
act.set(5u, true);
|
|
|
|
act.set(6u, true);
|
|
|
|
act.set(7u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[true, true, true, true, true, true, true, true, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(33u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(16u, true);
|
|
|
|
act.set(17u, true);
|
|
|
|
act.set(18u, true);
|
|
|
|
act.set(19u, true);
|
|
|
|
act.set(20u, true);
|
|
|
|
act.set(21u, true);
|
|
|
|
act.set(22u, true);
|
|
|
|
act.set(23u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, true, true, true, true, true, true, true, true,
|
|
|
|
false, false, false, false, false, false, false, false, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(33u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(24u, true);
|
|
|
|
act.set(25u, true);
|
|
|
|
act.set(26u, true);
|
|
|
|
act.set(27u, true);
|
|
|
|
act.set(28u, true);
|
|
|
|
act.set(29u, true);
|
|
|
|
act.set(30u, true);
|
|
|
|
act.set(31u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, false, false, false, false, false, false, false,
|
|
|
|
false, true, true, true, true, true, true, true, true, false]));
|
2012-01-17 19:05:07 -08:00
|
|
|
// mixed
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
act = Bitv::new(33u, false);
|
2012-07-29 16:00:55 -07:00
|
|
|
act.set(3u, true);
|
|
|
|
act.set(17u, true);
|
|
|
|
act.set(30u, true);
|
|
|
|
act.set(31u, true);
|
|
|
|
act.set(32u, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(act.eq_vec(
|
2013-07-17 21:12:01 +02:00
|
|
|
[false, false, false, true, false, false, false, false, false, false, false, false,
|
2013-07-12 09:52:49 +10:00
|
|
|
false, false, false, false, false, true, false, false, false, false, false, false,
|
|
|
|
false, false, false, false, false, false, true, true, true]));
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|
|
|
|
|
2012-05-31 11:37:39 -07:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_equal_differing_sizes() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let v0 = Bitv::new(10u, false);
|
|
|
|
let v1 = Bitv::new(11u, false);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(!v0.equal(&v1));
|
2012-05-31 11:37:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_equal_greatly_differing_sizes() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let v0 = Bitv::new(10u, false);
|
|
|
|
let v1 = Bitv::new(110u, false);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(!v0.equal(&v1));
|
2012-05-31 11:37:39 -07:00
|
|
|
}
|
2012-08-21 19:42:16 +01:00
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_equal_sneaky_small() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut a = bitv::Bitv::new(1, false);
|
2012-08-21 19:42:16 +01:00
|
|
|
a.set(0, true);
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut b = bitv::Bitv::new(1, true);
|
2012-08-21 19:42:16 +01:00
|
|
|
b.set(0, true);
|
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.equal(&b));
|
2012-08-21 19:42:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_equal_sneaky_big() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut a = bitv::Bitv::new(100, false);
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in range(0u, 100) {
|
2012-08-21 19:42:16 +01:00
|
|
|
a.set(i, true);
|
|
|
|
}
|
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut b = bitv::Bitv::new(100, true);
|
2013-08-03 12:45:23 -04:00
|
|
|
for i in range(0u, 100) {
|
2012-08-21 19:42:16 +01:00
|
|
|
b.set(i, true);
|
|
|
|
}
|
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.equal(&b));
|
2012-08-21 19:42:16 +01:00
|
|
|
}
|
|
|
|
|
2012-09-01 18:13:37 +01:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_from_bytes() {
|
2012-09-01 18:13:37 +01:00
|
|
|
let bitv = from_bytes([0b10110110, 0b00000000, 0b11111111]);
|
2013-05-27 18:04:00 -05:00
|
|
|
let str = ~"10110110" + "00000000" + "11111111";
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(bitv.to_str(), str);
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_to_bytes() {
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut bv = Bitv::new(3, true);
|
2012-09-01 18:13:37 +01:00
|
|
|
bv.set(1, false);
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(bv.to_bytes(), ~[0b10100000]);
|
2012-09-01 18:13:37 +01:00
|
|
|
|
2013-02-17 17:07:51 -05:00
|
|
|
let mut bv = Bitv::new(9, false);
|
2012-09-01 18:13:37 +01:00
|
|
|
bv.set(2, true);
|
|
|
|
bv.set(8, true);
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(bv.to_bytes(), ~[0b00100000, 0b10000000]);
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_from_bools() {
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(from_bools([true, false, true, true]).to_str() ==
|
2013-03-06 19:09:17 -08:00
|
|
|
~"1011");
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_to_bools() {
|
2012-09-01 18:13:37 +01:00
|
|
|
let bools = ~[false, false, true, false, false, true, true, false];
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(from_bytes([0b00100110]).to_bools(), bools);
|
2012-09-01 18:13:37 +01:00
|
|
|
}
|
2013-01-15 12:43:40 -05:00
|
|
|
|
2013-07-12 02:13:26 -04:00
|
|
|
#[test]
|
|
|
|
fn test_bitv_iterator() {
|
|
|
|
let bools = [true, false, true, true];
|
|
|
|
let bitv = from_bools(bools);
|
|
|
|
|
2013-08-03 12:45:23 -04:00
|
|
|
for (act, &ex) in bitv.iter().zip(bools.iter()) {
|
2013-07-12 02:13:26 -04:00
|
|
|
assert_eq!(ex, act);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bitv_set_iterator() {
|
|
|
|
let bools = [true, false, true, true];
|
|
|
|
let bitv = BitvSet::from_bitv(from_bools(bools));
|
|
|
|
|
|
|
|
let idxs: ~[uint] = bitv.iter().collect();
|
|
|
|
assert_eq!(idxs, ~[0, 2, 3]);
|
|
|
|
}
|
|
|
|
|
2013-01-15 12:43:40 -05:00
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_small_difference() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut b1 = Bitv::new(3, false);
|
|
|
|
let mut b2 = Bitv::new(3, false);
|
|
|
|
b1.set(0, true);
|
|
|
|
b1.set(1, true);
|
|
|
|
b2.set(1, true);
|
|
|
|
b2.set(2, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(b1.difference(&b2));
|
|
|
|
assert!(b1[0]);
|
|
|
|
assert!(!b1[1]);
|
|
|
|
assert!(!b1[2]);
|
2013-01-15 12:43:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_big_difference() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut b1 = Bitv::new(100, false);
|
|
|
|
let mut b2 = Bitv::new(100, false);
|
|
|
|
b1.set(0, true);
|
|
|
|
b1.set(40, true);
|
|
|
|
b2.set(40, true);
|
|
|
|
b2.set(80, true);
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(b1.difference(&b2));
|
|
|
|
assert!(b1[0]);
|
|
|
|
assert!(!b1[40]);
|
|
|
|
assert!(!b1[80]);
|
2013-01-15 12:43:40 -05:00
|
|
|
}
|
2013-02-04 11:14:33 -05:00
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_small_clear() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut b = Bitv::new(14, true);
|
|
|
|
b.clear();
|
2013-07-31 21:07:44 +02:00
|
|
|
do b.ones |i| {
|
|
|
|
fail!("found 1 at %?", i)
|
|
|
|
};
|
2013-02-04 11:14:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_big_clear() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut b = Bitv::new(140, true);
|
|
|
|
b.clear();
|
2013-07-31 21:07:44 +02:00
|
|
|
do b.ones |i| {
|
|
|
|
fail!("found 1 at %?", i)
|
|
|
|
};
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_bitv_set_basic() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut b = BitvSet::new();
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(b.insert(3));
|
|
|
|
assert!(!b.insert(3));
|
|
|
|
assert!(b.contains(&3));
|
|
|
|
assert!(b.insert(400));
|
|
|
|
assert!(!b.insert(400));
|
|
|
|
assert!(b.contains(&400));
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(b.len(), 2);
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bitv_set_intersection() {
|
|
|
|
let mut a = BitvSet::new();
|
|
|
|
let mut b = BitvSet::new();
|
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.insert(11));
|
|
|
|
assert!(a.insert(1));
|
|
|
|
assert!(a.insert(3));
|
|
|
|
assert!(a.insert(77));
|
|
|
|
assert!(a.insert(103));
|
|
|
|
assert!(a.insert(5));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(b.insert(2));
|
|
|
|
assert!(b.insert(11));
|
|
|
|
assert!(b.insert(77));
|
|
|
|
assert!(b.insert(5));
|
|
|
|
assert!(b.insert(3));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
let expected = [3, 5, 11, 77];
|
2013-07-31 21:07:44 +02:00
|
|
|
do a.intersection(&b) |x| {
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(*x, expected[i]);
|
2013-07-31 21:07:44 +02:00
|
|
|
i += 1;
|
|
|
|
true
|
|
|
|
};
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(i, expected.len());
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bitv_set_difference() {
|
|
|
|
let mut a = BitvSet::new();
|
|
|
|
let mut b = BitvSet::new();
|
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.insert(1));
|
|
|
|
assert!(a.insert(3));
|
|
|
|
assert!(a.insert(5));
|
|
|
|
assert!(a.insert(200));
|
|
|
|
assert!(a.insert(500));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(b.insert(3));
|
|
|
|
assert!(b.insert(200));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
let expected = [1, 5, 500];
|
2013-07-31 21:07:44 +02:00
|
|
|
do a.difference(&b) |x| {
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(*x, expected[i]);
|
2013-07-31 21:07:44 +02:00
|
|
|
i += 1;
|
|
|
|
true
|
|
|
|
};
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(i, expected.len());
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_bitv_set_symmetric_difference() {
|
|
|
|
let mut a = BitvSet::new();
|
|
|
|
let mut b = BitvSet::new();
|
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.insert(1));
|
|
|
|
assert!(a.insert(3));
|
|
|
|
assert!(a.insert(5));
|
|
|
|
assert!(a.insert(9));
|
|
|
|
assert!(a.insert(11));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(b.insert(3));
|
|
|
|
assert!(b.insert(9));
|
|
|
|
assert!(b.insert(14));
|
|
|
|
assert!(b.insert(220));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
let expected = [1, 5, 11, 14, 220];
|
2013-07-31 21:07:44 +02:00
|
|
|
do a.symmetric_difference(&b) |x| {
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(*x, expected[i]);
|
2013-07-31 21:07:44 +02:00
|
|
|
i += 1;
|
|
|
|
true
|
|
|
|
};
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(i, expected.len());
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_bitv_set_union() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut a = BitvSet::new();
|
|
|
|
let mut b = BitvSet::new();
|
2013-03-28 18:39:09 -07:00
|
|
|
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!(b.insert(1));
|
|
|
|
assert!(b.insert(5));
|
|
|
|
assert!(b.insert(9));
|
|
|
|
assert!(b.insert(13));
|
|
|
|
assert!(b.insert(19));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
|
|
|
let mut i = 0;
|
|
|
|
let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160];
|
2013-07-31 21:07:44 +02:00
|
|
|
do a.union(&b) |x| {
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(*x, expected[i]);
|
2013-07-31 21:07:44 +02:00
|
|
|
i += 1;
|
|
|
|
true
|
|
|
|
};
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(i, expected.len());
|
2013-02-17 20:01:47 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn test_bitv_remove() {
|
2013-02-17 20:01:47 -05:00
|
|
|
let mut a = BitvSet::new();
|
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.insert(1));
|
|
|
|
assert!(a.remove(&1));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.insert(100));
|
|
|
|
assert!(a.remove(&100));
|
2013-02-17 20:01:47 -05:00
|
|
|
|
2013-03-28 18:39:09 -07:00
|
|
|
assert!(a.insert(1000));
|
|
|
|
assert!(a.remove(&1000));
|
2013-05-18 22:02:45 -04:00
|
|
|
assert_eq!(a.capacity(), uint::bits);
|
2013-02-04 11:14:33 -05:00
|
|
|
}
|
2013-02-18 01:24:14 -05:00
|
|
|
|
2013-07-10 01:57:07 -04:00
|
|
|
#[test]
|
|
|
|
fn test_bitv_clone() {
|
|
|
|
let mut a = BitvSet::new();
|
|
|
|
|
|
|
|
assert!(a.insert(1));
|
|
|
|
assert!(a.insert(100));
|
|
|
|
assert!(a.insert(1000));
|
|
|
|
|
|
|
|
let mut b = a.clone();
|
|
|
|
|
|
|
|
assert_eq!(&a, &b);
|
|
|
|
|
|
|
|
assert!(b.remove(&1));
|
|
|
|
assert!(a.contains(&1));
|
|
|
|
|
|
|
|
assert!(a.remove(&1000));
|
|
|
|
assert!(b.contains(&1000));
|
|
|
|
}
|
|
|
|
|
2013-04-24 22:29:19 +10:00
|
|
|
fn rng() -> rand::IsaacRng {
|
2013-02-19 07:38:18 -08:00
|
|
|
let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
|
2013-04-24 00:00:43 +10:00
|
|
|
rand::IsaacRng::new_seeded(seed)
|
2013-02-18 01:24:14 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_uint_small(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = 0 as uint;
|
|
|
|
do b.iter {
|
|
|
|
bitv |= (1 << ((r.next() as uint) % uint::bits));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_small_bitv_small(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = SmallBitv::new(uint::bits);
|
|
|
|
do b.iter {
|
|
|
|
bitv.set((r.next() as uint) % uint::bits, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_big_bitv_small(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = BigBitv::new(~[0]);
|
|
|
|
do b.iter {
|
|
|
|
bitv.set((r.next() as uint) % uint::bits, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_big_bitv_big(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut storage = ~[];
|
2013-07-11 12:05:17 -07:00
|
|
|
storage.grow(BENCH_BITS / uint::bits, &0u);
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = BigBitv::new(storage);
|
|
|
|
do b.iter {
|
2013-07-01 13:51:13 +10:00
|
|
|
bitv.set((r.next() as uint) % BENCH_BITS, true);
|
2013-02-18 01:24:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_bitv_big(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-07-01 13:51:13 +10:00
|
|
|
let mut bitv = Bitv::new(BENCH_BITS, false);
|
2013-02-18 01:24:14 -05:00
|
|
|
do b.iter {
|
2013-07-01 13:51:13 +10:00
|
|
|
bitv.set((r.next() as uint) % BENCH_BITS, true);
|
2013-02-18 01:24:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_bitv_small(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = Bitv::new(uint::bits, false);
|
|
|
|
do b.iter {
|
|
|
|
bitv.set((r.next() as uint) % uint::bits, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_bitv_set_small(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = BitvSet::new();
|
|
|
|
do b.iter {
|
|
|
|
bitv.insert((r.next() as uint) % uint::bits);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_bitv_set_big(b: &mut BenchHarness) {
|
2013-05-07 17:57:58 -07:00
|
|
|
let mut r = rng();
|
2013-02-18 01:24:14 -05:00
|
|
|
let mut bitv = BitvSet::new();
|
|
|
|
do b.iter {
|
2013-07-01 13:51:13 +10:00
|
|
|
bitv.insert((r.next() as uint) % BENCH_BITS);
|
2013-02-18 01:24:14 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
2013-04-16 01:08:52 +10:00
|
|
|
fn bench_bitv_big_union(b: &mut BenchHarness) {
|
2013-07-01 13:51:13 +10:00
|
|
|
let mut b1 = Bitv::new(BENCH_BITS, false);
|
|
|
|
let b2 = Bitv::new(BENCH_BITS, false);
|
2013-02-18 01:24:14 -05:00
|
|
|
do b.iter {
|
|
|
|
b1.union(&b2);
|
|
|
|
}
|
|
|
|
}
|
2013-07-14 11:52:49 -07:00
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_btv_small_iter(b: &mut BenchHarness) {
|
|
|
|
let bitv = Bitv::new(uint::bits, false);
|
|
|
|
do b.iter {
|
2013-08-02 05:51:29 +09:00
|
|
|
let mut _sum = 0;
|
2013-08-03 12:45:23 -04:00
|
|
|
for pres in bitv.iter() {
|
2013-08-02 05:51:29 +09:00
|
|
|
_sum += pres as uint;
|
2013-07-14 11:52:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_bitv_big_iter(b: &mut BenchHarness) {
|
|
|
|
let bitv = Bitv::new(BENCH_BITS, false);
|
|
|
|
do b.iter {
|
2013-08-02 05:51:29 +09:00
|
|
|
let mut _sum = 0;
|
2013-08-03 12:45:23 -04:00
|
|
|
for pres in bitv.iter() {
|
2013-08-02 05:51:29 +09:00
|
|
|
_sum += pres as uint;
|
2013-07-14 11:52:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn bench_bitvset_iter(b: &mut BenchHarness) {
|
|
|
|
let bitv = BitvSet::from_bitv(from_fn(BENCH_BITS,
|
|
|
|
|idx| {idx % 3 == 0}));
|
|
|
|
do b.iter {
|
2013-08-02 05:51:29 +09:00
|
|
|
let mut _sum = 0;
|
2013-08-03 12:45:23 -04:00
|
|
|
for idx in bitv.iter() {
|
2013-08-02 05:51:29 +09:00
|
|
|
_sum += idx;
|
2013-07-14 11:52:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-01-17 19:05:07 -08:00
|
|
|
}
|