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