use crate::bit_chunk_iterator::BitChunks;
use crate::{bit_util, Buffer};
#[derive(Debug, Clone, Eq)]
pub struct BooleanBuffer {
buffer: Buffer,
offset: usize,
len: usize,
}
impl PartialEq for BooleanBuffer {
fn eq(&self, other: &Self) -> bool {
if self.len != other.len {
return false;
}
let lhs = self.bit_chunks();
let rhs = other.bit_chunks();
if lhs.iter().zip(rhs.iter()).any(|(a, b)| a != b) {
return false;
}
lhs.remainder_bits() == rhs.remainder_bits()
}
}
impl BooleanBuffer {
pub fn new(buffer: Buffer, offset: usize, len: usize) -> Self {
let total_len = offset.saturating_add(len);
let bit_len = buffer.len().saturating_mul(8);
assert!(total_len <= bit_len);
Self {
buffer,
offset,
len,
}
}
pub fn count_set_bits(&self) -> usize {
self.buffer.count_set_bits_offset(self.offset, self.len)
}
pub fn bit_chunks(&self) -> BitChunks {
BitChunks::new(self.values(), self.offset, self.len)
}
#[inline]
pub fn is_set(&self, i: usize) -> bool {
assert!(i < self.len);
unsafe { bit_util::get_bit_raw(self.buffer.as_ptr(), i + self.offset) }
}
#[inline]
pub fn offset(&self) -> usize {
self.offset
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}
#[inline]
pub fn values(&self) -> &[u8] {
&self.buffer
}
pub fn slice(&self, offset: usize, len: usize) -> Self {
assert!(
offset.saturating_add(len) <= self.len,
"the length + offset of the sliced BooleanBuffer cannot exceed the existing length"
);
Self {
buffer: self.buffer.clone(),
offset: self.offset + offset,
len,
}
}
pub fn sliced(&self) -> Buffer {
self.buffer.bit_slice(self.offset, self.len)
}
pub fn ptr_eq(&self, other: &Self) -> bool {
self.buffer.as_ptr() == other.buffer.as_ptr()
&& self.offset == other.offset
&& self.len == other.len
}
#[inline]
pub fn inner(&self) -> &Buffer {
&self.buffer
}
pub fn into_inner(self) -> Buffer {
self.buffer
}
}