use crate::fixed::{
iter::FixedVecSliceIter,
proxy::MutProxy,
traits::{Storable, Word},
FixedVec,
};
use dsi_bitstream::prelude::Endianness;
use std::ops::{Deref, DerefMut, Range};
#[derive(Debug)]
pub struct FixedVecSlice<V> {
pub(super) parent: V,
pub(super) range: Range<usize>,
}
impl<T, W, E, B, V> FixedVecSlice<V>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]>,
V: Deref<Target = FixedVec<T, W, E, B>>,
{
pub(super) fn new(parent: V, range: Range<usize>) -> Self {
debug_assert!(range.end <= parent.len());
Self { parent, range }
}
#[inline]
pub fn len(&self) -> usize {
self.range.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.range.is_empty()
}
#[inline]
pub fn get(&self, index: usize) -> Option<T> {
if index >= self.len() {
return None;
}
Some(unsafe { self.get_unchecked(index) })
}
#[inline(always)]
pub unsafe fn get_unchecked(&self, index: usize) -> T {
debug_assert!(index < self.len());
unsafe { self.parent.get_unchecked(self.range.start + index) }
}
pub fn iter(&self) -> FixedVecSliceIter<'_, T, W, E, B, V> {
FixedVecSliceIter::new(self)
}
pub fn binary_search(&self, value: &T) -> Result<usize, usize>
where
T: Ord,
{
let mut low = 0;
let mut high = self.len();
while low < high {
let mid = low + (high - low) / 2;
let mid_val = unsafe { self.get_unchecked(mid) };
match mid_val.cmp(value) {
std::cmp::Ordering::Less => low = mid + 1,
std::cmp::Ordering::Equal => return Ok(mid),
std::cmp::Ordering::Greater => high = mid,
}
}
Err(low)
}
}
impl<T, W, E, B, V> FixedVecSlice<V>
where
T: Storable<W>,
W: Word,
E: Endianness,
B: AsRef<[W]> + AsMut<[W]>,
V: Deref<Target = FixedVec<T, W, E, B>> + DerefMut,
{
pub fn at_mut(&mut self, index: usize) -> Option<MutProxy<'_, T, W, E, B>> {
if index >= self.len() {
return None;
}
Some(MutProxy::new(&mut self.parent, self.range.start + index))
}
}
impl<T, W, E, B, V1, V2> PartialEq<FixedVecSlice<V2>> for FixedVecSlice<V1>
where
T: Storable<W> + PartialEq,
W: Word,
E: Endianness,
B: AsRef<[W]>,
V1: Deref<Target = FixedVec<T, W, E, B>>,
V2: Deref<Target = FixedVec<T, W, E, B>>,
{
fn eq(&self, other: &FixedVecSlice<V2>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().eq(other.iter())
}
}
impl<T, W, E, B, V> Eq for FixedVecSlice<V>
where
T: Storable<W> + Eq,
W: Word,
E: Endianness,
B: AsRef<[W]>,
V: Deref<Target = FixedVec<T, W, E, B>>,
{
}
impl<T, W, E, B, B2, V> PartialEq<FixedVec<T, W, E, B2>> for FixedVecSlice<V>
where
T: Storable<W> + PartialEq,
W: Word,
E: Endianness,
B: AsRef<[W]>,
B2: AsRef<[W]>,
V: Deref<Target = FixedVec<T, W, E, B>>,
{
fn eq(&self, other: &FixedVec<T, W, E, B2>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().eq(other.iter())
}
}
impl<T, W, E, B, B2, V> PartialEq<FixedVecSlice<V>> for FixedVec<T, W, E, B>
where
T: Storable<W> + PartialEq,
W: Word,
E: Endianness,
B: AsRef<[W]>,
B2: AsRef<[W]>,
V: Deref<Target = FixedVec<T, W, E, B2>>,
{
fn eq(&self, other: &FixedVecSlice<V>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().eq(other.iter())
}
}
impl<T, W, E, B, T2, V> PartialEq<&[T2]> for FixedVecSlice<V>
where
T: Storable<W> + PartialEq<T2>,
W: Word,
E: Endianness,
B: AsRef<[W]>,
T2: Clone,
V: Deref<Target = FixedVec<T, W, E, B>>,
{
fn eq(&self, other: &&[T2]) -> bool {
if self.len() != other.len() {
return false;
}
self.iter().zip(other.iter()).all(|(a, b)| a == *b)
}
}
impl<T, W, E, B, B2, V> PartialEq<&FixedVec<T, W, E, B2>> for FixedVecSlice<V>
where
T: Storable<W> + PartialEq,
W: Word,
E: Endianness,
B: AsRef<[W]>,
B2: AsRef<[W]>,
V: Deref<Target = FixedVec<T, W, E, B>>,
{
fn eq(&self, other: &&FixedVec<T, W, E, B2>) -> bool {
self.eq(*other)
}
}