use wrap::Wrapper;
use std::mem;
use std::ops::Deref;
pub trait Refcount {
unsafe fn inc_ref(&self);
unsafe fn dec_ref(&self);
}
pub struct Ref<T> where T: Refcount {
ptr: *const T
}
unsafe impl<T> Send for Ref<T> where T: Refcount + Send { }
unsafe impl<T> Sync for Ref<T> where T: Refcount + Sync { }
impl<T> Ref<T> where T: Refcount {
pub fn new(source: &T) -> Ref<T> {
unsafe {
source.inc_ref();
}
Ref { ptr: source }
}
}
impl<T> Ref<T> where T: Refcount + Wrapper {
pub unsafe fn from_raw(ptr: *mut <T as Wrapper>::Raw) -> Ref<T> {
Ref { ptr: ptr as *const T }
}
}
pub unsafe fn ref_into_raw<T>(r: Ref<T>) -> *mut <T as Wrapper>::Raw
where T: Refcount + Wrapper
{
let ptr = r.ptr;
mem::forget(r);
ptr as *mut _
}
impl<T> Drop for Ref<T> where T: Refcount {
fn drop(&mut self) {
unsafe {
self.dec_ref();
}
}
}
impl<T> Clone for Ref<T> where T: Refcount {
fn clone(&self) -> Ref<T> {
Ref::new(self.deref())
}
}
impl<T> Deref for Ref<T> where T: Refcount {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.ptr }
}
}