use std::{ops::{Index, IndexMut, Deref, DerefMut, Add, Sub, Mul}, marker::PhantomData, ptr::NonNull, fmt::{Debug, Display}}; use crate::prelude::*; pub struct Gc { ptr: NonNull>, phantom: PhantomData> } struct GcInner { rc: usize, data: T } impl Gc { pub fn new(data: T) -> Self { let boxed = Box::new(GcInner { rc: 1, data, }); Self { ptr: NonNull::new(Box::into_raw(boxed)).unwrap(), phantom: PhantomData } } } impl Gc { pub fn into_inner(self) -> T { unsafe { self.ptr.as_ref().data.clone() } } fn data(&self) -> T { unsafe { self.ptr.as_ref().data.clone() } } } impl ValueClone for Gc { fn deep_clone(&self) -> Self { unsafe { let data = self.ptr.as_ref().data.deep_clone(); Self::new(data) } } fn shallow_clone(&self) -> Self { unsafe { let data = self.ptr.as_ref().data.shallow_clone(); Self::new(data) } } } impl From for Gc { fn from(value: T) -> Self { Gc::new(value) } } impl, Idx> IndexMut for Gc { fn index_mut(&mut self, index: Idx) -> &mut Self::Output { self.deref_mut().index_mut(index) } } impl, Idx> Index for Gc { type Output = T::Output; fn index(&self, index: Idx) -> &Self::Output { self.deref().index(index) } } impl DerefMut for Gc { fn deref_mut(&mut self) -> &mut Self::Target { unsafe { &mut self.ptr.as_mut().data } } } impl Deref for Gc { type Target = T; fn deref(&self) -> &Self::Target { unsafe { &self.ptr.as_ref().data } } } impl PartialEq for Gc { fn eq(&self, other: &Self) -> bool { self.deref().eq(other.deref()) } } impl Iterator for Gc { type Item = T::Item; fn next(&mut self) -> Option { self.deref_mut().next() } } impl Eq for Gc {} impl Clone for Gc { fn clone(&self) -> Self { unsafe { let inner = self.ptr.as_ptr().as_mut().unwrap(); inner.rc += 1; Self { ptr: self.ptr, phantom: PhantomData } } } } impl Drop for Gc { fn drop(&mut self) { unsafe { let inner = self.ptr.as_mut(); if inner.rc > 1 { inner.rc -= 1; } else { let _ = Box::from_raw(self.ptr.as_ptr()); } } } } impl Debug for Gc { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if f.alternate() { write!(f, "{:#?}", self.deref()) } else { write!(f, "{:?}", self.deref()) } } } impl Display for Gc { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { if f.alternate() { write!(f, "{:#}", self.deref()) } else { write!(f, "{}", self.deref()) } } } impl Add for Gc { type Output = T::Output; fn add(self, rhs: Self) -> Self::Output { let a = self.data(); let b = rhs.data(); a + b } } impl Sub for Gc { type Output = T::Output; fn sub(self, rhs: Self) -> Self::Output { let a = self.data(); let b = rhs.data(); a - b } } impl Mul for Gc { type Output = T::Output; fn mul(self, rhs: Self) -> Self::Output { let a = self.data(); let b = rhs.data(); a * b } }