use core::ptr;
use crate::link::Link;
use crate::Rc;
mod sealed {
use crate::Rc;
#[doc(hidden)]
pub trait Sealed {}
impl<T> Sealed for Rc<T> {}
}
pub unsafe trait Adopt: sealed::Sealed {
unsafe fn adopt_unchecked(this: &Self, other: &Self);
fn unadopt(this: &Self, other: &Self);
}
unsafe impl<T> Adopt for Rc<T> {
unsafe fn adopt_unchecked(this: &Self, other: &Self) {
if ptr::eq(this, other) {
let mut links = this.inner().links().borrow_mut();
links.insert(Link::loopback(other.ptr));
return;
}
let mut links = this.inner().links().borrow_mut();
links.insert(Link::forward(other.ptr));
drop(links);
let mut links = other.inner().links().borrow_mut();
links.insert(Link::backward(this.ptr));
}
fn unadopt(this: &Self, other: &Self) {
if ptr::eq(this, other) {
let mut links = unsafe { this.inner().links().borrow_mut() };
links.remove(Link::loopback(other.ptr), 1);
return;
}
let mut links = unsafe { this.inner().links().borrow_mut() };
links.remove(Link::forward(other.ptr), 1);
drop(links);
let mut links = unsafe { other.inner().links().borrow_mut() };
links.remove(Link::backward(this.ptr), 1);
}
}