use core::borrow::Borrow;
use core::fmt::Debug;
use core::mem::ManuallyDrop;
use core::ops::Deref;
use crate::concurrent::smr;
use crate::concurrent::smr::Guard as _;
use crate::sequential;
pub use crate::sequential::value::Arc;
pub trait Value: sequential::Value + Borrow<Self::Borrowed> {
const INDIRECT: bool;
type Borrowed;
type Guard<G>: smr::Guard<Self> + From<G>
where
G: smr::Guard<Self>;
unsafe fn borrow_from_raw_unchecked(raw: &u64) -> &Self::Borrowed;
}
macro_rules! impl_integer {
($($ty:ty),*) => {
$(
impl Value for $ty {
const INDIRECT: bool = false;
type Borrowed = Self;
type Guard<G>
= smr::no_op::Guard<G, Self>
where
G: smr::Guard<Self>;
#[inline]
unsafe fn borrow_from_raw_unchecked(raw: &u64) -> &Self::Borrowed {
unsafe { core::mem::transmute::<&u64, &Self>(raw) }
}
}
)*
};
}
impl_integer!(u64, i64);
impl<'v, T: 'v + Sized> Value for &'v T {
const INDIRECT: bool = false;
type Borrowed = Self;
type Guard<G>
= smr::no_op::Guard<G, Self>
where
G: smr::Guard<Self>;
#[inline]
unsafe fn borrow_from_raw_unchecked(raw: &u64) -> &Self::Borrowed {
unsafe { core::mem::transmute::<&u64, &Self>(raw) }
}
}
impl<T: Sized> Value for Box<T> {
const INDIRECT: bool = true;
type Borrowed = T;
type Guard<G>
= G
where
G: smr::Guard<Self>;
#[inline]
unsafe fn borrow_from_raw_unchecked(raw: &u64) -> &Self::Borrowed {
let borrow = unsafe { core::ptr::with_exposed_provenance::<T>((*raw) as usize).as_ref() };
if_validate!(borrow.unwrap(), unsafe { borrow.unwrap_unchecked() })
}
}
impl<T: Sized> Value for Arc<T> {
const INDIRECT: bool = true;
type Borrowed = ArcRef<T>;
type Guard<G>
= G
where
G: smr::Guard<Self>;
#[inline]
unsafe fn borrow_from_raw_unchecked(raw: &u64) -> &Self::Borrowed {
let borrow = unsafe {
core::ptr::with_exposed_provenance::<T>((*raw) as usize)
.cast::<ArcRef<T>>()
.as_ref()
};
if_validate!(borrow.unwrap(), unsafe { borrow.unwrap_unchecked() })
}
}
impl<T> Borrow<ArcRef<T>> for crate::sequential::value::Arc<T> {
fn borrow(&self) -> &ArcRef<T> {
unsafe { core::mem::transmute::<&T, &ArcRef<T>>(self.0.as_ref()) }
}
}
#[repr(transparent)]
#[derive(Debug)]
pub struct ArcRef<T>(T);
impl<T> Deref for ArcRef<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> ToOwned for ArcRef<T> {
type Owned = Arc<T>;
fn to_owned(&self) -> Self::Owned {
let ptr = unsafe { core::mem::transmute::<&Self, &T>(self) };
unsafe { crate::sync::Arc::increment_strong_count(ptr) };
Arc(unsafe { crate::sync::Arc::from_raw(ptr) })
}
}
pub struct Owned<G: smr::Guard<V>, V: Value> {
guard: V::Guard<G>,
raw: u64,
}
impl<G, V> Owned<G, V>
where
G: smr::Guard<V>,
V: Value,
{
pub(crate) unsafe fn wrap(guard: G, raw: u64) -> Self {
Self {
guard: V::Guard::<G>::from(guard),
raw,
}
}
}
impl<G, V> Deref for Owned<G, V>
where
G: smr::Guard<V>,
V: Value,
{
type Target = V::Borrowed;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { V::borrow_from_raw_unchecked(&self.raw) }
}
}
impl<G: smr::Guard<V>, V: Value> Drop for Owned<G, V> {
fn drop(&mut self) {
unsafe { self.guard.retire_value(self.raw) }
}
}
impl<G, V> Debug for Owned<G, V>
where
G: smr::Guard<V>,
V: Value,
V::Borrowed: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.deref().fmt(f)
}
}
pub struct Shared<G: smr::Guard<V>, V: Value> {
_guard: V::Guard<G>,
raw: u64,
}
impl<G, V> Shared<G, V>
where
G: smr::Guard<V>,
V: Value,
{
pub(crate) unsafe fn wrap(guard: G, raw: u64) -> Self {
Self {
_guard: V::Guard::<G>::from(guard),
raw,
}
}
}
impl<G, V> Deref for Shared<G, V>
where
G: smr::Guard<V>,
V: Value,
{
type Target = V::Borrowed;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { V::borrow_from_raw_unchecked(&self.raw) }
}
}
impl<G, V> Debug for Shared<G, V>
where
G: smr::Guard<V>,
V: Value,
V::Borrowed: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.deref().fmt(f)
}
}
pub struct Updated<G: smr::Guard<V>, V: Value> {
guard: V::Guard<G>,
old: u64,
new: u64,
}
impl<G, V> Updated<G, V>
where
G: smr::Guard<V>,
V: Value,
{
pub(crate) unsafe fn wrap(guard: G, old: u64, new: u64) -> Self {
Self {
guard: V::Guard::<G>::from(guard),
old,
new,
}
}
#[inline]
pub fn old(&self) -> &V::Borrowed {
unsafe { V::borrow_from_raw_unchecked(&self.old) }
}
#[inline]
#[expect(clippy::new_ret_no_self)]
pub fn new(&self) -> &V::Borrowed {
unsafe { V::borrow_from_raw_unchecked(&self.new) }
}
}
impl<G: smr::Guard<V>, V: Value> Drop for Updated<G, V> {
fn drop(&mut self) {
unsafe { self.guard.retire_value(self.old) }
}
}
impl<G, V> Debug for Updated<G, V>
where
G: smr::Guard<V>,
V: Value,
V::Borrowed: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Updated")
.field("old", self.old())
.field("new", self.new())
.finish()
}
}
pub struct Upserted<G: smr::Guard<V>, V: Value> {
guard: V::Guard<G>,
old: Option<u64>,
new: u64,
}
impl<G, V> Upserted<G, V>
where
G: smr::Guard<V>,
V: Value,
{
pub(crate) unsafe fn wrap(guard: G, old: Option<u64>, new: u64) -> Self {
Self {
guard: V::Guard::<G>::from(guard),
old,
new,
}
}
pub(crate) fn try_into_inserted(self) -> Result<Shared<G, V>, Self> {
let upserted = ManuallyDrop::new(self);
match upserted.old {
None => Ok(Shared {
_guard: unsafe { core::ptr::read(&upserted.guard) },
raw: upserted.new,
}),
Some(_) => Err(ManuallyDrop::into_inner(upserted)),
}
}
#[inline]
pub fn old(&self) -> Option<&V::Borrowed> {
self.old
.as_ref()
.map(|old| unsafe { V::borrow_from_raw_unchecked(old) })
}
#[inline]
#[expect(clippy::new_ret_no_self)]
pub fn new(&self) -> &V::Borrowed {
unsafe { V::borrow_from_raw_unchecked(&self.new) }
}
}
impl<G: smr::Guard<V>, V: Value> Drop for Upserted<G, V> {
fn drop(&mut self) {
let Some(old) = self.old else { return };
unsafe { self.guard.retire_value(old) }
}
}
impl<G, V> Debug for Upserted<G, V>
where
G: smr::Guard<V>,
V: Value,
V::Borrowed: Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Upserted")
.field("old", &self.old())
.field("new", self.new())
.finish()
}
}