diff options
Diffstat (limited to 'src/boxed.rs')
-rw-r--r-- | src/boxed.rs | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/src/boxed.rs b/src/boxed.rs deleted file mode 100644 index 3455fbd..0000000 --- a/src/boxed.rs +++ /dev/null @@ -1,161 +0,0 @@ -//! Aliasable `Box`. - -use core::ops::{Deref, DerefMut}; -use core::pin::Pin; -use core::ptr::NonNull; -use core::{fmt, mem}; - -pub use alloc::boxed::Box as UniqueBox; - -/// Basic aliasable (non `core::ptr::Unique`) alternative to -/// [`alloc::boxed::Box`]. -pub struct AliasableBox<T: ?Sized>(NonNull<T>); - -impl<T: ?Sized> AliasableBox<T> { - /// Construct an `AliasableBox` from a [`UniqueBox`]. - pub fn from_unique(ptr: UniqueBox<T>) -> Self { - let ptr = unsafe { NonNull::new_unchecked(UniqueBox::into_raw(ptr)) }; - Self(ptr) - } - - /// Consumes `self` and converts it into a non-aliasable [`UniqueBox`]. - #[inline] - pub fn into_unique(mut ptr: AliasableBox<T>) -> UniqueBox<T> { - // As we are consuming the `Box` structure we can safely assume any - // aliasing has ended and convert the aliasable `Box` back to into an - // unaliasable `UniqueBox`. - let unique = unsafe { ptr.reclaim_as_unique_box() }; - // Forget the aliasable `Box` so the allocation behind the `UniqueBox` - // is not deallocated. - mem::forget(ptr); - // Return the `UniqueBox`. - unique - } - - /// Convert a pinned [`AliasableBox`] to a `core::ptr::Unique` backed pinned - /// [`UniqueBox`]. - pub fn into_unique_pin(pin: Pin<AliasableBox<T>>) -> Pin<UniqueBox<T>> { - // SAFETY: The pointer is not changed, just the container. - unsafe { - let aliasable = Pin::into_inner_unchecked(pin); - Pin::new_unchecked(AliasableBox::into_unique(aliasable)) - } - } - - /// Convert a pinned `core::ptr::Unique` backed [`UniqueBox`] to a - /// pinned [`AliasableBox`]. - pub fn from_unique_pin(pin: Pin<UniqueBox<T>>) -> Pin<AliasableBox<T>> { - // SAFETY: The pointer is not changed, just the container. - unsafe { - let unique = Pin::into_inner_unchecked(pin); - Pin::new_unchecked(AliasableBox::from(unique)) - } - } - - #[inline] - unsafe fn reclaim_as_unique_box(&mut self) -> UniqueBox<T> { - UniqueBox::from_raw(self.0.as_ptr()) - } -} - -impl<T: ?Sized> From<UniqueBox<T>> for AliasableBox<T> { - fn from(ptr: UniqueBox<T>) -> Self { - Self::from_unique(ptr) - } -} - -impl<T: ?Sized> Drop for AliasableBox<T> { - fn drop(&mut self) { - // SAFETY: As `self` is being dropped we can safely assume any aliasing - // has ended and convert the `AliasableBox` back to into an unaliasable - // `UniqueBox` to handle the deallocation. - let _ = unsafe { self.reclaim_as_unique_box() }; - } -} - -impl<T: ?Sized> Deref for AliasableBox<T> { - type Target = T; - - #[inline] - fn deref(&self) -> &T { - // SAFETY: We own the data, so we can return a reference to it. - unsafe { self.0.as_ref() } - } -} - -impl<T: ?Sized> DerefMut for AliasableBox<T> { - #[inline] - fn deref_mut(&mut self) -> &mut T { - // SAFETY: We own the data, so we can return a reference to it. - unsafe { self.0.as_mut() } - } -} - -impl<T: ?Sized> AsRef<T> for AliasableBox<T> { - #[inline] - fn as_ref(&self) -> &T { - &*self - } -} - -impl<T: ?Sized> AsMut<T> for AliasableBox<T> { - fn as_mut(&mut self) -> &mut T { - &mut *self - } -} - -impl<T: ?Sized> fmt::Debug for AliasableBox<T> -where - T: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(self.as_ref(), f) - } -} - -unsafe impl<T: ?Sized> Send for AliasableBox<T> where T: Send {} -unsafe impl<T: ?Sized> Sync for AliasableBox<T> where T: Sync {} - -#[cfg(feature = "traits")] -unsafe impl<T: ?Sized> crate::StableDeref for AliasableBox<T> {} - -#[cfg(feature = "traits")] -unsafe impl<T: ?Sized> crate::AliasableDeref for AliasableBox<T> {} - -#[cfg(test)] -mod tests { - use super::{AliasableBox, UniqueBox}; - use alloc::format; - - #[test] - fn test_new() { - let aliasable = AliasableBox::from_unique(UniqueBox::new(10)); - assert_eq!(*aliasable, 10); - let unique = AliasableBox::into_unique(aliasable); - assert_eq!(*unique, 10); - } - - #[test] - fn test_new_pin() { - let aliasable = AliasableBox::from_unique_pin(UniqueBox::pin(10)); - assert_eq!(*aliasable, 10); - let unique = AliasableBox::into_unique_pin(aliasable); - assert_eq!(*unique, 10); - } - - #[test] - fn test_refs() { - let mut aliasable = AliasableBox::from_unique(UniqueBox::new(10)); - let ptr: *const u8 = &*aliasable; - let as_mut_ptr: *const u8 = aliasable.as_mut(); - let as_ref_ptr: *const u8 = aliasable.as_ref(); - assert_eq!(ptr, as_mut_ptr); - assert_eq!(ptr, as_ref_ptr); - } - - #[test] - fn test_debug() { - let aliasable = AliasableBox::from_unique(UniqueBox::new(10)); - assert_eq!(format!("{:?}", aliasable), "10"); - } -} |