1use core::cell::UnsafeCell;
2use core::mem::MaybeUninit;
3use core::ptr;
4
5pub(crate) struct UninitCell<T>(MaybeUninit<UnsafeCell<T>>);
6impl<T> UninitCell<T> {
7 pub const fn uninit() -> Self {
8 Self(MaybeUninit::uninit())
9 }
10
11 pub unsafe fn as_mut_ptr(&self) -> *mut T {
12 (*self.0.as_ptr()).get()
13 }
14
15 #[allow(clippy::mut_from_ref)]
16 pub unsafe fn as_mut(&self) -> &mut T {
17 &mut *self.as_mut_ptr()
18 }
19
20 #[inline(never)]
21 pub unsafe fn write_in_place(&self, func: impl FnOnce() -> T) {
22 ptr::write(self.as_mut_ptr(), src:func())
23 }
24
25 pub unsafe fn drop_in_place(&self) {
26 ptr::drop_in_place(self.as_mut_ptr())
27 }
28}
29
30unsafe impl<T> Sync for UninitCell<T> {}
31
32#[repr(transparent)]
33pub struct SyncUnsafeCell<T> {
34 value: UnsafeCell<T>,
35}
36
37unsafe impl<T: Sync> Sync for SyncUnsafeCell<T> {}
38
39impl<T> SyncUnsafeCell<T> {
40 #[inline]
41 pub const fn new(value: T) -> Self {
42 Self {
43 value: UnsafeCell::new(value),
44 }
45 }
46
47 pub unsafe fn set(&self, value: T) {
48 *self.value.get() = value;
49 }
50
51 pub unsafe fn get(&self) -> T
52 where
53 T: Copy,
54 {
55 *self.value.get()
56 }
57}
58