use crate::fixed::{
FixedVec,
proxy::MutProxy,
slice::FixedVecSlice,
traits::{Storable, Word},
};
use dsi_bitstream::prelude::Endianness;
use std::{cmp::min, fmt, iter::FusedIterator, marker::PhantomData};
#[derive(Debug)]
pub struct ChunksMut<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
vec_ptr: *mut FixedVec<T, W, E, B>,
end: usize,
current_pos: usize,
chunk_size: usize,
_phantom: PhantomData<&'a mut FixedVec<T, W, E, B>>,
}
impl<'a, T, W, E, B> ChunksMut<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
pub(super) fn new(vec: &'a mut FixedVec<T, W, E, B>, chunk_size: usize) -> Self {
assert!(chunk_size != 0, "chunk_size cannot be zero");
let end = vec.len();
Self {
vec_ptr: vec as *mut _,
chunk_size,
current_pos: 0,
end,
_phantom: PhantomData,
}
}
}
impl<'a, T, W, E, B> Iterator for ChunksMut<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
type Item = FixedVecSlice<&'a mut FixedVec<T, W, E, B>>;
fn next(&mut self) -> Option<Self::Item> {
if self.current_pos >= self.end {
return None;
}
let start = self.current_pos;
let len = min(self.chunk_size, self.end - start);
self.current_pos += len;
let vec_ref = unsafe { &mut *self.vec_ptr };
let slice = FixedVecSlice::new(vec_ref, start..start + len);
Some(slice)
}
}
impl<T, W, E, B> FusedIterator for ChunksMut<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
}
pub struct IterMut<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
vec_ptr: *mut FixedVec<T, W, E, B>,
pub(super) current_index: usize,
pub(super) end_index: usize,
_phantom: PhantomData<&'a mut FixedVec<T, W, E, B>>,
}
impl<'a, T, W, E, B> IterMut<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
pub(super) fn new(vec: &'a mut FixedVec<T, W, E, B>) -> Self {
let len = vec.len();
Self {
vec_ptr: vec as *mut _,
current_index: 0,
end_index: len,
_phantom: PhantomData,
}
}
}
impl<'a, T, W, E, B> Iterator for IterMut<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
type Item = MutProxy<'a, T, W, E, B>;
fn next(&mut self) -> Option<Self::Item> {
if self.current_index >= self.end_index {
return None;
}
let proxy = unsafe { MutProxy::new(&mut *self.vec_ptr, self.current_index) };
self.current_index += 1;
Some(proxy)
}
}
impl<T, W, E, B> FusedIterator for IterMut<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
}
impl<T, W, E, B> fmt::Debug for IterMut<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IterMut")
.field("remaining", &(self.end_index - self.current_index))
.finish()
}
}
pub struct IterMutUnchecked<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
iter: IterMut<'a, T, W, E, B>,
}
impl<'a, T, W, E, B> IterMutUnchecked<'a, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
pub(super) fn new(vec: &'a mut FixedVec<T, W, E, B>) -> Self {
Self {
iter: IterMut::new(vec),
}
}
#[inline]
pub unsafe fn next_unchecked(&mut self) -> MutProxy<'a, T, W, E, B> {
unsafe { self.iter.next().unwrap_unchecked() }
}
}
impl<T, W, E, B> fmt::Debug for IterMutUnchecked<'_, T, W, E, B>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IterMutUnchecked")
.field("remaining", &(self.iter.end_index - self.iter.current_index))
.finish()
}
}