1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
use std::{marker::PhantomData, ptr::NonNull};
/// An owned pointer
///
/// **NOTE**: Does not deallocate when dropped
pub(crate) struct OwnedPtr<T: ?Sized> {
ptr: NonNull<T>,
}
impl<T: ?Sized> Copy for OwnedPtr<T> {}
impl<T: ?Sized> Clone for OwnedPtr<T> {
fn clone(&self) -> Self {
*self
}
}
unsafe impl<T> Send for OwnedPtr<T> where T: Send {}
unsafe impl<T> Sync for OwnedPtr<T> where T: Send {}
impl<T> OwnedPtr<T> {
pub(crate) fn new(value: T) -> Self {
Self::from_boxed(Box::new(value))
}
pub(crate) fn from_boxed(boxed: Box<T>) -> Self {
// Safety: `Box::into_raw` is guaranteed to be non-null
Self {
ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) },
}
}
/// Convert the pointer to another type
pub(crate) fn cast<U>(self) -> OwnedPtr<U> {
OwnedPtr {
ptr: self.ptr.cast(),
}
}
/// Context the pointer into a Box
///
/// # Safety
///
/// Dropping the Box will deallocate a layout of `T` and run the destructor of `T`.
///
/// A cast pointer must therefore be cast back to the original type before calling this method.
pub(crate) unsafe fn into_box(self) -> Box<T> {
unsafe { Box::from_raw(self.ptr.as_ptr()) }
}
pub(crate) const fn as_ref(&self) -> RefPtr<'_, T> {
RefPtr {
ptr: self.ptr,
_marker: PhantomData,
}
}
pub(crate) fn as_mut(&mut self) -> MutPtr<'_, T> {
MutPtr {
ptr: self.ptr,
_marker: PhantomData,
}
}
}
/// Convenience lifetime annotated mutable pointer which facilitates returning an inferred lifetime
/// in a `fn` pointer.
pub(crate) struct RefPtr<'a, T: ?Sized> {
pub(crate) ptr: NonNull<T>,
_marker: PhantomData<&'a T>,
}
/// Safety: RefPtr indicates a shared reference to a value and as such exhibits the same Send +
/// Sync behavior of &'a T
unsafe impl<'a, T: ?Sized> Send for RefPtr<'a, T> where &'a T: Send {}
unsafe impl<'a, T: ?Sized> Sync for RefPtr<'a, T> where &'a T: Sync {}
impl<'a, T: ?Sized> Copy for RefPtr<'a, T> {}
impl<'a, T: ?Sized> Clone for RefPtr<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T: ?Sized> RefPtr<'a, T> {
pub(crate) fn new(ptr: &'a T) -> Self {
Self {
ptr: NonNull::from(ptr),
_marker: PhantomData,
}
}
/// Convert the pointer to another type
pub(crate) fn cast<U>(self) -> RefPtr<'a, U> {
RefPtr {
ptr: self.ptr.cast(),
_marker: PhantomData,
}
}
/// Returns a shared reference to the owned value
///
/// # Safety
///
/// See: [`NonNull::as_ref`]
#[inline]
pub(crate) unsafe fn as_ref(&self) -> &'a T {
unsafe { self.ptr.as_ref() }
}
}
/// Convenience lifetime annotated mutable pointer which facilitates returning an inferred lifetime
/// in a `fn` pointer.
pub(crate) struct MutPtr<'a, T: ?Sized> {
pub(crate) ptr: NonNull<T>,
_marker: PhantomData<&'a mut T>,
}
/// Safety: RefPtr indicates an exclusive reference to a value and as such exhibits the same Send +
/// Sync behavior of &'a mut T
unsafe impl<'a, T: ?Sized> Send for MutPtr<'a, T> where &'a mut T: Send {}
unsafe impl<'a, T: ?Sized> Sync for MutPtr<'a, T> where &'a mut T: Sync {}
impl<'a, T: ?Sized> Copy for MutPtr<'a, T> {}
impl<'a, T: ?Sized> Clone for MutPtr<'a, T> {
fn clone(&self) -> Self {
*self
}
}
impl<'a, T: ?Sized> MutPtr<'a, T> {
/// Convert the pointer to another type
pub(crate) fn cast<U>(self) -> MutPtr<'a, U> {
MutPtr {
ptr: self.ptr.cast(),
_marker: PhantomData,
}
}
/// Returns a mutable reference to the owned value with the lifetime decoupled from self
///
/// # Safety
///
/// See: [`NonNull::as_mut`]
#[inline]
pub(crate) unsafe fn into_mut(mut self) -> &'a mut T {
unsafe { self.ptr.as_mut() }
}
}