use std::{mem::MaybeUninit, sync::Once};
use crate::SyncUnsafeCell;
pub struct OnceInit<T> {
inner: SyncUnsafeCell<MaybeUninit<T>>,
init: Once,
}
impl<T> OnceInit<T> {
pub const fn uninit() -> Self {
Self {
inner: SyncUnsafeCell::new(MaybeUninit::uninit()),
init: Once::new(),
}
}
#[track_caller]
pub fn get(&self) -> &T {
assert!(self.init.is_completed());
let ptr = self.inner.get();
unsafe { (*ptr).assume_init_ref() }
}
pub fn set(&self, val: T) {
self.init.call_once(|| {
let ptr = self.inner.get();
unsafe { (*ptr).write(val) };
});
}
}