123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- #![allow(dead_code)]
- use std::cell::UnsafeCell;
- use std::fmt::Debug;
- use std::mem::MaybeUninit;
- use std::ops::{Deref, DerefMut};
- use std::sync::atomic::{AtomicBool, Ordering};
- use std::sync::Mutex;
- pub struct Lazy<T> {
-
- init_lock: Mutex<()>,
-
- value: UnsafeCell<MaybeUninit<T>>,
-
- initialized: AtomicBool,
- }
- impl<T> Lazy<T> {
-
-
- pub const fn new() -> Lazy<T> {
- Lazy {
- value: UnsafeCell::new(MaybeUninit::uninit()),
- initialized: AtomicBool::new(false),
- init_lock: Mutex::new(()),
- }
- }
-
- #[inline(always)]
- pub fn initialized(&self) -> bool {
- let initialized = self.initialized.load(Ordering::Acquire);
- if initialized {
- return true;
- }
- return false;
- }
-
-
- #[inline(always)]
- pub fn ensure(&self) {
- if self.initialized() {
- return;
- }
- panic!("Lazy value was not initialized");
- }
- pub fn init(&self, value: T) {
- assert!(!self.initialized());
-
- let _init_guard = self.init_lock.lock();
-
- let initialized = self.initialized();
- if initialized {
- return;
- }
- unsafe {
- (*self.value.get()).as_mut_ptr().write(value);
- }
- self.initialized.store(true, Ordering::Release);
- }
-
-
-
- pub fn get(&self) -> &T {
- self.ensure();
- return unsafe { self.get_unchecked() };
- }
-
-
- pub fn try_get(&self) -> Option<&T> {
- if self.initialized() {
- return Some(unsafe { self.get_unchecked() });
- }
- return None;
- }
-
-
-
-
- pub fn get_mut(&mut self) -> &mut T {
- self.ensure();
- return unsafe { self.get_mut_unchecked() };
- }
- #[inline(always)]
- pub unsafe fn get_unchecked(&self) -> &T {
- return &*(*self.value.get()).as_ptr();
- }
- #[inline(always)]
- pub unsafe fn get_mut_unchecked(&mut self) -> &mut T {
- return &mut *(*self.value.get()).as_mut_ptr();
- }
- }
- impl<T> Deref for Lazy<T> {
- type Target = T;
- #[inline(always)]
- fn deref(&self) -> &T {
- return self.get();
- }
- }
- impl<T> DerefMut for Lazy<T> {
- #[inline(always)]
- fn deref_mut(&mut self) -> &mut T {
- return self.get_mut();
- }
- }
- impl<T: Debug> Debug for Lazy<T> {
- fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- if let Some(value) = self.try_get() {
- return write!(f, "Lazy({:?})", value);
- } else {
- return write!(f, "Lazy(uninitialized)");
- }
- }
- }
- impl<T> Drop for Lazy<T> {
- fn drop(&mut self) {
- if self.initialized() {
- unsafe {
- (*self.value.get()).as_mut_ptr().drop_in_place();
- }
- }
- }
- }
- unsafe impl<T: Send + Sync> Sync for Lazy<T> {}
- unsafe impl<T: Send> Send for Lazy<T> {}
|