#![cfg(test)]
use core::cell::Cell;
use rand::random;
use crate::{
order::HiLo,
prelude::*,
};
mod api;
mod iter;
mod ops;
mod traits;
#[test]
#[allow(clippy::many_single_char_names)]
fn copying() {
let a = bits![mut u8, Lsb0; 0; 4];
let b = bits![u16, Msb0; 0, 1, 0, 1];
a.clone_from_bitslice(b);
assert_eq!(a, b);
let mut a = random::<[u32; 3]>();
let b = random::<[u32; 3]>();
a.view_bits_mut::<Lsb0>()[4 .. 92]
.copy_from_bitslice(&b.view_bits::<Lsb0>()[4 .. 92]);
assert_eq!([a[0] & 0xFF_FF_FF_F0, a[1], a[2] & 0x0F_FF_FF_FF], [
b[0] & 0xFF_FF_FF_F0,
b[1],
b[2] & 0x0F_FF_FF_FF
],);
let mut c = random::<u32>();
let d = random::<u32>();
c.view_bits_mut::<Msb0>()[4 .. 28]
.copy_from_bitslice(&d.view_bits::<Msb0>()[4 .. 28]);
assert_eq!(c & 0x0F_FF_FF_F0, d & 0x0F_FF_FF_F0);
let mut e = 0x01_23_45_67u32;
let f = 0x89_AB_CD_EFu32;
e.view_bits_mut::<HiLo>()[.. 28]
.copy_from_bitslice(&f.view_bits::<HiLo>()[4 ..]);
assert_eq!(e, 0x91_B8_DA_FC);
let mut g = random::<[u32; 3]>();
let mut h = random::<[u32; 3]>();
let i = g;
let j = h;
g.view_bits_mut::<Lsb0>()
.swap_with_bitslice(h.view_bits_mut::<Lsb0>());
assert_eq!((g, h), (j, i));
g.view_bits_mut::<Msb0>()
.swap_with_bitslice(h.view_bits_mut::<Msb0>());
assert_eq!((g, h), (i, j));
g.view_bits_mut::<Lsb0>()
.swap_with_bitslice(h.view_bits_mut::<Msb0>());
assert_eq!(g.view_bits::<Lsb0>(), j.view_bits::<Msb0>());
assert_eq!(h.view_bits::<Msb0>(), i.view_bits::<Lsb0>());
let mut k = random::<[u32; 3]>();
let j = k;
unsafe {
k.view_bits_mut::<Lsb0>().copy_within_unchecked(32 .., 0);
assert_eq!(k, [j[1], j[2], j[2]]);
k.view_bits_mut::<Msb0>().copy_within_unchecked(.. 64, 32);
assert_eq!(k, [j[1], j[1], j[2]]);
k.view_bits_mut::<HiLo>().copy_within_unchecked(32 .., 0);
assert_eq!(k, [j[1], j[2], j[2]]);
}
}
#[test]
fn writing() {
let bits = bits![mut 0; 2];
bits.set(0, true);
unsafe {
bits.set_unchecked(1, true);
}
assert_eq!(bits, bits![1;2]);
assert!(bits.replace(0, false));
assert!(unsafe { bits.replace_unchecked(1, false) });
assert_eq!(bits, bits![0;2]);
}
#[test]
fn bit_counting() {
let data = [0x12u8, 0xFE, 0x34, 0xDC];
let lsb0 = data.view_bits::<Lsb0>();
let msb0 = data.view_bits::<Msb0>();
assert_eq!(lsb0[2 .. 6].count_ones(), 1);
assert_eq!(lsb0[2 .. 6].count_zeros(), 3);
assert_eq!(msb0[2 .. 30].count_ones(), 17);
assert_eq!(msb0[2 .. 30].count_zeros(), 11);
assert!(!bits![].any());
assert!(!bits![0, 0].any());
assert!(bits![0, 1].any());
assert!(bits![].all());
assert!(!bits![0, 1].all());
assert!(bits![1, 1].all());
assert!(bits![].not_any());
assert!(bits![0, 0].not_any());
assert!(!bits![0, 1].not_any());
assert!(!bits![].not_all());
assert!(bits![0, 1].not_all());
assert!(!bits![1, 1].not_all());
assert!(!bits![0; 2].some());
assert!(bits![0, 1].some());
assert!(!bits![1; 2].some());
assert!(bits![usize, Lsb0;].first_one().is_none());
assert!(bits![usize, Msb0;].first_one().is_none());
assert!(bits![usize, Lsb0;].last_one().is_none());
assert!(bits![usize, Msb0;].last_one().is_none());
assert!(bits![usize, Lsb0;].first_zero().is_none());
assert!(bits![usize, Msb0;].first_zero().is_none());
assert!(bits![usize, Lsb0;].last_zero().is_none());
assert!(bits![usize, Msb0;].last_zero().is_none());
assert!([0u8; 1].view_bits::<Lsb0>()[1 .. 7].first_one().is_none());
assert!([0u8; 3].view_bits::<Lsb0>()[1 .. 23].first_one().is_none());
assert!([0u8; 1].view_bits::<Msb0>()[1 .. 7].first_one().is_none());
assert!([0u8; 3].view_bits::<Msb0>()[1 .. 23].first_one().is_none());
assert!([0u8; 1].view_bits::<Lsb0>()[1 .. 7].last_one().is_none());
assert!([0u8; 3].view_bits::<Lsb0>()[1 .. 23].last_one().is_none());
assert!([0u8; 1].view_bits::<Msb0>()[1 .. 7].last_one().is_none());
assert!([0u8; 3].view_bits::<Msb0>()[1 .. 23].last_one().is_none());
assert!([!0u8; 1].view_bits::<Lsb0>()[1 .. 7].first_zero().is_none());
assert!(
[!0u8; 3].view_bits::<Lsb0>()[1 .. 23]
.first_zero()
.is_none()
);
assert!([!0u8; 1].view_bits::<Msb0>()[1 .. 7].first_zero().is_none());
assert!(
[!0u8; 3].view_bits::<Msb0>()[1 .. 23]
.first_zero()
.is_none()
);
assert!([!0u8; 1].view_bits::<Lsb0>()[1 .. 7].last_zero().is_none());
assert!([!0u8; 3].view_bits::<Lsb0>()[1 .. 23].last_zero().is_none());
assert!([!0u8; 1].view_bits::<Msb0>()[1 .. 7].last_zero().is_none());
assert!([!0u8; 3].view_bits::<Msb0>()[1 .. 23].last_zero().is_none());
let data = 0b0100_0100u8;
assert_eq!(data.view_bits::<Lsb0>()[1 .. 7].first_one(), Some(1));
assert_eq!(data.view_bits::<Lsb0>()[1 .. 7].last_one(), Some(5));
assert_eq!(data.view_bits::<Msb0>()[1 .. 7].first_one(), Some(0));
assert_eq!(data.view_bits::<Msb0>()[1 .. 7].last_one(), Some(4));
let data = 0b1011_1011u8;
assert_eq!(data.view_bits::<Lsb0>()[1 .. 7].first_zero(), Some(1));
assert_eq!(data.view_bits::<Lsb0>()[1 .. 7].last_zero(), Some(5));
assert_eq!(data.view_bits::<Msb0>()[1 .. 7].first_zero(), Some(0));
assert_eq!(data.view_bits::<Msb0>()[1 .. 7].last_zero(), Some(4));
let data = [0u8, 0b1001_0110, 0];
assert_eq!(data.view_bits::<Lsb0>()[12 ..].first_one(), Some(0));
assert_eq!(data.view_bits::<Lsb0>()[4 ..].first_one(), Some(5));
assert_eq!(data.view_bits::<Lsb0>()[.. 12].first_one(), Some(9));
assert_eq!(data.view_bits::<Msb0>()[12 ..].first_one(), Some(1));
assert_eq!(data.view_bits::<Msb0>()[4 ..].first_one(), Some(4));
assert_eq!(data.view_bits::<Msb0>()[.. 12].first_one(), Some(8));
assert_eq!(data.view_bits::<Lsb0>()[12 ..].last_one(), Some(3));
assert_eq!(data.view_bits::<Lsb0>()[4 ..].last_one(), Some(11));
assert_eq!(data.view_bits::<Lsb0>()[.. 12].last_one(), Some(10));
assert_eq!(data.view_bits::<Msb0>()[12 ..].last_one(), Some(2));
assert_eq!(data.view_bits::<Msb0>()[4 ..].last_one(), Some(10));
assert_eq!(data.view_bits::<Msb0>()[.. 12].last_one(), Some(11));
let data = [!0u8, 0b1001_0110, !0];
assert_eq!(data.view_bits::<Lsb0>()[12 ..].first_zero(), Some(1));
assert_eq!(data.view_bits::<Lsb0>()[4 ..].first_zero(), Some(4));
assert_eq!(data.view_bits::<Lsb0>()[.. 12].first_zero(), Some(8));
assert_eq!(data.view_bits::<Msb0>()[12 ..].first_zero(), Some(0));
assert_eq!(data.view_bits::<Msb0>()[4 ..].first_zero(), Some(5));
assert_eq!(data.view_bits::<Msb0>()[.. 12].first_zero(), Some(9));
assert_eq!(data.view_bits::<Lsb0>()[12 ..].last_zero(), Some(2));
assert_eq!(data.view_bits::<Lsb0>()[4 ..].last_zero(), Some(10));
assert_eq!(data.view_bits::<Lsb0>()[.. 12].last_zero(), Some(11));
assert_eq!(data.view_bits::<Msb0>()[12 ..].last_zero(), Some(3));
assert_eq!(data.view_bits::<Msb0>()[4 ..].last_zero(), Some(11));
assert_eq!(data.view_bits::<Msb0>()[.. 12].last_zero(), Some(10));
assert_eq!(15u8.view_bits::<Lsb0>().leading_ones(), 4);
assert_eq!(15u8.view_bits::<Msb0>().leading_ones(), 0);
assert_eq!(15u8.view_bits::<Lsb0>().leading_zeros(), 0);
assert_eq!(15u8.view_bits::<Msb0>().leading_zeros(), 4);
assert_eq!(15u8.view_bits::<Lsb0>().trailing_ones(), 0);
assert_eq!(15u8.view_bits::<Msb0>().trailing_ones(), 4);
assert_eq!(15u8.view_bits::<Lsb0>().trailing_zeros(), 4);
assert_eq!(15u8.view_bits::<Msb0>().trailing_zeros(), 0);
}
#[test]
fn shunting() {
let bits = bits![mut 0, 1, 0, 0, 1];
bits.shift_left(0);
bits.shift_right(0);
assert_eq!(bits, bits![0, 1, 0, 0, 1]);
let bits = bits![mut 1;5];
bits.shift_left(1);
bits.shift_right(2);
bits.shift_left(1);
assert_eq!(bits, bits![0, 1, 1, 1, 0]);
}
#[test]
fn aliasing() {
let bits = bits![Cell<u32>, Lsb0; 0];
let (a, b) = (bits, bits);
a.set_aliased(0, true);
assert!(bits[0]);
b.set_aliased(0, false);
assert!(!bits[0]);
}
#[test]
fn cooking() {
use core::convert::TryFrom;
use crate::{
ptr::BitPtr,
slice,
};
let mut data = [0usize; 80];
let len = crate::mem::bits_of::<usize>() * 80;
let ref_ptr = data.as_ptr();
let mut_ptr = data.as_mut_ptr();
unsafe {
assert_eq!(
slice::from_raw_parts_unchecked(
BitPtr::try_from(ref_ptr).unwrap(),
len
)
.as_bitspan(),
data.view_bits::<Lsb0>().as_bitspan(),
);
assert_eq!(
slice::from_raw_parts_unchecked_mut(
BitPtr::try_from(mut_ptr).unwrap(),
len
)
.as_bitspan(),
data.view_bits_mut::<Msb0>().as_bitspan(),
);
}
}