use core::{
convert::From,
fmt,
marker::{PhantomData, Unsize},
ops::{CoerceUnsized, DispatchFromDyn},
ptr::NonNull,
};
#[repr(transparent)]
pub struct Unique<T: ?Sized> {
pointer: NonNull<T>,
_marker: PhantomData<T>,
}
impl<T: ?Sized> fmt::Debug for Unique<T> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.pointer.as_ptr(), fmt)
}
}
unsafe impl<T: Send + ?Sized> Send for Unique<T> {}
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> {}
impl<T: Sized> Unique<T> {
#[inline]
pub const fn dangling() -> Self {
Self {
pointer: NonNull::dangling(),
_marker: PhantomData,
}
}
}
#[allow(clippy::use_self)]
impl<T: ?Sized> Unique<T> {
#[inline]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
Self {
pointer: NonNull::new_unchecked(ptr),
_marker: PhantomData,
}
}
#[inline]
pub fn new(ptr: *mut T) -> Option<Self> {
NonNull::new(ptr).map(Into::into)
}
#[inline]
pub const fn as_ptr(self) -> *mut T {
self.pointer.as_ptr()
}
#[inline]
pub unsafe fn as_ref(&self) -> &T {
self.pointer.as_ref()
}
#[inline]
pub unsafe fn as_mut(&mut self) -> &mut T {
self.pointer.as_mut()
}
#[inline]
pub const fn cast<U>(self) -> Unique<U> {
Unique {
pointer: self.pointer.cast(),
_marker: PhantomData,
}
}
}
impl<T: ?Sized> Clone for Unique<T> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<T: ?Sized> Copy for Unique<T> {}
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> {}
impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Unique<U>> for Unique<T> where T: Unsize<U> {}
impl<T: ?Sized> From<NonNull<T>> for Unique<T> {
#[inline]
fn from(p: NonNull<T>) -> Self {
unsafe { Self::new_unchecked(p.as_ptr()) }
}
}
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
#[inline]
fn from(p: Unique<T>) -> Self {
unsafe { Self::new_unchecked(p.as_ptr()) }
}
}