use std::marker::PhantomData;
use std::ops::Deref;
#[derive(Clone)]
pub struct Pure<'a, T> {
data: T,
refs: Vec<*const T>,
_phantom: PhantomData<&'a T>,
}
unsafe impl<'a, T> Send for Pure<'a, T> {}
unsafe impl<'a, T> Sync for Pure<'a, T> {}
impl<'a, T> Pure<'a, T> {
pub fn new(data: T) -> Self {
Self {
data,
refs: Vec::new(),
_phantom: PhantomData,
}
}
pub fn borrow(&self) -> &'a T {
#[allow(mutable_transmutes)]
let self_: &mut Self = unsafe { std::mem::transmute(self) };
let boxed = unsafe { Box::from_raw(&mut self_.data as *mut T) };
let boxed = Box::leak(boxed) as &T;
let refer = boxed as *const T;
self_.refs.push(refer);
boxed
}
}
impl<'a, T> Deref for Pure<'a, T> {
type Target = T;
fn deref(&self) -> &'a Self::Target {
self.borrow()
}
}
impl<'a, T> Drop for Pure<'a, T> {
fn drop(&mut self) {
for ref_ in self.refs.iter() {
drop(*ref_)
}
}
}