use crate::*;
use std::{convert::Infallible, cell::RefCell, marker::PhantomData};
use std::any::Any;
use std::collections::HashSet;
pub trait AsAny: Any {
fn as_any(&self) -> &dyn Any;
}
impl<T: Any> AsAny for T {
#[inline(always)]
fn as_any(&self) -> &dyn Any {
self
}
}
pub trait GcCompat: AsAny {
fn points_to(&self, buffer: &mut HashSet<usize>);
}
macro_rules! empty_gccompat {
( $( $t:ty ),* ) => {
$(
impl GcCompat for $t {
fn points_to(&self, _m: &mut HashSet<usize>) {}
}
)*
};
}
empty_gccompat!((), bool, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, usize, isize, std::string::String, Infallible, BigInt);
impl<A, B> GcCompat for (A, B) where A: GcCompat, B: GcCompat {
fn points_to(&self, m: &mut HashSet<usize>) {
let (a, b) = self;
a.points_to(m);
b.points_to(m);
}
}
impl<T: GcCompat> GcCompat for Option<T> {
fn points_to(&self, m: &mut HashSet<usize>) {
match self {
Some(x) => x.points_to(m),
None => {},
}
}
}
impl<T: GcCompat, E: GcCompat> GcCompat for Result<T, E> {
fn points_to(&self, m: &mut HashSet<usize>) {
match self {
Ok(x) => x.points_to(m),
Err(x) => x.points_to(m),
}
}
}
impl<G: GcCompat + ?Sized> GcCompat for Box<G> {
fn points_to(&self, buffer: &mut HashSet<usize>) {
(**self).points_to(buffer)
}
}
impl<G: GcCompat> GcCompat for RefCell<G> {
fn points_to(&self, buffer: &mut HashSet<usize>) {
self.borrow().points_to(buffer)
}
}
impl<G: GcCompat> GcCompat for PhantomData<G> {
fn points_to(&self, _buffer: &mut HashSet<usize>) {}
}