use core::mem;
use core::ops::Index;
use core::ops::Range;
use super::{FALSE, TRUE};
use crate::local_prelude::*;
use crate::util::div_rem;
pub struct BitSlice {
pub(crate) slice: [Block],
}
impl BitSlice {
#[inline]
pub fn new(slice: &[Block]) -> &Self {
unsafe { mem::transmute(slice) }
}
#[inline]
pub fn new_mut(slice: &mut [Block]) -> &mut Self {
unsafe { mem::transmute(slice) }
}
#[inline]
pub fn iter_bits(&self, len: usize) -> Iter {
Iter {
bit_slice: self,
range: 0..len,
}
}
pub fn iter_blocks(&self) -> impl Iterator<Item = &Block> {
self.slice.iter()
}
pub fn iter_blocks_mut(&mut self) -> impl Iterator<Item = &mut Block> {
self.slice.iter_mut()
}
#[inline]
pub fn get(&self, bit: usize) -> bool {
let (block, i) = div_rem(bit, BITS);
match self.slice.get(block) {
None => false,
Some(b) => (b & (1 << i)) != 0,
}
}
#[inline]
pub fn small_slice_aligned(&self, bit: usize, len: u8) -> u32 {
let (block, i) = div_rem(bit, BITS);
match self.slice.get(block) {
None => 0,
Some(&b) => {
let len_mask = (1 << len) - 1;
(b >> i) & len_mask
}
}
}
}
impl Index<usize> for BitSlice {
type Output = bool;
#[inline]
fn index(&self, bit: usize) -> &bool {
let (block, i) = div_rem(bit, BITS);
match self.slice.get(block) {
None => &FALSE,
Some(b) => {
if (b & (1 << i)) != 0 {
&TRUE
} else {
&FALSE
}
}
}
}
}
#[derive(Clone)]
pub struct Iter<'a> {
bit_slice: &'a BitSlice,
range: Range<usize>,
}
impl<'a> Iterator for Iter<'a> {
type Item = bool;
#[inline]
fn next(&mut self) -> Option<bool> {
self.range.next().map(|i| self.bit_slice[i])
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}
}