use std::ptr::NonNull;
#[repr(transparent)]
#[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
pub struct NonNullConst<T>
where
T: ?Sized,
{
ptr: NonNull<T>,
}
impl<T> NonNullConst<T> {
#[inline]
pub const fn dangling() -> NonNullConst<T> {
Self {
ptr: NonNull::dangling(),
}
}
}
impl<T> NonNullConst<T>
where
T: ?Sized,
{
#[inline]
pub const unsafe fn new_unchecked(ptr: *const T) -> NonNullConst<T> {
Self {
ptr: NonNull::new_unchecked(ptr as *mut T),
}
}
#[inline]
pub fn new(ptr: *const T) -> Option<NonNullConst<T>> {
let ptr = NonNull::new(ptr as *mut T);
ptr.map(|ptr| Self { ptr })
}
#[inline]
#[allow(clippy::wrong_self_convention)]
pub unsafe fn into_mut(&self) -> NonNull<T> {
self.ptr
}
#[inline]
#[allow(clippy::wrong_self_convention)]
pub const fn as_ptr(self) -> *const T {
self.ptr.as_ptr() as *const T
}
#[inline]
pub unsafe fn as_ref(&self) -> &T {
self.ptr.as_ref()
}
#[inline]
pub const fn cast<U>(self) -> NonNullConst<U> {
NonNullConst {
ptr: self.ptr.cast(),
}
}
}
impl<T> From<&T> for NonNullConst<T>
where
T: ?Sized,
{
fn from(value: &T) -> Self {
Self { ptr: value.into() }
}
}
impl<T> From<&mut T> for NonNullConst<T>
where
T: ?Sized,
{
fn from(value: &mut T) -> Self {
Self { ptr: value.into() }
}
}
impl<T> From<&[T]> for NonNullConst<T>
where
T: Sized,
{
fn from(slice: &[T]) -> Self {
unsafe { Self::new_unchecked(slice.as_ptr()) }
}
}
impl<T> From<&mut [T]> for NonNullConst<T>
where
T: Sized,
{
fn from(slice: &mut [T]) -> Self {
unsafe { Self::new_unchecked(slice.as_ptr()) }
}
}
impl<T, const N: usize> From<&[T; N]> for NonNullConst<T>
where
T: Sized,
{
fn from(array: &[T; N]) -> Self {
unsafe { Self::new_unchecked(array.as_ptr()) }
}
}
impl<T, const N: usize> From<&mut [T; N]> for NonNullConst<T>
where
T: Sized,
{
fn from(array: &mut [T; N]) -> Self {
unsafe { Self::new_unchecked(array.as_ptr()) }
}
}
impl<T> From<NonNull<T>> for NonNullConst<T>
where
T: ?Sized,
{
fn from(ptr: NonNull<T>) -> Self {
Self { ptr }
}
}
impl<T> Copy for NonNullConst<T> {}
impl<T> Clone for NonNullConst<T> {
fn clone(&self) -> Self {
unsafe { Self::new_unchecked(self.as_ptr()) }
}
}