use super::{internal::*};
use alloc::boxed::Box;
use core::{hash::*, ptr};
use crossbeam_epoch::{Guard, pin};
#[derive(Debug, Eq)]
pub struct Xarc<T: Send> {
pub(crate) ptr: *mut XarcData<T>,
}
impl<T: Send> Xarc<T> {
#[must_use]
pub fn new(value: T) -> Self {
Xarc {
ptr: Box::into_raw(Box::new(XarcData::new(value))),
}
}
#[must_use]
pub fn null() -> Self {
Xarc {
ptr: ptr::null_mut(),
}
}
#[must_use]
pub(crate) fn init(ptr: *mut XarcData<T>) -> Self {
Xarc {
ptr,
}
}
pub(crate) fn try_from(ptr: *mut XarcData<T>, guard: &Guard) -> Result<Self, ()> {
try_increment(ptr, guard)?;
Ok(Xarc::init(ptr))
}
pub fn reset(&mut self) {
let guard = pin();
decrement(self.ptr, &guard);
self.ptr = ptr::null_mut();
}
#[must_use]
pub fn is_null(&self) -> bool {
self.ptr.is_null()
}
#[must_use]
pub fn maybe_deref(&self) -> Option<&T> {
if !self.ptr.is_null() {
unsafe {
Some(&(*self.ptr).value)
}
}
else {
None
}
}
#[must_use]
pub unsafe fn unguarded_maybe_deref_mut(&mut self) -> Option<&mut T> {
if !self.ptr.is_null() {
Some(&mut (*self.ptr).value)
}
else {
None
}
}
}
impl<T: Send> Clone for Xarc<T> {
fn clone(&self) -> Self {
unguarded_increment(self.ptr);
Xarc::init(self.ptr)
}
}
impl<T: Send> Drop for Xarc<T> {
fn drop(&mut self) {
decrement(self.ptr, &pin());
}
}
impl<T: Send> Hash for Xarc<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
ptr::hash(self.ptr, state);
}
}
impl<T: Send> PartialEq for Xarc<T> {
#[must_use]
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
unsafe impl<T: Send> Send for Xarc<T> {}
unsafe impl<T: Send> Sync for Xarc<T> {}