#![allow(unused)]
use crate::{
Finaly, Generator, LazySequentializer, LockNature, LockResult, Phase, Phased, Sequential,
Sequentializer, StaticInfo, Uninit, UniqueLazySequentializer,
};
use core::cell::UnsafeCell;
use core::fmt::{self, Debug, Display, Formatter};
use core::hint::unreachable_unchecked;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
use core::ops::{Deref, DerefMut};
#[cfg(debug_mode)]
use crate::CyclicPanic;
#[cfg(any(feature = "parking_lot_core", debug_mode))]
use std::panic::RefUnwindSafe;
pub(crate) trait LazyPolicy {
fn shall_init(_: Phase) -> bool;
fn is_accessible(p: Phase) -> bool;
fn post_init_is_accessible(p: Phase) -> bool;
fn initialized_is_accessible(p: Phase) -> bool;
}
pub(crate) struct UnInited<T>(UnsafeCell<MaybeUninit<T>>);
impl<T: Finaly> Finaly for UnInited<T> {
#[inline(always)]
fn finaly(&self) {
unsafe { &*self.get() }.finaly();
}
}
impl<T> UnInited<T> {
#[allow(clippy::declare_interior_mutable_const)] pub const INIT: Self = Self(UnsafeCell::new(MaybeUninit::uninit()));
}
pub(crate) struct Primed<T>(UnsafeCell<T>);
impl<T: Uninit> Finaly for Primed<T> {
#[inline(always)]
fn finaly(&self) {
unsafe { &mut *self.0.get() }.uninit();
}
}
impl<T> Primed<T> {
pub const fn prime(v: T) -> Self {
Self(UnsafeCell::new(v))
}
}
pub(crate) struct DropedUnInited<T>(UnsafeCell<MaybeUninit<T>>);
impl<T> Finaly for DropedUnInited<T> {
#[inline(always)]
fn finaly(&self) {
unsafe { self.get().drop_in_place() };
}
}
impl<T> DropedUnInited<T> {
#[allow(clippy::declare_interior_mutable_const)]
pub const INIT: Self = Self(UnsafeCell::new(MaybeUninit::uninit()));
}
pub(crate) trait LazyData {
type Target;
fn get(&self) -> *mut Self::Target;
unsafe fn init(&self, v: Self::Target);
fn init_mut(&mut self, v: Self::Target);
}
impl<T> LazyData for UnInited<T> {
type Target = T;
#[inline(always)]
fn get(&self) -> *mut T {
self.0.get() as *mut T
}
#[inline(always)]
unsafe fn init(&self, v: T) {
self.get().write(v)
}
#[inline(always)]
fn init_mut(&mut self, v: T) {
*self.0.get_mut() = MaybeUninit::new(v)
}
}
impl<T> LazyData for DropedUnInited<T> {
type Target = T;
#[inline(always)]
fn get(&self) -> *mut T {
self.0.get() as *mut T
}
#[inline(always)]
unsafe fn init(&self, v: T) {
self.get().write(v)
}
#[inline(always)]
fn init_mut(&mut self, v: T) {
*self.0.get_mut() = MaybeUninit::new(v)
}
}
impl<T> LazyData for Primed<T> {
type Target = T;
#[inline(always)]
fn get(&self) -> *mut T {
self.0.get()
}
#[inline(always)]
unsafe fn init(&self, v: T) {
*self.get() = v
}
#[inline(always)]
fn init_mut(&mut self, v: T) {
*self.0.get_mut() = v
}
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct AccessError {
pub phase: Phase,
}
impl Display for AccessError {
fn fmt(&self, ft: &mut Formatter<'_>) -> fmt::Result {
write!(ft, "Error: inaccessible lazy in {}", self.phase)
}
}
#[cfg(feature = "parking_lot_core")]
impl std::error::Error for AccessError {}
pub(crate) struct GenericLazySeq<T, M> {
value: T,
sequentializer: M,
}
pub(crate) struct GenericLockedLazySeq<T, M> {
value: T,
sequentializer: M,
}
pub(crate) struct GenericLazy<T, F, M, S> {
seq: GenericLazySeq<T, M>,
generator: F,
phantom: PhantomData<S>,
#[cfg(debug_mode)]
_info: Option<StaticInfo>,
}
unsafe impl<T: LazyData, M: Sync> Sync for GenericLazySeq<T, M> where <T as LazyData>::Target: Sync {}
unsafe impl<T: LazyData, M: Sync> Send for GenericLazySeq<T, M> where <T as LazyData>::Target: Send {}
#[cfg(any(feature = "parking_lot_core", debug_mode))]
impl<T: LazyData, M: RefUnwindSafe> RefUnwindSafe for GenericLazySeq<T, M> where
<T as LazyData>::Target: RefUnwindSafe
{
}
unsafe impl<T: LazyData, M: Sync> Sync for GenericLockedLazySeq<T, M> where
<T as LazyData>::Target: Send
{
}
unsafe impl<T: LazyData, M: Sync> Send for GenericLockedLazySeq<T, M> where
<T as LazyData>::Target: Send
{
}
#[cfg(any(feature = "parking_lot_core", debug_mode))]
impl<T: LazyData, M: RefUnwindSafe> RefUnwindSafe for GenericLockedLazySeq<T, M> where
<T as LazyData>::Target: RefUnwindSafe
{
}
impl<T, F, M, S> GenericLazy<T, F, M, S> {
#[inline(always)]
pub const unsafe fn new(generator: F, sequentializer: M, value: T) -> Self {
Self {
seq: GenericLazySeq {
value,
sequentializer,
},
generator,
phantom: PhantomData,
#[cfg(debug_mode)]
_info: None,
}
}
#[inline(always)]
pub const unsafe fn new_with_info(
generator: F,
sequentializer: M,
value: T,
_info: StaticInfo,
) -> Self {
Self {
seq: GenericLazySeq {
value,
sequentializer,
},
generator,
phantom: PhantomData,
#[cfg(debug_mode)]
_info: Some(_info),
}
}
#[inline(always)]
pub fn sequentializer(this: &Self) -> &M {
&this.seq.sequentializer
}
#[inline(always)]
pub fn get_raw_data(this: &Self) -> &T {
&this.seq.value
}
}
impl<'a, T, F, M, S> GenericLazy<T, F, M, S>
where
T: 'a + LazyData,
M: 'a,
M: LazySequentializer<'a, GenericLazySeq<T, M>>,
F: 'a + Generator<T::Target>,
S: 'a + LazyPolicy,
{
#[inline(always)]
pub unsafe fn get_unchecked(&'a self) -> &'a T::Target {
&*self.seq.value.get()
}
#[inline(always)]
pub fn try_get(&'a self) -> Result<&'a T::Target, AccessError> {
check_access::<*mut T::Target, S>(
self.seq.value.get(),
Phased::phase(&self.seq.sequentializer),
)
.map(|ptr| unsafe { &*ptr })
}
#[inline(always)]
pub fn get(&'a self) -> &'a T::Target {
self.try_get().unwrap()
}
#[inline(always)]
pub unsafe fn get_mut_unchecked(&'a mut self) -> &'a mut T::Target {
&mut *self.seq.value.get()
}
#[inline(always)]
pub fn try_get_mut(&'a mut self) -> Result<&'a mut T::Target, AccessError> {
check_access::<*mut T::Target, S>(
self.seq.value.get(),
Phased::phase(&self.seq.sequentializer),
)
.map(|ptr| unsafe { &mut *ptr })
}
#[inline(always)]
pub fn get_mut(&'a mut self) -> &'a mut T::Target {
self.try_get_mut().unwrap()
}
#[inline(always)]
pub unsafe fn init_then_get_unchecked(&'a self) -> &'a T::Target {
self.init();
self.get_unchecked()
}
#[inline(always)]
pub fn init_then_try_get(&'a self) -> Result<&'a T::Target, AccessError> {
let phase = self.init();
post_init_check_access::<*mut T::Target, S>(self.seq.value.get(), phase)
.map(|ptr| unsafe { &*ptr })
}
#[inline(always)]
pub fn init_then_get(&'a self) -> &'a T::Target {
Self::init_then_try_get(self).unwrap()
}
#[inline(always)]
pub fn init(&'a self) -> Phase {
may_debug(
|| {
<M as LazySequentializer<'a, GenericLazySeq<T, M>>>::init(
&self.seq,
S::shall_init,
|data: &T| {
let d = Generator::generate(&self.generator);
unsafe { data.init(d) };
},
)
},
#[cfg(debug_mode)]
&self._info,
)
}
}
impl<T, F, M, S> GenericLazy<T, F, M, S>
where
M: UniqueLazySequentializer<GenericLazySeq<T, M>>,
T: LazyData,
S: LazyPolicy,
F: Generator<T::Target>,
{
#[inline(always)]
pub unsafe fn only_init_then_get_mut_unchecked(&mut self) -> &mut T::Target {
self.only_init_unique();
&mut *self.seq.value.get()
}
#[inline(always)]
pub fn only_init_then_try_get_mut(&mut self) -> Result<&mut T::Target, AccessError> {
let phase = self.only_init_unique();
post_init_check_access::<*mut T::Target, S>(self.seq.value.get(), phase)
.map(|ptr| unsafe { &mut *ptr })
}
#[inline(always)]
pub fn only_init_then_get_mut(&mut self) -> &mut T::Target {
Self::only_init_then_try_get_mut(self).unwrap()
}
#[inline(always)]
pub fn only_init_unique(&mut self) -> Phase {
let generator = &self.generator;
let seq = &mut self.seq;
<M as UniqueLazySequentializer<GenericLazySeq<T, M>>>::init_unique(
seq,
S::shall_init,
|data: &mut T| {
let d = Generator::generate(generator);
unsafe { data.init_mut(d) };
},
)
}
}
unsafe impl<T: LazyData, M> Sequential for GenericLazySeq<T, M> {
type Data = T;
type Sequentializer = M;
#[inline(always)]
fn sequentializer(this: &Self) -> &Self::Sequentializer {
&this.sequentializer
}
#[inline(always)]
fn sequentializer_data_mut(this: &mut Self) -> (&mut Self::Sequentializer, &mut Self::Data) {
(&mut this.sequentializer, &mut this.value)
}
#[inline(always)]
fn data(this: &Self) -> &Self::Data {
&this.value
}
}
#[must_use = "If unused the write lock is immediatly released"]
pub(crate) struct WriteGuard<T>(T);
impl<T> Deref for WriteGuard<T>
where
T: Deref,
<T as Deref>::Target: LazyData,
{
type Target = <<T as Deref>::Target as LazyData>::Target;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*(*self.0).get() }
}
}
impl<T> DerefMut for WriteGuard<T>
where
T: Deref,
<T as Deref>::Target: LazyData,
{
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *(*self.0).get() }
}
}
impl<T> Phased for WriteGuard<T>
where
T: Phased,
{
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.0)
}
}
impl<T> Debug for WriteGuard<T>
where
T: Deref,
<T as Deref>::Target: LazyData,
<<T as Deref>::Target as LazyData>::Target: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_tuple("WriteGuard").field(&**self).finish()
}
}
#[must_use = "If unused the read lock is immediatly released"]
#[derive(Clone)]
pub(crate) struct ReadGuard<T>(T);
impl<T> Deref for ReadGuard<T>
where
T: Deref,
<T as Deref>::Target: LazyData,
{
type Target = <<T as Deref>::Target as LazyData>::Target;
#[inline(always)]
fn deref(&self) -> &Self::Target {
unsafe { &*(*self.0).get() }
}
}
impl<T> Debug for ReadGuard<T>
where
T: Deref,
<T as Deref>::Target: LazyData,
<<T as Deref>::Target as LazyData>::Target: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_tuple("ReadGuard").field(&**self).finish()
}
}
impl<T, U> From<WriteGuard<T>> for ReadGuard<U>
where
U: From<T>,
{
#[inline(always)]
fn from(v: WriteGuard<T>) -> Self {
Self(v.0.into())
}
}
impl<T> Phased for ReadGuard<T>
where
T: Phased,
{
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.0)
}
}
#[cfg(any(feature = "parking_lot_core", debug_mode))]
impl<T: LazyData> RefUnwindSafe for ReadGuard<T> where <T as LazyData>::Target: RefUnwindSafe {}
#[cfg(any(feature = "parking_lot_core", debug_mode))]
impl<T: LazyData> RefUnwindSafe for WriteGuard<T> where <T as LazyData>::Target: RefUnwindSafe {}
pub(crate) struct GenericLockedLazy<T, F, M, S> {
seq: GenericLockedLazySeq<T, M>,
generator: F,
phantom: PhantomData<S>,
#[cfg(debug_mode)]
_info: Option<StaticInfo>,
}
impl<T, F, M, S> GenericLockedLazy<T, F, M, S> {
#[inline(always)]
pub const unsafe fn new(generator: F, sequentializer: M, value: T) -> Self {
Self {
seq: GenericLockedLazySeq {
value,
sequentializer,
},
generator,
phantom: PhantomData,
#[cfg(debug_mode)]
_info: None,
}
}
#[inline(always)]
pub const unsafe fn new_with_info(
generator: F,
sequentializer: M,
value: T,
_info: StaticInfo,
) -> Self {
Self {
seq: GenericLockedLazySeq {
value,
sequentializer,
},
generator,
phantom: PhantomData,
#[cfg(debug_mode)]
_info: Some(_info),
}
}
#[inline(always)]
pub fn sequentializer(this: &Self) -> &M {
&this.seq.sequentializer
}
}
impl<'a, T, F, M, S> GenericLockedLazy<T, F, M, S>
where
T: 'a + LazyData,
M: 'a,
M: LazySequentializer<'a, GenericLockedLazySeq<T, M>>,
F: 'a + Generator<T::Target>,
S: 'a + LazyPolicy,
M::ReadGuard: Phased,
M::WriteGuard: Phased,
{
#[inline(always)]
pub unsafe fn get_mut_unchecked(&'a mut self) -> &'a mut T::Target {
&mut *self.seq.value.get()
}
#[inline(always)]
pub fn try_get_mut(&'a mut self) -> Result<&'a mut T::Target, AccessError> {
check_access::<*mut T::Target, S>(
self.seq.value.get(),
Phased::phase(&self.seq.sequentializer),
)
.map(|ptr| unsafe { &mut *ptr })
}
#[inline(always)]
pub fn get_mut(&'a mut self) -> &'a mut T::Target {
self.try_get_mut().unwrap()
}
#[inline(always)]
pub unsafe fn fast_read_lock_unchecked(this: &'a Self) -> Option<ReadGuard<M::ReadGuard>> {
<M as Sequentializer<'a, GenericLockedLazySeq<T, M>>>::try_lock(
&this.seq,
|_| LockNature::Read,
M::INITIALIZED_HINT,
)
.map(|l| {
if let LockResult::Read(l) = l {
ReadGuard(l)
} else {
unreachable_unchecked()
}
})
}
#[inline(always)]
pub fn fast_try_read_lock(
this: &'a Self,
) -> Option<Result<ReadGuard<M::ReadGuard>, AccessError>> {
unsafe { Self::fast_read_lock_unchecked(this) }
.map(checked_access::<ReadGuard<M::ReadGuard>, S>)
}
#[inline(always)]
pub fn fast_read_lock(this: &'a Self) -> Option<ReadGuard<M::ReadGuard>> {
Self::fast_try_read_lock(this).map(|r| r.unwrap())
}
#[inline(always)]
pub unsafe fn read_lock_unchecked(this: &'a Self) -> ReadGuard<M::ReadGuard> {
if let LockResult::Read(l) = <M as Sequentializer<'a, GenericLockedLazySeq<T, M>>>::lock(
&this.seq,
|_| LockNature::Read,
M::INITIALIZED_HINT,
) {
ReadGuard(l)
} else {
unreachable_unchecked()
}
}
#[inline(always)]
pub fn try_read_lock(this: &'a Self) -> Result<ReadGuard<M::ReadGuard>, AccessError> {
checked_access::<ReadGuard<M::ReadGuard>, S>(unsafe { Self::read_lock_unchecked(this) })
}
#[inline(always)]
pub fn read_lock(this: &'a Self) -> ReadGuard<M::ReadGuard> {
Self::try_read_lock(this).unwrap()
}
#[inline(always)]
pub unsafe fn fast_write_lock_unchecked(this: &'a Self) -> Option<WriteGuard<M::WriteGuard>> {
<M as Sequentializer<'a, GenericLockedLazySeq<T, M>>>::try_lock(
&this.seq,
|_| LockNature::Write,
M::INITIALIZED_HINT,
)
.map(|l| {
if let LockResult::Write(l) = l {
WriteGuard(l)
} else {
unreachable_unchecked()
}
})
}
#[inline(always)]
pub fn fast_try_write_lock(
this: &'a Self,
) -> Option<Result<WriteGuard<M::WriteGuard>, AccessError>> {
unsafe { Self::fast_write_lock_unchecked(this) }
.map(checked_access::<WriteGuard<M::WriteGuard>, S>)
}
#[inline(always)]
pub fn fast_write_lock(this: &'a Self) -> Option<WriteGuard<M::WriteGuard>> {
Self::fast_try_write_lock(this).map(|r| r.unwrap())
}
#[inline(always)]
pub unsafe fn write_lock_unchecked(this: &'a Self) -> WriteGuard<M::WriteGuard> {
if let LockResult::Write(l) = <M as Sequentializer<'a, GenericLockedLazySeq<T, M>>>::lock(
&this.seq,
|_| LockNature::Write,
M::INITIALIZED_HINT,
) {
WriteGuard(l)
} else {
unreachable_unchecked()
}
}
#[inline(always)]
pub fn try_write_lock(this: &'a Self) -> Result<WriteGuard<M::WriteGuard>, AccessError> {
checked_access::<WriteGuard<M::WriteGuard>, S>(unsafe { Self::write_lock_unchecked(this) })
}
#[inline(always)]
pub fn write_lock(this: &'a Self) -> WriteGuard<M::WriteGuard> {
Self::try_write_lock(this).unwrap()
}
#[inline(always)]
pub unsafe fn init_then_read_lock_unchecked(this: &'a Self) -> ReadGuard<M::ReadGuard> {
let r = may_debug(
|| {
<M as LazySequentializer<'a, GenericLockedLazySeq<T, M>>>::init_then_read_guard(
&this.seq,
S::shall_init,
|data: &T| {
let d = Generator::generate(&this.generator);
#[allow(unused_unsafe)]
unsafe {
data.init(d)
};
},
)
},
#[cfg(debug_mode)]
&this._info,
);
ReadGuard(r)
}
#[inline(always)]
pub fn init_then_try_read_lock(this: &'a Self) -> Result<ReadGuard<M::ReadGuard>, AccessError> {
post_init_checked_access::<ReadGuard<M::ReadGuard>, S>(unsafe {
Self::init_then_read_lock_unchecked(this)
})
}
#[inline(always)]
pub fn init_then_read_lock(this: &'a Self) -> ReadGuard<M::ReadGuard> {
Self::init_then_try_read_lock(this).unwrap()
}
#[inline(always)]
pub unsafe fn fast_init_then_read_lock_unchecked(
this: &'a Self,
) -> Option<ReadGuard<M::ReadGuard>> {
may_debug(
|| {
<M as LazySequentializer<'a, GenericLockedLazySeq<T, M>>>::try_init_then_read_guard(
&this.seq,
S::shall_init,
|data: &T| {
let d = Generator::generate(&this.generator);
#[allow(unused_unsafe)]
unsafe {
data.init(d)
};
},
)
},
#[cfg(debug_mode)]
&this._info,
)
.map(ReadGuard)
}
#[inline(always)]
pub fn fast_init_then_try_read_lock(
this: &'a Self,
) -> Option<Result<ReadGuard<M::ReadGuard>, AccessError>> {
unsafe { Self::fast_init_then_read_lock_unchecked(this) }
.map(post_init_checked_access::<ReadGuard<M::ReadGuard>, S>)
}
#[inline(always)]
pub fn fast_init_then_read_lock(this: &'a Self) -> Option<ReadGuard<M::ReadGuard>> {
Self::fast_init_then_try_read_lock(this).map(|r| r.unwrap())
}
#[inline(always)]
pub unsafe fn init_then_write_lock_unchecked(this: &'a Self) -> WriteGuard<M::WriteGuard> {
let r = may_debug(
|| {
<M as LazySequentializer<'a, GenericLockedLazySeq<T, M>>>::init_then_write_guard(
&this.seq,
S::shall_init,
|data: &T| {
let d = Generator::generate(&this.generator);
#[allow(unused_unsafe)]
unsafe {
data.init(d)
};
},
)
},
#[cfg(debug_mode)]
&this._info,
);
WriteGuard(r)
}
#[inline(always)]
pub fn init_then_try_write_lock(
this: &'a Self,
) -> Result<WriteGuard<M::WriteGuard>, AccessError> {
post_init_checked_access::<WriteGuard<M::WriteGuard>, S>(unsafe {
Self::init_then_write_lock_unchecked(this)
})
}
#[inline(always)]
#[inline(always)]
pub fn init_then_write_lock(this: &'a Self) -> WriteGuard<M::WriteGuard> {
Self::init_then_try_write_lock(this).unwrap()
}
#[inline(always)]
pub unsafe fn fast_init_then_write_lock_unchecked(
this: &'a Self,
) -> Option<WriteGuard<M::WriteGuard>> {
may_debug(
|| {
<M as LazySequentializer<'a, GenericLockedLazySeq<T, M>>>::try_init_then_write_guard(
&this.seq,
S::shall_init,
|data: &T| {
let d = Generator::generate(&this.generator);
#[allow(unused_unsafe)]
unsafe { data.init(d) };
},
)
},
#[cfg(debug_mode)]
&this._info,
)
.map(WriteGuard)
}
#[inline(always)]
pub fn fast_init_then_try_write_lock(
this: &'a Self,
) -> Option<Result<WriteGuard<M::WriteGuard>, AccessError>> {
unsafe { Self::fast_init_then_write_lock_unchecked(this) }
.map(post_init_checked_access::<WriteGuard<M::WriteGuard>, S>)
}
#[inline(always)]
pub fn fast_init_then_write_lock(this: &'a Self) -> Option<WriteGuard<M::WriteGuard>> {
Self::fast_init_then_try_write_lock(this).map(|r| r.unwrap())
}
}
impl<T, F, M, S> GenericLockedLazy<T, F, M, S>
where
M: UniqueLazySequentializer<GenericLockedLazySeq<T, M>>,
T: LazyData,
S: LazyPolicy,
F: Generator<T::Target>,
{
#[inline(always)]
pub unsafe fn only_init_then_get_mut_unchecked(&mut self) -> &mut T::Target {
self.only_init_unique();
&mut *self.seq.value.get()
}
#[inline(always)]
pub fn only_init_then_try_get_mut(&mut self) -> Result<&mut T::Target, AccessError> {
let phase = self.only_init_unique();
check_access::<*mut T::Target, S>(self.seq.value.get(), phase)
.map(|ptr| unsafe { &mut *ptr })
}
#[inline(always)]
pub fn only_init_then_get_mut(&mut self) -> &mut T::Target {
Self::only_init_then_try_get_mut(self).unwrap()
}
#[inline(always)]
pub fn only_init_unique(&mut self) -> Phase {
let generator = &self.generator;
let seq = &mut self.seq;
<M as UniqueLazySequentializer<GenericLockedLazySeq<T, M>>>::init_unique(
seq,
S::shall_init,
|data: &mut T| {
let d = Generator::generate(generator);
unsafe { data.init_mut(d) };
},
)
}
}
unsafe impl<T: LazyData, M> Sequential for GenericLockedLazySeq<T, M> {
type Data = T;
type Sequentializer = M;
#[inline(always)]
fn sequentializer(this: &Self) -> &Self::Sequentializer {
&this.sequentializer
}
#[inline(always)]
fn sequentializer_data_mut(this: &mut Self) -> (&mut Self::Sequentializer, &mut Self::Data) {
(&mut this.sequentializer, &mut this.value)
}
#[inline(always)]
fn data(this: &Self) -> &Self::Data {
&this.value
}
}
impl<F, T, M, S> Deref for GenericLockedLazy<T, F, M, S> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.seq.value
}
}
impl<T, M> Deref for GenericLockedLazySeq<T, M> {
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&self.value
}
}
impl<F, T, M: Phased, S> Phased for GenericLockedLazy<T, F, M, S> {
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.seq.sequentializer)
}
}
impl<F, T, M: Phased, S> Phased for GenericLazy<T, F, M, S> {
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.seq.sequentializer)
}
}
#[inline(always)]
fn may_debug<R, F: FnOnce() -> R>(f: F, #[cfg(debug_mode)] info: &Option<StaticInfo>) -> R {
#[cfg(not(debug_mode))]
{
f()
}
#[cfg(debug_mode)]
{
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(f)) {
Ok(r) => r,
Err(x) => {
if x.is::<CyclicPanic>() {
match info {
Some(info) => panic!("Circular initialization of {:#?}", info),
None => panic!("Circular lazy initialization detected"),
}
} else {
std::panic::resume_unwind(x)
}
}
}
}
}
#[inline(always)]
fn check_access<T, S: LazyPolicy>(l: T, phase: Phase) -> Result<T, AccessError> {
if S::is_accessible(phase) {
Ok(l)
} else {
Err(AccessError { phase })
}
}
#[inline(always)]
fn checked_access<T: Phased, S: LazyPolicy>(l: T) -> Result<T, AccessError> {
let phase = Phased::phase(&l);
check_access::<T, S>(l, phase)
}
#[inline(always)]
fn post_init_check_access<T, S: LazyPolicy>(l: T, phase: Phase) -> Result<T, AccessError> {
if S::post_init_is_accessible(phase) {
Ok(l)
} else {
Err(AccessError { phase })
}
}
#[inline(always)]
fn post_init_checked_access<T: Phased, S: LazyPolicy>(l: T) -> Result<T, AccessError> {
let phase = Phased::phase(&l);
post_init_check_access::<T, S>(l, phase)
}