use super::{BitContainer, BitContainerFor};
use core::fmt::Debug;
mod bit_convert;
pub use bit_convert::BitConvert;
mod substitute;
use substitute::Substitute;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BitIterableContainer<U: BitConvert>(U);
impl<U: InnerType> From<U> for BitIterableContainer<U> {
fn from(value: U) -> Self {
Self(value)
}
}
pub trait InnerType
where
Self: BitConvert,
Self: Copy,
{
}
impl<T> InnerType for T
where
Self: BitConvert,
Self: Copy,
{
}
impl<T, U> BitContainerFor<T> for BitIterableContainer<U>
where
T: BitConvert,
U: InnerType,
{
fn store_raw(&mut self, value: T, offset: usize, size: usize) {
self.0 = U::from_bits(Substitute::new(
self.0.into_bits(),
value.into_bits(),
offset..(offset + size),
));
}
fn retrieve_raw(&self, offset: usize, size: usize) -> T {
T::from_bits(self.0.into_bits().skip(offset).take(size))
}
}
impl<U: BitConvert> BitContainer for BitIterableContainer<U> {
type Inner = U;
const SIZE: usize = ::core::mem::size_of::<U>() * 8;
fn empty() -> Self {
Self(U::from_bits(core::iter::repeat(false)))
}
fn into_inner(self) -> Self::Inner {
self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bit_iterable_container_into_inner() {
let container: BitIterableContainer<u32> = BitIterableContainer(0b1010101010111100u32);
assert_eq!(container.into_inner(), 0b1010101010111100u32)
}
#[test]
fn bit_iterable_from_inner() {
let container: BitIterableContainer<u32> =
BitIterableContainer::from(0b1010101010111100u32);
assert_eq!(container.0, 0b1010101010111100u32)
}
#[test]
fn bit_iterable_container_empty() {
let container: BitIterableContainer<u32> = BitIterableContainer::empty();
assert_eq!(container.0, 0u32)
}
#[test]
fn bit_iterable_container_store_basic() {
let mut container: BitIterableContainer<u32> = BitIterableContainer(0);
container.store(0b1011u8, 0, 4);
assert_eq!(container.0, 0b1011u32)
}
#[test]
fn bit_iterable_container_store_at_index() {
let mut container: BitIterableContainer<u32> = BitIterableContainer(0);
container.store(0b1011u8, 4, 4);
assert_eq!(container.0, 0b1011_0000u32)
}
#[test]
fn bit_iterable_container_store_max() {
let mut container: BitIterableContainer<u32> = BitIterableContainer(0);
container.store(u32::MAX, 0, 32);
assert_eq!(container.0, u32::MAX)
}
#[test]
fn bit_iterable_container_store_min() {
let mut container: BitIterableContainer<u32> = BitIterableContainer(u32::MAX);
container.store(0u32, 0, 32);
assert_eq!(container.0, 0)
}
#[test]
fn bit_iterable_container_store_overwrite() {
let mut container: BitIterableContainer<u32> = BitIterableContainer(0b1011u32);
container.store(0b100u8, 0, 3);
assert_eq!(container.0, 0b1100u32);
container.store(0b0u8, 0, 4);
assert_eq!(container.0, 0u32);
}
#[test]
fn bit_iterable_container_retrieve_basic() {
let container: BitIterableContainer<u32> = BitIterableContainer(0b1011u32);
assert_eq!(container.retrieve::<u32>(0, 4), 0b1011u32);
assert_eq!(container.retrieve::<u32>(0, 2), 0b0011u32);
}
#[test]
fn bit_iterable_container_retrieve_max() {
let container: BitIterableContainer<u32> = BitIterableContainer(u32::MAX);
assert_eq!(container.retrieve::<u32>(0, 32), u32::MAX);
}
#[test]
fn bit_iterable_container_retrieve_at_index() {
let container: BitIterableContainer<u32> = BitIterableContainer(0b1011u32);
assert_eq!(container.retrieve::<u32>(2, 2), 0b0010u32);
assert_eq!(container.retrieve::<u32>(2, 10), 0b0010u32);
}
}