use super::*;
struct VecRefMutBorrow<'a>(&'a Cell<Option<usize>>);
pub struct VecRefMut<'a, T: ?Sized> {
mut_borrow: VecRefMutBorrow<'a>,
value: &'a mut T,
}
impl<'a, T: ?Sized> VecRefMut<'a, T> {
pub(crate) fn new(vec: &'a VecCell<T>, index: usize) -> Option<Self>
where
T: Sized
{
if vec.borrows.get() > 0 || vec.mut_borrow.get().is_some() {
return None
}
if index >= vec.len() {
return None
}
vec.mut_borrow.set(Some(index));
Some(Self {
mut_borrow: VecRefMutBorrow(&vec.mut_borrow),
value: unsafe {
vec.get_mut_unchecked(index)
}
})
}
pub fn get(&self) -> &T {
&*self.value
}
pub fn map<'b, U: ?Sized, F>(original: VecRefMut<'b, T>, f: F) -> VecRefMut<'b, U>
where
F: FnOnce(&mut T) -> &mut U
{
let VecRefMut { value, mut_borrow } = original;
VecRefMut {
value: f(value),
mut_borrow
}
}
pub fn try_map<'b, U: ?Sized, F, E>(original: VecRefMut<'b, T>, f: F) -> Result<VecRefMut<'b, U>, E>
where
F: FnOnce(&mut T) -> Result<&mut U, E>
{
let VecRefMut { value, mut_borrow } = original;
Ok(VecRefMut {
value: f(value)?,
mut_borrow: mut_borrow
})
}
}
impl<'a, T: ?Sized> Deref for VecRefMut<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.value
}
}
impl<'a, T: ?Sized> DerefMut for VecRefMut<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.value
}
}
impl<'a> Drop for VecRefMutBorrow<'a> {
#[inline]
fn drop(&mut self) {
debug_assert!(self.0.get().is_some());
self.0.set(None);
}
}
impl<'a, T: Debug + ?Sized> Debug for VecRefMut<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VecRefMut")
.field(&self.value)
.finish()
}
}
impl<'a, T: Display + ?Sized> Display for VecRefMut<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
<T as Display>::fmt(&self.value, f)
}
}
impl<'a, T: PartialEq + ?Sized> PartialEq for VecRefMut<'a, T> {
fn eq(&self, other: &Self) -> bool {
self.get() == other.get()
}
}
impl<'a, T: PartialEq + ?Sized> PartialEq<T> for VecRefMut<'a, T> {
fn eq(&self, other: &T) -> bool {
self.get() == other
}
}