bitable 0.1.0

An all-const, compile-time checked, safe bit handling library with zero runtime overhead
Documentation
use super::common::*;
use super::mask::Mask;
use super::set::Set;

/// A bit field: a group of contiguous bits
#[derive(Debug)] //, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Field<const OFFSET: u8, const SIZE: u8>;

#[allow(private_bounds)]
impl<const OFFSET: u8, const SIZE: u8> const Field<OFFSET, SIZE> {
    const ASSERT_SIZE: () = { assert_size(SIZE); };

    // Core unchecked methods, gateways to Set

    fn unchecked_read<In, Out>(&self, bitset: &In) -> Out
    where In: const Set<Out, OFFSET, SIZE>,
          Out: const CastFromUReg,
    {
        let mask: Mask = self.into();
        let bits = mask.apply(bitset) >> OFFSET;
        Out::cast_from(bits)
    }
    fn unchecked_read_at<In, Out>(&self, bitset: &In, idx: usize) -> Out
    where In: const Set<Out, OFFSET, SIZE>,
          Out: const CastFromUReg,
    {
        let mask: Mask = self.into();
        let bits = mask.apply_at(bitset, idx) >> OFFSET;
        Out::cast_from(bits)
    }
    // fn unchecked_write<In, Out>(&self, bitset: &mut In, value: bool)
    // where In: const Set<Out, OFFSET, SIZE>,
    //       Out: const CastFromUReg,
    // {
    //     let mask: Mask = self.into();
    //     todo!();
    // }

    // Public API methods

    pub fn read<In, Out>(&self, bitset: &In) -> Out
    where In: const Set<Out, OFFSET, SIZE>,
          Out: const CastFromUReg,
    {
        let _ = <In>::ASSERT_FIELD;
        self.unchecked_read::<In, Out>(bitset)
    }
    pub fn read_at<In, Out>(&self, bitset: &In, idx: usize) -> Out
    where In: const Set<Out, OFFSET, SIZE>,
          Out: const CastFromUReg,
    {
        let _ = <In>::ASSERT_FIELD;
        self.unchecked_read_at::<In, Out>(bitset, idx)
    }

    // pub fn write<In, Out>(&self, bitset: &mut In, value: UReg)
    // where In: const Set<Out, OFFSET, SIZE>,
    //       Out: const CastFromUReg,
    // {
    //     let _ = <In>::ASSERT_FIELD;
    //     todo!();
    // }

    pub fn new() -> Self {
        let _ = Self::ASSERT_SIZE;
        Self
    }

    // #[cfg(test)]
    // pub(crate) fn mask(&self) -> BitMask<u32> {
    //     BitMask::<u32>::from(*self)
    // }
}

// ---------------------------------------------------------------------------
// Conversion between core types
// ---------------------------------------------------------------------------

impl<const OFFSET: u8, const SIZE: u8> const From<&Field<OFFSET, SIZE>> for Mask
{
    fn from(_: &Field<OFFSET, SIZE>) -> Self {
        let mask = field_mask(OFFSET, SIZE);
        Mask::new(mask)
    }
}