use errors::{Result};
use digit;
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BitPos(usize);
pub type DigitPos = usize;
impl BitPos {
#[inline]
pub fn to_usize(self) -> usize {
self.0
}
#[inline]
pub fn new(pos: usize) -> Result<BitPos> {
Ok(BitPos(pos))
}
#[inline]
pub(crate) fn to_pos_within_digit(self) -> BitPos {
BitPos(self.0 % digit::BITS)
}
#[inline]
pub(crate) fn to_digit_and_bit_pos(self) -> (DigitPos, BitPos) {
let digit_pos = DigitPos::from(self.0 / digit::BITS);
let bit_pos = BitPos::from(self.0 % digit::BITS);
(digit_pos, bit_pos)
}
}
impl From<usize> for BitPos {
#[inline]
fn from(pos: usize) -> BitPos {
BitPos(pos)
}
}
#[cfg(test)]
mod tests {
use super::*;
mod to_digit_and_bit_pos {
use super::*;
#[test]
fn powers_of_two() {
assert_eq!(
BitPos::new(64).unwrap().to_digit_and_bit_pos(),
(1, BitPos::new(0).unwrap())
);
assert_eq!(
BitPos::new(256).unwrap().to_digit_and_bit_pos(),
(4, BitPos::new(0).unwrap())
)
}
#[test]
fn zero() {
assert_eq!(
BitPos::new(0).unwrap().to_digit_and_bit_pos(),
(0, BitPos::new(0).unwrap())
)
}
#[test]
fn odds() {
assert_eq!(
BitPos::new(1).unwrap().to_digit_and_bit_pos(),
(0, BitPos::new(1).unwrap())
);
assert_eq!(
BitPos::new(63).unwrap().to_digit_and_bit_pos(),
(0, BitPos::new(63).unwrap())
);
assert_eq!(
BitPos::new(255).unwrap().to_digit_and_bit_pos(),
(3, BitPos::new(63).unwrap())
)
}
}
}