1 use std::marker::PhantomData; 2 use std::mem::{self, MaybeUninit}; 3 use std::ops::Deref; 4 use std::ptr::{addr_of, NonNull}; 5 6 pub(crate) struct Owned<T, Init = T> { 7 ptr: NonNull<T>, 8 marker: PhantomData<NonNull<Init>>, 9 } 10 11 impl<T> Owned<T> { new_uninit() -> Owned<MaybeUninit<T>, T>12 pub fn new_uninit() -> Owned<MaybeUninit<T>, T> { 13 // FIXME: use Box::new_uninit when stable 14 let boxed = Box::new(MaybeUninit::<T>::uninit()); 15 Owned { 16 ptr: unsafe { NonNull::new_unchecked(Box::into_raw(boxed)) }, 17 marker: PhantomData, 18 } 19 } 20 assume_init(definitely_init: Owned<MaybeUninit<T>, T>) -> Owned<T>21 pub unsafe fn assume_init(definitely_init: Owned<MaybeUninit<T>, T>) -> Owned<T> { 22 let ptr = definitely_init.ptr; 23 mem::forget(definitely_init); 24 Owned { 25 ptr: ptr.cast(), 26 marker: PhantomData, 27 } 28 } 29 } 30 31 #[repr(transparent)] 32 pub(crate) struct InitPtr<T> { 33 pub ptr: *mut T, 34 } 35 36 impl<T, Init> Deref for Owned<T, Init> { 37 type Target = InitPtr<Init>; 38 deref(&self) -> &Self::Target39 fn deref(&self) -> &Self::Target { 40 unsafe { &*addr_of!(self.ptr).cast::<InitPtr<Init>>() } 41 } 42 } 43 44 impl<T, Init> Drop for Owned<T, Init> { drop(&mut self)45 fn drop(&mut self) { 46 let _ = unsafe { Box::from_raw(self.ptr.as_ptr()) }; 47 } 48 } 49