use super::BitsMut;
use storage::{BlockType, Address};
use BitVec;
pub trait Bits {
type Block: BlockType;
fn bit_len(&self) -> u64;
fn block_len(&self) -> usize {
Self::Block::ceil_div_nbits(self.bit_len())
}
fn get_bit(&self, position: u64) -> bool {
assert!(position < self.bit_len(), "Bits::get_bit: out of bounds");
let address = Address::new::<Self::Block>(position);
let block = self.get_raw_block(address.block_index);
block.get_bit(address.bit_offset)
}
fn get_block(&self, position: usize) -> Self::Block {
assert!(position < self.block_len(),
format!("Bits::get_block: out of bounds ({}/{})",
position, self.block_len()));
let first_bit = Self::Block::mul_nbits(position);
let bit_count = Self::Block::block_bits(self.bit_len(), position);
let mut result = Self::Block::zero();
let mut mask = Self::Block::one();
for i in 0 .. bit_count as u64 {
if self.get_bit(first_bit + i) {
result = result | mask;
}
mask = mask << 1;
}
result
}
fn get_raw_block(&self, position: usize) -> Self::Block {
self.get_block(position)
}
fn get_bits(&self, start: u64, count: usize) -> Self::Block {
let limit = start + count as u64;
assert!(limit <= self.bit_len(), "Bits::get_bits: out of bounds");
let address = Address::new::<Self::Block>(start);
let margin = Self::Block::nbits() - address.bit_offset;
if margin >= count {
let block = self.get_raw_block(address.block_index);
return block.get_bits(address.bit_offset, count)
}
let extra = count - margin;
let block1 = self.get_raw_block(address.block_index);
let block2 = self.get_raw_block(address.block_index + 1);
let low_bits = block1.get_bits(address.bit_offset, margin);
let high_bits = block2.get_bits(0, extra);
(high_bits << margin) | low_bits
}
fn to_bit_vec(&self) -> BitVec<Self::Block> {
BitVec::from_bits(self)
}
}
pub (crate) fn get_masked_block<T: Bits>(bits: T, position: usize) -> T::Block {
let block_bits = T::Block::block_bits(bits.bit_len(), position);
bits.get_raw_block(position).get_bits(0, block_bits)
}
impl<'a, T: Bits + ?Sized> Bits for &'a T {
type Block = T::Block;
fn bit_len(&self) -> u64 {
T::bit_len(*self)
}
fn block_len(&self) -> usize {
T::block_len(*self)
}
fn get_bit(&self, position: u64) -> bool {
T::get_bit(*self, position)
}
fn get_block(&self, position: usize) -> Self::Block {
T::get_block(*self, position)
}
fn get_raw_block(&self, position: usize) -> Self::Block {
T::get_raw_block(*self, position)
}
fn get_bits(&self, start: u64, count: usize) -> Self::Block {
T::get_bits(*self, start, count)
}
}
impl<'a, T: Bits + ?Sized> Bits for &'a mut T {
type Block = T::Block;
fn bit_len(&self) -> u64 {
T::bit_len(*self)
}
fn block_len(&self) -> usize {
T::block_len(*self)
}
fn get_bit(&self, position: u64) -> bool {
T::get_bit(*self, position)
}
fn get_block(&self, position: usize) -> Self::Block {
T::get_block(*self, position)
}
fn get_raw_block(&self, position: usize) -> Self::Block {
T::get_raw_block(*self, position)
}
fn get_bits(&self, start: u64, count: usize) -> Self::Block {
T::get_bits(*self, start, count)
}
}
impl<Block: BlockType> Bits for Box<dyn Bits<Block = Block>> {
type Block = Block;
fn bit_len(&self) -> u64 {
(**self).bit_len()
}
fn block_len(&self) -> usize {
(**self).block_len()
}
fn get_bit(&self, position: u64) -> bool {
(**self).get_bit(position)
}
fn get_block(&self, position: usize) -> Self::Block {
(**self).get_block(position)
}
fn get_raw_block(&self, position: usize) -> Self::Block {
(**self).get_raw_block(position)
}
fn get_bits(&self, start: u64, count: usize) -> Self::Block {
(**self).get_bits(start, count)
}
}
impl<Block: BlockType> Bits for Box<dyn BitsMut<Block = Block>> {
type Block = Block;
fn bit_len(&self) -> u64 {
(**self).bit_len()
}
fn block_len(&self) -> usize {
(**self).block_len()
}
fn get_bit(&self, position: u64) -> bool {
(**self).get_bit(position)
}
fn get_block(&self, position: usize) -> Self::Block {
(**self).get_block(position)
}
fn get_raw_block(&self, position: usize) -> Self::Block {
(**self).get_raw_block(position)
}
fn get_bits(&self, start: u64, count: usize) -> Self::Block {
(**self).get_bits(start, count)
}
}
impl<Block: BlockType> Bits for [Block] {
type Block = Block;
fn bit_len(&self) -> u64 {
Block::mul_nbits(self.len())
}
fn block_len(&self) -> usize {
self.len()
}
fn get_bit(&self, position: u64) -> bool {
let address = Address::new::<Block>(position);
self[address.block_index].get_bit(address.bit_offset)
}
fn get_block(&self, position: usize) -> Block {
self[position]
}
}
impl<Block: BlockType> Bits for Vec<Block> {
type Block = Block;
fn bit_len(&self) -> u64 {
<[Block]>::bit_len(&self)
}
fn block_len(&self) -> usize {
<[Block]>::block_len(&self)
}
fn get_bit(&self, position: u64) -> bool {
<[Block]>::get_bit(&self, position)
}
fn get_block(&self, position: usize) -> Block {
<[Block]>::get_block(&self, position)
}
fn get_raw_block(&self, position: usize) -> Block {
<[Block]>::get_raw_block(&self, position)
}
}
impl Bits for [bool] {
type Block = u8;
#[inline]
fn bit_len(&self) -> u64 {
self.len() as u64
}
#[inline]
fn get_bit(&self, position: u64) -> bool {
self[position.to_usize().expect("Vec<bool>::get_bit: overflow")]
}
}
impl Bits for Vec<bool> {
type Block = u8;
#[inline]
fn bit_len(&self) -> u64 {
self.as_slice().bit_len()
}
#[inline]
fn get_bit(&self, position: u64) -> bool {
self.as_slice().get_bit(position)
}
}