#![doc = include_str!("../README.md")]
#![warn(clippy::cargo_common_metadata)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::missing_panics_doc)]
#![warn(clippy::must_use_candidate)]
#![warn(clippy::semicolon_if_nothing_returned)]
#![warn(missing_docs)]
#![warn(rustdoc::missing_crate_level_docs)]
#![cfg_attr(not(feature = "std"), no_std)]
use core::cmp::Ordering;
use core::ptr::*;
use core::num::NonZeroUsize;
#[repr(transparent)]
pub struct ConstPtr<T: ?Sized>(NonNull<T>);
unsafe impl<T: ?Sized + Send> Send for ConstPtr<T> {}
unsafe impl<T: ?Sized + Send + Sync> Sync for ConstPtr<T> {}
impl<T: ?Sized> ConstPtr<T> {
#[inline]
pub const unsafe fn new_unchecked(ptr: *const T) -> Self {
debug_assert!(!ptr.is_null(), "passed null pointer to ConstPtr::new_unchecked()");
ConstPtr(core::mem::transmute::<*const T, NonNull<T>>(ptr))
}
#[inline]
pub const fn from(reference: &T) -> Self {
unsafe { ConstPtr::new_unchecked(reference) }
}
#[inline]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn new(ptr: *const T) -> Option<Self> {
if !ptr.is_null() {
Some(unsafe { ConstPtr(core::mem::transmute::<*const T, NonNull<T>>(ptr)) })
} else {
None
}
}
#[must_use]
#[inline]
pub fn addr(self) -> NonZeroUsize
{
self.0.addr()
}
#[must_use]
#[inline(always)]
pub const fn as_ptr(self) -> *const T {
self.0.as_ptr()
}
#[must_use]
#[inline(always)]
pub const unsafe fn as_ref<'a>(&self) -> &'a T {
unsafe { &*self.0.as_ptr() }
}
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub const fn cast<U>(self) -> ConstPtr<U> {
unsafe { ConstPtr::new_unchecked(self.as_ptr() as *const U) }
}
}
impl<T> ConstPtr<[T]> {
}
impl<T: ?Sized> Copy for ConstPtr<T> {}
impl<T: ?Sized> Clone for ConstPtr<T> {
#[inline(always)]
fn clone(&self) -> Self {
*self
}
}
impl<T: ?Sized> core::fmt::Pointer for ConstPtr<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
impl<T: ?Sized> core::fmt::Debug for ConstPtr<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
core::fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
impl<T: ?Sized> Eq for ConstPtr<T> {}
impl<T: ?Sized> PartialEq for ConstPtr<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
addr_eq(self.as_ptr(), other.as_ptr())
}
}
impl<T: ?Sized> Ord for ConstPtr<T> {
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.addr().cmp(&other.addr())
}
}
impl<T: ?Sized> PartialOrd for ConstPtr<T> {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[cfg(feature = "std")]
impl<T: ?Sized> std::hash::Hash for ConstPtr<T> {
#[inline]
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.as_ptr().hash(state);
}
}
impl<T: ?Sized> From<&mut T> for ConstPtr<T> {
#[inline]
fn from(reference: &mut T) -> Self {
ConstPtr::from(reference)
}
}
impl<T: ?Sized> From<&T> for ConstPtr<T> {
#[inline]
fn from(reference: &T) -> Self {
ConstPtr::from(reference)
}
}