use crate::{Idx, IndexSlice, IndexVec};
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
#[derive(Clone, PartialEq, Eq, Hash, get_size2::GetSize)]
pub struct FrozenIndexVec<I, T> {
raw: Box<[T]>,
index: PhantomData<I>,
}
impl<I: Idx, T> FrozenIndexVec<I, T> {
#[inline]
fn from_raw(raw: Box<[T]>) -> Self {
Self {
raw,
index: PhantomData,
}
}
#[inline]
fn as_slice(&self) -> &IndexSlice<I, T> {
IndexSlice::from_raw(&self.raw)
}
#[inline]
fn as_mut_slice(&mut self) -> &mut IndexSlice<I, T> {
IndexSlice::from_raw_mut(&mut self.raw)
}
}
impl<I, T> Debug for FrozenIndexVec<I, T>
where
T: Debug,
{
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.raw, f)
}
}
impl<I: Idx, T> Deref for FrozenIndexVec<I, T> {
type Target = IndexSlice<I, T>;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<I: Idx, T> DerefMut for FrozenIndexVec<I, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_slice()
}
}
impl<I: Idx, T> From<IndexVec<I, T>> for FrozenIndexVec<I, T> {
#[inline]
fn from(vec: IndexVec<I, T>) -> Self {
Self::from_raw(vec.raw.into_boxed_slice())
}
}
impl<I: Idx, T> FromIterator<T> for FrozenIndexVec<I, T> {
#[inline]
fn from_iter<Iter: IntoIterator<Item = T>>(iter: Iter) -> Self {
Self::from_raw(iter.into_iter().collect())
}
}
#[expect(unsafe_code)]
unsafe impl<I: Idx, T> Send for FrozenIndexVec<I, T> where T: Send {}
#[expect(unsafe_code)]
#[cfg(feature = "salsa")]
unsafe impl<I, T: salsa::SalsaValue> salsa::SalsaValue for FrozenIndexVec<I, T> {}