use std::marker::PhantomData;
use crate::alloc::MemPool;
use crate::stm::Journal;
use crate::{PSafe, TxOutSafe};
use std::fmt;
use std::ops::{Deref, DerefMut};
#[derive(Eq)]
pub struct NonNull<T: PSafe + ?Sized> {
ptr: *const T
}
impl<T: PSafe + ?Sized> Copy for NonNull<T> {}
impl<T: PSafe + ?Sized> Clone for NonNull<T> {
fn clone(&self) -> Self {
Self {
ptr: self.ptr,
}
}
}
impl<T: ?Sized> !TxOutSafe for NonNull<T> {}
impl<T: ?Sized> !Send for NonNull<T> {}
impl<T: ?Sized> !Sync for NonNull<T> {}
impl<T: PSafe + ?Sized> PartialEq for NonNull<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
impl<T: PSafe> NonNull<T> {
#[inline]
pub const fn new_unchecked(ptr: *const T) -> Self {
Self {
ptr,
}
}
#[inline]
pub fn new(ptr: *const T) -> Option<Self> {
if !ptr.is_null() {
Some(Self::new_unchecked(ptr))
} else {
None
}
}
pub fn as_ref<'a, 'b>(&'a self) -> &'b T {
unsafe { &*self.ptr }
}
}
impl<T: PSafe + ?Sized> Deref for NonNull<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T { unsafe { &*self.ptr } }
}
impl<T: fmt::Display + PSafe + ?Sized> fmt::Display for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { (*self.ptr).fmt(f) }
}
}
impl<T: fmt::Debug + PSafe + ?Sized> fmt::Debug for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { (*self.ptr).fmt(f) }
}
}
#[derive(Eq)]
pub struct LogNonNull<T: PSafe + ?Sized, A: MemPool> {
ptr: *mut T,
journal: *const Journal<A>,
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))]
logged: *mut u8,
phantom: PhantomData<*mut T>
}
impl<T: PSafe + ?Sized, A: MemPool> Copy for LogNonNull<T, A> {}
impl<T: PSafe + ?Sized, A: MemPool> Clone for LogNonNull<T, A> {
fn clone(&self) -> Self {
Self {
ptr: self.ptr,
journal: self.journal,
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))]
logged: self.logged,
phantom: PhantomData
}
}
}
impl<T: ?Sized, A: MemPool> !TxOutSafe for LogNonNull<T, A> {}
impl<T: ?Sized, A: MemPool> !Send for LogNonNull<T, A> {}
impl<T: ?Sized, A: MemPool> !Sync for LogNonNull<T, A> {}
impl<T: PSafe + ?Sized, A: MemPool> PartialEq for LogNonNull<T, A> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.ptr == other.ptr
}
}
impl<T: PSafe, A: MemPool> LogNonNull<T, A> {
#[inline]
pub const unsafe fn new_unchecked(ptr: *mut T,
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))]
logged: *mut u8,
j: &Journal<A>
) -> Self {
Self {
ptr,
journal: j as *const _,
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))]
logged,
phantom: PhantomData
}
}
#[inline]
pub unsafe fn new(ptr: *mut T,
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))]
logged: *mut u8,
j: &Journal<A>
) -> Option<Self> {
#[cfg(any(feature = "use_pspd", feature = "use_vspd"))] {
if !ptr.is_null() {
Some(Self::new_unchecked(ptr, j))
} else {
None
}
}
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))] {
if !ptr.is_null() && !logged.is_null() {
Some(Self::new_unchecked(ptr, logged, j))
} else {
None
}
}
}
}
impl<T: PSafe + ?Sized, A: MemPool> Deref for LogNonNull<T, A> {
type Target = T;
#[inline]
fn deref(&self) -> &T { unsafe { &*self.ptr } }
}
impl<T: PSafe + ?Sized, A: MemPool> DerefMut for LogNonNull<T, A> {
#[inline]
fn deref_mut(&mut self) -> &mut T {
unsafe {
let value = &mut *self.ptr;
#[cfg(not(any(feature = "use_pspd", feature = "use_vspd")))] {
use crate::ptr::Ptr;
use crate::stm::{Notifier, Logger};
if *self.logged == 0 {
value.create_log(&*self.journal, Notifier::NonAtomic(Ptr::from_raw(self.logged)));
}
}
value
}
}
}
impl<T: fmt::Display + PSafe + ?Sized, A: MemPool> fmt::Display for LogNonNull<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { (*self.ptr).fmt(f) }
}
}
impl<T: fmt::Debug + PSafe + ?Sized, A: MemPool> fmt::Debug for LogNonNull<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
unsafe { (*self.ptr).fmt(f) }
}
}