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