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;
pub struct AliasableVec<T> {
ptr: NonNull<T>,
len: usize,
cap: usize,
}
impl<T> AliasableVec<T> {
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 }
}
#[inline]
pub fn into_unique(mut vec: AliasableVec<T>) -> UniqueVec<T> {
let unique = unsafe { vec.reclaim_as_unique_vec() };
mem::forget(vec);
unique
}
pub fn into_unique_pin(pin: Pin<AliasableVec<T>>) -> Pin<UniqueVec<T>> {
unsafe {
let aliasable = Pin::into_inner_unchecked(pin);
Pin::new_unchecked(AliasableVec::into_unique(aliasable))
}
}
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) {
let _ = unsafe { self.reclaim_as_unique_vec() };
}
}
impl<T> Deref for AliasableVec<T> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
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] {
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]");
}
}