use crate::phase_locker::{
SyncPhaseGuard, SyncPhaseLocker, SyncReadPhaseGuard, UnSyncPhaseGuard, UnSyncPhaseLocker,
UnSyncReadPhaseGuard,
};
use crate::{
generic_lazy::{
self, AccessError, DropedUnInited, GenericLazy, GenericLockedLazy, LazyData, LazyPolicy,
Primed, UnInited,
},
lazy_sequentializer::UnSyncSequentializer,
Finaly, Generator, GeneratorTolerance, Phase, Phased, StaticInfo, Uninit,
};
#[cfg(feature = "thread_local")]
use crate::exit_sequentializer::ThreadExitSequentializer;
use crate::{exit_sequentializer::ExitSequentializer, lazy_sequentializer::SyncSequentializer};
use core::cell::Cell;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
struct InitializedChecker<T>(PhantomData<T>);
impl<Tol: GeneratorTolerance> LazyPolicy for InitializedChecker<Tol> {
#[inline(always)]
fn shall_init(p: Phase) -> bool {
if Tol::INIT_FAILURE {
!p.intersects(Phase::INITIALIZED)
} else {
p.is_empty()
}
}
#[inline(always)]
fn is_accessible(p: Phase) -> bool {
p.intersects(Phase::INITIALIZED)
}
#[inline(always)]
fn post_init_is_accessible(p: Phase) -> bool {
if Tol::INIT_FAILURE {
Self::initialized_is_accessible(p)
} else {
Self::is_accessible(p)
}
}
#[inline(always)]
fn initialized_is_accessible(_: Phase) -> bool {
true
}
}
struct InitializedSoftFinalizedCheckerGeneric<T, const REG_ALWAYS: bool>(PhantomData<T>);
impl<Tol: GeneratorTolerance, const REG_ALWAYS: bool> LazyPolicy
for InitializedSoftFinalizedCheckerGeneric<Tol, REG_ALWAYS>
{
#[inline(always)]
fn shall_init(p: Phase) -> bool {
if Tol::INIT_FAILURE {
!p.intersects(Phase::INITIALIZED)
} else {
p.is_empty()
}
}
#[inline(always)]
fn is_accessible(p: Phase) -> bool {
p.intersects(Phase::INITIALIZED)
}
#[inline(always)]
fn post_init_is_accessible(p: Phase) -> bool {
if Tol::INIT_FAILURE && (REG_ALWAYS || Tol::FINAL_REGISTRATION_FAILURE) {
debug_assert!(!REG_ALWAYS || p.intersects(Phase::REGISTERED));
Self::initialized_is_accessible(p)
} else {
Self::is_accessible(p)
}
}
#[inline(always)]
fn initialized_is_accessible(_: Phase) -> bool {
true
}
}
struct InitializedHardFinalizedCheckerGeneric<T, const REG_ALWAYS: bool>(PhantomData<T>);
impl<Tol: GeneratorTolerance, const REG_ALWAYS: bool> LazyPolicy
for InitializedHardFinalizedCheckerGeneric<Tol, REG_ALWAYS>
{
#[inline(always)]
fn shall_init(p: Phase) -> bool {
if Tol::INIT_FAILURE {
!p.intersects(Phase::INITIALIZED)
} else {
p.is_empty()
}
}
#[inline(always)]
fn is_accessible(p: Phase) -> bool {
p.intersects(Phase::INITIALIZED) && Self::initialized_is_accessible(p)
}
#[inline(always)]
fn post_init_is_accessible(p: Phase) -> bool {
if Tol::INIT_FAILURE && (REG_ALWAYS || Tol::FINAL_REGISTRATION_FAILURE) {
debug_assert!(!REG_ALWAYS || p.intersects(Phase::REGISTERED));
Self::initialized_is_accessible(p)
} else {
Self::is_accessible(p)
}
}
#[inline(always)]
fn initialized_is_accessible(p: Phase) -> bool {
!p.intersects(Phase::FINALIZED | Phase::FINALIZATION_PANICKED)
}
}
type InitializedSoftFinalizedChecker<T> = InitializedSoftFinalizedCheckerGeneric<T, false>;
type InitializedHardFinalizedChecker<T> = InitializedHardFinalizedCheckerGeneric<T, false>;
type InitializedSoftFinalizedCheckerLesser<T> = InitializedSoftFinalizedCheckerGeneric<T, true>;
type InitializedHardFinalizedCheckerLesser<T> = InitializedHardFinalizedCheckerGeneric<T, true>;
#[cfg(all(feature = "thread_local", cxa_thread_at_exit))]
type InitializedSoftFinalizedTLChecker<T> = InitializedSoftFinalizedCheckerGeneric<T, true>;
#[cfg(all(feature = "thread_local", cxa_thread_at_exit))]
type InitializedHardFinalizedTLChecker<T> = InitializedHardFinalizedCheckerGeneric<T, true>;
#[cfg(all(feature = "thread_local", not(cxa_thread_at_exit)))]
type InitializedSoftFinalizedTLChecker<T> = InitializedSoftFinalizedCheckerGeneric<T, false>;
#[cfg(all(feature = "thread_local", not(cxa_thread_at_exit)))]
type InitializedHardFinalizedTLChecker<T> = InitializedHardFinalizedCheckerGeneric<T, false>;
pub trait LazyAccess: Sized {
type Target;
fn get(this: Self) -> Self::Target;
fn try_get(this: Self) -> Result<Self::Target, AccessError>;
fn phase(this: Self) -> Phase;
fn init(this: Self) -> Phase;
}
macro_rules! impl_lazy {
($tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:path, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker $(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?}
impl_lazy! {@deref $tp,$data$(,T:$tr)?$(,G:$trg)?}
};
(global $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?,$doc:literal $(cfg($attr:meta))?) => {
impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe,'static}
impl_lazy! {@deref_global $tp,$data$(,T:$tr)?$(,G:$trg)?}
};
(static $tp:ident, $man:ident$(<$x:ident>)?, $checker: ident, $data:ty, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?,$doc:literal $(cfg($attr:meta))?) => {
impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe,'static}
impl_lazy! {@deref_static $tp,$data$(,T:$tr)?$(,G:$trg)?}
};
(thread_local_static $tp:ident, $man:ident$(<$x:ident>)?, $checker: ident, $data:ty, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?,$doc:literal $(cfg($attr:meta))?) => {
impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe,'static}
impl_lazy! {@deref_thread_local $tp,$data$(,T:$tr)?$(,G:$trg)?}
};
(@deref $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn get(this: &Self) -> &T {
this.__private.init_then_get()
}
#[inline(always)]
pub fn try_get(this: &Self) -> Result<&'_ T,AccessError> {
this.__private.try_get()
}
#[inline(always)]
pub fn get_mut(this: &mut Self) -> &mut T {
this.__private.only_init_then_get_mut()
}
#[inline(always)]
pub fn try_get_mut(this: &mut Self) -> Result<&'_ mut T,AccessError> {
this.__private.try_get_mut()
}
#[inline(always)]
pub fn phase(this: & Self) -> Phase {
Phased::phase(&this.__private)
}
#[inline(always)]
pub fn init(this: & Self) -> Phase {
GenericLazy::init(&this.__private)
}
}
impl<T, G> Deref for $tp<T, G>
where G: Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
Self::get(self)
}
}
impl<T, G> DerefMut for $tp<T, G>
where G: Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
#[inline(always)]
fn deref_mut(&mut self) -> &mut Self::Target {
Self::get_mut(self)
}
}
impl<'a,T,G> LazyAccess for &'a $tp<T,G>
where G: Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = &'a T;
#[inline(always)]
fn get(this: Self) -> &'a T {
$tp::get(this)
}
#[inline(always)]
fn try_get(this: Self) -> Result<&'a T,AccessError>{
$tp::try_get(this)
}
#[inline(always)]
fn phase(this: Self) -> Phase{
$tp::phase(this)
}
#[inline(always)]
fn init(this: Self) -> Phase {
$tp::init(this)
}
}
};
(@deref_static $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn get(this: &'static Self) -> &'static T {
this.__private.init_then_get()
}
#[inline(always)]
pub fn try_get(this: &'static Self) -> Result<&'static T,AccessError> {
this.__private.try_get()
}
#[inline(always)]
pub fn phase(this: &'static Self) -> Phase {
Phased::phase(&this.__private)
}
#[inline(always)]
pub fn init(this: &'static Self) -> Phase {
GenericLazy::init(&this.__private)
}
}
impl<T, G> Deref for $tp<T, G>
where G: 'static + Generator<T>,
T:'static,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
Self::get(unsafe{as_static(self)})
}
}
impl<T,G> LazyAccess for &'static $tp<T,G>
where G: 'static + Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = &'static T;
#[inline(always)]
fn get(this: Self) -> &'static T {
$tp::get(this)
}
#[inline(always)]
fn try_get(this: Self) -> Result<&'static T,AccessError>{
$tp::try_get(this)
}
#[inline(always)]
fn phase(this: Self) -> Phase{
$tp::phase(this)
}
#[inline(always)]
fn init(this: Self) -> Phase {
$tp::init(this)
}
}
};
(@deref_global $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn try_get(this: &'static Self) -> Result<&'static T, AccessError> {
if inited::global_inited_hint() {
Ok(unsafe{this.__private.get_unchecked()})
} else {
this.__private.try_get()
}
}
#[inline(always)]
pub fn get(this: &'static Self) -> &'static T {
if inited::global_inited_hint() {
unsafe{this.__private.get_unchecked()}
} else {
this.__private.init_then_get()
}
}
#[inline(always)]
pub fn phase(this: &'static Self) -> Phase {
Phased::phase(&this.__private)
}
#[inline(always)]
pub fn init(this: &'static Self) -> Phase {
GenericLazy::init(&this.__private)
}
}
impl<T, G> Deref for $tp<T, G>
where G: 'static + Generator<T>,
T:'static,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
Self::get(unsafe{as_static(self)})
}
}
impl<T,G> LazyAccess for &'static $tp<T,G>
where G: 'static + Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = &'static T;
#[inline(always)]
fn get(this: Self) -> &'static T {
$tp::get(this)
}
#[inline(always)]
fn try_get(this: Self) -> Result<&'static T,AccessError>{
$tp::try_get(this)
}
#[inline(always)]
fn phase(this: Self) -> Phase{
$tp::phase(this)
}
#[inline(always)]
fn init(this: Self) -> Phase{
$tp::init(this)
}
}
};
(@deref_thread_local $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
T:'static,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn get(this: &Self) -> &T {
unsafe {as_static(&this.__private).init_then_get()}
}
#[inline(always)]
pub fn try_get(this: &Self) -> Result<&T,AccessError> {
unsafe{as_static(&this.__private).try_get()}
}
#[inline(always)]
pub fn phase(this: &Self) -> Phase {
Phased::phase(unsafe{as_static(&this.__private)})
}
#[inline(always)]
pub fn init(this: &Self) -> Phase {
GenericLazy::init(unsafe{as_static(&this.__private)})
}
}
impl<T, G> Deref for $tp<T, G>
where G: 'static + Generator<T>,
T:'static,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = T;
#[inline(always)]
fn deref(&self) -> &Self::Target {
Self::get(self)
}
}
impl<'a,T,G> LazyAccess for &'a $tp<T,G>
where G: 'static + Generator<T>,
T:'static,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
type Target = &'a T;
#[inline(always)]
fn get(this: Self) -> &'a T {
$tp::get(this)
}
#[inline(always)]
fn try_get(this: Self) -> Result<&'a T,AccessError>{
$tp::try_get(this)
}
#[inline(always)]
fn phase(this: Self) -> Phase{
$tp::phase(this)
}
#[inline(always)]
fn init(this: Self) -> Phase {
$tp::init(this)
}
}
};
(@proc $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty,$locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?,$doc:literal $(cfg($attr:meta))? $(,$safe:ident)?$(,$static:lifetime)?) => {
#[doc=$doc]
$(#[cfg_attr(docsrs,doc(cfg($attr)))])?
pub struct $tp<T, G = fn() -> T> {
__private: GenericLazy<$data, G, $man$(::<$x>)?, $checker::<G>>,
}
impl<T, G> Phased for $tp<T, G>
where G: $($static +)? Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
fn phase(this: &Self) -> Phase {
Phased::phase(&this.__private)
}
}
impl<T, G> $tp<T, G> {
#[inline(always)]
pub const $($safe)? fn from_generator(f: G) -> Self {
#[allow(unused_unsafe)]
Self {
__private: unsafe{GenericLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::INIT)},
}
}
#[inline(always)]
pub const $($safe)? fn from_generator_with_info(f: G, info: StaticInfo) -> Self {
#[allow(unused_unsafe)]
Self {
__private: unsafe{GenericLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::INIT,info)},
}
}
}
};
}
impl_lazy! {Lazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>,SyncPhaseLocker,
"A type that initialize itself only once on the first access"}
impl_lazy! {global LesserLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>,SyncPhaseLocker,
"The actual type of statics attributed with [#[dynamic]](macro@crate::dynamic). \
\
The method [from_generator](Self::from_generator) is unsafe because this kind of static \
can only safely be used through this attribute macros."
}
impl_lazy! {static LazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedChecker,UnInited::<T>,SyncPhaseLocker,T:Finaly,G:Sync,
"The actual type of statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable static."
}
impl_lazy! {global LesserLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedCheckerLesser,UnInited::<T>,SyncPhaseLocker,T:Finaly,G:Sync,
"The actual type of statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic). \
\
The method [from_generator](Self::from_generator) is unsafe because this kind of static \
can only safely be used through this attribute macros."
}
impl_lazy! {UnSyncLazy,UnSyncSequentializer<G>,InitializedChecker,UnInited::<T>,UnSyncPhaseLocker,
"A version of [Lazy] whose reference can not be passed to other thread"
}
#[cfg(feature = "thread_local")]
impl_lazy! {thread_local_static UnSyncLazyFinalize,ThreadExitSequentializer<G>,InitializedSoftFinalizedTLChecker,UnInited::<T>,UnSyncPhaseLocker,T:Finaly,
"The actual type of thread_local statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable static." cfg(feature="thread_local")
}
#[cfg(feature = "thread_local")]
impl_lazy! {thread_local_static UnSyncLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,DropedUnInited::<T>,UnSyncPhaseLocker,
"The actual type of thread_local statics attributed with [#[dynamic(drop)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable static." cfg(feature="thread_local")
}
use core::fmt::{self, Debug, Formatter};
macro_rules! non_static_debug {
($tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T:Debug, G> Debug for $tp<T, G>
where G: Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if ($tp::phase(self) & Phase::INITIALIZED).is_empty() {
write!(f,"UnInitialized")
} else {
write!(f,"{:?}",**self)
}
}
}
}
}
macro_rules! non_static_impls {
($tp:ident, $data:ty $(,T: $tr:ident)? $(,G: $trg:ident)?) => {
impl<T, G> $tp<T, Cell<Option<G>>>
where
G: FnOnce() -> T,
{
#[inline(always)]
pub fn new(g: G) -> Self {
Self::from_generator(Cell::new(Some(g)))
}
}
impl<T: Default> Default for $tp<T, fn() -> T> {
#[inline(always)]
fn default() -> Self {
Self::from_generator(T::default)
}
}
};
}
non_static_impls! {Lazy,UnInited::<T>}
non_static_debug! {Lazy,UnInited::<T>}
non_static_impls! {UnSyncLazy,UnInited::<T>}
non_static_debug! {UnSyncLazy,UnInited::<T>}
impl<T, G> Drop for Lazy<T, G> {
#[inline(always)]
fn drop(&mut self) {
if Phased::phase(GenericLazy::sequentializer(&self.__private))
.intersects(Phase::INITIALIZED)
{
unsafe {
GenericLazy::get_raw_data(&self.__private)
.get()
.drop_in_place()
}
}
}
}
impl<T, G> Drop for UnSyncLazy<T, G> {
#[inline(always)]
fn drop(&mut self) {
if Phased::phase(GenericLazy::sequentializer(&self.__private))
.intersects(Phase::INITIALIZED)
{
unsafe {
GenericLazy::get_raw_data(&self.__private)
.get()
.drop_in_place()
}
}
}
}
macro_rules! non_static_mut_debug {
($tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T:Debug, G> Debug for $tp<T, G>
where G: Generator<T>,
$(G:$trg, T:Sync,)?
$(T:$tr,)?
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
if ($tp::phase(self) & Phase::INITIALIZED).is_empty() {
write!(f,"UnInitialized")
} else {
write!(f,"{:?}",*self.read())
}
}
}
}
}
macro_rules! extend_locked_lazy {
() => {
non_static_impls! {LockedLazy,UnInited::<T>}
non_static_mut_debug! {LockedLazy,UnInited::<T>}
impl<T: Send, G: Generator<T>> LockedLazy<T, G> {
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
self.__private.only_init_then_get_mut()
}
#[inline(always)]
pub fn try_get_mut(&mut self) -> Result<&mut T, AccessError> {
self.__private.try_get_mut()
}
}
impl<T, G> Drop for LockedLazy<T, G> {
#[inline(always)]
fn drop(&mut self) {
if Phased::phase(GenericLockedLazy::sequentializer(&self.__private))
.intersects(Phase::INITIALIZED)
{
unsafe { (&*self.__private).get().drop_in_place() }
}
}
}
};
}
macro_rules! extend_unsync_locked_lazy {
() => {
non_static_impls! {UnSyncLockedLazy,UnInited::<T>}
non_static_mut_debug! {UnSyncLockedLazy,UnInited::<T>}
impl<T, G: Generator<T>> UnSyncLockedLazy<T, G> {
#[inline(always)]
pub fn get_mut(&mut self) -> &mut T {
self.__private.only_init_then_get_mut()
}
#[inline(always)]
pub fn try_get_mut(&mut self) -> Result<&mut T, AccessError> {
self.__private.try_get_mut()
}
}
impl<T, G> Drop for UnSyncLockedLazy<T, G> {
#[inline(always)]
fn drop(&mut self) {
if Phased::phase(GenericLockedLazy::sequentializer(&self.__private))
.intersects(Phase::INITIALIZED)
{
unsafe { (&*self.__private).get().drop_in_place() }
}
}
}
};
}
macro_rules! impl_mut_lazy {
($mod: ident $(:$extension:ident)?, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker:ty, $gdw: ident, $gd: ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?}
impl_mut_lazy! {@lock $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker}
$($extension!{})?
}
#[doc(inline)]
pub use $mod::$tp;
};
(static $mod: ident, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker: ty, $gdw: ident,$gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
impl_mut_lazy! {@lock $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)? , 'static}
impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker}
}
#[doc(inline)]
pub use $mod::$tp;
};
(const_static $mod: ident, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker: ty, $gdw: ident,$gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
impl_mut_lazy! {@const_lock $tp,$checker, $data,$gdw,$gd$(,T:$tr)?$(,G:$trg)? , 'static}
impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker}
}
#[doc(inline)]
pub use $mod::$tp;
};
(thread_local $mod: ident $(:$extension:ident)?, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty,$locker: ty, $gdw: ident,$gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe}
impl_mut_lazy! {@lock_thread_local $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker, unsafe}
$($extension!{})?
}
#[doc(inline)]
pub use $mod::$tp;
};
(global $mod: ident, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty,$locker: ty, $gdw: ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe, 'static}
impl_mut_lazy! {@lock_global $tp,$checker,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker, unsafe}
}
#[doc(inline)]
pub use $mod::$tp;
};
(primed_static $mod: ident, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker:ty, $gdw: ident, $gd: ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
impl_mut_lazy! {@lock $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?, 'static}
impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker}
impl_mut_lazy! {@prime_static $tp, $checker, $data, $gdw, $gd$(,T:$tr)?$(,G:$trg)?}
}
#[doc(inline)]
pub use $mod::$tp;
};
(global_primed_static $mod: ident, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker:ty, $gdw: ident, $gd: ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
impl_mut_lazy! {@lock_global $tp,$checker,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker}
impl_mut_lazy! {@prime_global $tp, $checker, $data, $gdw, $gd$(,T:$tr)?$(,G:$trg)?}
}
#[doc(inline)]
pub use $mod::$tp;
};
(primed_thread_local $mod: ident, $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty,$locker: ty, $gdw: ident,$gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
pub mod $mod {
use super::*;
impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe}
impl_mut_lazy! {@lock_thread_local $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker, unsafe}
impl_mut_lazy! {@prime_thread_local $tp, $checker, $data, $gdw, $gd$(,T:$tr)?$(,G:$trg)?}
}
#[doc(inline)]
pub use $mod::$tp;
};
(@lock $tp:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)? $(,$static:lifetime)?) => {
impl<T, G> $tp<T, G>
where G:$($static +)? Generator<T>,
$(T: $static,)?
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn read(&$($static)? self) -> ReadGuard<'_,T> {
ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
}
#[inline(always)]
pub fn fast_read(&$($static)? self) -> Option<ReadGuard<'_,T>> {
GenericLockedLazy::fast_init_then_read_lock(&self.__private).map(ReadGuard)
}
#[inline(always)]
pub fn try_read(&$($static)? self) -> Result<ReadGuard<'_,T>,AccessError> {
GenericLockedLazy::try_read_lock(&self.__private).map(ReadGuard)
}
#[inline(always)]
pub fn fast_try_read(&$($static)? self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
GenericLockedLazy::fast_try_read_lock(&self.__private).map(|r| r.map(ReadGuard))
}
#[inline(always)]
pub fn write(&$($static)? self) -> WriteGuard<'_,T> {
WriteGuard(GenericLockedLazy::init_then_write_lock(&self.__private))
}
#[inline(always)]
pub fn fast_write(&$($static)? self) -> Option<WriteGuard<'_,T>> {
GenericLockedLazy::fast_init_then_write_lock(&self.__private).map(WriteGuard)
}
#[inline(always)]
pub fn try_write(&$($static)? self) -> Result<WriteGuard<'_,T>,AccessError> {
GenericLockedLazy::try_write_lock(&self.__private).map(WriteGuard)
}
#[inline(always)]
pub fn fast_try_write(&$($static)? self) -> Option<Result<WriteGuard<'_,T>,AccessError>> {
GenericLockedLazy::fast_try_write_lock(&self.__private).map(|r| r.map(WriteGuard))
}
#[inline(always)]
pub fn init(&$($static)? self) {
let _ = GenericLockedLazy::init_then_write_lock(&self.__private);
}
}
};
(@const_lock $tp:ident, $checker: ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)? $(,$static:lifetime)?) => {
impl<T, G> $tp<T, G>
where G: $($static +)? Generator<T>,
T:Uninit,
$(T:$static ,)?
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn read(&'static self) -> ReadGuard<'_,T> {
let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
ReadGuard(l)
}
#[inline(always)]
pub fn fast_read(&'static self) -> Option<ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
if let Some(l) = &l {
assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
}
l.map(ReadGuard)
}
#[inline(always)]
pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
}
};
(@lock_thread_local $tp:ident, $data:ty,$gdw:ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
use super::as_static;
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
T: 'static,
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn read(&self) -> ReadGuard<'_,T> {
ReadGuard(GenericLockedLazy::init_then_read_lock(unsafe{as_static(&self.__private)}))
}
#[inline(always)]
pub fn fast_read(&self) -> Option<ReadGuard<'_,T>> {
GenericLockedLazy::fast_init_then_read_lock(unsafe{as_static(&self.__private)}).map(ReadGuard)
}
#[inline(always)]
pub fn try_read(&self) -> Result<ReadGuard<'_,T>,AccessError> {
GenericLockedLazy::try_read_lock(unsafe{as_static(&self.__private)}).map(ReadGuard)
}
#[inline(always)]
pub fn fast_try_read(&self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
GenericLockedLazy::fast_try_read_lock(unsafe{as_static(&self.__private)}).map(|r| r.map(ReadGuard))
}
#[inline(always)]
pub fn write(&self) -> WriteGuard<'_,T> {
WriteGuard(GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)}))
}
#[inline(always)]
pub fn fast_write(&self) -> Option<WriteGuard<'_,T>> {
GenericLockedLazy::fast_init_then_write_lock(unsafe{as_static(&self.__private)}).map(WriteGuard)
}
#[inline(always)]
pub fn try_write(&self) -> Result<WriteGuard<'_,T>,AccessError> {
GenericLockedLazy::try_write_lock(unsafe{as_static(&self.__private)}).map(WriteGuard)
}
#[inline(always)]
pub fn fast_try_write(&self) ->
Option<Result<WriteGuard<'_,T>,AccessError>> {
GenericLockedLazy::fast_try_write_lock(unsafe{as_static(&self.__private)}).map(|r| r.map(WriteGuard))
}
#[inline(always)]
pub fn init(&self) -> Phase {
let l = GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)});
Phased::phase(&l)
}
}
};
(@lock_global $tp:ident, $checker:ident, $data:ty,$gdw:ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
use super::inited;
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
T: 'static,
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn read(&'static self) -> ReadGuard<'_,T> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
ReadGuard(l)
} else {
ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
}
}
#[inline(always)]
pub fn fast_read(&'static self) -> Option<ReadGuard<'_,T>> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
if let Some(l) = &l {
assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
}
l
} else {
GenericLockedLazy::fast_init_then_read_lock(&self.__private)
}.map(ReadGuard)
}
#[inline(always)]
pub fn try_read(&'static self) -> Result<ReadGuard<'_,T>,AccessError> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(l)
} else {
Err(AccessError{phase:p})
}
} else {
GenericLockedLazy::try_read_lock(&self.__private)
}.map(ReadGuard)
}
#[inline(always)]
pub fn fast_try_read(&'static self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
l.map(|l| {
let p = Phased::phase(&l);
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(l)
} else {
Err(AccessError{phase:p})
}
})
} else {
GenericLockedLazy::fast_try_read_lock(&self.__private)
}.map(|r| r.map(ReadGuard))
}
#[inline(always)]
pub fn write(&'static self) -> WriteGuard<'_,T> {
WriteGuard(if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
l
} else {
GenericLockedLazy::init_then_write_lock(&self.__private)
})
}
#[inline(always)]
pub fn fast_write(&'static self) -> Option<WriteGuard<'_,T>> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::fast_write_lock_unchecked(&self.__private)};
if let Some(l) = &l {
assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
}
l
} else {
GenericLockedLazy::fast_init_then_write_lock(&self.__private)
}.map(WriteGuard)
}
#[inline(always)]
pub fn try_write(&'static self) -> Result<WriteGuard<'_,T>,AccessError> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(l)
} else {
Err(AccessError{phase:p})
}
} else {
GenericLockedLazy::try_write_lock(&self.__private)
}.map(WriteGuard)
}
#[inline(always)]
pub fn fast_try_write(&'static self) -> Option<Result<WriteGuard<'_,T>,AccessError>> {
if inited::global_inited_hint() {
let l = unsafe{GenericLockedLazy::fast_write_lock_unchecked(&self.__private)};
l.map(|l| {
let p = Phased::phase(&l);
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(l)
} else {
Err(AccessError{phase:p})
}
})
} else {
GenericLockedLazy::fast_try_write_lock(&self.__private)
}.map(|r| r.map(WriteGuard))
}
#[inline(always)]
pub fn init(&'static self) -> Phase {
let l = GenericLockedLazy::init_then_write_lock(&self.__private);
Phased::phase(&l)
}
}
};
(@prime_static $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
T: 'static,
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn primed_read_non_initializing(&'static self) ->
Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
#[inline(always)]
pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe {GenericLockedLazy::init_then_read_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
#[inline(always)]
pub fn primed_write_non_initializing(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
}
#[inline(always)]
pub fn primed_write(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
}
}
};
(@prime_global $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
T: 'static,
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn primed_read_non_initializing(&'static self) ->
Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if inited::global_inited_hint() {
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
} else {
if <$checker::<G>>::is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
}
#[inline(always)]
pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe {GenericLockedLazy::init_then_read_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if inited::global_inited_hint() {
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
} else {
if <$checker::<G>>::is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
}
#[inline(always)]
pub fn primed_write_non_initializing(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if inited::global_inited_hint() {
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
} else {
if <$checker::<G>>::is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
}
}
#[inline(always)]
pub fn primed_write(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(&self.__private)};
let p = Phased::phase(&l);
if inited::global_inited_hint() {
if <$checker::<G>>::initialized_is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
} else {
if <$checker::<G>>::is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
}
}
}
};
(@prime_thread_local $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
impl<T, G> $tp<T, G>
where G: 'static + Generator<T>,
T:'static,
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn primed_read_non_initializing(&self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::read_lock_unchecked(as_static(&self.__private))};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
#[inline(always)]
pub fn primed_read(&self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::init_then_read_lock_unchecked(as_static(&self.__private))};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(ReadGuard(l))
} else {
Err(ReadGuard(l))
}
}
#[inline(always)]
pub fn primed_write_non_initializing(&self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::write_lock_unchecked(as_static(&self.__private))};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
}
#[inline(always)]
pub fn primed_write(&self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(as_static(&self.__private))};
let p = Phased::phase(&l);
if <$checker::<G>>::is_accessible(p) {
Ok(WriteGuard(l))
} else {
Err(ReadGuard(l.into()))
}
}
}
};
(@uninited $tp:ident, $man:ident$(<$x:ident>)?, $data:ty, $locker: ty$(,$safe:ident)?) => {
impl<T, G> $tp<T, G> {
#[inline(always)]
pub const $($safe)? fn from_generator(f: G) -> Self {
#[allow(unused_unsafe)]
Self {
__private: unsafe{GenericLockedLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::INIT)},
}
}
#[inline(always)]
pub const $($safe)? fn from_generator_with_info(f: G, info: StaticInfo) -> Self {
#[allow(unused_unsafe)]
Self {
__private: unsafe{GenericLockedLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::INIT,info)},
}
}
}
};
(@prime $tp:ident, $man:ident$(<$x:ident>)?, $data:ty, $locker: ty $(,$safe:ident)?) => {
impl<T, G> $tp<T, G> {
#[inline(always)]
pub const $($safe)? fn from_generator(v: T, f: G) -> Self {
#[allow(unused_unsafe)]
Self {
__private: unsafe{GenericLockedLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::prime(v))},
}
}
#[inline(always)]
pub const $($safe)? fn from_generator_with_info(v: T, f: G, info: StaticInfo) -> Self {
#[allow(unused_unsafe)]
Self {
__private: unsafe{GenericLockedLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::prime(v),info)},
}
}
}
};
(@proc $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker: ty, $gdw: ident, $gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?
,$doc:literal $(cfg($attr:meta))? $(,$safe:ident)? $(,$static:lifetime)?) => {
#[doc=$doc]
$(#[cfg_attr(docsrs,doc(cfg($attr)))])?
pub struct $tp<T, G = fn() -> T> {
__private: GenericLockedLazy<$data, G, $man$(<$x>)?, $checker::<G>>,
}
#[must_use="If unused the write lock is immediatly released"]
#[derive(Debug)]
pub struct WriteGuard<'a,T>(generic_lazy::WriteGuard<$gdw::<'a,$data>>);
#[must_use="If unused the write lock is immediatly released"]
#[derive(Debug)]
pub struct ReadGuard<'a,T>(generic_lazy::ReadGuard<$gd::<'a,$data>>);
impl<'a,T> Clone for ReadGuard<'a,T> {
#[inline(always)]
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<'a,T> From<WriteGuard<'a,T>> for ReadGuard<'a,T> {
#[inline(always)]
fn from(that:WriteGuard<'a,T>) -> Self {
Self(that.0.into())
}
}
use core::ops::{Deref,DerefMut};
impl<'a,T> Deref for WriteGuard<'a,T>
$(where T: $static)?
{
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&*self.0
}
}
impl<'a,T> DerefMut for WriteGuard<'a,T>
$(where T: $static)?
{
#[inline(always)]
fn deref_mut(&mut self) -> &mut T {
&mut *self.0
}
}
impl<'a,T> Deref for ReadGuard<'a,T>
$(where T: $static)?
{
type Target = T;
#[inline(always)]
fn deref(&self) -> &T {
&*self.0
}
}
impl<'a, T> Phased for ReadGuard<'a,T>
$(where T: $static)?
{
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.0)
}
}
impl<'a, T> Phased for WriteGuard<'a,T>
$(where T: $static)?
{
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.0)
}
}
impl<T, G> Phased for $tp<T, G>
where
$(T: $static ,)?
G: $($static +)? Generator<T>
{
#[inline(always)]
fn phase(this: &Self) -> Phase {
Phased::phase(&this.__private)
}
}
impl<T, G> $tp<T, G>
where
$(T: $static ,)?
G: $($static +)? Generator<T>,
$(G:$trg, T:Send,)?
$(T:$tr,)?
{
#[inline(always)]
pub fn phase(&$($static)? self) -> Phase {
Phased::phase(&self.__private)
}
}
};
}
impl_mut_lazy! {locked_lazy:extend_locked_lazy, LockedLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
"A mutable locked lazy that initialize its content on the first lock"}
impl_mut_lazy! {global lesser_locked_lazy, LesserLockedLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
"The actual type of mutable statics attributed with [#[dynamic]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe because this kind of static \
can only safely be used through this attribute macros."
}
impl_mut_lazy! {primed_static primed_locked_lazy, PrimedLockedLazy,SyncSequentializer<G>,InitializedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
"The actual type of mutable statics attributed with [#[dynamic(primed)]](macro@crate::dynamic)"}
impl_mut_lazy! {global_primed_static primed_lesser_locked_lazy, PrimedLesserLockedLazy,SyncSequentializer<G>,InitializedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
"The actual type of mutable statics attributed with [#[dynamic(primed)]](macro@crate::dynamic)"}
impl_mut_lazy! {static locked_lazy_finalize,LockedLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedChecker,UnInited::<T>,SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard, T:Finaly,G:Sync,
"The actual type of mutable statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic)"
}
impl_mut_lazy! {global lesser_locked_lazy_finalize,LesserLockedLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedCheckerLesser,UnInited::<T>,SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Finaly, G:Sync,
"The actual type of mutable statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe because this kind of static \
can only safely be used through this attribute macros."
}
impl_mut_lazy! {static locked_lazy_droped,LockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,DropedUnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
"The actual type of statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic)"
}
impl_mut_lazy! {global lesser_locked_lazy_droped,LesserLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedCheckerLesser,DropedUnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
"The actual type of mutable statics attributed with #[dynamic(drop)] \
\
The method (new)[Self::from_generator] is unsafe because this kind of static \
can only safely be used through this attribute macros."
}
impl_mut_lazy! {primed_static primed_locked_lazy_droped,PrimedLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Uninit, G:Sync,
"The actual type of mutable statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic)"
}
impl_mut_lazy! {global_primed_static global_primed_locked_lazy_droped,PrimedLesserLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Uninit, G:Sync,
"The actual type of mutable statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic)"
}
impl_mut_lazy! {unsync_locked_lazy:extend_unsync_locked_lazy,UnSyncLockedLazy,UnSyncSequentializer<G>,InitializedChecker,UnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
"A RefCell that initializes its content on the first access"
}
#[cfg(feature = "thread_local")]
impl_mut_lazy! {primed_thread_local unsync_primed_locked_lazy,UnSyncPrimedLockedLazy,UnSyncSequentializer<G>,InitializedChecker,Primed::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
"The actual type of mutable thread_local statics attributed with [#[dynamic(primed)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
}
#[cfg(feature = "thread_local")]
impl_mut_lazy! {primed_thread_local unsync_primed_locked_lazy_droped,UnSyncPrimedLockedLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,Primed::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard, T:Uninit,
"The actual type of mutable thread_local statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
}
#[cfg(feature = "thread_local")]
impl_mut_lazy! {thread_local unsync_locked_lazy_finalize,UnSyncLockedLazyFinalize,ThreadExitSequentializer<G>,InitializedSoftFinalizedTLChecker,UnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,T:Finaly,
"The actual type of mutable thread_local statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
}
#[cfg(feature = "thread_local")]
impl_mut_lazy! {thread_local unsync_locked_lazy_droped,UnSyncLockedLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,DropedUnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
"The actual type of thread_local mutable statics attributed with [#[dynamic(drop)]](macro@crate::dynamic) \
\
The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
}
#[cfg(all(support_priority, not(feature = "test_no_global_lazy_hint")))]
mod inited {
use core::sync::atomic::{AtomicBool, Ordering};
static LAZY_INIT_ENSURED: AtomicBool = AtomicBool::new(false);
#[static_init_macro::constructor(__lazy_init_finished)]
extern "C" fn mark_inited() {
LAZY_INIT_ENSURED.store(true, Ordering::Release);
}
#[inline(always)]
pub(super) fn global_inited_hint() -> bool {
LAZY_INIT_ENSURED.load(Ordering::Acquire)
}
}
#[cfg(not(all(support_priority, not(feature = "test_no_global_lazy_hint"))))]
mod inited {
#[inline(always)]
pub(super) const fn global_inited_hint() -> bool {
false
}
}
#[cfg(test)]
mod test_lazy {
use super::Lazy;
static _X: Lazy<u32, fn() -> u32> = Lazy::from_generator(|| 22);
#[test]
fn test() {
assert_eq!(*_X, 22);
}
}
#[cfg(feature = "test_no_global_lazy_hint")]
#[cfg(test)]
mod test_quasi_lazy {
use super::LesserLazy;
static _X: LesserLazy<u32, fn() -> u32> = unsafe { LesserLazy::from_generator(|| 22) };
#[test]
fn test() {
assert_eq!(*_X, 22);
}
}
#[cfg(all(test, feature = "thread_local"))]
mod test_local_lazy {
use super::UnSyncLazy;
#[thread_local]
static _X: UnSyncLazy<u32, fn() -> u32> = UnSyncLazy::from_generator(|| 22);
#[test]
fn test() {
assert_eq!(*_X, 22);
}
}
#[cfg(test)]
mod test_lazy_finalize {
use super::LazyFinalize;
use crate::Finaly;
#[derive(Debug)]
struct A(u32);
impl Finaly for A {
fn finaly(&self) {}
}
static _X: LazyFinalize<A, fn() -> A> = unsafe { LazyFinalize::from_generator(|| A(22)) };
#[test]
fn test() {
assert_eq!((*_X).0, 22);
}
}
#[cfg(feature = "test_no_global_lazy_hint")]
#[cfg(test)]
mod test_quasi_lazy_finalize {
use super::LesserLazyFinalize;
use crate::Finaly;
#[derive(Debug)]
struct A(u32);
impl Finaly for A {
fn finaly(&self) {}
}
static _X: LesserLazyFinalize<A, fn() -> A> =
unsafe { LesserLazyFinalize::from_generator(|| A(22)) };
#[test]
fn test() {
assert_eq!((*_X).0, 22);
}
}
#[cfg(all(test, feature = "thread_local"))]
mod test_local_lazy_finalize {
use super::UnSyncLazyFinalize;
use crate::Finaly;
#[derive(Debug)]
struct A(u32);
impl Finaly for A {
fn finaly(&self) {}
}
#[thread_local]
static _X: UnSyncLazyFinalize<A, fn() -> A> =
unsafe { UnSyncLazyFinalize::from_generator(|| A(22)) };
#[test]
fn test() {
assert_eq!((*_X).0, 22);
}
}
#[cfg(all(test, feature = "thread_local"))]
mod test_droped_local_lazy_finalize {
use super::UnSyncLazyDroped;
#[derive(Debug)]
struct A(u32);
#[thread_local]
static _X: UnSyncLazyDroped<A> = unsafe { UnSyncLazyDroped::from_generator(|| A(22)) };
#[test]
fn test() {
assert_eq!(_X.0, 22);
}
}
#[cfg(test)]
mod test_mut_lazy {
use super::LockedLazy;
static _X: LockedLazy<u32, fn() -> u32> = LockedLazy::from_generator(|| 22);
#[test]
fn test() {
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(test)]
mod test_primed_mut_lazy_droped {
use super::PrimedLockedLazyDroped;
use crate::Uninit;
#[derive(Debug)]
struct A(u32);
impl Uninit for A {
fn uninit(&mut self) {
self.0 = 0
}
}
static _X: PrimedLockedLazyDroped<A> = PrimedLockedLazyDroped::from_generator(A(42), || A(22));
#[test]
fn test() {
assert_eq!(_X.primed_read_non_initializing().unwrap_err().0, 42);
assert_eq!(_X.read().0, 22);
_X.write().0 = 33;
assert_eq!(_X.read().0, 33);
}
}
#[cfg(test)]
mod test_primed_mut_lazy {
use super::PrimedLockedLazy;
static _X: PrimedLockedLazy<u32> = PrimedLockedLazy::from_generator(42, || 22);
#[test]
fn test() {
assert_eq!(*_X.primed_read_non_initializing().unwrap_err(), 42);
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(feature = "test_no_global_lazy_hint")]
#[cfg(test)]
mod test_quasi_mut_lazy {
use super::LesserLockedLazy;
static _X: LesserLockedLazy<u32, fn() -> u32> =
unsafe { LesserLockedLazy::from_generator(|| 22) };
#[test]
fn test() {
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(test)]
mod test_mut_lazy_finalize {
use super::LockedLazyFinalize;
use crate::Finaly;
#[derive(Debug)]
struct A(u32);
impl Finaly for A {
fn finaly(&self) {}
}
static _X: LockedLazyFinalize<A, fn() -> A> = LockedLazyFinalize::from_generator(|| A(22));
#[test]
fn test() {
assert!((*_X.read()).0 == 22);
*_X.write() = A(33);
assert_eq!((*_X.read()).0, 33);
}
}
#[cfg(feature = "test_no_global_lazy_hint")]
#[cfg(test)]
mod test_quasi_mut_lazy_finalize {
use super::LesserLockedLazyFinalize;
use crate::Finaly;
#[derive(Debug)]
struct A(u32);
impl Finaly for A {
fn finaly(&self) {}
}
static _X: LesserLockedLazyFinalize<A, fn() -> A> =
unsafe { LesserLockedLazyFinalize::from_generator(|| A(22)) };
#[test]
fn test() {
assert!((*_X.read()).0 == 22);
*_X.write() = A(33);
assert_eq!((*_X.read()).0, 33);
}
}
#[cfg(test)]
mod test_mut_lazy_dropped {
use super::LockedLazyDroped;
static _X: LockedLazyDroped<u32, fn() -> u32> = LockedLazyDroped::from_generator(|| 22);
#[test]
fn test() {
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(feature = "test_no_global_lazy_hint")]
#[cfg(test)]
mod test_quasi_mut_lazy_dropped {
use super::LesserLockedLazyDroped;
static _X: LesserLockedLazyDroped<u32, fn() -> u32> =
unsafe { LesserLockedLazyDroped::from_generator(|| 22) };
#[test]
fn test() {
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(test)]
#[cfg(feature = "thread_local")]
mod test_unsync_mut_lazy {
use super::UnSyncLockedLazy;
#[thread_local]
static _X: UnSyncLockedLazy<u32, fn() -> u32> = UnSyncLockedLazy::from_generator(|| 22);
#[test]
fn test() {
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(test)]
#[cfg(feature = "thread_local")]
mod test_unsync_mut_primed_lazy {
use super::UnSyncPrimedLockedLazy;
#[thread_local]
static _X: UnSyncPrimedLockedLazy<u32> =
unsafe { UnSyncPrimedLockedLazy::from_generator(42, || 22) };
#[test]
fn test() {
assert_eq!(*_X.primed_read_non_initializing().unwrap_err(), 42);
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[cfg(test)]
#[cfg(feature = "thread_local")]
mod test_unsync_mut_primed_lazy_droped {
use super::UnSyncPrimedLockedLazyDroped;
use crate::Uninit;
#[derive(Debug)]
struct A(u32);
impl Uninit for A {
fn uninit(&mut self) {
self.0 = 0
}
}
#[thread_local]
static _X: UnSyncPrimedLockedLazyDroped<A> =
unsafe { UnSyncPrimedLockedLazyDroped::from_generator(A(42), || A(22)) };
#[test]
fn test() {
assert_eq!(_X.primed_read_non_initializing().unwrap_err().0, 42);
assert_eq!(_X.read().0, 22);
_X.write().0 = 33;
assert_eq!(_X.read().0, 33);
}
}
#[cfg(test)]
#[cfg(feature = "thread_local")]
mod test_unsync_mut_lazy_finalize {
use super::UnSyncLockedLazyFinalize;
use crate::Finaly;
#[derive(Debug)]
struct A(u32);
impl Finaly for A {
fn finaly(&self) {}
}
#[thread_local]
static _X: UnSyncLockedLazyFinalize<A, fn() -> A> =
unsafe { UnSyncLockedLazyFinalize::from_generator(|| A(22)) };
#[test]
fn test() {
assert!((*_X.read()).0 == 22);
*_X.write() = A(33);
assert_eq!((*_X.read()).0, 33);
}
}
#[cfg(test)]
#[cfg(feature = "thread_local")]
mod test_unsync_mut_lazy_droped {
use super::UnSyncLockedLazyDroped;
#[thread_local]
static _X: UnSyncLockedLazyDroped<u32, fn() -> u32> =
unsafe { UnSyncLockedLazyDroped::from_generator(|| 22) };
#[test]
fn test() {
assert_eq!(*_X.read(), 22);
*_X.write() = 33;
assert_eq!(*_X.read(), 33);
}
}
#[inline(always)]
unsafe fn as_static<T>(v: &T) -> &'static T {
&*(v as *const _)
}