use semx_bitops::{
BITS_PER_LONG, bit, bit_mask, bit_ull, bit_word, bits_to_longs, change_bit, clear_bit,
deposit32, deposit64, extract8, extract16, extract32, extract64, find_first_bit,
find_first_zero_bit, find_last_bit, find_next_bit, find_next_zero_bit, half_shuffle32,
half_shuffle64, half_unshuffle32, half_unshuffle64, make_64bit_mask, set_bit,
test_and_change_bit, test_and_clear_bit, test_and_set_bit, test_bit,
};
#[test]
fn bits_per_long() {
#[cfg(target_pointer_width = "64")]
assert_eq!(BITS_PER_LONG, 64);
#[cfg(target_pointer_width = "32")]
assert_eq!(BITS_PER_LONG, 32);
}
#[test]
fn bit_and_bit_ull() {
assert_eq!(bit(0), 1);
assert_eq!(bit(1), 2);
assert_eq!(bit(2), 4);
assert_eq!(bit(28), 0x1000_0000);
assert_eq!(bit(31), 0x8000_0000);
assert_eq!(bit_ull(63), 1u64 << 63);
assert_eq!(bit_ull(0), 1);
}
#[test]
fn bit_mask_and_word() {
assert_eq!(bit_mask(0), 1);
assert_eq!(bit_mask(3), 8);
assert_eq!(bit_mask(BITS_PER_LONG), 1);
assert_eq!(bit_mask(BITS_PER_LONG + 3), 8);
assert_eq!(bit_word(0), 0);
assert_eq!(bit_word(BITS_PER_LONG - 1), 0);
assert_eq!(bit_word(BITS_PER_LONG), 1);
assert_eq!(bit_word(BITS_PER_LONG + 1), 1);
}
#[test]
fn bits_to_longs_cases() {
assert_eq!(bits_to_longs(0), 0);
assert_eq!(bits_to_longs(1), 1);
assert_eq!(bits_to_longs(BITS_PER_LONG), 1);
assert_eq!(bits_to_longs(BITS_PER_LONG + 1), 2);
assert_eq!(bits_to_longs(BITS_PER_LONG * 3), 3);
}
#[test]
fn make_64bit_mask_cases() {
assert_eq!(make_64bit_mask(0, 1), 1);
assert_eq!(make_64bit_mask(0, 2), 0b11);
assert_eq!(make_64bit_mask(1, 3), 0b1110);
assert_eq!(make_64bit_mask(0, 64), u64::MAX);
assert_eq!(make_64bit_mask(32, 32), 0xFFFF_FFFF_0000_0000);
assert_eq!(make_64bit_mask(60, 4), 0xF000_0000_0000_0000);
assert_eq!(make_64bit_mask(63, 1), 1u64 << 63);
}
#[test]
fn set_clear_change() {
let mut bits = [0usize; 1];
set_bit(0, &mut bits);
assert_eq!(bits[0], 1);
set_bit(5, &mut bits);
assert_eq!(bits[0], 0b10_0001);
clear_bit(0, &mut bits);
assert_eq!(bits[0], 0b10_0000);
change_bit(5, &mut bits);
assert_eq!(bits[0], 0);
change_bit(5, &mut bits);
assert_eq!(bits[0], 0b10_0000);
}
#[test]
fn set_clear_change_cross_word() {
let mut bits = [0usize; 2];
set_bit(BITS_PER_LONG, &mut bits);
assert_eq!(bits[0], 0);
assert_eq!(bits[1], 1);
clear_bit(BITS_PER_LONG, &mut bits);
assert_eq!(bits[1], 0);
change_bit(BITS_PER_LONG + 3, &mut bits);
assert_eq!(bits[1], 8);
}
#[test]
fn test_and_set() {
let mut bits = [0usize; 1];
assert!(!test_and_set_bit(3, &mut bits));
assert!(test_and_set_bit(3, &mut bits));
assert_eq!(bits[0], 8);
}
#[test]
fn test_and_clear() {
let mut bits = [0b1111usize; 1];
assert!(test_and_clear_bit(1, &mut bits));
assert!(!test_and_clear_bit(1, &mut bits));
assert_eq!(bits[0], 0b1101);
}
#[test]
fn test_and_change() {
let mut bits = [0usize; 1];
assert!(!test_and_change_bit(2, &mut bits));
assert!(test_bit(2, &bits));
assert!(test_and_change_bit(2, &mut bits));
assert!(!test_bit(2, &bits));
}
#[test]
fn test_bit_cases() {
let bits = [0b1010usize; 1];
assert!(!test_bit(0, &bits));
assert!(test_bit(1, &bits));
assert!(!test_bit(2, &bits));
assert!(test_bit(3, &bits));
}
#[test]
fn test_bit_cross_word() {
let mut bits = [0usize; 2];
set_bit(BITS_PER_LONG + 5, &mut bits);
assert!(!test_bit(5, &bits));
assert!(test_bit(BITS_PER_LONG + 5, &bits));
assert!(!test_bit(BITS_PER_LONG + 4, &bits));
}
#[test]
fn find_first_bit_cases() {
let bits = [0usize; 2];
assert_eq!(find_first_bit(&bits, 128), 128);
let bits = [0, 1usize];
assert_eq!(find_first_bit(&bits, 128), BITS_PER_LONG);
let bits = [8usize; 1];
assert_eq!(find_first_bit(&bits, BITS_PER_LONG), 3);
}
#[test]
fn find_first_zero_bit_cases() {
let bits = [usize::MAX; 2];
assert_eq!(find_first_zero_bit(&bits, 128), 128);
let bits = [usize::MAX, usize::MAX - 1];
assert_eq!(find_first_zero_bit(&bits, 128), BITS_PER_LONG);
}
#[test]
fn find_last_bit_cases() {
let bits = [0usize; 2];
assert_eq!(find_last_bit(&bits, 128), 128);
let bits = [0, 1usize];
assert_eq!(find_last_bit(&bits, 128), BITS_PER_LONG);
let bits = [0b1010usize; 1];
assert_eq!(find_last_bit(&bits, BITS_PER_LONG), 3);
}
#[test]
fn find_next_bit_cases() {
let bits = [0b1010_1100usize; 1];
assert_eq!(find_next_bit(&bits, BITS_PER_LONG, 0), 2);
assert_eq!(find_next_bit(&bits, BITS_PER_LONG, 3), 3);
assert_eq!(find_next_bit(&bits, BITS_PER_LONG, 4), 5);
assert_eq!(find_next_bit(&bits, BITS_PER_LONG, 8), BITS_PER_LONG);
}
#[test]
fn find_next_zero_bit_cases() {
let bits = [0b1111_0011usize; 1];
assert_eq!(find_next_zero_bit(&bits, BITS_PER_LONG, 0), 2);
assert_eq!(find_next_zero_bit(&bits, BITS_PER_LONG, 2), 2);
assert_eq!(find_next_zero_bit(&bits, BITS_PER_LONG, 4), 8);
}
#[test]
fn find_next_bit_offset_past_end() {
let bits = [usize::MAX; 1];
assert_eq!(find_next_bit(&bits, BITS_PER_LONG, BITS_PER_LONG), BITS_PER_LONG);
assert_eq!(find_next_bit(&bits, BITS_PER_LONG, BITS_PER_LONG + 10), BITS_PER_LONG);
assert_eq!(find_next_zero_bit(&bits, BITS_PER_LONG, BITS_PER_LONG), BITS_PER_LONG);
}
#[test]
fn find_multi_word() {
let mut bits = [0usize; 3];
set_bit(BITS_PER_LONG + 5, &mut bits);
set_bit(BITS_PER_LONG * 2 + 10, &mut bits);
assert_eq!(find_first_bit(&bits, BITS_PER_LONG * 3), BITS_PER_LONG + 5);
assert_eq!(find_last_bit(&bits, BITS_PER_LONG * 3), BITS_PER_LONG * 2 + 10);
assert_eq!(find_next_bit(&bits, BITS_PER_LONG * 3, BITS_PER_LONG + 6), BITS_PER_LONG * 2 + 10);
}
#[test]
fn extract_cases() {
assert_eq!(extract8(0xC4, 1, 2), 2);
assert_eq!(extract8(0xFF, 0, 8), 0xFF);
assert_eq!(extract16(0x18C4, 4, 4), 0xC);
assert_eq!(extract16(0xFFFF, 0, 16), 0xFFFF);
assert_eq!(extract32(0x8000_008E, 1, 3), 7);
assert_eq!(extract32(0xFFFF_FFFF, 0, 32), 0xFFFF_FFFF);
assert_eq!(extract64(0x01A0_00F7_000C, 32, 8), 0xA0);
assert_eq!(extract64(u64::MAX, 0, 64), u64::MAX);
}
#[test]
fn deposit_cases() {
assert_eq!(deposit32(0x8000_008E, 4, 2, 1), 0x8000_009E);
assert_eq!(deposit32(0, 0, 32, 0xFFFF_FFFF), 0xFFFF_FFFF);
assert_eq!(deposit64(0x01A0_00F7_000C, 32, 2, 3), 0x01A3_00F7_000C);
assert_eq!(deposit64(0, 0, 64, u64::MAX), u64::MAX);
}
#[test]
fn deposit_extract_roundtrip() {
let val = deposit32(0, 8, 4, 0xA);
assert_eq!(extract32(val, 8, 4), 0xA);
let val = deposit64(0, 16, 8, 0xBE);
assert_eq!(extract64(val, 16, 8), 0xBE);
}
#[test]
fn shuffle32_roundtrip() {
let original = 0b1111u32;
let shuffled = half_shuffle32(original);
assert_eq!(shuffled, 0b101_0101);
assert_eq!(half_unshuffle32(shuffled), original);
}
#[test]
fn shuffle64_roundtrip() {
let original: u64 = 0b1111_0000_0000_0000_0000;
let shuffled = half_shuffle64(original);
assert_eq!(shuffled, 0x55_0000_0000);
assert_eq!(half_unshuffle64(shuffled), original);
}
#[test]
fn find_size_zero() {
let bits = [0usize; 0];
assert_eq!(find_first_bit(&bits, 0), 0);
assert_eq!(find_first_zero_bit(&bits, 0), 0);
assert_eq!(find_last_bit(&bits, 0), 0);
assert_eq!(find_next_bit(&bits, 0, 0), 0);
assert_eq!(find_next_zero_bit(&bits, 0, 0), 0);
}
#[test]
fn shuffle_zero() {
assert_eq!(half_shuffle32(0), 0);
assert_eq!(half_unshuffle32(0), 0);
assert_eq!(half_shuffle64(0), 0);
assert_eq!(half_unshuffle64(0), 0);
}