diff options
Diffstat (limited to 'vendor/bit_field/src')
-rw-r--r-- | vendor/bit_field/src/lib.rs | 374 | ||||
-rw-r--r-- | vendor/bit_field/src/tests.rs | 450 |
2 files changed, 824 insertions, 0 deletions
diff --git a/vendor/bit_field/src/lib.rs b/vendor/bit_field/src/lib.rs new file mode 100644 index 0000000..21e682b --- /dev/null +++ b/vendor/bit_field/src/lib.rs @@ -0,0 +1,374 @@ +//! Provides the abstraction of a bit field, which allows for bit-level update and retrieval +//! operations. + +#![no_std] + +#[cfg(test)] +mod tests; + +use core::ops::{Bound, Range, RangeBounds}; + +/// A generic trait which provides methods for extracting and setting specific bits or ranges of +/// bits. +pub trait BitField { + /// The number of bits in this bit field. + /// + /// ```rust + /// use bit_field::BitField; + /// + /// assert_eq!(u32::BIT_LENGTH, 32); + /// assert_eq!(u64::BIT_LENGTH, 64); + /// ``` + const BIT_LENGTH: usize; + + /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while + /// index `length() - 1` is the most significant bit. + /// + /// ```rust + /// use bit_field::BitField; + /// + /// let value: u32 = 0b110101; + /// + /// assert_eq!(value.get_bit(1), false); + /// assert_eq!(value.get_bit(2), true); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the bit index is out of bounds of the bit field. + fn get_bit(&self, bit: usize) -> bool; + + /// Obtains the range of bits specified by `range`; note that index 0 is the least significant + /// bit, while index `length() - 1` is the most significant bit. + /// + /// ```rust + /// use bit_field::BitField; + /// + /// let value: u32 = 0b110101; + /// + /// assert_eq!(value.get_bits(0..3), 0b101); + /// assert_eq!(value.get_bits(2..6), 0b1101); + /// assert_eq!(value.get_bits(..), 0b110101); + /// assert_eq!(value.get_bits(3..=3), value.get_bit(3) as u32); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the start or end indexes of the range are out of bounds of the + /// bit field. + fn get_bits<T: RangeBounds<usize>>(&self, range: T) -> Self; + + /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and + /// false means a value of '0'); note that index 0 is the least significant bit, while index + /// `length() - 1` is the most significant bit. + /// + /// ```rust + /// use bit_field::BitField; + /// + /// let mut value = 0u32; + /// + /// value.set_bit(1, true); + /// assert_eq!(value, 2u32); + /// + /// value.set_bit(3, true); + /// assert_eq!(value, 10u32); + /// + /// value.set_bit(1, false); + /// assert_eq!(value, 8u32); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the bit index is out of the bounds of the bit field. + fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self; + + /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be + /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of + /// the other bits in `value` are set to 1, this function will panic. + /// + /// ```rust + /// use bit_field::BitField; + /// + /// let mut value = 0u32; + /// + /// value.set_bits(0..2, 0b11); + /// assert_eq!(value, 0b11); + /// + /// value.set_bits(2..=3, 0b11); + /// assert_eq!(value, 0b1111); + /// + /// value.set_bits(..4, 0b1010); + /// assert_eq!(value, 0b1010); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the range is out of bounds of the bit field, or if there are `1`s + /// not in the lower N bits of `value`. + fn set_bits<T: RangeBounds<usize>>(&mut self, range: T, value: Self) -> &mut Self; +} + +pub trait BitArray<T: BitField> { + /// Returns the length, eg number of bits, in this bit array. + /// + /// ```rust + /// use bit_field::BitArray; + /// + /// assert_eq!([0u8, 4u8, 8u8].bit_length(), 24); + /// assert_eq!([0u32, 5u32].bit_length(), 64); + /// ``` + fn bit_length(&self) -> usize; + + /// Obtains the bit at the index `bit`; note that index 0 is the least significant bit, while + /// index `length() - 1` is the most significant bit. + /// + /// ```rust + /// use bit_field::BitArray; + /// + /// let value: [u32; 1] = [0b110101]; + /// + /// assert_eq!(value.get_bit(1), false); + /// assert_eq!(value.get_bit(2), true); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the bit index is out of bounds of the bit array. + fn get_bit(&self, bit: usize) -> bool; + + /// Obtains the range of bits specified by `range`; note that index 0 is the least significant + /// bit, while index `length() - 1` is the most significant bit. + /// + /// ```rust + /// use bit_field::BitArray; + /// + /// let value: [u32; 2] = [0b110101, 0b11]; + /// + /// assert_eq!(value.get_bits(0..3), 0b101); + /// assert_eq!(value.get_bits(..6), 0b110101); + /// assert_eq!(value.get_bits(31..33), 0b10); + /// assert_eq!(value.get_bits(5..=32), 0b1_0000_0000_0000_0000_0000_0000_001); + /// assert_eq!(value.get_bits(34..), 0); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the start or end indexes of the range are out of bounds of the + /// bit array, or if the range can't be contained by the bit field T. + fn get_bits<U: RangeBounds<usize>>(&self, range: U) -> T; + + /// Sets the bit at the index `bit` to the value `value` (where true means a value of '1' and + /// false means a value of '0'); note that index 0 is the least significant bit, while index + /// `length() - 1` is the most significant bit. + /// + /// ```rust + /// use bit_field::BitArray; + /// + /// let mut value = [0u32]; + /// + /// value.set_bit(1, true); + /// assert_eq!(value, [2u32]); + /// + /// value.set_bit(3, true); + /// assert_eq!(value, [10u32]); + /// + /// value.set_bit(1, false); + /// assert_eq!(value, [8u32]); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the bit index is out of the bounds of the bit array. + fn set_bit(&mut self, bit: usize, value: bool); + + /// Sets the range of bits defined by the range `range` to the lower bits of `value`; to be + /// specific, if the range is N bits long, the N lower bits of `value` will be used; if any of + /// the other bits in `value` are set to 1, this function will panic. + /// + /// ```rust + /// use bit_field::BitArray; + /// + /// let mut value = [0u32, 0u32]; + /// + /// value.set_bits(0..2, 0b11); + /// assert_eq!(value, [0b11, 0u32]); + /// + /// value.set_bits(31..35, 0b1010); + /// assert_eq!(value, [0x0003, 0b101]); + /// ``` + /// + /// ## Panics + /// + /// This method will panic if the range is out of bounds of the bit array, + /// if the range can't be contained by the bit field T, or if there are `1`s + /// not in the lower N bits of `value`. + fn set_bits<U: RangeBounds<usize>>(&mut self, range: U, value: T); +} + +/// An internal macro used for implementing BitField on the standard integral types. +macro_rules! bitfield_numeric_impl { + ($($t:ty)*) => ($( + impl BitField for $t { + const BIT_LENGTH: usize = ::core::mem::size_of::<Self>() as usize * 8; + + #[track_caller] + #[inline] + fn get_bit(&self, bit: usize) -> bool { + assert!(bit < Self::BIT_LENGTH); + + (*self & (1 << bit)) != 0 + } + + #[track_caller] + #[inline] + fn get_bits<T: RangeBounds<usize>>(&self, range: T) -> Self { + let range = to_regular_range(&range, Self::BIT_LENGTH); + + assert!(range.start < Self::BIT_LENGTH); + assert!(range.end <= Self::BIT_LENGTH); + assert!(range.start < range.end); + + // shift away high bits + let bits = *self << (Self::BIT_LENGTH - range.end) >> (Self::BIT_LENGTH - range.end); + + // shift away low bits + bits >> range.start + } + + #[track_caller] + #[inline] + fn set_bit(&mut self, bit: usize, value: bool) -> &mut Self { + assert!(bit < Self::BIT_LENGTH); + + if value { + *self |= 1 << bit; + } else { + *self &= !(1 << bit); + } + + self + } + + #[track_caller] + #[inline] + fn set_bits<T: RangeBounds<usize>>(&mut self, range: T, value: Self) -> &mut Self { + let range = to_regular_range(&range, Self::BIT_LENGTH); + + assert!(range.start < Self::BIT_LENGTH); + assert!(range.end <= Self::BIT_LENGTH); + assert!(range.start < range.end); + assert!(value << (Self::BIT_LENGTH - (range.end - range.start)) >> + (Self::BIT_LENGTH - (range.end - range.start)) == value, + "value does not fit into bit range"); + + let bitmask: Self = !(!0 << (Self::BIT_LENGTH - range.end) >> + (Self::BIT_LENGTH - range.end) >> + range.start << range.start); + + // set bits + *self = (*self & bitmask) | (value << range.start); + + self + } + } + )*) +} + +bitfield_numeric_impl! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize } + +impl<T: BitField> BitArray<T> for [T] { + #[inline] + fn bit_length(&self) -> usize { + self.len() * T::BIT_LENGTH + } + + #[track_caller] + #[inline] + fn get_bit(&self, bit: usize) -> bool { + let slice_index = bit / T::BIT_LENGTH; + let bit_index = bit % T::BIT_LENGTH; + self[slice_index].get_bit(bit_index) + } + + #[track_caller] + #[inline] + fn get_bits<U: RangeBounds<usize>>(&self, range: U) -> T { + let range = to_regular_range(&range, self.bit_length()); + + assert!(range.len() <= T::BIT_LENGTH); + + let slice_start = range.start / T::BIT_LENGTH; + let slice_end = range.end / T::BIT_LENGTH; + let bit_start = range.start % T::BIT_LENGTH; + let bit_end = range.end % T::BIT_LENGTH; + let len = range.len(); + + assert!(slice_end - slice_start <= 1); + + if slice_start == slice_end { + self[slice_start].get_bits(bit_start..bit_end) + } else if bit_end == 0 { + self[slice_start].get_bits(bit_start..T::BIT_LENGTH) + } else { + let mut ret = self[slice_start].get_bits(bit_start..T::BIT_LENGTH); + ret.set_bits( + (T::BIT_LENGTH - bit_start)..len, + self[slice_end].get_bits(0..bit_end), + ); + ret + } + } + + #[track_caller] + #[inline] + fn set_bit(&mut self, bit: usize, value: bool) { + let slice_index = bit / T::BIT_LENGTH; + let bit_index = bit % T::BIT_LENGTH; + self[slice_index].set_bit(bit_index, value); + } + + #[track_caller] + #[inline] + fn set_bits<U: RangeBounds<usize>>(&mut self, range: U, value: T) { + let range = to_regular_range(&range, self.bit_length()); + + assert!(range.len() <= T::BIT_LENGTH); + + let slice_start = range.start / T::BIT_LENGTH; + let slice_end = range.end / T::BIT_LENGTH; + let bit_start = range.start % T::BIT_LENGTH; + let bit_end = range.end % T::BIT_LENGTH; + + assert!(slice_end - slice_start <= 1); + + if slice_start == slice_end { + self[slice_start].set_bits(bit_start..bit_end, value); + } else if bit_end == 0 { + self[slice_start].set_bits(bit_start..T::BIT_LENGTH, value); + } else { + self[slice_start].set_bits( + bit_start..T::BIT_LENGTH, + value.get_bits(0..T::BIT_LENGTH - bit_start), + ); + self[slice_end].set_bits( + 0..bit_end, + value.get_bits(T::BIT_LENGTH - bit_start..T::BIT_LENGTH), + ); + } + } +} + +fn to_regular_range<T: RangeBounds<usize>>(generic_rage: &T, bit_length: usize) -> Range<usize> { + let start = match generic_rage.start_bound() { + Bound::Excluded(&value) => value + 1, + Bound::Included(&value) => value, + Bound::Unbounded => 0, + }; + let end = match generic_rage.end_bound() { + Bound::Excluded(&value) => value, + Bound::Included(&value) => value + 1, + Bound::Unbounded => bit_length, + }; + + start..end +} diff --git a/vendor/bit_field/src/tests.rs b/vendor/bit_field/src/tests.rs new file mode 100644 index 0000000..dd470e8 --- /dev/null +++ b/vendor/bit_field/src/tests.rs @@ -0,0 +1,450 @@ +use BitArray; +use BitField; + +#[test] +fn test_integer_bit_lengths() { + assert_eq!(u8::BIT_LENGTH, 8); + assert_eq!(u16::BIT_LENGTH, 16); + assert_eq!(u32::BIT_LENGTH, 32); + assert_eq!(u64::BIT_LENGTH, 64); + assert_eq!(u128::BIT_LENGTH, 128); + + assert_eq!(i8::BIT_LENGTH, 8); + assert_eq!(i16::BIT_LENGTH, 16); + assert_eq!(i32::BIT_LENGTH, 32); + assert_eq!(i64::BIT_LENGTH, 64); + assert_eq!(i128::BIT_LENGTH, 128); +} + +#[test] +fn test_set_reset_u8() { + let mut field = 0b11110010u8; + let mut bit_i = |i| { + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + field.set_bit(i, false); + assert_eq!(field.get_bit(i), false); + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + }; + for i in 0..8 { + bit_i(i); + } +} + +#[test] +fn test_set_reset_u16() { + let mut field = 0b1111001010010110u16; + let mut bit_i = |i| { + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + field.set_bit(i, false); + assert_eq!(field.get_bit(i), false); + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + }; + for i in 0..16 { + bit_i(i); + } +} + +#[test] +fn test_read_u32() { + let field = 0b1111111111010110u32; + assert_eq!(field.get_bit(0), false); + assert_eq!(field.get_bit(1), true); + assert_eq!(field.get_bit(2), true); + assert_eq!(field.get_bit(3), false); + assert_eq!(field.get_bit(4), true); + assert_eq!(field.get_bit(5), false); + for i in 6..16 { + assert_eq!(field.get_bit(i), true); + } + for i in 16..32 { + assert_eq!(field.get_bit(i), false); + } + + assert_eq!(field.get_bits(16..), 0); + assert_eq!(field.get_bits(16..32), 0); + assert_eq!(field.get_bits(16..=31), 0); + + assert_eq!(field.get_bits(6..16), 0b1111111111); + assert_eq!(field.get_bits(6..=15), 0b1111111111); + + assert_eq!(field.get_bits(..6), 0b010110); + assert_eq!(field.get_bits(0..6), 0b010110); + assert_eq!(field.get_bits(0..=5), 0b010110); + + assert_eq!(field.get_bits(..10), 0b1111010110); + assert_eq!(field.get_bits(0..10), 0b1111010110); + assert_eq!(field.get_bits(0..=9), 0b1111010110); + + assert_eq!(field.get_bits(5..12), 0b1111110); + assert_eq!(field.get_bits(5..=11), 0b1111110); +} + +#[test] +fn test_set_reset_u32() { + let mut field = 0b1111111111010110u32; + let mut bit_i = |i| { + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + field.set_bit(i, false); + assert_eq!(field.get_bit(i), false); + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + }; + for i in 0..32 { + bit_i(i); + } +} + +#[test] +fn test_set_range_u32() { + let mut field = 0b1111111111010110u32; + field.set_bits(10..15, 0b00000); + assert_eq!(field.get_bits(10..15), 0b00000); + assert_eq!(field.get_bits(10..=14), 0b00000); + field.set_bits(10..15, 0b10101); + assert_eq!(field.get_bits(10..15), 0b10101); + assert_eq!(field.get_bits(10..=14), 0b10101); + field.set_bits(10..15, 0b01010); + assert_eq!(field.get_bits(10..15), 0b01010); + assert_eq!(field.get_bits(10..=14), 0b01010); + field.set_bits(10..15, 0b11111); + assert_eq!(field.get_bits(10..15), 0b11111); + assert_eq!(field.get_bits(10..=14), 0b11111); + + field.set_bits(10..=14, 0b00000); + assert_eq!(field.get_bits(10..15), 0b00000); + assert_eq!(field.get_bits(10..=14), 0b00000); + field.set_bits(10..=14, 0b10101); + assert_eq!(field.get_bits(10..15), 0b10101); + assert_eq!(field.get_bits(10..=14), 0b10101); + field.set_bits(10..=14, 0b01010); + assert_eq!(field.get_bits(10..15), 0b01010); + assert_eq!(field.get_bits(10..=14), 0b01010); + field.set_bits(10..=14, 0b11111); + assert_eq!(field.get_bits(10..15), 0b11111); + assert_eq!(field.get_bits(10..=14), 0b11111); + + field.set_bits(0..16, 0xdead); + field.set_bits(14..32, 0xbeaf); + assert_eq!(field.get_bits(0..16), 0xdead); + assert_eq!(field.get_bits(14..32), 0xbeaf); + + field.set_bits(..16, 0xdead); + field.set_bits(14.., 0xbeaf); + assert_eq!(field.get_bits(..16), 0xdead); + assert_eq!(field.get_bits(14..), 0xbeaf); +} + +#[test] +fn test_read_u64() { + let field = 0b1111111111010110u64 << 32; + for i in 0..32 { + assert_eq!(field.get_bit(i), false); + } + assert_eq!(field.get_bit(32), false); + assert_eq!(field.get_bit(33), true); + assert_eq!(field.get_bit(34), true); + assert_eq!(field.get_bit(35), false); + assert_eq!(field.get_bit(36), true); + assert_eq!(field.get_bit(37), false); + for i in 38..48 { + assert_eq!(field.get_bit(i), true); + } + for i in 48..64 { + assert_eq!(field.get_bit(i), false); + } + + assert_eq!(field.get_bits(..32), 0); + assert_eq!(field.get_bits(0..32), 0); + assert_eq!(field.get_bits(0..=31), 0); + + assert_eq!(field.get_bits(48..), 0); + assert_eq!(field.get_bits(48..64), 0); + assert_eq!(field.get_bits(48..=63), 0); + + assert_eq!(field.get_bits(38..48), 0b1111111111); + assert_eq!(field.get_bits(38..=47), 0b1111111111); + + assert_eq!(field.get_bits(32..38), 0b010110); + assert_eq!(field.get_bits(32..=37), 0b010110); + + assert_eq!(field.get_bits(32..42), 0b1111010110); + assert_eq!(field.get_bits(32..=41), 0b1111010110); + + assert_eq!(field.get_bits(37..44), 0b1111110); + assert_eq!(field.get_bits(37..=43), 0b1111110); +} + +#[test] +fn test_set_reset_u64() { + let mut field = 0b1111111111010110u64 << 32; + let mut bit_i = |i| { + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + field.set_bit(i, false); + assert_eq!(field.get_bit(i), false); + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + }; + for i in 0..64 { + bit_i(i); + } +} + +#[test] +fn test_set_range_u64() { + let mut field = 0b1111111111010110u64 << 32; + field.set_bits(42..47, 0b00000); + assert_eq!(field.get_bits(42..47), 0b00000); + assert_eq!(field.get_bits(42..=46), 0b00000); + field.set_bits(10..15, 0b10101); + assert_eq!(field.get_bits(10..15), 0b10101); + assert_eq!(field.get_bits(10..=14), 0b10101); + field.set_bits(40..45, 0b01010); + assert_eq!(field.get_bits(40..45), 0b01010); + assert_eq!(field.get_bits(40..=44), 0b01010); + field.set_bits(40..45, 0b11111); + assert_eq!(field.get_bits(40..45), 0b11111); + assert_eq!(field.get_bits(40..=44), 0b11111); + + field.set_bits(42..=46, 0b00000); + assert_eq!(field.get_bits(42..47), 0b00000); + assert_eq!(field.get_bits(42..=46), 0b00000); + field.set_bits(10..=14, 0b10101); + assert_eq!(field.get_bits(10..15), 0b10101); + assert_eq!(field.get_bits(10..=14), 0b10101); + field.set_bits(40..=44, 0b01010); + assert_eq!(field.get_bits(40..45), 0b01010); + assert_eq!(field.get_bits(40..=44), 0b01010); + field.set_bits(40..=44, 0b11111); + assert_eq!(field.get_bits(40..45), 0b11111); + assert_eq!(field.get_bits(40..=44), 0b11111); + + field.set_bits(0..16, 0xdead); + field.set_bits(14..32, 0xbeaf); + field.set_bits(32..64, 0xcafebabe); + assert_eq!(field.get_bits(0..16), 0xdead); + assert_eq!(field.get_bits(14..32), 0xbeaf); + assert_eq!(field.get_bits(32..64), 0xcafebabe); + + field.set_bits(..16, 0xdead); + field.set_bits(14..=31, 0xbeaf); + field.set_bits(32.., 0xcafebabe); + assert_eq!(field.get_bits(..16), 0xdead); + assert_eq!(field.get_bits(14..=31), 0xbeaf); + assert_eq!(field.get_bits(32..), 0xcafebabe); +} + +#[test] +fn test_read_u128() { + let field = 0b1111111111010110u128 << 32; + for i in 0..32 { + assert_eq!(field.get_bit(i), false); + } + assert_eq!(field.get_bit(32), false); + assert_eq!(field.get_bit(33), true); + assert_eq!(field.get_bit(34), true); + assert_eq!(field.get_bit(35), false); + assert_eq!(field.get_bit(36), true); + assert_eq!(field.get_bit(37), false); + for i in 38..48 { + assert_eq!(field.get_bit(i), true); + } + for i in 48..64 { + assert_eq!(field.get_bit(i), false); + } + + assert_eq!(field.get_bits(..32), 0); + assert_eq!(field.get_bits(0..32), 0); + assert_eq!(field.get_bits(0..=31), 0); + + assert_eq!(field.get_bits(48..), 0); + assert_eq!(field.get_bits(48..64), 0); + assert_eq!(field.get_bits(48..=63), 0); + + assert_eq!(field.get_bits(38..48), 0b1111111111); + assert_eq!(field.get_bits(38..=47), 0b1111111111); + + assert_eq!(field.get_bits(32..38), 0b010110); + assert_eq!(field.get_bits(32..=37), 0b010110); + + assert_eq!(field.get_bits(32..42), 0b1111010110); + assert_eq!(field.get_bits(32..=41), 0b1111010110); + + assert_eq!(field.get_bits(37..44), 0b1111110); + assert_eq!(field.get_bits(37..=43), 0b1111110); +} + +#[test] +fn test_set_reset_u128() { + let mut field = 0b1111111111010110u128 << 32; + let mut bit_i = |i| { + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + field.set_bit(i, false); + assert_eq!(field.get_bit(i), false); + field.set_bit(i, true); + assert_eq!(field.get_bit(i), true); + }; + for i in 0..64 { + bit_i(i); + } +} + +#[test] +fn test_set_range_u128() { + let mut field = 0b1111111111010110u128 << 32; + field.set_bits(42..47, 0b00000); + assert_eq!(field.get_bits(42..47), 0b00000); + assert_eq!(field.get_bits(42..=46), 0b00000); + field.set_bits(10..15, 0b10101); + assert_eq!(field.get_bits(10..15), 0b10101); + assert_eq!(field.get_bits(10..=14), 0b10101); + field.set_bits(40..45, 0b01010); + assert_eq!(field.get_bits(40..45), 0b01010); + assert_eq!(field.get_bits(40..=44), 0b01010); + field.set_bits(40..45, 0b11111); + assert_eq!(field.get_bits(40..45), 0b11111); + assert_eq!(field.get_bits(40..=44), 0b11111); + + field.set_bits(42..=46, 0b00000); + assert_eq!(field.get_bits(42..47), 0b00000); + assert_eq!(field.get_bits(42..=46), 0b00000); + field.set_bits(10..=14, 0b10101); + assert_eq!(field.get_bits(10..15), 0b10101); + assert_eq!(field.get_bits(10..=14), 0b10101); + field.set_bits(40..=44, 0b01010); + assert_eq!(field.get_bits(40..45), 0b01010); + assert_eq!(field.get_bits(40..=44), 0b01010); + field.set_bits(40..=44, 0b11111); + assert_eq!(field.get_bits(40..45), 0b11111); + assert_eq!(field.get_bits(40..=44), 0b11111); + + field.set_bits(0..16, 0xdead); + field.set_bits(14..32, 0xbeaf); + field.set_bits(32..64, 0xcafebabe); + assert_eq!(field.get_bits(0..16), 0xdead); + assert_eq!(field.get_bits(14..32), 0xbeaf); + assert_eq!(field.get_bits(32..64), 0xcafebabe); + + field.set_bits(..16, 0xdead); + field.set_bits(14..=31, 0xbeaf); + field.set_bits(32.., 0xcafebabe); + assert_eq!(field.get_bits(..16), 0xdead); + assert_eq!(field.get_bits(14..=31), 0xbeaf); + assert_eq!(field.get_bits(32..), 0xcafebabe); +} + +#[test] +fn test_array_length() { + assert_eq!((&[2u8, 3u8, 4u8]).bit_length(), 24); + assert_eq!((&[2i8, 3i8, 4i8, 5i8]).bit_length(), 32); + + assert_eq!((&[2u16, 3u16, 4u16]).bit_length(), 48); + assert_eq!((&[2i16, 3i16, 4i16, 5i16]).bit_length(), 64); + + assert_eq!((&[2u32, 3u32, 4u32]).bit_length(), 96); + assert_eq!((&[2i32, 3i32, 4i32, 5i32]).bit_length(), 128); + + assert_eq!((&[2u64, 3u64, 4u64]).bit_length(), 192); + assert_eq!((&[2i64, 3i64, 4i64, 5i64]).bit_length(), 256); +} + +#[test] +fn test_set_bit_array() { + let mut test_val = [0xffu8]; + &test_val.set_bit(0, false); + assert_eq!(test_val, [0xfeu8]); + &test_val.set_bit(4, false); + assert_eq!(test_val, [0xeeu8]); + + let mut test_array = [0xffu8, 0x00u8, 0xffu8]; + &test_array.set_bit(7, false); + &test_array.set_bit(8, true); + &test_array.set_bit(16, false); + + assert_eq!(test_array, [0x7fu8, 0x01u8, 0xfeu8]); +} + +#[test] +fn test_get_bit_array() { + let test_val = [0xefu8]; + assert_eq!(test_val.get_bit(1), true); + assert_eq!(test_val.get_bit(4), false); + + let test_array = [0xffu8, 0x00u8, 0xffu8]; + assert_eq!(test_array.get_bit(7), true); + assert_eq!(test_array.get_bit(8), false); + assert_eq!(test_array.get_bit(16), true); +} + +#[test] +fn test_set_bits_array() { + let mut test_val = [0xffu8]; + + test_val.set_bits(0..4, 0x0u8); + assert_eq!(test_val, [0xf0u8]); + + test_val.set_bits(0..4, 0xau8); + assert_eq!(test_val, [0xfau8]); + + test_val.set_bits(4..8, 0xau8); + assert_eq!(test_val, [0xaau8]); + + test_val.set_bits(.., 0xffu8); + assert_eq!(test_val, [0xffu8]); + + test_val.set_bits(2..=5, 0x0u8); + assert_eq!(test_val, [0xc3u8]); + + let mut test_array = [0xffu8, 0x00u8, 0xffu8]; + + test_array.set_bits(7..9, 0b10); + assert_eq!(test_array, [0x7f, 0x01, 0xff]); + + test_array.set_bits(12..20, 0xaa); + assert_eq!(test_array, [0x7f, 0xa1, 0xfa]); + + test_array.set_bits(16..24, 0xaa); + assert_eq!(test_array, [0x7f, 0xa1, 0xaa]); + + test_array.set_bits(6..14, 0x00); + assert_eq!(test_array, [0x3f, 0x80, 0xaa]); + + test_array.set_bits(..4, 0x00); + assert_eq!(test_array, [0x30, 0x80, 0xaa]); + + test_array.set_bits(20.., 0x00); + assert_eq!(test_array, [0x30, 0x80, 0x0a]); + + test_array.set_bits(7..=11, 0x1f); + assert_eq!(test_array, [0xb0, 0x8f, 0x0a]); +} + +#[test] +fn test_get_bits_array() { + let mut test_val = [0xf0u8]; + assert_eq!(test_val.get_bits(0..4), 0x0u8); + + test_val = [0xfau8]; + assert_eq!(test_val.get_bits(0..4), 0xau8); + + test_val = [0xaau8]; + assert_eq!(test_val.get_bits(4..8), 0xau8); + + let mut test_array: [u8; 3] = [0xff, 0x01, 0xff]; + assert_eq!(test_array.get_bits(7..9), 0b11u8); + + test_array = [0x7f, 0xa1, 0xfa]; + assert_eq!(test_array.get_bits(12..20), 0xaa); + + test_array = [0x7f, 0xa1, 0xaa]; + assert_eq!(test_array.get_bits(16..24), 0xaa); + + test_array = [0x3f, 0x80, 0xaa]; + assert_eq!(test_array.get_bits(6..14), 0x00); +} |