use crate::alloc::AllocMut;
use crate::error::Error;
use crate::{Alloc, Gc, GcMut};
use std::ops::{Deref, DerefMut};
pub trait Accessor<T: ?Sized, A>: Sized
where
A: Alloc<T>,
{
type Guard<'g>: Deref<Target = T>
where
Self: 'g;
#[inline(always)]
fn read<'g>(&'g self, object: &'g Gc<T, A>) -> Self::Guard<'g> {
self.try_read(object)
.unwrap_or_else(|err| failed_access(err))
}
#[inline(always)]
fn try_read<'g>(&'g self, object: &'g Gc<T, A>) -> Result<Self::Guard<'g>, Error> {
unsafe { self.access(&object.handle) }
}
fn is_alive(&self, _object: &Gc<T, A>) -> Option<bool> {
None
}
unsafe fn access<'g>(
&'g self,
handle: &'g <A as Alloc<T>>::RawHandle,
) -> Result<Self::Guard<'g>, Error>;
}
pub trait AccessorMut<T: ?Sized, A>: Accessor<T, A>
where
A: AllocMut<T>,
{
type GuardMut<'g>: DerefMut<Target = T>
where
Self: 'g;
#[inline(always)]
fn write<'g>(&'g self, object: &'g GcMut<T, A>) -> Self::GuardMut<'g> {
self.try_write(object)
.unwrap_or_else(|err| failed_access(err))
}
#[inline(always)]
fn try_write<'g>(&'g self, object: &'g GcMut<T, A>) -> Result<Self::GuardMut<'g>, Error> {
unsafe { self.access_mut(&object.handle) }
}
unsafe fn access_mut<'g>(
&'g self,
handle: &'g <A as Alloc<<A as Alloc<T>>::MutTy>>::RawHandle,
) -> Result<Self::GuardMut<'g>, Error>;
}
#[inline(never)]
#[cold]
fn failed_access(err: Error) -> ! {
panic!("Failed to access GC object: {:?}", err)
}