static_init/
lazy.rs

1use crate::phase_locker::{
2    SyncPhaseGuard, SyncPhaseLocker, SyncReadPhaseGuard, UnSyncPhaseGuard, UnSyncPhaseLocker,
3    UnSyncReadPhaseGuard,
4};
5use crate::{
6    generic_lazy::{
7        self, AccessError, DropedUnInited, GenericLazy, GenericLockedLazy, LazyData, LazyPolicy,
8        Primed, UnInited,
9    },
10    lazy_sequentializer::UnSyncSequentializer,
11    Finaly, Generator, GeneratorTolerance, Phase, Phased, StaticInfo, Uninit,
12};
13
14#[cfg(feature = "thread_local")]
15use crate::exit_sequentializer::ThreadExitSequentializer;
16
17use crate::{exit_sequentializer::ExitSequentializer, lazy_sequentializer::SyncSequentializer};
18
19use core::cell::Cell;
20use core::marker::PhantomData;
21use core::ops::{Deref, DerefMut};
22
23struct InitializedChecker<T>(PhantomData<T>);
24
25impl<Tol: GeneratorTolerance> LazyPolicy for InitializedChecker<Tol> {
26    #[inline(always)]
27    fn shall_init(p: Phase) -> bool {
28        if Tol::INIT_FAILURE {
29            !p.intersects(Phase::INITIALIZED)
30        } else {
31            p.is_empty()
32        }
33    }
34    #[inline(always)]
35    fn is_accessible(p: Phase) -> bool {
36        p.intersects(Phase::INITIALIZED)
37    }
38    #[inline(always)]
39    fn post_init_is_accessible(p: Phase) -> bool {
40        if Tol::INIT_FAILURE {
41            Self::initialized_is_accessible(p)
42        } else {
43            Self::is_accessible(p)
44        }
45    }
46    #[inline(always)]
47    fn initialized_is_accessible(_: Phase) -> bool {
48        true
49    }
50}
51
52struct InitializedSoftFinalizedCheckerGeneric<T, const REG_ALWAYS: bool>(PhantomData<T>);
53
54impl<Tol: GeneratorTolerance, const REG_ALWAYS: bool> LazyPolicy
55    for InitializedSoftFinalizedCheckerGeneric<Tol, REG_ALWAYS>
56{
57    #[inline(always)]
58    fn shall_init(p: Phase) -> bool {
59        if Tol::INIT_FAILURE {
60            !p.intersects(Phase::INITIALIZED)
61        } else {
62            p.is_empty()
63        }
64    }
65    #[inline(always)]
66    fn is_accessible(p: Phase) -> bool {
67        p.intersects(Phase::INITIALIZED)
68    }
69    #[inline(always)]
70    fn post_init_is_accessible(p: Phase) -> bool {
71        if Tol::INIT_FAILURE && (REG_ALWAYS || Tol::FINAL_REGISTRATION_FAILURE) {
72            debug_assert!(!REG_ALWAYS || p.intersects(Phase::REGISTERED));
73            Self::initialized_is_accessible(p)
74        } else {
75            Self::is_accessible(p)
76        }
77    }
78    #[inline(always)]
79    fn initialized_is_accessible(_: Phase) -> bool {
80        true
81    }
82}
83
84struct InitializedHardFinalizedCheckerGeneric<T, const REG_ALWAYS: bool>(PhantomData<T>);
85
86impl<Tol: GeneratorTolerance, const REG_ALWAYS: bool> LazyPolicy
87    for InitializedHardFinalizedCheckerGeneric<Tol, REG_ALWAYS>
88{
89    #[inline(always)]
90    fn shall_init(p: Phase) -> bool {
91        if Tol::INIT_FAILURE {
92            !p.intersects(Phase::INITIALIZED)
93        } else {
94            p.is_empty()
95        }
96    }
97    #[inline(always)]
98    fn is_accessible(p: Phase) -> bool {
99        p.intersects(Phase::INITIALIZED) && Self::initialized_is_accessible(p)
100    }
101    #[inline(always)]
102    fn post_init_is_accessible(p: Phase) -> bool {
103        if Tol::INIT_FAILURE && (REG_ALWAYS || Tol::FINAL_REGISTRATION_FAILURE) {
104            debug_assert!(!REG_ALWAYS || p.intersects(Phase::REGISTERED));
105            Self::initialized_is_accessible(p)
106        } else {
107            Self::is_accessible(p)
108        }
109    }
110    #[inline(always)]
111    fn initialized_is_accessible(p: Phase) -> bool {
112        !p.intersects(Phase::FINALIZED | Phase::FINALIZATION_PANICKED)
113    }
114}
115
116type InitializedSoftFinalizedChecker<T> = InitializedSoftFinalizedCheckerGeneric<T, false>;
117
118type InitializedHardFinalizedChecker<T> = InitializedHardFinalizedCheckerGeneric<T, false>;
119
120//Lesser lazy are initializer before main so registration will always succeed
121type InitializedSoftFinalizedCheckerLesser<T> = InitializedSoftFinalizedCheckerGeneric<T, true>;
122
123type InitializedHardFinalizedCheckerLesser<T> = InitializedHardFinalizedCheckerGeneric<T, true>;
124
125/// Thread local final registration always succeed for thread local on glibc plateforms
126#[cfg(all(feature = "thread_local", cxa_thread_at_exit))]
127type InitializedSoftFinalizedTLChecker<T> = InitializedSoftFinalizedCheckerGeneric<T, true>;
128
129#[cfg(all(feature = "thread_local", cxa_thread_at_exit))]
130type InitializedHardFinalizedTLChecker<T> = InitializedHardFinalizedCheckerGeneric<T, true>;
131
132#[cfg(all(feature = "thread_local", not(cxa_thread_at_exit)))]
133type InitializedSoftFinalizedTLChecker<T> = InitializedSoftFinalizedCheckerGeneric<T, false>;
134
135#[cfg(all(feature = "thread_local", not(cxa_thread_at_exit)))]
136type InitializedHardFinalizedTLChecker<T> = InitializedHardFinalizedCheckerGeneric<T, false>;
137
138/// Helper trait to ease access static lazy associated functions
139pub trait LazyAccess: Sized {
140    type Target;
141    /// Initialize if necessary then return a reference to the target.
142    ///
143    /// # Panics
144    ///
145    /// Panic if previous attempt to initialize has panicked and the lazy policy does not
146    /// tolorate further initialization attempt or if initialization
147    /// panic.
148    fn get(this: Self) -> Self::Target;
149    /// Return a reference to the target if initialized otherwise return an error.
150    fn try_get(this: Self) -> Result<Self::Target, AccessError>;
151    /// The current phase of the static
152    fn phase(this: Self) -> Phase;
153    /// Initialize the static if there were no previous attempt to initialize it.
154    fn init(this: Self) -> Phase;
155}
156
157macro_rules! impl_lazy {
158    ($tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:path, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?, $doc:literal $(cfg($attr:meta))?) => {
159        impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker $(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?}
160        impl_lazy! {@deref $tp,$data$(,T:$tr)?$(,G:$trg)?}
161    };
162    (global $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?,$doc:literal $(cfg($attr:meta))?) => {
163        impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe,'static}
164        impl_lazy! {@deref_global $tp,$data$(,T:$tr)?$(,G:$trg)?}
165    };
166    (static $tp:ident, $man:ident$(<$x:ident>)?, $checker: ident, $data:ty, $locker:ty $(,T: $tr: ident)?$(,G: $trg:ident)?,$doc:literal $(cfg($attr:meta))?) => {
167        impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe,'static}
168        impl_lazy! {@deref_static $tp,$data$(,T:$tr)?$(,G:$trg)?}
169    };
170    (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))?) => {
171        impl_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe,'static}
172        impl_lazy! {@deref_thread_local $tp,$data$(,T:$tr)?$(,G:$trg)?}
173    };
174    (@deref $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
175        impl<T, G> $tp<T, G>
176        where G: Generator<T>,
177        $(G:$trg, T:Sync,)?
178        $(T:$tr,)?
179        {
180            #[inline(always)]
181            /// Initialize if necessary then return a reference to the target.
182            ///
183            /// # Panics
184            ///
185            /// Panic if previous attempt to initialize has panicked and the lazy policy does not
186            /// tolorate further initialization attempt or if initialization
187            /// panic.
188            pub fn get(this: &Self) -> &T {
189                this.__private.init_then_get()
190            }
191            #[inline(always)]
192            /// Return a reference to the target if initialized otherwise return an error.
193            pub fn try_get(this: &Self) -> Result<&'_ T,AccessError> {
194                this.__private.try_get()
195            }
196            #[inline(always)]
197            /// Initialize and return a mutable reference to the target
198            ///
199            /// This method is extremly efficient as it does not requires any
200            /// form of locking when initializing
201            pub fn get_mut(this: &mut Self) -> &mut T {
202                this.__private.only_init_then_get_mut()
203            }
204            #[inline(always)]
205            /// Return a mutable reference to the target if initialized otherwise return an error.
206            ///
207            /// This method is extremly efficient as it does not requires any
208            /// form of locking when initializing
209            pub fn try_get_mut(this: &mut Self) -> Result<&'_ mut T,AccessError> {
210                this.__private.try_get_mut()
211            }
212            #[inline(always)]
213            /// Return the phase
214            pub fn phase(this: & Self) -> Phase {
215                Phased::phase(&this.__private)
216            }
217            #[inline(always)]
218            /// Initialize the lazy if not yet initialized
219            ///
220            /// # Panic
221            ///
222            /// Panic if the generator panics
223            pub fn init(this: & Self) -> Phase {
224                GenericLazy::init(&this.__private)
225            }
226        }
227        impl<T, G> Deref for $tp<T, G>
228        where G: Generator<T>,
229        $(G:$trg, T:Sync,)?
230        $(T:$tr,)?
231        {
232            type Target = T;
233            #[inline(always)]
234            fn deref(&self) -> &Self::Target {
235                Self::get(self)
236            }
237        }
238
239        impl<T, G> DerefMut for $tp<T, G>
240        where G: Generator<T>,
241        $(G:$trg, T:Sync,)?
242        $(T:$tr,)?
243        {
244            #[inline(always)]
245            fn deref_mut(&mut self) -> &mut Self::Target {
246                Self::get_mut(self)
247            }
248        }
249
250        impl<'a,T,G> LazyAccess for &'a $tp<T,G>
251            where G: Generator<T>,
252            $(G:$trg, T:Sync,)?
253            $(T:$tr,)?
254            {
255            type Target = &'a T;
256             #[inline(always)]
257             fn get(this: Self) -> &'a T {
258                 $tp::get(this)
259             }
260             #[inline(always)]
261             fn try_get(this: Self) -> Result<&'a T,AccessError>{
262                 $tp::try_get(this)
263             }
264             #[inline(always)]
265             fn phase(this: Self) -> Phase{
266                 $tp::phase(this)
267             }
268             #[inline(always)]
269             fn init(this: Self) -> Phase {
270                 $tp::init(this)
271             }
272        }
273
274    };
275    (@deref_static $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
276        impl<T, G> $tp<T, G>
277        where G: 'static + Generator<T>,
278        $(G:$trg, T:Sync,)?
279        $(T:$tr,)?
280        {
281            #[inline(always)]
282            /// Initialize if necessary then return a reference to the target.
283            ///
284            /// # Panics
285            ///
286            /// Panic if previous attempt to initialize has panicked and the lazy policy does not
287            /// tolorate further initialization attempt or if initialization
288            /// panic.
289            pub fn get(this: &'static Self) -> &'static T {
290                 // SAFETY The object is required to have 'static lifetime by construction
291                 this.__private.init_then_get()
292            }
293            #[inline(always)]
294            /// Return a reference to the target if initialized otherwise return an error.
295            pub fn try_get(this: &'static Self) -> Result<&'static T,AccessError> {
296                 // SAFETY The object is required to have 'static lifetime by construction
297                 this.__private.try_get()
298            }
299            #[inline(always)]
300            /// Return the phase
301            pub fn phase(this: &'static Self) -> Phase {
302                Phased::phase(&this.__private)
303            }
304            #[inline(always)]
305            /// Initialize the lazy if not yet initialized
306            ///
307            /// # Panic
308            ///
309            /// Panic if the generator panics
310            pub fn init(this: &'static Self) -> Phase {
311                GenericLazy::init(&this.__private)
312            }
313        }
314        impl<T, G> Deref for $tp<T, G>
315        where G: 'static + Generator<T>,
316        T:'static,
317        $(G:$trg, T:Sync,)?
318        $(T:$tr,)?
319        {
320            type Target = T;
321            #[inline(always)]
322            fn deref(&self) -> &Self::Target {
323                 // SAFETY The object is required to have 'static lifetime by construction
324                 Self::get(unsafe{as_static(self)})
325            }
326        }
327
328        impl<T,G> LazyAccess for &'static $tp<T,G>
329            where G: 'static + Generator<T>,
330            $(G:$trg, T:Sync,)?
331            $(T:$tr,)?
332            {
333            type Target = &'static T;
334             #[inline(always)]
335             fn get(this: Self) -> &'static T {
336                 $tp::get(this)
337             }
338             #[inline(always)]
339             fn try_get(this: Self) -> Result<&'static T,AccessError>{
340                 $tp::try_get(this)
341             }
342             #[inline(always)]
343             fn phase(this: Self) -> Phase{
344                 $tp::phase(this)
345             }
346             #[inline(always)]
347             fn init(this: Self) -> Phase {
348                 $tp::init(this)
349             }
350        }
351
352    };
353    (@deref_global $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
354        impl<T, G> $tp<T, G>
355        where G: 'static + Generator<T>,
356        $(G:$trg, T:Sync,)?
357        $(T:$tr,)?
358        {
359            #[inline(always)]
360            /// Return a reference to the target if initialized otherwise return an error.
361            pub fn try_get(this: &'static Self) -> Result<&'static T, AccessError> {
362                if inited::global_inited_hint() {
363                    // SAFETY The object is initialized a program start-up as long
364                    // as it is constructed through the macros #[dynamic(quasi_lazy)]
365                    // If initialization failed, the program terminates before the
366                    // global_inited_hint is set. So if the global_initied_hint is
367                    // set all LesserLazy are guaranteed to be initialized
368                    // Moreover global lazy are never dropped
369                    // TODO: get_unchecked
370                    Ok(unsafe{this.__private.get_unchecked()})
371                } else {
372                    this.__private.try_get()
373                }
374            }
375            #[inline(always)]
376            /// Initialize if necessary then return a reference to the target.
377            ///
378            /// # Panics
379            ///
380            /// Panic if previous attempt to initialize has panicked and the lazy policy does not
381            /// tolorate further initialization attempt or if initialization
382            /// panic.
383            pub fn get(this: &'static Self) -> &'static T {
384                if inited::global_inited_hint() {
385                    // SAFETY The object is initialized a program start-up as long
386                    // as it is constructed through the macros #[dynamic(quasi_lazy)]
387                    // If initialization failed, the program terminates before the
388                    // global_inited_hint is set. So if the global_initied_hint is
389                    // set all LesserLazy are guaranteed to be initialized
390                    // Moreover global lazy are never dropped
391                    unsafe{this.__private.get_unchecked()}
392                } else {
393                    this.__private.init_then_get()
394                }
395            }
396            #[inline(always)]
397            /// Return the phase
398            pub fn phase(this: &'static Self) -> Phase {
399                Phased::phase(&this.__private)
400            }
401            #[inline(always)]
402            /// Initialize the lazy if not yet initialized
403            ///
404            /// # Panic
405            ///
406            /// Panic if the generator panics
407            pub fn init(this: &'static Self) -> Phase {
408                GenericLazy::init(&this.__private)
409            }
410        }
411        impl<T, G> Deref for $tp<T, G>
412        where G: 'static + Generator<T>,
413        T:'static,
414        $(G:$trg, T:Sync,)?
415        $(T:$tr,)?
416        {
417            type Target = T;
418            #[inline(always)]
419            fn deref(&self) -> &Self::Target {
420                // SAFETY The object is initialized a program start-up as long
421                // as it is constructed through the macros #[dynamic(quasi_lazy)]
422                // If initialization failed, the program terminates before the
423                // global_inited_hint is set. So if the global_initied_hint is
424                // set all LesserLazy are guaranteed to be initialized
425                Self::get(unsafe{as_static(self)})
426            }
427        }
428        impl<T,G> LazyAccess for &'static $tp<T,G>
429            where G: 'static + Generator<T>,
430            $(G:$trg, T:Sync,)?
431            $(T:$tr,)?
432            {
433            type Target = &'static T;
434             #[inline(always)]
435             fn get(this: Self) -> &'static T {
436                 $tp::get(this)
437             }
438             #[inline(always)]
439             fn try_get(this: Self) -> Result<&'static T,AccessError>{
440                 $tp::try_get(this)
441             }
442             #[inline(always)]
443             fn phase(this: Self) -> Phase{
444                 $tp::phase(this)
445             }
446             #[inline(always)]
447             fn init(this: Self) -> Phase{
448                 $tp::init(this)
449             }
450        }
451
452    };
453    (@deref_thread_local $tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
454        impl<T, G> $tp<T, G>
455        //where $data: 'static + LazyData<Target=T>,
456        where G: 'static + Generator<T>,
457        T:'static,
458        $(G:$trg, T:Sync,)?
459        $(T:$tr,)?
460        {
461            #[inline(always)]
462            /// Initialize if necessary then return a reference to the target.
463            ///
464            /// # Panics
465            ///
466            /// Panic if previous attempt to initialize has panicked and the lazy policy does not
467            /// tolorate further initialization attempt or if initialization
468            /// panic.
469            pub fn get(this: &Self) -> &T {
470                 // SAFETY The object is required to have 'static lifetime by construction
471                 unsafe {as_static(&this.__private).init_then_get()}
472            }
473            #[inline(always)]
474            /// Return a reference to the target if initialized otherwise return an error.
475            pub fn try_get(this: &Self) -> Result<&T,AccessError> {
476                 // SAFETY The object is required to have 'static lifetime by construction
477                 unsafe{as_static(&this.__private).try_get()}
478            }
479            #[inline(always)]
480            /// Return the phase
481            pub fn phase(this: &Self) -> Phase {
482                Phased::phase(unsafe{as_static(&this.__private)})
483            }
484            #[inline(always)]
485            /// Initialize the lazy if not yet initialized
486            ///
487            /// # Panic
488            ///
489            /// Panic if the generator panics
490            pub fn init(this: &Self) -> Phase {
491                GenericLazy::init(unsafe{as_static(&this.__private)})
492            }
493        }
494
495        impl<T, G> Deref for $tp<T, G>
496        where G: 'static + Generator<T>,
497        T:'static,
498        $(G:$trg, T:Sync,)?
499        $(T:$tr,)?
500        {
501            type Target = T;
502            #[inline(always)]
503            fn deref(&self) -> &Self::Target {
504                 Self::get(self)
505            }
506        }
507
508        impl<'a,T,G> LazyAccess for &'a $tp<T,G>
509            where G: 'static + Generator<T>,
510            T:'static,
511            $(G:$trg, T:Sync,)?
512            $(T:$tr,)?
513            {
514            type Target = &'a T;
515             #[inline(always)]
516             fn get(this: Self) -> &'a T {
517                 $tp::get(this)
518             }
519             #[inline(always)]
520             fn try_get(this: Self) -> Result<&'a T,AccessError>{
521                 $tp::try_get(this)
522             }
523             #[inline(always)]
524             fn phase(this: Self) -> Phase{
525                 $tp::phase(this)
526             }
527             #[inline(always)]
528             fn init(this: Self) -> Phase {
529                 $tp::init(this)
530             }
531        }
532
533    };
534    (@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)?) => {
535        #[doc=$doc]
536        $(#[cfg_attr(docsrs,doc(cfg($attr)))])?
537        pub struct $tp<T, G = fn() -> T> {
538            __private: GenericLazy<$data, G, $man$(::<$x>)?, $checker::<G>>,
539        }
540        impl<T, G> Phased for $tp<T, G>
541        //where $data: $($static +)? LazyData<Target=T>,
542        where G: $($static +)? Generator<T>,
543        $(G:$trg, T:Sync,)?
544        $(T:$tr,)?
545        {
546            fn phase(this: &Self) -> Phase {
547                Phased::phase(&this.__private)
548            }
549        }
550
551        impl<T, G> $tp<T, G> {
552            #[inline(always)]
553            /// Build a new static object
554            ///
555            /// # Safety
556            ///
557            /// This function may be unsafe if building any thing else than a thread local object
558            /// or a static will be the cause of undefined behavior
559            pub const $($safe)? fn from_generator(f: G) -> Self {
560                #[allow(unused_unsafe)]
561                Self {
562
563                    __private: unsafe{GenericLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::INIT)},
564                }
565            }
566            #[inline(always)]
567            /// Build a new static object with debug information
568            ///
569            /// # Safety
570            ///
571            /// This function may be unsafe if building any thing else than a thread local object
572            /// or a static will be the cause of undefined behavior
573            pub const $($safe)?  fn from_generator_with_info(f: G, info: StaticInfo) -> Self {
574                #[allow(unused_unsafe)]
575                Self {
576                    __private: unsafe{GenericLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::INIT,info)},
577                }
578            }
579        }
580
581    };
582}
583
584impl_lazy! {Lazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>,SyncPhaseLocker,
585"A type that initialize itself only once on the first access"}
586
587impl_lazy! {global LesserLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>,SyncPhaseLocker,
588"The actual type of statics attributed with [#[dynamic]](macro@crate::dynamic). \
589\
590The method [from_generator](Self::from_generator) is unsafe because this kind of static \
591can only safely be used through this attribute macros."
592}
593
594impl_lazy! {static LazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedChecker,UnInited::<T>,SyncPhaseLocker,T:Finaly,G:Sync,
595"The actual type of statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic) \
596\
597The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable static."
598}
599
600impl_lazy! {global LesserLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedCheckerLesser,UnInited::<T>,SyncPhaseLocker,T:Finaly,G:Sync,
601"The actual type of statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic). \
602\
603The method [from_generator](Self::from_generator) is unsafe because this kind of static \
604can only safely be used through this attribute macros."
605}
606
607impl_lazy! {UnSyncLazy,UnSyncSequentializer<G>,InitializedChecker,UnInited::<T>,UnSyncPhaseLocker,
608"A version of [Lazy] whose reference can not be passed to other thread"
609}
610
611#[cfg(feature = "thread_local")]
612impl_lazy! {thread_local_static UnSyncLazyFinalize,ThreadExitSequentializer<G>,InitializedSoftFinalizedTLChecker,UnInited::<T>,UnSyncPhaseLocker,T:Finaly,
613"The actual type of thread_local statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
614\
615The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable static." cfg(feature="thread_local")
616}
617#[cfg(feature = "thread_local")]
618impl_lazy! {thread_local_static UnSyncLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,DropedUnInited::<T>,UnSyncPhaseLocker,
619"The actual type of thread_local statics attributed with [#[dynamic(drop)]](macro@crate::dynamic) \
620\
621The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable static." cfg(feature="thread_local")
622}
623
624use core::fmt::{self, Debug, Formatter};
625macro_rules! non_static_debug {
626    ($tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
627        impl<T:Debug, G> Debug for $tp<T, G>
628            //where $data: LazyData<Target=T>,
629            where G: Generator<T>,
630            $(G:$trg, T:Sync,)?
631            $(T:$tr,)?
632        {
633            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
634                if ($tp::phase(self) & Phase::INITIALIZED).is_empty() {
635                    write!(f,"UnInitialized")
636                } else {
637                    write!(f,"{:?}",**self)
638                }
639            }
640        }
641    }
642}
643macro_rules! non_static_impls {
644    ($tp:ident, $data:ty $(,T: $tr:ident)? $(,G: $trg:ident)?) => {
645        impl<T, G> $tp<T, Cell<Option<G>>>
646        where
647            G: FnOnce() -> T,
648        {
649            #[inline(always)]
650            pub fn new(g: G) -> Self {
651                Self::from_generator(Cell::new(Some(g)))
652            }
653        }
654        impl<T: Default> Default for $tp<T, fn() -> T> {
655            #[inline(always)]
656            fn default() -> Self {
657                Self::from_generator(T::default)
658            }
659        }
660    };
661}
662non_static_impls! {Lazy,UnInited::<T>}
663non_static_debug! {Lazy,UnInited::<T>}
664non_static_impls! {UnSyncLazy,UnInited::<T>}
665non_static_debug! {UnSyncLazy,UnInited::<T>}
666
667impl<T, G> Drop for Lazy<T, G> {
668    #[inline(always)]
669    fn drop(&mut self) {
670        if Phased::phase(GenericLazy::sequentializer(&self.__private))
671            .intersects(Phase::INITIALIZED)
672        {
673            unsafe {
674                GenericLazy::get_raw_data(&self.__private)
675                    .get()
676                    .drop_in_place()
677            }
678        }
679    }
680}
681impl<T, G> Drop for UnSyncLazy<T, G> {
682    #[inline(always)]
683    fn drop(&mut self) {
684        if Phased::phase(GenericLazy::sequentializer(&self.__private))
685            .intersects(Phase::INITIALIZED)
686        {
687            unsafe {
688                GenericLazy::get_raw_data(&self.__private)
689                    .get()
690                    .drop_in_place()
691            }
692        }
693    }
694}
695
696macro_rules! non_static_mut_debug {
697    ($tp:ident, $data:ty $(,T: $tr: ident)?$(,G: $trg:ident)?) => {
698        impl<T:Debug, G> Debug for $tp<T, G>
699            where G: Generator<T>,
700            $(G:$trg, T:Sync,)?
701            $(T:$tr,)?
702        {
703            fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
704                if ($tp::phase(self) & Phase::INITIALIZED).is_empty() {
705                    write!(f,"UnInitialized")
706                } else {
707                    write!(f,"{:?}",*self.read())
708                }
709            }
710        }
711    }
712}
713
714macro_rules! extend_locked_lazy {
715    () => {
716        non_static_impls! {LockedLazy,UnInited::<T>}
717        non_static_mut_debug! {LockedLazy,UnInited::<T>}
718        impl<T: Send, G: Generator<T>> LockedLazy<T, G> {
719            #[inline(always)]
720            /// Initialize and return a mutable reference to the target
721            ///
722            /// This method is extremly efficient as it does not requires any
723            /// form of locking when initializing
724            pub fn get_mut(&mut self) -> &mut T {
725                self.__private.only_init_then_get_mut()
726            }
727            #[inline(always)]
728            /// Return a mutable reference to the target if initialized otherwise return an error.
729            ///
730            /// This method is extremly efficient as it does not requires any
731            /// form of locking when initializing
732            pub fn try_get_mut(&mut self) -> Result<&mut T, AccessError> {
733                self.__private.try_get_mut()
734            }
735        }
736        impl<T, G> Drop for LockedLazy<T, G> {
737            #[inline(always)]
738            fn drop(&mut self) {
739                if Phased::phase(GenericLockedLazy::sequentializer(&self.__private))
740                    .intersects(Phase::INITIALIZED)
741                {
742                    unsafe { (&*self.__private).get().drop_in_place() }
743                }
744            }
745        }
746    };
747}
748macro_rules! extend_unsync_locked_lazy {
749    () => {
750        non_static_impls! {UnSyncLockedLazy,UnInited::<T>}
751        non_static_mut_debug! {UnSyncLockedLazy,UnInited::<T>}
752
753        impl<T, G: Generator<T>> UnSyncLockedLazy<T, G> {
754            #[inline(always)]
755            /// Initialize and return a mutable reference to the target
756            ///
757            /// This method is extremly efficient as it does not requires any
758            /// form of locking when initializing
759            pub fn get_mut(&mut self) -> &mut T {
760                self.__private.only_init_then_get_mut()
761            }
762            #[inline(always)]
763            /// Return a mutable reference to the target if initialized otherwise return an error.
764            ///
765            /// This method is extremly efficient as it does not requires any
766            /// form of locking when initializing
767            pub fn try_get_mut(&mut self) -> Result<&mut T, AccessError> {
768                self.__private.try_get_mut()
769            }
770        }
771
772        impl<T, G> Drop for UnSyncLockedLazy<T, G> {
773            #[inline(always)]
774            fn drop(&mut self) {
775                if Phased::phase(GenericLockedLazy::sequentializer(&self.__private))
776                    .intersects(Phase::INITIALIZED)
777                {
778                    unsafe { (&*self.__private).get().drop_in_place() }
779                }
780            }
781        }
782    };
783}
784
785macro_rules! impl_mut_lazy {
786    ($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))?) => {
787        pub mod $mod {
788            use super::*;
789        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?}
790        impl_mut_lazy! {@lock $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
791        impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker}
792            $($extension!{})?
793        }
794        #[doc(inline)]
795        pub use $mod::$tp;
796    };
797    (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))?) => {
798        pub mod $mod {
799            use super::*;
800        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
801        impl_mut_lazy! {@lock $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)? , 'static}
802        impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker}
803        }
804        #[doc(inline)]
805        pub use $mod::$tp;
806    };
807    (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))?) => {
808        pub mod $mod {
809            use super::*;
810        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
811        impl_mut_lazy! {@const_lock $tp,$checker, $data,$gdw,$gd$(,T:$tr)?$(,G:$trg)? , 'static}
812        impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker}
813        }
814        #[doc(inline)]
815        pub use $mod::$tp;
816    };
817    (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))?) => {
818        pub mod $mod {
819            use super::*;
820        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe}
821        impl_mut_lazy! {@lock_thread_local $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
822        impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker, unsafe}
823            $($extension!{})?
824        }
825        #[doc(inline)]
826        pub use $mod::$tp;
827    };
828    (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))?) => {
829        pub mod $mod {
830            use super::*;
831        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe, 'static}
832        impl_mut_lazy! {@lock_global $tp,$checker,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
833        impl_mut_lazy! {@uninited $tp, $man$(<$x>)?, $data, $locker, unsafe}
834        }
835        #[doc(inline)]
836        pub use $mod::$tp;
837    };
838    (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))?) => {
839        pub mod $mod {
840            use super::*;
841        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
842        impl_mut_lazy! {@lock $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?, 'static}
843        impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker}
844        impl_mut_lazy! {@prime_static $tp, $checker, $data, $gdw, $gd$(,T:$tr)?$(,G:$trg)?}
845        }
846        #[doc(inline)]
847        pub use $mod::$tp;
848    };
849    (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))?) => {
850        pub mod $mod {
851            use super::*;
852        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, 'static}
853        impl_mut_lazy! {@lock_global $tp,$checker,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
854        impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker}
855        impl_mut_lazy! {@prime_global $tp, $checker, $data, $gdw, $gd$(,T:$tr)?$(,G:$trg)?}
856        }
857        #[doc(inline)]
858        pub use $mod::$tp;
859    };
860    (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))?) => {
861        pub mod $mod {
862            use super::*;
863        impl_mut_lazy! {@proc $tp,$man$(<$x>)?,$checker,$data,$locker,$gdw,$gd$(,T:$tr)?$(,G:$trg)?,$doc $(cfg($attr))?, unsafe}
864        impl_mut_lazy! {@lock_thread_local $tp,$data,$gdw,$gd$(,T:$tr)?$(,G:$trg)?}
865        impl_mut_lazy! {@prime $tp, $man$(<$x>)?, $data, $locker, unsafe}
866        impl_mut_lazy! {@prime_thread_local $tp, $checker, $data, $gdw, $gd$(,T:$tr)?$(,G:$trg)?}
867        }
868        #[doc(inline)]
869        pub use $mod::$tp;
870    };
871    (@lock $tp:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)? $(,$static:lifetime)?) => {
872        impl<T, G> $tp<T, G>
873        //where $data: $($static+)? LazyData<Target=T>,
874        where G:$($static +)? Generator<T>,
875        $(T: $static,)?
876        $(G:$trg, T:Send,)?
877        $(T:$tr,)?
878        {
879            #[inline(always)]
880            /// Initialize if necessary and returns a read lock
881            ///
882            /// # Panic
883            ///
884            /// Panics if initialization panics or if initialization has panicked in a previous attempt to initialize.
885            pub fn read(&$($static)? self) -> ReadGuard<'_,T> {
886               ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
887            }
888            #[inline(always)]
889            /// Initialize if necessary and returns some read lock if the lazy is not
890            /// already write locked. If the lazy is already write locked it returns `None`
891            ///
892            /// # Panic
893            ///
894            /// If locks succeeds, panics if initialization panics or if initialization has panicked in a previous attempt to initialize.
895            pub fn fast_read(&$($static)? self) -> Option<ReadGuard<'_,T>> {
896               GenericLockedLazy::fast_init_then_read_lock(&self.__private).map(ReadGuard)
897            }
898            #[inline(always)]
899            /// Get a read lock if the lazy is initialized or an [AccessError]
900            pub fn try_read(&$($static)? self) -> Result<ReadGuard<'_,T>,AccessError> {
901               GenericLockedLazy::try_read_lock(&self.__private).map(ReadGuard)
902            }
903            #[inline(always)]
904            /// if the lazy is not already write locked: get a read lock if the lazy is initialized or an [AccessError].
905            /// Otherwise returns `None`
906            pub fn fast_try_read(&$($static)? self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
907               GenericLockedLazy::fast_try_read_lock(&self.__private).map(|r| r.map(ReadGuard))
908            }
909            #[inline(always)]
910            /// Initialize if necessary and returns a write lock
911            ///
912            /// # Panic
913            ///
914            /// Panics if initialization panics or if initialization has panicked in a previous attempt to initialize.
915            pub fn write(&$($static)? self) -> WriteGuard<'_,T> {
916               WriteGuard(GenericLockedLazy::init_then_write_lock(&self.__private))
917            }
918            #[inline(always)]
919            /// Initialize if necessary and returns some write lock if the lazy is not
920            /// already write locked. If the lazy is already read or write locked it returns `None`
921            ///
922            /// # Panic
923            ///
924            /// If locks succeeds, panics if initialization panics or if initialization has panicked in a previous attempt to initialize.
925            pub fn fast_write(&$($static)? self) -> Option<WriteGuard<'_,T>> {
926               GenericLockedLazy::fast_init_then_write_lock(&self.__private).map(WriteGuard)
927            }
928            #[inline(always)]
929            /// Get a read lock if the lazy is initialized or an [AccessError]
930            pub fn try_write(&$($static)? self) -> Result<WriteGuard<'_,T>,AccessError> {
931               GenericLockedLazy::try_write_lock(&self.__private).map(WriteGuard)
932            }
933            #[inline(always)]
934            /// if the lazy is not already read or write locked: get a write lock if the lazy is initialized or an [AccessError] . Otherwise returns `None`
935            pub fn fast_try_write(&$($static)? self) -> Option<Result<WriteGuard<'_,T>,AccessError>> {
936               GenericLockedLazy::fast_try_write_lock(&self.__private).map(|r| r.map(WriteGuard))
937            }
938            #[inline(always)]
939            /// Initialize the lazy if no previous attempt to initialized it where performed
940            pub fn init(&$($static)? self) {
941                let _ = GenericLockedLazy::init_then_write_lock(&self.__private);
942            }
943        }
944
945    };
946    (@const_lock $tp:ident, $checker: ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)? $(,$static:lifetime)?) => {
947        impl<T, G> $tp<T, G>
948        where G: $($static +)? Generator<T>,
949        T:Uninit,
950        $(T:$static ,)?
951        $(G:$trg, T:Send,)?
952        $(T:$tr,)?
953        {
954            #[inline(always)]
955            /// get read lock
956            ///
957            /// # Panic
958            ///
959            /// Panics if the lazy was droped
960            pub fn read(&'static self) -> ReadGuard<'_,T> {
961                    let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
962                    assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
963                    ReadGuard(l)
964            }
965            /// Returns some read lock if the lazy is not
966            /// already write locked. If the lazy is already write locked it returns `None`
967            ///
968            /// # Panic
969            ///
970            /// If locks succeeds, panics if the lazy was droped
971            #[inline(always)]
972            pub fn fast_read(&'static self) -> Option<ReadGuard<'_,T>> {
973                    let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
974                    if let Some(l) = &l {
975                        assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
976                    }
977                    l.map(ReadGuard)
978            }
979            #[inline(always)]
980            /// Return a read lock to the initialized value or an
981            /// error containing a read lock to the post uninited value
982            pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
983               let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
984               let p = Phased::phase(&l);
985               if <$checker::<G>>::initialized_is_accessible(p) {
986                   Ok(ReadGuard(l))
987               } else {
988                   Err(ReadGuard(l))
989               }
990            }
991        }
992
993    };
994    (@lock_thread_local $tp:ident, $data:ty,$gdw:ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
995
996        use super::as_static;
997
998        impl<T, G> $tp<T, G>
999        //where $data: 'static + LazyData<Target=T>,
1000        where G: 'static + Generator<T>,
1001        T: 'static,
1002        $(G:$trg, T:Send,)?
1003        $(T:$tr,)?
1004        {
1005            #[inline(always)]
1006            /// Initialize if necessary and returns a read lock
1007            ///
1008            /// # Panic
1009            ///
1010            /// Panics if initialization panics or if initialization has panicked in a previous
1011            /// attempt to initialize.
1012            pub fn read(&self) -> ReadGuard<'_,T> {
1013                ReadGuard(GenericLockedLazy::init_then_read_lock(unsafe{as_static(&self.__private)}))
1014            }
1015            #[inline(always)]
1016            /// Initialize if necessary and returns some read lock if the lazy is not already write
1017            /// locked. If the lazy is already write locked it returns `None`
1018            ///
1019            /// # Panic
1020            ///
1021            /// If locks succeeds, panics if initialization panics or if initialization has
1022            /// panicked in a previous attempt to initialize.
1023            pub fn fast_read(&self) -> Option<ReadGuard<'_,T>> {
1024               GenericLockedLazy::fast_init_then_read_lock(unsafe{as_static(&self.__private)}).map(ReadGuard)
1025            }
1026            #[inline(always)]
1027            /// Get a read lock if the lazy is initialized or an [AccessError]
1028            pub fn try_read(&self) -> Result<ReadGuard<'_,T>,AccessError> {
1029               GenericLockedLazy::try_read_lock(unsafe{as_static(&self.__private)}).map(ReadGuard)
1030            }
1031            #[inline(always)]
1032            /// if the lazy is not already write locked: get a read lock if the lazy is initialized
1033            /// or an [AccessError]. Otherwise returns `None`
1034            pub fn fast_try_read(&self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
1035               GenericLockedLazy::fast_try_read_lock(unsafe{as_static(&self.__private)}).map(|r| r.map(ReadGuard))
1036            }
1037            #[inline(always)]
1038            /// Initialize if necessary and returns a write lock
1039            ///
1040            /// # Panic
1041            ///
1042            /// Panics if initialization panics or if initialization has panicked in a previous
1043            /// attempt to initialize.
1044            pub fn write(&self) -> WriteGuard<'_,T> {
1045                WriteGuard(GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)}))
1046            }
1047            #[inline(always)]
1048            /// Initialize if necessary and returns some write lock if the lazy is not
1049            /// already write locked. If the lazy is already read or write locked it returns `None`
1050            ///
1051            /// # Panic
1052            ///
1053            /// If locks succeeds, panics if initialization panics or if initialization has
1054            /// panicked in a previous attempt to initialize.
1055            pub fn fast_write(&self) -> Option<WriteGuard<'_,T>> {
1056               GenericLockedLazy::fast_init_then_write_lock(unsafe{as_static(&self.__private)}).map(WriteGuard)
1057            }
1058            #[inline(always)]
1059            /// Get a read lock if the lazy is initialized or an [AccessError]
1060            pub fn try_write(&self) -> Result<WriteGuard<'_,T>,AccessError> {
1061               GenericLockedLazy::try_write_lock(unsafe{as_static(&self.__private)}).map(WriteGuard)
1062            }
1063            #[inline(always)]
1064            /// if the lazy is not already read or write locked: get a write lock if the lazy is
1065            /// initialized or an [AccessError] . Otherwise returns `None`
1066            pub fn fast_try_write(&self) ->
1067               Option<Result<WriteGuard<'_,T>,AccessError>> {
1068               GenericLockedLazy::fast_try_write_lock(unsafe{as_static(&self.__private)}).map(|r| r.map(WriteGuard))
1069            }
1070            #[inline(always)]
1071            /// Initialize the lazy if no previous attempt to initialized it where performed
1072            pub fn init(&self) -> Phase {
1073                let l = GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)});
1074                Phased::phase(&l)
1075            }
1076        }
1077
1078    };
1079    (@lock_global $tp:ident, $checker:ident, $data:ty,$gdw:ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1080
1081        use super::inited;
1082
1083        impl<T, G> $tp<T, G>
1084        //where $data: 'static + LazyData<Target=T>,
1085        where G: 'static + Generator<T>,
1086        T: 'static,
1087        $(G:$trg, T:Send,)?
1088        $(T:$tr,)?
1089        {
1090            #[inline(always)]
1091            /// Initialize if necessary and returns a read lock
1092            ///
1093            /// # Panic
1094            ///
1095            /// Panics if initialization panics or if initialization has panicked in a previous attempt to initialize.
1096            pub fn read(&'static self) -> ReadGuard<'_,T> {
1097                if inited::global_inited_hint() {
1098                    let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
1099                    assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
1100                    ReadGuard(l)
1101                } else {
1102                    ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
1103                }
1104            }
1105            /// Initialize if necessary and returns some read lock if the lazy is not
1106            /// already write locked. If the lazy is already write locked it returns `None`
1107            ///
1108            /// # Panic
1109            ///
1110            /// If locks succeeds, panics if initialization panics or if initialization has panicked in a previous attempt to initialize.
1111            #[inline(always)]
1112            pub fn fast_read(&'static self) -> Option<ReadGuard<'_,T>> {
1113                if inited::global_inited_hint() {
1114                    let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
1115                    if let Some(l) = &l {
1116                        assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
1117                    }
1118                    l
1119                } else {
1120                    GenericLockedLazy::fast_init_then_read_lock(&self.__private)
1121                }.map(ReadGuard)
1122            }
1123            #[inline(always)]
1124            /// Get a read lock if the lazy is initialized or an [AccessError]
1125            pub fn try_read(&'static self) -> Result<ReadGuard<'_,T>,AccessError> {
1126                if inited::global_inited_hint() {
1127                    let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
1128                    let p = Phased::phase(&l);
1129                    if <$checker::<G>>::initialized_is_accessible(p) {
1130                        Ok(l)
1131                    } else {
1132                        Err(AccessError{phase:p})
1133                    }
1134                } else {
1135                    GenericLockedLazy::try_read_lock(&self.__private)
1136                }.map(ReadGuard)
1137            }
1138            /// if the lazy is not already write locked: get a read lock if the lazy is initialized
1139            /// or an [AccessError]. Otherwise returns `None`
1140            #[inline(always)]
1141            pub fn fast_try_read(&'static self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
1142                if inited::global_inited_hint() {
1143                    let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
1144                    l.map(|l| {
1145                        let p = Phased::phase(&l);
1146                        if <$checker::<G>>::initialized_is_accessible(p) {
1147                            Ok(l)
1148                        } else {
1149                            Err(AccessError{phase:p})
1150                        }
1151                    })
1152                } else {
1153                    GenericLockedLazy::fast_try_read_lock(&self.__private)
1154                }.map(|r| r.map(ReadGuard))
1155            }
1156            /// Initialize if necessary and returns a write lock
1157            ///
1158            /// # Panic
1159            ///
1160            /// Panics if initialization panics or if initialization has panicked in a previous
1161            /// attempt to initialize.
1162            #[inline(always)]
1163            pub fn write(&'static self) -> WriteGuard<'_,T> {
1164                WriteGuard(if inited::global_inited_hint() {
1165                    let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1166                    assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
1167                    l
1168                } else {
1169                    GenericLockedLazy::init_then_write_lock(&self.__private)
1170                })
1171            }
1172            /// Initialize if necessary and returns some write lock if the lazy is not
1173            /// already write locked. If the lazy is already read or write locked it returns `None`
1174            ///
1175            /// # Panic
1176            ///
1177            /// If locks succeeds, panics if initialization panics or if initialization has
1178            /// panicked in a previous attempt to initialize.
1179            #[inline(always)]
1180            pub fn fast_write(&'static self) -> Option<WriteGuard<'_,T>> {
1181                if inited::global_inited_hint() {
1182                    let l = unsafe{GenericLockedLazy::fast_write_lock_unchecked(&self.__private)};
1183                    if let Some(l) = &l {
1184                        assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
1185                    }
1186                    l
1187                } else {
1188                    GenericLockedLazy::fast_init_then_write_lock(&self.__private)
1189                }.map(WriteGuard)
1190            }
1191            /// Get a read lock if the lazy is initialized or an [AccessError]
1192            #[inline(always)]
1193            pub fn try_write(&'static self) -> Result<WriteGuard<'_,T>,AccessError> {
1194                if inited::global_inited_hint() {
1195                    let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1196                    let p = Phased::phase(&l);
1197                    if <$checker::<G>>::initialized_is_accessible(p) {
1198                        Ok(l)
1199                    } else {
1200                        Err(AccessError{phase:p})
1201                    }
1202                } else {
1203                    GenericLockedLazy::try_write_lock(&self.__private)
1204                }.map(WriteGuard)
1205            }
1206            /// if the lazy is not already read or write locked: get a write lock if the lazy is
1207            /// initialized or an [AccessError] . Otherwise returns `None`
1208            #[inline(always)]
1209            pub fn fast_try_write(&'static self) -> Option<Result<WriteGuard<'_,T>,AccessError>> {
1210                if inited::global_inited_hint() {
1211                    let l = unsafe{GenericLockedLazy::fast_write_lock_unchecked(&self.__private)};
1212                    l.map(|l| {
1213                        let p = Phased::phase(&l);
1214                        if <$checker::<G>>::initialized_is_accessible(p) {
1215                            Ok(l)
1216                        } else {
1217                            Err(AccessError{phase:p})
1218                        }
1219                    })
1220                } else {
1221                    GenericLockedLazy::fast_try_write_lock(&self.__private)
1222                }.map(|r| r.map(WriteGuard))
1223            }
1224            /// Initialize the lazy if no previous attempt to initialized it where performed
1225            #[inline(always)]
1226            pub fn init(&'static self) -> Phase {
1227                let l = GenericLockedLazy::init_then_write_lock(&self.__private);
1228                Phased::phase(&l)
1229            }
1230        }
1231
1232    };
1233    (@prime_static $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1234        impl<T, G> $tp<T, G>
1235        //where $data: 'static + LazyData<Target=T>,
1236        where G: 'static + Generator<T>,
1237        T: 'static,
1238        $(G:$trg, T:Send,)?
1239        $(T:$tr,)?
1240        {
1241            #[inline(always)]
1242            /// Return a read lock to the initialized value or an error containing a read lock to
1243            /// the primed or post uninited value
1244            pub fn primed_read_non_initializing(&'static self) ->
1245               Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1246               let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
1247               let p = Phased::phase(&l);
1248               if <$checker::<G>>::is_accessible(p) {
1249                   Ok(ReadGuard(l))
1250               } else {
1251                   Err(ReadGuard(l))
1252               }
1253            }
1254            #[inline(always)]
1255            /// Initialize if possible and either return a read lock to the initialized value or an
1256            /// error containing a read lock to the primed or post uninited value
1257            pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1258               let l = unsafe {GenericLockedLazy::init_then_read_lock_unchecked(&self.__private)};
1259               let p = Phased::phase(&l);
1260               if <$checker::<G>>::is_accessible(p) {
1261                   Ok(ReadGuard(l))
1262               } else {
1263                   Err(ReadGuard(l))
1264               }
1265            }
1266            #[inline(always)]
1267            /// Return a write lock that refers to the initialized value or an
1268            /// error containing a read lock that refers to the primed or post uninited value
1269            pub fn primed_write_non_initializing(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1270               let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1271               let p = Phased::phase(&l);
1272               if <$checker::<G>>::is_accessible(p) {
1273                   Ok(WriteGuard(l))
1274               } else {
1275                   Err(ReadGuard(l.into()))
1276               }
1277            }
1278            #[inline(always)]
1279            /// Initialize if possible and either return a write lock that refers to the
1280            /// initialized value or an error containing a read lock that refers to the primed or
1281            /// post uninited value
1282            pub fn primed_write(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1283               let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(&self.__private)};
1284               let p = Phased::phase(&l);
1285               if <$checker::<G>>::is_accessible(p) {
1286                   Ok(WriteGuard(l))
1287               } else {
1288                   Err(ReadGuard(l.into()))
1289               }
1290            }
1291        }
1292    };
1293    (@prime_global $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1294        impl<T, G> $tp<T, G>
1295        //where $data: 'static + LazyData<Target=T>,
1296        where G: 'static + Generator<T>,
1297        T: 'static,
1298        $(G:$trg, T:Send,)?
1299        $(T:$tr,)?
1300        {
1301            #[inline(always)]
1302            /// Return a read lock to the initialized value or an error containing a read lock to
1303            /// the primed or post uninited value
1304            pub fn primed_read_non_initializing(&'static self) ->
1305               Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1306               let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
1307               let p = Phased::phase(&l);
1308               if inited::global_inited_hint() {
1309                  if <$checker::<G>>::initialized_is_accessible(p) {
1310                      Ok(ReadGuard(l))
1311                  } else {
1312                      Err(ReadGuard(l))
1313                  }
1314               } else {
1315                  if <$checker::<G>>::is_accessible(p) {
1316                      Ok(ReadGuard(l))
1317                  } else {
1318                      Err(ReadGuard(l))
1319                  }
1320               }
1321            }
1322            #[inline(always)]
1323            /// Initialize if possible and either return a read lock to the initialized value or an
1324            /// error containing a read lock to the primed or post uninited value
1325            pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1326               let l = unsafe {GenericLockedLazy::init_then_read_lock_unchecked(&self.__private)};
1327               let p = Phased::phase(&l);
1328               if inited::global_inited_hint() {
1329                  if <$checker::<G>>::initialized_is_accessible(p) {
1330                      Ok(ReadGuard(l))
1331                  } else {
1332                      Err(ReadGuard(l))
1333                  }
1334               } else {
1335                  if <$checker::<G>>::is_accessible(p) {
1336                      Ok(ReadGuard(l))
1337                  } else {
1338                      Err(ReadGuard(l))
1339                  }
1340               }
1341            }
1342            #[inline(always)]
1343            /// Return a write lock that refers to the initialized value or an
1344            /// error containing a read lock that refers to the primed or post uninited value
1345            pub fn primed_write_non_initializing(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1346               let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1347               let p = Phased::phase(&l);
1348               if inited::global_inited_hint() {
1349                  if <$checker::<G>>::initialized_is_accessible(p) {
1350                      Ok(WriteGuard(l))
1351                  } else {
1352                      Err(ReadGuard(l.into()))
1353                  }
1354               } else {
1355                  if <$checker::<G>>::is_accessible(p) {
1356                      Ok(WriteGuard(l))
1357                  } else {
1358                      Err(ReadGuard(l.into()))
1359                  }
1360               }
1361            }
1362            #[inline(always)]
1363            /// Initialize if possible and either return a write lock that refers to the
1364            /// initialized value or an error containing a read lock that refers to the primed or
1365            /// post uninited value
1366            pub fn primed_write(&'static self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1367               let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(&self.__private)};
1368               let p = Phased::phase(&l);
1369               if inited::global_inited_hint() {
1370                  if <$checker::<G>>::initialized_is_accessible(p) {
1371                      Ok(WriteGuard(l))
1372                  } else {
1373                      Err(ReadGuard(l.into()))
1374                  }
1375               } else {
1376                  if <$checker::<G>>::is_accessible(p) {
1377                      Ok(WriteGuard(l))
1378                  } else {
1379                      Err(ReadGuard(l.into()))
1380                  }
1381               }
1382            }
1383        }
1384    };
1385    (@prime_thread_local $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1386        impl<T, G> $tp<T, G>
1387        //where $data: 'static + LazyData<Target=T>,
1388        where G: 'static + Generator<T>,
1389        T:'static,
1390        $(G:$trg, T:Send,)?
1391        $(T:$tr,)?
1392        {
1393            #[inline(always)]
1394            /// Return a read lock to the initialized value or an
1395            /// error containing a read lock to the primed or post uninited value
1396            pub fn primed_read_non_initializing(&self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1397               let l = unsafe{GenericLockedLazy::read_lock_unchecked(as_static(&self.__private))};
1398               let p = Phased::phase(&l);
1399               if <$checker::<G>>::is_accessible(p) {
1400                   Ok(ReadGuard(l))
1401               } else {
1402                   Err(ReadGuard(l))
1403               }
1404            }
1405            #[inline(always)]
1406            /// Initialize if possible and either return a read lock to the initialized value or an
1407            /// error containing a read lock to the primed or post uninited value
1408            pub fn primed_read(&self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1409               let l = unsafe{GenericLockedLazy::init_then_read_lock_unchecked(as_static(&self.__private))};
1410               let p = Phased::phase(&l);
1411               if <$checker::<G>>::is_accessible(p) {
1412                   Ok(ReadGuard(l))
1413               } else {
1414                   Err(ReadGuard(l))
1415               }
1416            }
1417            #[inline(always)]
1418            /// Return a write lock that refers to the initialized value or an
1419            /// error containing a read lock that refers to the primed or post uninited value
1420            pub fn primed_write_non_initializing(&self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1421               let l = unsafe{GenericLockedLazy::write_lock_unchecked(as_static(&self.__private))};
1422               let p = Phased::phase(&l);
1423               if <$checker::<G>>::is_accessible(p) {
1424                   Ok(WriteGuard(l))
1425               } else {
1426                   Err(ReadGuard(l.into()))
1427               }
1428            }
1429            #[inline(always)]
1430            /// Initialize if possible and either return a write lock that refers to the initialized value or an
1431            /// error containing a read lock that refers to the primed or post uninited value
1432            pub fn primed_write(&self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1433               let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(as_static(&self.__private))};
1434               let p = Phased::phase(&l);
1435               if <$checker::<G>>::is_accessible(p) {
1436                   Ok(WriteGuard(l))
1437               } else {
1438                   Err(ReadGuard(l.into()))
1439               }
1440            }
1441        }
1442    };
1443    (@uninited $tp:ident, $man:ident$(<$x:ident>)?, $data:ty, $locker: ty$(,$safe:ident)?) => {
1444        impl<T, G> $tp<T, G> {
1445            #[inline(always)]
1446            /// Build a new static object.
1447            ///
1448            /// # Safety
1449            ///
1450            /// This function may be unsafe if build this object as anything else than
1451            /// a static or a thread local static would be the cause of undefined behavior
1452            pub const $($safe)? fn from_generator(f: G) -> Self {
1453                #[allow(unused_unsafe)]
1454                Self {
1455
1456                    __private: unsafe{GenericLockedLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::INIT)},
1457                }
1458            }
1459            #[inline(always)]
1460            /// Build a new static object with debug informations.
1461            ///
1462            /// # Safety
1463            ///
1464            /// This function may be unsafe if build this object as anything else than
1465            /// a static or a thread local static would be the cause of undefined behavior
1466            pub const $($safe)?  fn from_generator_with_info(f: G, info: StaticInfo) -> Self {
1467                #[allow(unused_unsafe)]
1468                Self {
1469                    __private: unsafe{GenericLockedLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::INIT,info)},
1470                }
1471            }
1472        }
1473    };
1474    (@prime $tp:ident, $man:ident$(<$x:ident>)?, $data:ty, $locker: ty $(,$safe:ident)?) => {
1475        impl<T, G> $tp<T, G> {
1476            #[inline(always)]
1477            /// Build a new static object.
1478            ///
1479            /// # Safety
1480            ///
1481            /// This function may be unsafe if build this object as anything else than
1482            /// a static or a thread local static would be the cause of undefined behavior
1483            pub const $($safe)? fn from_generator(v: T, f: G) -> Self {
1484                #[allow(unused_unsafe)]
1485                Self {
1486
1487                    __private: unsafe{GenericLockedLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::prime(v))},
1488                }
1489            }
1490            #[inline(always)]
1491            /// Build a new static object with debug informations.
1492            ///
1493            /// # Safety
1494            ///
1495            /// This function may be unsafe if build this object as anything else than
1496            /// a static or a thread local static would be the cause of undefined behavior
1497            pub const $($safe)?  fn from_generator_with_info(v: T, f: G, info: StaticInfo) -> Self {
1498                #[allow(unused_unsafe)]
1499                Self {
1500                    __private: unsafe{GenericLockedLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::prime(v),info)},
1501                }
1502            }
1503        }
1504    };
1505    (@proc $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker: ty, $gdw: ident, $gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?
1506    ,$doc:literal $(cfg($attr:meta))? $(,$safe:ident)? $(,$static:lifetime)?) => {
1507        #[doc=$doc]
1508        $(#[cfg_attr(docsrs,doc(cfg($attr)))])?
1509        pub struct $tp<T, G = fn() -> T> {
1510            __private: GenericLockedLazy<$data, G, $man$(<$x>)?, $checker::<G>>,
1511        }
1512
1513        #[must_use="If unused the write lock is immediatly released"]
1514        #[derive(Debug)]
1515        pub struct WriteGuard<'a,T>(generic_lazy::WriteGuard<$gdw::<'a,$data>>);
1516
1517        #[must_use="If unused the write lock is immediatly released"]
1518        #[derive(Debug)]
1519        pub struct ReadGuard<'a,T>(generic_lazy::ReadGuard<$gd::<'a,$data>>);
1520
1521        impl<'a,T> Clone for ReadGuard<'a,T> {
1522            #[inline(always)]
1523            fn clone(&self) -> Self {
1524                Self(self.0.clone())
1525            }
1526        }
1527        impl<'a,T> From<WriteGuard<'a,T>> for ReadGuard<'a,T> {
1528            #[inline(always)]
1529            fn from(that:WriteGuard<'a,T>) -> Self {
1530                Self(that.0.into())
1531            }
1532        }
1533
1534        use core::ops::{Deref,DerefMut};
1535
1536        impl<'a,T> Deref for WriteGuard<'a,T>
1537        $(where T: $static)?
1538        {
1539            type Target = T;
1540            #[inline(always)]
1541            fn deref(&self) -> &T {
1542                &*self.0
1543            }
1544        }
1545        impl<'a,T> DerefMut for WriteGuard<'a,T>
1546        $(where T: $static)?
1547        {
1548            #[inline(always)]
1549            fn deref_mut(&mut self) -> &mut T {
1550                &mut *self.0
1551            }
1552        }
1553        impl<'a,T> Deref for ReadGuard<'a,T>
1554        $(where T: $static)?
1555        {
1556            type Target = T;
1557            #[inline(always)]
1558            fn deref(&self) -> &T {
1559                &*self.0
1560            }
1561        }
1562
1563        impl<'a, T> Phased for ReadGuard<'a,T>
1564        $(where T: $static)?
1565        {
1566            #[inline(always)]
1567            fn phase(this: &Self) -> Phase {
1568                Phased::phase(&this.0)
1569            }
1570        }
1571
1572        impl<'a, T> Phased for WriteGuard<'a,T>
1573        $(where T: $static)?
1574        {
1575            #[inline(always)]
1576            fn phase(this: &Self) -> Phase {
1577                Phased::phase(&this.0)
1578            }
1579        }
1580
1581        impl<T, G> Phased for $tp<T, G>
1582        where
1583        $(T: $static ,)?
1584        G: $($static +)? Generator<T>
1585        {
1586            #[inline(always)]
1587            fn phase(this: &Self) -> Phase {
1588                Phased::phase(&this.__private)
1589            }
1590        }
1591
1592        impl<T, G> $tp<T, G>
1593        where
1594        $(T: $static ,)?
1595        G: $($static +)? Generator<T>,
1596        $(G:$trg, T:Send,)?
1597        $(T:$tr,)?
1598        {
1599            #[inline(always)]
1600            /// Returns the current phase and synchronize with the end
1601            /// of the transition to the returned phase.
1602            pub fn phase(&$($static)? self) -> Phase {
1603                Phased::phase(&self.__private)
1604            }
1605        }
1606    };
1607}
1608
1609impl_mut_lazy! {locked_lazy:extend_locked_lazy, LockedLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1610"A mutable locked lazy that initialize its content on the first lock"}
1611
1612impl_mut_lazy! {global lesser_locked_lazy, LesserLockedLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1613"The actual type of mutable statics attributed with [#[dynamic]](macro@crate::dynamic) \
1614\
1615The method [from_generator](Self::from_generator) is unsafe because this kind of static \
1616can only safely be used through this attribute macros."
1617}
1618
1619impl_mut_lazy! {primed_static primed_locked_lazy, PrimedLockedLazy,SyncSequentializer<G>,InitializedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1620"The actual type of mutable statics attributed with [#[dynamic(primed)]](macro@crate::dynamic)"}
1621
1622impl_mut_lazy! {global_primed_static primed_lesser_locked_lazy, PrimedLesserLockedLazy,SyncSequentializer<G>,InitializedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1623"The actual type of mutable statics attributed with [#[dynamic(primed)]](macro@crate::dynamic)"}
1624
1625impl_mut_lazy! {static locked_lazy_finalize,LockedLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedChecker,UnInited::<T>,SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard, T:Finaly,G:Sync,
1626"The actual type of mutable statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic)"
1627}
1628
1629impl_mut_lazy! {global lesser_locked_lazy_finalize,LesserLockedLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedCheckerLesser,UnInited::<T>,SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Finaly, G:Sync,
1630"The actual type of mutable statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
1631\
1632The method [from_generator](Self::from_generator) is unsafe because this kind of static \
1633can only safely be used through this attribute macros."
1634}
1635impl_mut_lazy! {static locked_lazy_droped,LockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,DropedUnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
1636"The actual type of statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic)"
1637}
1638
1639impl_mut_lazy! {global lesser_locked_lazy_droped,LesserLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedCheckerLesser,DropedUnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
1640"The actual type of mutable statics attributed with #[dynamic(drop)] \
1641\
1642The method (new)[Self::from_generator] is unsafe because this kind of static \
1643can only safely be used through this attribute macros."
1644}
1645
1646impl_mut_lazy! {primed_static primed_locked_lazy_droped,PrimedLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Uninit, G:Sync,
1647"The actual type of mutable statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic)"
1648}
1649
1650impl_mut_lazy! {global_primed_static global_primed_locked_lazy_droped,PrimedLesserLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Uninit, G:Sync,
1651"The actual type of mutable statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic)"
1652}
1653
1654//impl_mut_lazy! {const_static const_locked_lazy_droped, ConstLockedLazyDroped,ExitSequentializer<G>,InitializedSoftFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
1655//"The actual type of statics (non mutable) attributed with [#[dynamic(lazy,drop)]](macro@crate::dynamic)"
1656//}
1657
1658impl_mut_lazy! {unsync_locked_lazy:extend_unsync_locked_lazy,UnSyncLockedLazy,UnSyncSequentializer<G>,InitializedChecker,UnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
1659"A RefCell that initializes its content on the first access"
1660}
1661
1662#[cfg(feature = "thread_local")]
1663impl_mut_lazy! {primed_thread_local unsync_primed_locked_lazy,UnSyncPrimedLockedLazy,UnSyncSequentializer<G>,InitializedChecker,Primed::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
1664"The actual type of mutable thread_local statics attributed with [#[dynamic(primed)]](macro@crate::dynamic) \
1665\
1666The method [from_generator](Self::from_generator)  is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1667}
1668#[cfg(feature = "thread_local")]
1669impl_mut_lazy! {primed_thread_local unsync_primed_locked_lazy_droped,UnSyncPrimedLockedLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,Primed::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard, T:Uninit,
1670"The actual type of mutable thread_local statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic) \
1671\
1672The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1673}
1674
1675#[cfg(feature = "thread_local")]
1676impl_mut_lazy! {thread_local unsync_locked_lazy_finalize,UnSyncLockedLazyFinalize,ThreadExitSequentializer<G>,InitializedSoftFinalizedTLChecker,UnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,T:Finaly,
1677"The actual type of mutable thread_local statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
1678\
1679The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1680}
1681#[cfg(feature = "thread_local")]
1682impl_mut_lazy! {thread_local unsync_locked_lazy_droped,UnSyncLockedLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,DropedUnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
1683"The actual type of thread_local mutable statics attributed with [#[dynamic(drop)]](macro@crate::dynamic) \
1684\
1685The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1686}
1687
1688#[cfg(all(support_priority, not(feature = "test_no_global_lazy_hint")))]
1689mod inited {
1690
1691    use core::sync::atomic::{AtomicBool, Ordering};
1692
1693    static LAZY_INIT_ENSURED: AtomicBool = AtomicBool::new(false);
1694
1695    #[static_init_macro::constructor(__lazy_init_finished)]
1696    extern "C" fn mark_inited() {
1697        LAZY_INIT_ENSURED.store(true, Ordering::Release);
1698    }
1699
1700    #[inline(always)]
1701    pub(super) fn global_inited_hint() -> bool {
1702        LAZY_INIT_ENSURED.load(Ordering::Acquire)
1703    }
1704}
1705#[cfg(not(all(support_priority, not(feature = "test_no_global_lazy_hint"))))]
1706mod inited {
1707    #[inline(always)]
1708    pub(super) const fn global_inited_hint() -> bool {
1709        false
1710    }
1711}
1712
1713#[cfg(test)]
1714mod test_lazy {
1715    use super::Lazy;
1716    static _X: Lazy<u32, fn() -> u32> = Lazy::from_generator(|| 22);
1717
1718    #[test]
1719    fn test() {
1720        assert_eq!(*_X, 22);
1721    }
1722}
1723
1724#[cfg(feature = "test_no_global_lazy_hint")]
1725#[cfg(test)]
1726mod test_quasi_lazy {
1727    use super::LesserLazy;
1728    static _X: LesserLazy<u32, fn() -> u32> = unsafe { LesserLazy::from_generator(|| 22) };
1729    #[test]
1730    fn test() {
1731        assert_eq!(*_X, 22);
1732    }
1733}
1734#[cfg(all(test, feature = "thread_local"))]
1735mod test_local_lazy {
1736    use super::UnSyncLazy;
1737    #[thread_local]
1738    static _X: UnSyncLazy<u32, fn() -> u32> = UnSyncLazy::from_generator(|| 22);
1739    #[test]
1740    fn test() {
1741        assert_eq!(*_X, 22);
1742    }
1743}
1744#[cfg(test)]
1745mod test_lazy_finalize {
1746    use super::LazyFinalize;
1747    use crate::Finaly;
1748    #[derive(Debug)]
1749    struct A(u32);
1750    impl Finaly for A {
1751        fn finaly(&self) {}
1752    }
1753    static _X: LazyFinalize<A, fn() -> A> = unsafe { LazyFinalize::from_generator(|| A(22)) };
1754    #[test]
1755    fn test() {
1756        assert_eq!((*_X).0, 22);
1757    }
1758}
1759#[cfg(feature = "test_no_global_lazy_hint")]
1760#[cfg(test)]
1761mod test_quasi_lazy_finalize {
1762    use super::LesserLazyFinalize;
1763    use crate::Finaly;
1764    #[derive(Debug)]
1765    struct A(u32);
1766    impl Finaly for A {
1767        fn finaly(&self) {}
1768    }
1769    static _X: LesserLazyFinalize<A, fn() -> A> =
1770        unsafe { LesserLazyFinalize::from_generator(|| A(22)) };
1771    #[test]
1772    fn test() {
1773        assert_eq!((*_X).0, 22);
1774    }
1775}
1776#[cfg(all(test, feature = "thread_local"))]
1777mod test_local_lazy_finalize {
1778    use super::UnSyncLazyFinalize;
1779    use crate::Finaly;
1780    #[derive(Debug)]
1781    struct A(u32);
1782    impl Finaly for A {
1783        fn finaly(&self) {}
1784    }
1785    #[thread_local]
1786    static _X: UnSyncLazyFinalize<A, fn() -> A> =
1787        unsafe { UnSyncLazyFinalize::from_generator(|| A(22)) };
1788    #[test]
1789    fn test() {
1790        assert_eq!((*_X).0, 22);
1791    }
1792}
1793#[cfg(all(test, feature = "thread_local"))]
1794mod test_droped_local_lazy_finalize {
1795    use super::UnSyncLazyDroped;
1796    #[derive(Debug)]
1797    struct A(u32);
1798    #[thread_local]
1799    static _X: UnSyncLazyDroped<A> = unsafe { UnSyncLazyDroped::from_generator(|| A(22)) };
1800    #[test]
1801    fn test() {
1802        assert_eq!(_X.0, 22);
1803    }
1804}
1805
1806#[cfg(test)]
1807mod test_mut_lazy {
1808    use super::LockedLazy;
1809    static _X: LockedLazy<u32, fn() -> u32> = LockedLazy::from_generator(|| 22);
1810    #[test]
1811    fn test() {
1812        assert_eq!(*_X.read(), 22);
1813        *_X.write() = 33;
1814        assert_eq!(*_X.read(), 33);
1815    }
1816}
1817
1818#[cfg(test)]
1819mod test_primed_mut_lazy_droped {
1820    use super::PrimedLockedLazyDroped;
1821    use crate::Uninit;
1822    #[derive(Debug)]
1823    struct A(u32);
1824    impl Uninit for A {
1825        fn uninit(&mut self) {
1826            self.0 = 0
1827        }
1828    }
1829    static _X: PrimedLockedLazyDroped<A> = PrimedLockedLazyDroped::from_generator(A(42), || A(22));
1830    #[test]
1831    fn test() {
1832        assert_eq!(_X.primed_read_non_initializing().unwrap_err().0, 42);
1833        assert_eq!(_X.read().0, 22);
1834        _X.write().0 = 33;
1835        assert_eq!(_X.read().0, 33);
1836    }
1837}
1838
1839#[cfg(test)]
1840mod test_primed_mut_lazy {
1841    use super::PrimedLockedLazy;
1842    static _X: PrimedLockedLazy<u32> = PrimedLockedLazy::from_generator(42, || 22);
1843    #[test]
1844    fn test() {
1845        assert_eq!(*_X.primed_read_non_initializing().unwrap_err(), 42);
1846        assert_eq!(*_X.read(), 22);
1847        *_X.write() = 33;
1848        assert_eq!(*_X.read(), 33);
1849    }
1850}
1851
1852#[cfg(feature = "test_no_global_lazy_hint")]
1853#[cfg(test)]
1854mod test_quasi_mut_lazy {
1855    use super::LesserLockedLazy;
1856    static _X: LesserLockedLazy<u32, fn() -> u32> =
1857        unsafe { LesserLockedLazy::from_generator(|| 22) };
1858    #[test]
1859    fn test() {
1860        assert_eq!(*_X.read(), 22);
1861        *_X.write() = 33;
1862        assert_eq!(*_X.read(), 33);
1863    }
1864}
1865#[cfg(test)]
1866mod test_mut_lazy_finalize {
1867    use super::LockedLazyFinalize;
1868    use crate::Finaly;
1869    #[derive(Debug)]
1870    struct A(u32);
1871    impl Finaly for A {
1872        fn finaly(&self) {}
1873    }
1874    static _X: LockedLazyFinalize<A, fn() -> A> = LockedLazyFinalize::from_generator(|| A(22));
1875    #[test]
1876    fn test() {
1877        assert!((*_X.read()).0 == 22);
1878        *_X.write() = A(33);
1879        assert_eq!((*_X.read()).0, 33);
1880    }
1881}
1882#[cfg(feature = "test_no_global_lazy_hint")]
1883#[cfg(test)]
1884mod test_quasi_mut_lazy_finalize {
1885    use super::LesserLockedLazyFinalize;
1886    use crate::Finaly;
1887    #[derive(Debug)]
1888    struct A(u32);
1889    impl Finaly for A {
1890        fn finaly(&self) {}
1891    }
1892    static _X: LesserLockedLazyFinalize<A, fn() -> A> =
1893        unsafe { LesserLockedLazyFinalize::from_generator(|| A(22)) };
1894    #[test]
1895    fn test() {
1896        assert!((*_X.read()).0 == 22);
1897        *_X.write() = A(33);
1898        assert_eq!((*_X.read()).0, 33);
1899    }
1900}
1901#[cfg(test)]
1902mod test_mut_lazy_dropped {
1903    use super::LockedLazyDroped;
1904    static _X: LockedLazyDroped<u32, fn() -> u32> = LockedLazyDroped::from_generator(|| 22);
1905    #[test]
1906    fn test() {
1907        assert_eq!(*_X.read(), 22);
1908        *_X.write() = 33;
1909        assert_eq!(*_X.read(), 33);
1910    }
1911}
1912#[cfg(feature = "test_no_global_lazy_hint")]
1913#[cfg(test)]
1914mod test_quasi_mut_lazy_dropped {
1915    use super::LesserLockedLazyDroped;
1916    static _X: LesserLockedLazyDroped<u32, fn() -> u32> =
1917        unsafe { LesserLockedLazyDroped::from_generator(|| 22) };
1918    #[test]
1919    fn test() {
1920        assert_eq!(*_X.read(), 22);
1921        *_X.write() = 33;
1922        assert_eq!(*_X.read(), 33);
1923    }
1924}
1925#[cfg(test)]
1926#[cfg(feature = "thread_local")]
1927mod test_unsync_mut_lazy {
1928    use super::UnSyncLockedLazy;
1929    #[thread_local]
1930    static _X: UnSyncLockedLazy<u32, fn() -> u32> = UnSyncLockedLazy::from_generator(|| 22);
1931    #[test]
1932    fn test() {
1933        assert_eq!(*_X.read(), 22);
1934        *_X.write() = 33;
1935        assert_eq!(*_X.read(), 33);
1936    }
1937}
1938
1939#[cfg(test)]
1940#[cfg(feature = "thread_local")]
1941mod test_unsync_mut_primed_lazy {
1942    use super::UnSyncPrimedLockedLazy;
1943    #[thread_local]
1944    static _X: UnSyncPrimedLockedLazy<u32> =
1945        unsafe { UnSyncPrimedLockedLazy::from_generator(42, || 22) };
1946    #[test]
1947    fn test() {
1948        assert_eq!(*_X.primed_read_non_initializing().unwrap_err(), 42);
1949        assert_eq!(*_X.read(), 22);
1950        *_X.write() = 33;
1951        assert_eq!(*_X.read(), 33);
1952    }
1953}
1954#[cfg(test)]
1955#[cfg(feature = "thread_local")]
1956mod test_unsync_mut_primed_lazy_droped {
1957    use super::UnSyncPrimedLockedLazyDroped;
1958    use crate::Uninit;
1959    #[derive(Debug)]
1960    struct A(u32);
1961    impl Uninit for A {
1962        fn uninit(&mut self) {
1963            self.0 = 0
1964        }
1965    }
1966    #[thread_local]
1967    static _X: UnSyncPrimedLockedLazyDroped<A> =
1968        unsafe { UnSyncPrimedLockedLazyDroped::from_generator(A(42), || A(22)) };
1969    #[test]
1970    fn test() {
1971        assert_eq!(_X.primed_read_non_initializing().unwrap_err().0, 42);
1972        assert_eq!(_X.read().0, 22);
1973        _X.write().0 = 33;
1974        assert_eq!(_X.read().0, 33);
1975    }
1976}
1977
1978#[cfg(test)]
1979#[cfg(feature = "thread_local")]
1980mod test_unsync_mut_lazy_finalize {
1981    use super::UnSyncLockedLazyFinalize;
1982    use crate::Finaly;
1983    #[derive(Debug)]
1984    struct A(u32);
1985    impl Finaly for A {
1986        fn finaly(&self) {}
1987    }
1988    #[thread_local]
1989    static _X: UnSyncLockedLazyFinalize<A, fn() -> A> =
1990        unsafe { UnSyncLockedLazyFinalize::from_generator(|| A(22)) };
1991    #[test]
1992    fn test() {
1993        assert!((*_X.read()).0 == 22);
1994        *_X.write() = A(33);
1995        assert_eq!((*_X.read()).0, 33);
1996    }
1997}
1998#[cfg(test)]
1999#[cfg(feature = "thread_local")]
2000mod test_unsync_mut_lazy_droped {
2001    use super::UnSyncLockedLazyDroped;
2002    #[thread_local]
2003    static _X: UnSyncLockedLazyDroped<u32, fn() -> u32> =
2004        unsafe { UnSyncLockedLazyDroped::from_generator(|| 22) };
2005    #[test]
2006    fn test() {
2007        assert_eq!(*_X.read(), 22);
2008        *_X.write() = 33;
2009        assert_eq!(*_X.read(), 33);
2010    }
2011}
2012
2013#[inline(always)]
2014/// # Safety
2015/// v must refer to a static
2016unsafe fn as_static<T>(v: &T) -> &'static T {
2017    &*(v as *const _)
2018}