use std::{
mem,
ops::{Deref, DerefMut},
sync::atomic::{AtomicUsize, Ordering},
};
#[derive(Debug)]
pub struct CellRefMut<'a, T>
where
T: ?Sized + 'a,
{
pub(crate) flag: &'a AtomicUsize,
pub(crate) value: &'a mut T,
}
impl<'a, T> CellRefMut<'a, T>
where
T: ?Sized,
{
pub fn map<U, F>(self, f: F) -> CellRefMut<'a, U>
where
F: FnOnce(&mut T) -> &mut U,
U: ?Sized,
{
let flag = unsafe { &*(self.flag as *const _) };
let value = unsafe { &mut *(self.value as *mut _) };
mem::forget(self);
CellRefMut {
flag,
value: f(value),
}
}
}
impl<'a, T> Deref for CellRefMut<'a, T>
where
T: ?Sized,
{
type Target = T;
fn deref(&self) -> &T {
self.value
}
}
impl<'a, T> DerefMut for CellRefMut<'a, T>
where
T: ?Sized,
{
fn deref_mut(&mut self) -> &mut T {
self.value
}
}
impl<'a, T> Drop for CellRefMut<'a, T>
where
T: ?Sized,
{
fn drop(&mut self) {
self.flag.store(0, Ordering::Release)
}
}