use std::{ mem::ManuallyDrop, ops::{Deref, DerefMut}, }; pub struct VecStorage { ptr: *mut T, cap: usize, } impl Default for VecStorage { fn default() -> Self { let mut v = ManuallyDrop::new(vec![]); Self { ptr: v.as_mut_ptr(), cap: v.capacity(), } } } impl VecStorage { pub fn take<'a>(&'a mut self) -> RealizedVec<'a, T, T> { self.take_as() } pub fn take_as<'a, U>(&'a mut self) -> RealizedVec<'a, T, U> { assert_size_eq!(T, U); assert_align_eq!(T, U); unsafe { RealizedVec { vec: ManuallyDrop::new(self.to_vector()), storage: self, } } } unsafe fn to_vector(&mut self) -> Vec { Vec::from_raw_parts(self.ptr as _, 0, self.cap) } } impl Drop for VecStorage { fn drop(&mut self) { unsafe { drop(self.to_vector::()); } } } pub struct RealizedVec<'a, T, U> { vec: ManuallyDrop>, storage: &'a mut VecStorage, } impl<'a, T, U> Drop for RealizedVec<'a, T, U> { fn drop(&mut self) { self.vec.clear(); self.storage.ptr = self.vec.as_mut_ptr() as _; self.storage.cap = self.vec.capacity(); } } impl<'a, T, U> Deref for RealizedVec<'a, T, U> { type Target = Vec; fn deref(&self) -> &Self::Target { self.vec.deref() } } impl<'a, T, U> DerefMut for RealizedVec<'a, T, U> { fn deref_mut(&mut self) -> &mut Self::Target { self.vec.deref_mut() } }