use semx_bitops::bitmap::BitMap;
#[test]
fn new_then_init() {
let mut bm = BitMap::new();
assert_eq!(bm.nr(), 0);
bm.init(128);
assert_eq!(bm.nr(), 128);
assert!(bm.is_empty());
}
#[test]
fn create_various_sizes() {
for nr in [0, 1, 63, 64, 65, 128, 200] {
let bm = BitMap::create(nr);
assert_eq!(bm.nr(), nr);
assert!(bm.is_empty());
}
}
#[test]
fn zero_length_bitmap() {
let bm = BitMap::create(0);
assert!(bm.is_empty());
assert!(bm.is_full());
assert_eq!(bm.count_ones(), 0);
assert_eq!(bm.find_first_bit(), 0);
assert_eq!(bm.find_first_zero_bit(), 0);
assert_eq!(bm.find_last_bit(), 0);
let other = BitMap::create(0);
assert!(bm.is_equal(&other));
assert!(!bm.intersects(&other));
}
#[test]
fn single_bit_bitmap() {
let mut bm = BitMap::create(1);
assert!(bm.is_empty());
assert!(!bm.is_full());
bm.set_bit(0);
assert!(bm.is_full());
assert!(!bm.is_empty());
assert!(bm.test_bit(0));
assert_eq!(bm.count_ones(), 1);
bm.clear_bit(0);
assert!(bm.is_empty());
assert!(!bm.test_bit(0));
}
#[test]
fn exact_word_boundary() {
let mut bm = BitMap::create(64);
assert!(bm.is_empty());
bm.set_fill();
assert!(bm.is_full());
assert_eq!(bm.count_ones(), 64);
bm.clear_bit(63);
assert!(!bm.is_full());
assert_eq!(bm.count_ones(), 63);
bm.set_zero();
bm.set_bit(63);
assert_eq!(bm.find_first_bit(), 63);
assert_eq!(bm.find_last_bit(), 63);
}
#[test]
fn just_over_word_boundary() {
let mut bm = BitMap::create(65);
bm.set_fill();
assert!(bm.is_full());
assert_eq!(bm.count_ones(), 65);
bm.clear_bit(64);
assert!(!bm.is_full());
assert_eq!(bm.count_ones(), 64);
}
#[test]
fn set_zero_and_fill() {
for nr in [10, 64, 100] {
let mut bm = BitMap::create(nr);
bm.set_fill();
assert_eq!(bm.count_ones(), nr);
assert!(bm.is_full());
bm.set_zero();
assert_eq!(bm.count_ones(), 0);
assert!(bm.is_empty());
}
}
#[test]
fn set_clear_change_bit() {
let mut bm = BitMap::create(128);
bm.set_bit(0);
bm.set_bit(63);
bm.set_bit(64);
bm.set_bit(127);
assert_eq!(bm.count_ones(), 4);
bm.clear_bit(63);
assert!(!bm.test_bit(63));
assert_eq!(bm.count_ones(), 3);
bm.change_bit(0);
assert!(!bm.test_bit(0));
bm.change_bit(0);
assert!(bm.test_bit(0));
}
#[test]
fn test_and_set() {
let mut bm = BitMap::create(64);
assert!(!bm.test_and_set_bit(10));
assert!(bm.test_and_set_bit(10));
}
#[test]
fn test_and_clear() {
let mut bm = BitMap::create(64);
bm.set_bit(10);
assert!(bm.test_and_clear_bit(10));
assert!(!bm.test_and_clear_bit(10));
}
#[test]
fn test_and_change() {
let mut bm = BitMap::create(64);
assert!(!bm.test_and_change_bit(5));
assert!(bm.test_bit(5));
assert!(bm.test_and_change_bit(5));
assert!(!bm.test_bit(5));
}
#[test]
fn bitmap_set_and_clear_range() {
let mut bm = BitMap::create(128);
bm.set_range(0, 128);
assert!(bm.is_full());
bm.clear_range(0, 128);
assert!(bm.is_empty());
}
#[test]
fn range_across_word_boundary() {
let mut bm = BitMap::create(128);
bm.set_range(60, 10);
assert_eq!(bm.count_ones(), 10);
for i in 60..70 {
assert!(bm.test_bit(i));
}
assert!(!bm.test_bit(59));
assert!(!bm.test_bit(70));
bm.clear_range(62, 5);
assert_eq!(bm.count_ones(), 5);
for i in 62..67 {
assert!(!bm.test_bit(i));
}
}
#[test]
fn find_first_and_last_bit() {
let mut bm = BitMap::create(200);
assert_eq!(bm.find_first_bit(), 200);
assert_eq!(bm.find_last_bit(), 200);
bm.set_bit(50);
bm.set_bit(150);
assert_eq!(bm.find_first_bit(), 50);
assert_eq!(bm.find_last_bit(), 150);
}
#[test]
fn find_first_zero_bit() {
let mut bm = BitMap::create(128);
assert_eq!(bm.find_first_zero_bit(), 0);
bm.set_fill();
assert_eq!(bm.find_first_zero_bit(), 128);
bm.clear_bit(100);
assert_eq!(bm.find_first_zero_bit(), 100);
}
#[test]
fn find_next_bit_walk() {
let mut bm = BitMap::create(200);
let positions = [3, 65, 127, 128, 199];
for &p in &positions {
bm.set_bit(p);
}
let mut found = Vec::new();
let mut offset = 0;
loop {
let pos = bm.find_next_bit(offset);
if pos >= bm.nr() {
break;
}
found.push(pos);
offset = pos + 1;
}
assert_eq!(found, positions);
}
#[test]
fn find_next_zero_bit_walk() {
let mut bm = BitMap::create(10);
bm.set_fill();
bm.clear_bit(2);
bm.clear_bit(7);
let mut found = Vec::new();
let mut offset = 0;
loop {
let pos = bm.find_next_zero_bit(offset);
if pos >= bm.nr() {
break;
}
found.push(pos);
offset = pos + 1;
}
assert_eq!(found, vec![2, 7]);
}
#[test]
fn find_next_zero_area() {
let mut bm = BitMap::create(100);
assert_eq!(bm.find_next_zero_area(0, 30, 0), 0);
bm.set_range(0, 50);
assert_eq!(bm.find_next_zero_area(0, 30, 0), 50);
assert!(bm.find_next_zero_area(0, 60, 0) > bm.nr());
}
#[test]
fn and_or_xor() {
let mut a = BitMap::create(128);
let mut b = BitMap::create(128);
let mut result = BitMap::create(128);
a.set_range(0, 64);
b.set_range(32, 64);
result.and(&a, &b);
assert_eq!(result.count_ones(), 32);
result.or(&a, &b);
assert_eq!(result.count_ones(), 96);
result.xor(&a, &b);
assert_eq!(result.count_ones(), 64);
}
#[test]
fn andnot() {
let mut a = BitMap::create(128);
let mut b = BitMap::create(128);
let mut result = BitMap::create(128);
a.set_range(0, 80);
b.set_range(40, 80);
result.andnot(&a, &b);
assert_eq!(result.count_ones(), 40);
for i in 0..40 {
assert!(result.test_bit(i));
}
}
#[test]
fn complement() {
let mut src = BitMap::create(100);
let mut dst = BitMap::create(100);
src.set_range(10, 20);
dst.complement(&src);
assert_eq!(src.count_ones() + dst.count_ones(), 100);
}
#[test]
fn is_equal_and_not_equal() {
let mut a = BitMap::create(100);
let mut b = BitMap::create(100);
assert!(a.is_equal(&b));
a.set_bit(99);
assert!(!a.is_equal(&b));
b.set_bit(99);
assert!(a.is_equal(&b));
}
#[test]
fn is_intersects() {
let mut a = BitMap::create(128);
let mut b = BitMap::create(128);
a.set_range(0, 50);
b.set_range(50, 50);
assert!(!a.intersects(&b));
b.set_bit(49);
assert!(a.intersects(&b));
}
#[test]
fn copy_from() {
let mut src = BitMap::create(200);
src.set_range(60, 80);
let mut dst = BitMap::create(200);
dst.copy_from(&src);
assert!(dst.is_equal(&src));
assert_eq!(dst.count_ones(), 80);
}
#[test]
fn extend_preserves_data() {
let mut bm = BitMap::create(64);
bm.set_fill();
bm.extend(64);
assert_eq!(bm.nr(), 128);
assert_eq!(bm.count_ones(), 64);
for i in 64..128 {
assert!(!bm.test_bit(i));
}
}
#[test]
fn extend_clears_tail_garbage() {
let mut bm = BitMap::create(10);
bm.set_fill();
bm.extend(10);
assert_eq!(bm.nr(), 20);
assert_eq!(bm.count_ones(), 10);
}
#[test]
fn extend_from_zero() {
let mut bm = BitMap::create(0);
bm.extend(100);
assert_eq!(bm.nr(), 100);
assert!(bm.is_empty());
bm.set_bit(99);
assert!(bm.test_bit(99));
}
#[test]
fn default_trait() {
let bm = BitMap::default();
assert_eq!(bm.nr(), 0);
}
#[test]
fn reinit_resets_bitmap() {
let mut bm = BitMap::create(100);
bm.set_fill();
assert_eq!(bm.count_ones(), 100);
bm.init(50);
assert_eq!(bm.nr(), 50);
assert!(bm.is_empty());
}
#[test]
fn set_and_clear_zero_range() {
let mut bm = BitMap::create(64);
bm.set_range(10, 0);
assert!(bm.is_empty());
bm.set_fill();
bm.clear_range(10, 0);
assert!(bm.is_full());
}
#[test]
fn set_range_at_word_start() {
let mut bm = BitMap::create(256);
bm.set_range(64, 64);
assert_eq!(bm.count_ones(), 64);
assert!(!bm.test_bit(63));
assert!(bm.test_bit(64));
assert!(bm.test_bit(127));
assert!(!bm.test_bit(128));
}
#[test]
fn find_next_bit_offset_past_end() {
let mut bm = BitMap::create(64);
bm.set_fill();
assert_eq!(bm.find_next_bit(64), 64);
assert_eq!(bm.find_next_bit(100), 64);
assert_eq!(bm.find_next_zero_bit(64), 64);
assert_eq!(bm.find_next_zero_bit(100), 64);
}
#[test]
fn is_equal_ignores_tail_bits() {
let mut a = BitMap::create(100);
let mut b = BitMap::create(100);
a.set_fill();
b.set_fill();
assert!(a.is_equal(&b));
}
#[test]
fn intersects_only_in_last_partial_word() {
let mut a = BitMap::create(100);
let mut b = BitMap::create(100);
a.set_bit(99);
b.set_bit(99);
assert!(a.intersects(&b));
b.clear_bit(99);
b.set_bit(98);
assert!(!a.intersects(&b));
}
#[test]
fn empty_full_only_tail_word() {
let mut bm = BitMap::create(100);
bm.set_bit(99);
assert!(!bm.is_empty());
assert!(!bm.is_full());
bm.set_fill();
bm.clear_range(0, 64);
assert!(!bm.is_empty());
assert!(!bm.is_full());
}
#[test]
fn find_next_zero_area_aligned() {
let mut bm = BitMap::create(256);
bm.set_range(0, 3);
let idx = bm.find_next_zero_area(0, 4, 7);
assert_eq!(idx & 7, 0);
assert_eq!(idx, 8);
for i in idx..idx + 4 {
assert!(!bm.test_bit(i));
}
}
#[test]
fn count_one_word_boundary() {
let mut bm = BitMap::create(64);
bm.set_fill();
assert_eq!(bm.count_ones(), 64);
let mut bm = BitMap::create(65);
bm.set_fill();
assert_eq!(bm.count_ones(), 65);
bm.clear_bit(64);
assert_eq!(bm.count_ones(), 64);
}