use core::ops::Deref;
use crate::sync::Mutex;
pub struct LazyLock<T> {
data: Mutex<Option<T>>,
create_new: fn() -> T,
}
unsafe impl <T> Send for LazyLock<T> {
}
unsafe impl <T> Sync for LazyLock<T> {
}
impl <T> LazyLock<T> {
pub const fn new(f: fn() -> T) -> Self {
Self {
data: Mutex::new(None),
create_new: f,
}
}
}
impl <T> Deref for LazyLock<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
if let Some(value) = self.data.lock().expect("failed to lock lazy lock").as_ref() {
unsafe { (value as *const T).as_ref_unchecked() }
} else {
let mut guard = self.data.lock().expect("failed to lock lazy lock");
*guard = Some((self.create_new)());
unsafe { (guard.as_ref().expect("no item in lazylock") as *const T).as_ref_unchecked() }
}
}
}