use crate::PinnedVec;
use core::ops::{Deref, DerefMut};
use core::{cell::UnsafeCell, marker::PhantomData};
use orx_self_or::SoM;
pub struct ImpVec<T, P, S>
where
P: PinnedVec<T>,
S: SoM<P>,
{
pinned_vec: UnsafeCell<S>,
phantom: PhantomData<(T, P)>,
}
impl<T, P, S> ImpVec<T, P, S>
where
P: PinnedVec<T>,
S: SoM<P>,
{
#[allow(clippy::mut_from_ref)]
#[inline(always)]
fn pinned_mut(&self) -> &mut P {
unsafe { &mut *self.pinned_vec.get() }.get_mut()
}
#[inline(always)]
fn pinned(&self) -> &P {
unsafe { &*self.pinned_vec.get() }.get_ref()
}
pub(super) fn new(pinned_vec: S) -> Self {
Self {
pinned_vec: pinned_vec.into(),
phantom: PhantomData,
}
}
pub fn into_inner(self) -> S {
self.pinned_vec.into_inner()
}
#[inline(always)]
pub fn imp_push(&self, value: T) {
self.pinned_mut().push(value);
}
#[inline(always)]
pub fn imp_push_get_ref(&self, value: T) -> &T {
let pinned = self.pinned_mut();
pinned.push(value);
&pinned[pinned.len() - 1]
}
pub fn imp_extend_from_slice(&self, slice: &[T])
where
T: Clone,
{
self.pinned_mut().extend_from_slice(slice);
}
}
impl<T, P, S> Deref for ImpVec<T, P, S>
where
P: PinnedVec<T>,
S: SoM<P>,
{
type Target = P;
fn deref(&self) -> &Self::Target {
self.pinned()
}
}
impl<T, P, S> DerefMut for ImpVec<T, P, S>
where
P: PinnedVec<T>,
S: SoM<P>,
{
fn deref_mut(&mut self) -> &mut Self::Target {
self.pinned_mut()
}
}