use alloc::borrow::Cow;
use crate::{CowPolicy, MelinoeMut, MelinoeRef, ReadPermit, RetainDecision, WritePermit};
use super::BrandedVecDeque;
impl<'brand, T> BrandedVecDeque<'brand, T> {
#[inline]
pub fn get<'a, P>(&'a self, index: usize, permit: P) -> Option<MelinoeRef<'a, 'brand, T>>
where
P: ReadPermit<'brand> + 'a,
{
self.cells.get(index).map(|cell| cell.borrow(permit))
}
#[inline]
pub fn get_mut<'a, P>(&'a self, index: usize, permit: P) -> Option<MelinoeMut<'a, 'brand, T>>
where
P: WritePermit<'brand> + 'a,
{
self.cells.get(index).map(|cell| cell.borrow_mut(permit))
}
#[inline]
pub fn as_slices<'a, P>(&'a self, _permit: P) -> (&'a [T], &'a [T])
where
P: ReadPermit<'brand> + 'a,
{
let (s1, s2) = self.cells.as_slices();
unsafe {
let s1_ptr = s1.as_ptr() as *const T;
let s2_ptr = s2.as_ptr() as *const T;
(
core::slice::from_raw_parts(s1_ptr, s1.len()),
core::slice::from_raw_parts(s2_ptr, s2.len()),
)
}
}
#[allow(clippy::mut_from_ref)]
#[inline]
pub fn as_mut_slices<'a, P>(&'a self, _permit: P) -> (&'a mut [T], &'a mut [T])
where
P: WritePermit<'brand> + 'a,
{
let (s1, s2) = self.cells.as_slices();
unsafe {
let s1_ptr = s1.as_ptr() as *const core::cell::UnsafeCell<T> as *mut T;
let s2_ptr = s2.as_ptr() as *const core::cell::UnsafeCell<T> as *mut T;
(
core::slice::from_raw_parts_mut(s1_ptr, s1.len()),
core::slice::from_raw_parts_mut(s2_ptr, s2.len()),
)
}
}
#[inline]
pub fn borrow_cow<'a, P>(&'a self, permit: P) -> Cow<'a, [T]>
where
T: Clone,
P: ReadPermit<'brand> + 'a,
{
let (s1, s2) = self.as_slices(permit);
if s2.is_empty() {
Cow::Borrowed(s1)
} else {
let mut v = alloc::vec::Vec::with_capacity(s1.len() + s2.len());
v.extend_from_slice(s1);
v.extend_from_slice(s2);
Cow::Owned(v)
}
}
#[inline]
pub fn retain_cow<'a, P>(&'a self, permit: P) -> Cow<'a, [T]>
where
T: Clone,
P: ReadPermit<'brand> + 'a,
{
let (s1, s2) = self.as_slices(permit);
let mut v = alloc::vec::Vec::with_capacity(s1.len() + s2.len());
v.extend_from_slice(s1);
v.extend_from_slice(s2);
Cow::Owned(v)
}
#[inline]
pub fn cow_if<'a, P>(&'a self, permit: P, decision: RetainDecision) -> Cow<'a, [T]>
where
T: Clone,
P: ReadPermit<'brand> + 'a,
{
match decision {
RetainDecision::Borrow => self.borrow_cow(permit),
RetainDecision::Retain => self.retain_cow(permit),
}
}
#[inline]
pub fn cow_with<'a, P, C>(&'a self, permit: P, _policy: C) -> Cow<'a, [T]>
where
T: Clone,
P: ReadPermit<'brand> + 'a,
C: CowPolicy,
{
let (s1, s2) = self.as_slices(permit);
if s2.is_empty() {
C::cow(s1)
} else {
let mut v = alloc::vec::Vec::with_capacity(s1.len() + s2.len());
v.extend_from_slice(s1);
v.extend_from_slice(s2);
Cow::Owned(v)
}
}
#[inline]
#[must_use]
pub fn clone_with<'a, P>(&'a self, permit: P) -> Self
where
T: Clone,
P: ReadPermit<'brand> + 'a,
{
let (s1, s2) = self.as_slices(permit);
let mut cloned = Self::with_capacity(self.len());
cloned.extend(s1.iter().cloned().chain(s2.iter().cloned()));
cloned
}
}