1use core::borrow::{Borrow, BorrowMut};
2use core::mem;
3use core::ops::{Deref, DerefMut};
4use core::ptr;
5
6#[repr(transparent)]
7pub(crate) struct Once<T: ?Sized>(mem::ManuallyDrop<T>);
8
9pub struct RefOnce<'a, T: ?Sized> {
11 slot: &'a mut Once<T>,
12}
13
14impl<'a, T> RefOnce<'a, T> {
15 pub fn new(value: T, slot: &'a mut mem::MaybeUninit<T>) -> Self {
16 slot.write(value);
17 RefOnce {
18 slot: unsafe { mem::transmute::<&'a mut mem::MaybeUninit<T>, &'a mut Once<T>>(slot) },
19 }
20 }
21
22 pub fn into_inner(this: Self) -> T {
23 let mut this = mem::ManuallyDrop::new(this);
24 unsafe { mem::ManuallyDrop::take(&mut this.slot.0) }
25 }
26}
27
28impl<'a, T: ?Sized> RefOnce<'a, T> {
29 pub fn into_raw(this: Self) -> *mut T {
32 let this = mem::ManuallyDrop::new(this);
33 (unsafe { ptr::addr_of!(this.slot).read() } as *mut Once<T>) as *mut T
34 }
35
36 pub unsafe fn from_raw(ptr: *mut T) -> Self {
45 RefOnce {
46 slot: unsafe { &mut *(ptr as *mut Once<T>) },
47 }
48 }
49}
50
51impl<T: ?Sized> Deref for RefOnce<'_, T> {
52 type Target = T;
53
54 fn deref(&self) -> &Self::Target {
55 &self.slot.0
56 }
57}
58
59impl<T: ?Sized> DerefMut for RefOnce<'_, T> {
60 fn deref_mut(&mut self) -> &mut Self::Target {
61 &mut self.slot.0
62 }
63}
64
65impl<T: ?Sized> Borrow<T> for RefOnce<'_, T> {
66 fn borrow(&self) -> &T {
67 &self.slot.0
68 }
69}
70
71impl<T: ?Sized> BorrowMut<T> for RefOnce<'_, T> {
72 fn borrow_mut(&mut self) -> &mut T {
73 &mut self.slot.0
74 }
75}
76
77impl<T: ?Sized> Drop for RefOnce<'_, T> {
78 fn drop(&mut self) {
79 unsafe { mem::ManuallyDrop::drop(&mut self.slot.0) }
80 }
81}