use std::{
cell::{Cell, RefCell},
marker,
};
use hashbrown::raw::RawTable;
use crate::{
collections::SmallMap,
values::{FrozenValue, Tracer, Value},
};
pub unsafe trait Trace<'v> {
fn trace(&mut self, tracer: &Tracer<'v>);
}
unsafe impl<'v, T: Trace<'v>> Trace<'v> for Vec<T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
self.iter_mut().for_each(|x| x.trace(tracer));
}
}
unsafe impl<'v, T: Trace<'v>> Trace<'v> for [T] {
fn trace(&mut self, tracer: &Tracer<'v>) {
self.iter_mut().for_each(|x| x.trace(tracer));
}
}
unsafe impl<'v, T: Trace<'v>> Trace<'v> for RawTable<T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
unsafe {
self.iter().for_each(|e| e.as_mut().trace(tracer));
}
}
}
unsafe impl<'v, K: Trace<'v>, V: Trace<'v>> Trace<'v> for SmallMap<K, V> {
fn trace(&mut self, tracer: &Tracer<'v>) {
self.iter_mut().for_each(|(k, v)| {
#[allow(clippy::cast_ref_to_mut)]
let k_mut = unsafe { &mut *(k as *const K as *mut K) };
k_mut.trace(tracer);
v.trace(tracer);
})
}
}
unsafe impl<'v, T: Trace<'v>> Trace<'v> for Option<T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
if let Some(x) = self {
x.trace(tracer)
}
}
}
unsafe impl<'v, T: Trace<'v>> Trace<'v> for RefCell<T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
self.get_mut().trace(tracer)
}
}
unsafe impl<'v, T: Trace<'v> + Copy> Trace<'v> for Cell<T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
self.get_mut().trace(tracer);
}
}
unsafe impl<'v, T: Trace<'v> + ?Sized> Trace<'v> for Box<T> {
fn trace(&mut self, tracer: &Tracer<'v>) {
Box::as_mut(self).trace(tracer)
}
}
unsafe impl<'v, T1: Trace<'v>, T2: Trace<'v>> Trace<'v> for (T1, T2) {
fn trace(&mut self, tracer: &Tracer<'v>) {
self.0.trace(tracer);
self.1.trace(tracer);
}
}
unsafe impl<'v> Trace<'v> for Value<'v> {
fn trace(&mut self, tracer: &Tracer<'v>) {
tracer.trace(self)
}
}
unsafe impl<'v> Trace<'v> for FrozenValue {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for String {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for usize {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for i32 {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for u32 {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for u64 {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for bool {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v> Trace<'v> for std::time::Instant {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}
unsafe impl<'v, T> Trace<'v> for marker::PhantomData<T> {
fn trace(&mut self, _tracer: &Tracer<'v>) {}
}