use std::mem::size_of;
use std::ops::ControlFlow;
use crate::Primitive;
#[inline]
pub unsafe fn set_array_bit_unchecked<const FLAG: bool, T>(blocks: &mut [T], index: usize) -> bool
where
T: Primitive
{
let bits_size: usize = size_of::<T>() * 8; let block_index = index / bits_size;
let bit_index = index & (bits_size -1);
set_bit_unchecked::<FLAG, T>(blocks.get_unchecked_mut(block_index), bit_index)
}
#[inline]
pub unsafe fn set_bit_unchecked<const FLAG: bool, T>(block: &mut T, bit_index: usize) -> bool
where
T: Primitive
{
let block_mask: T = T::ONE << bit_index;
let masked_block = *block & block_mask;
if FLAG {
*block |= block_mask;
} else {
*block &= !block_mask;
}
!masked_block.is_zero()
}
#[inline]
pub unsafe fn get_array_bit_unchecked<T>(blocks: &[T], index: usize) -> bool
where
T: Primitive
{
let bits_size: usize = size_of::<T>() * 8; let block_index = index / bits_size;
let bit_index = index & (bits_size -1);
get_bit_unchecked(*blocks.get_unchecked(block_index), bit_index)
}
#[inline]
pub unsafe fn get_bit_unchecked<T: Primitive>(block: T, bit_index: usize) -> bool {
let block_mask: T = T::ONE << bit_index;
let masked_block = block & block_mask;
!masked_block.is_zero()
}
#[inline]
pub fn traverse_array_one_bits<P, F, B>(array: &[P], mut f: F) -> ControlFlow<B>
where
P: Primitive,
F: FnMut(usize) -> ControlFlow<B>
{
let len = array.len();
for i in 0..len{
let element = unsafe{*array.get_unchecked(i)};
let control = traverse_one_bits(
element,
|r|{
let index = i*size_of::<P>()*8 + r;
f(index)
}
);
if let Some(e) = control.break_value() {
return ControlFlow::Break(e);
}
}
ControlFlow::Continue(())
}
#[inline]
pub fn traverse_one_bits<P, F, B>(mut element: P, mut f: F) -> ControlFlow<B>
where
P: Primitive,
F: FnMut(usize) -> ControlFlow<B>
{
while !element.is_zero() {
let index = element.trailing_zeros() as usize;
let control = f(index);
if let Some(e) = control.break_value() {
return ControlFlow::Break(e);
}
let t: P = element & element.wrapping_neg();
element ^= t;
}
ControlFlow::Continue(())
}
#[inline]
pub fn one_bits_iter<P>(element: P) -> OneBitsIter<P> {
OneBitsIter {element}
}
#[repr(transparent)]
#[derive(Copy, Clone)]
pub struct OneBitsIter<P>{
element: P
}
impl<P> Iterator for OneBitsIter<P>
where
P: Primitive,
{
type Item = usize;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
if !self.element.is_zero() {
let index = self.element.trailing_zeros() as usize;
let t: P = self.element & self.element.wrapping_neg();
self.element ^= t;
Some(index)
} else {
None
}
}
}