xarc 0.3.0

`xarc` provides atomically swappable atomically refcounted smart pointers as a safer building block for lockfree algorithms than raw atomic pointers. `Xarc` is comparable to `Arc` but with the additional ability to atomically be swapped into and out of `AtomicXarc`. `Xarc` is dereferenceable but cannot have its contents atomically swapped. `AtomicXarc` can have its contents atomically swapped but is not dereferenceable.
Documentation
use alloc::boxed::Box;
use core::sync::atomic::{AtomicUsize, Ordering};
use crossbeam_epoch::Guard;
use crossbeam_utils::CachePadded;

pub(crate) struct XarcCount {
    count: CachePadded<AtomicUsize>,
}

impl XarcCount {
    #[must_use]
    fn new() -> XarcCount {
        XarcCount {
            count: CachePadded::new(AtomicUsize::new(1)),
        }
    }

    #[must_use]
    pub(crate) fn decrement(&self) -> usize {
        self.count.fetch_sub(1, Ordering::Relaxed)
    }

    pub(crate) fn try_increment(&self) -> Result<usize, usize> {
        let mut count = self.count.load(Ordering::Relaxed);
        while count > 0 {
            match self.count.compare_exchange_weak(count, count + 1, Ordering::Relaxed, Ordering::Relaxed) {
                Ok(c) => return Ok(c),
                Err(c) => count = c,
            }
        }
        Err(count)
    }

    #[must_use]
    fn unsafe_increment(&self) -> usize {
        self.count.fetch_add(1, Ordering::Relaxed)
    }
}

pub(crate) struct XarcData<T: Send> {
    pub(crate) count: XarcCount,
    pub(crate) value: T,
}

impl<T: Send> XarcData<T> {
    #[must_use]
    pub(crate) fn new(value: T) -> Self {
        XarcData {
            count: XarcCount::new(),
            value,
        }
    }
}

pub(crate) fn decrement<T: Send>(ptr: *mut XarcData<T>, guard: &Guard) {
    unsafe {
        if !ptr.is_null() && (*ptr).count.decrement() == 1 {
            let boxed = Box::from_raw(ptr);
            guard.defer_unchecked(move || {
                drop(boxed);
            });
        }
    }
}

pub(crate) fn try_increment<T: Send>(ptr: *mut XarcData<T>, _guard: &Guard) -> Result<(), ()> {
    unsafe {
        if ptr.is_null() || (*ptr).count.try_increment().is_ok() {
            Ok(())
        }
        else {
            Err(())
        }
    }
}

pub(crate) fn unguarded_increment<T: Send>(ptr: *mut XarcData<T>) {
    unsafe {
        if !ptr.is_null() && (*ptr).count.unsafe_increment() < 1 {
            panic!("Unguarded XarcCount increment from 0!");
        }
    }
}