use std::fmt::{Debug, Formatter};
use std::ops::Deref;
use crate::heap_entry::{EntryLike, HeapEntry};
use crate::trace::Trace;
pub struct Gc<T> {
entry: *const HeapEntry<T>,
}
impl<T> Clone for Gc<T> {
fn clone(&self) -> Self {
*self
}
}
impl<T> Copy for Gc<T> {}
impl<T> Gc<T> {
pub(super) unsafe fn new(entry: *const HeapEntry<T>) -> Self {
Self { entry }
}
pub(super) fn entry(&self) -> &HeapEntry<T> {
unsafe { &*self.entry }
}
pub fn is_root(&self) -> bool where T: Trace {
self.entry().is_root()
}
}
impl<T: Trace> Deref for Gc<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { (*self.entry).get() }
}
}
impl<T> Debug for Gc<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Gc")
.field("entry", &self.entry)
.finish()
}
}
unsafe impl<T: Trace> Trace for Gc<T> {
fn mark_children(&self) {
self.entry().mark_reachable();
}
}