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
120type InitializedSoftFinalizedCheckerLesser<T> = InitializedSoftFinalizedCheckerGeneric<T, true>;
122
123type InitializedHardFinalizedCheckerLesser<T> = InitializedHardFinalizedCheckerGeneric<T, true>;
124
125#[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
138pub trait LazyAccess: Sized {
140 type Target;
141 fn get(this: Self) -> Self::Target;
149 fn try_get(this: Self) -> Result<Self::Target, AccessError>;
151 fn phase(this: Self) -> Phase;
153 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 pub fn get(this: &Self) -> &T {
189 this.__private.init_then_get()
190 }
191 #[inline(always)]
192 pub fn try_get(this: &Self) -> Result<&'_ T,AccessError> {
194 this.__private.try_get()
195 }
196 #[inline(always)]
197 pub fn get_mut(this: &mut Self) -> &mut T {
202 this.__private.only_init_then_get_mut()
203 }
204 #[inline(always)]
205 pub fn try_get_mut(this: &mut Self) -> Result<&'_ mut T,AccessError> {
210 this.__private.try_get_mut()
211 }
212 #[inline(always)]
213 pub fn phase(this: & Self) -> Phase {
215 Phased::phase(&this.__private)
216 }
217 #[inline(always)]
218 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 pub fn get(this: &'static Self) -> &'static T {
290 this.__private.init_then_get()
292 }
293 #[inline(always)]
294 pub fn try_get(this: &'static Self) -> Result<&'static T,AccessError> {
296 this.__private.try_get()
298 }
299 #[inline(always)]
300 pub fn phase(this: &'static Self) -> Phase {
302 Phased::phase(&this.__private)
303 }
304 #[inline(always)]
305 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 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 pub fn try_get(this: &'static Self) -> Result<&'static T, AccessError> {
362 if inited::global_inited_hint() {
363 Ok(unsafe{this.__private.get_unchecked()})
371 } else {
372 this.__private.try_get()
373 }
374 }
375 #[inline(always)]
376 pub fn get(this: &'static Self) -> &'static T {
384 if inited::global_inited_hint() {
385 unsafe{this.__private.get_unchecked()}
392 } else {
393 this.__private.init_then_get()
394 }
395 }
396 #[inline(always)]
397 pub fn phase(this: &'static Self) -> Phase {
399 Phased::phase(&this.__private)
400 }
401 #[inline(always)]
402 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 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 G: 'static + Generator<T>,
457 T:'static,
458 $(G:$trg, T:Sync,)?
459 $(T:$tr,)?
460 {
461 #[inline(always)]
462 pub fn get(this: &Self) -> &T {
470 unsafe {as_static(&this.__private).init_then_get()}
472 }
473 #[inline(always)]
474 pub fn try_get(this: &Self) -> Result<&T,AccessError> {
476 unsafe{as_static(&this.__private).try_get()}
478 }
479 #[inline(always)]
480 pub fn phase(this: &Self) -> Phase {
482 Phased::phase(unsafe{as_static(&this.__private)})
483 }
484 #[inline(always)]
485 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 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 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 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 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 pub fn get_mut(&mut self) -> &mut T {
725 self.__private.only_init_then_get_mut()
726 }
727 #[inline(always)]
728 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 pub fn get_mut(&mut self) -> &mut T {
760 self.__private.only_init_then_get_mut()
761 }
762 #[inline(always)]
763 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 G:$($static +)? Generator<T>,
875 $(T: $static,)?
876 $(G:$trg, T:Send,)?
877 $(T:$tr,)?
878 {
879 #[inline(always)]
880 #[allow(elided_named_lifetimes)]
886 pub fn read(&$($static)? self) -> ReadGuard<'_,T> {
887 ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
888 }
889 #[inline(always)]
890 #[allow(elided_named_lifetimes)]
897 pub fn fast_read(&$($static)? self) -> Option<ReadGuard<'_,T>> {
898 GenericLockedLazy::fast_init_then_read_lock(&self.__private).map(ReadGuard)
899 }
900 #[inline(always)]
901 #[allow(elided_named_lifetimes)]
903 pub fn try_read(&$($static)? self) -> Result<ReadGuard<'_,T>,AccessError> {
904 GenericLockedLazy::try_read_lock(&self.__private).map(ReadGuard)
905 }
906 #[inline(always)]
907 #[allow(elided_named_lifetimes)]
910 pub fn fast_try_read(&$($static)? self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
911 GenericLockedLazy::fast_try_read_lock(&self.__private).map(|r| r.map(ReadGuard))
912 }
913 #[inline(always)]
914 #[allow(elided_named_lifetimes)]
920 pub fn write(&$($static)? self) -> WriteGuard<'_,T> {
921 WriteGuard(GenericLockedLazy::init_then_write_lock(&self.__private))
922 }
923 #[inline(always)]
924 #[allow(elided_named_lifetimes)]
931 pub fn fast_write(&$($static)? self) -> Option<WriteGuard<'_,T>> {
932 GenericLockedLazy::fast_init_then_write_lock(&self.__private).map(WriteGuard)
933 }
934 #[inline(always)]
935 #[allow(elided_named_lifetimes)]
937 pub fn try_write(&$($static)? self) -> Result<WriteGuard<'_,T>,AccessError> {
938 GenericLockedLazy::try_write_lock(&self.__private).map(WriteGuard)
939 }
940 #[inline(always)]
941 #[allow(elided_named_lifetimes)]
943 pub fn fast_try_write(&$($static)? self) -> Option<Result<WriteGuard<'_,T>,AccessError>> {
944 GenericLockedLazy::fast_try_write_lock(&self.__private).map(|r| r.map(WriteGuard))
945 }
946 #[inline(always)]
947 pub fn init(&$($static)? self) {
949 let _ = GenericLockedLazy::init_then_write_lock(&self.__private);
950 }
951 }
952
953 };
954 (@const_lock $tp:ident, $checker: ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)? $(,$static:lifetime)?) => {
955 impl<T, G> $tp<T, G>
956 where G: $($static +)? Generator<T>,
957 T:Uninit,
958 $(T:$static ,)?
959 $(G:$trg, T:Send,)?
960 $(T:$tr,)?
961 {
962 #[inline(always)]
963 pub fn read(&'static self) -> ReadGuard<'_,T> {
969 let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
970 assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
971 ReadGuard(l)
972 }
973 #[inline(always)]
980 pub fn fast_read(&'static self) -> Option<ReadGuard<'_,T>> {
981 let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
982 if let Some(l) = &l {
983 assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
984 }
985 l.map(ReadGuard)
986 }
987 #[inline(always)]
988 pub fn primed_read(&'static self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
991 let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
992 let p = Phased::phase(&l);
993 if <$checker::<G>>::initialized_is_accessible(p) {
994 Ok(ReadGuard(l))
995 } else {
996 Err(ReadGuard(l))
997 }
998 }
999 }
1000
1001 };
1002 (@lock_thread_local $tp:ident, $data:ty,$gdw:ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1003
1004 use super::as_static;
1005
1006 impl<T, G> $tp<T, G>
1007 where G: 'static + Generator<T>,
1009 T: 'static,
1010 $(G:$trg, T:Send,)?
1011 $(T:$tr,)?
1012 {
1013 #[inline(always)]
1014 pub fn read(&self) -> ReadGuard<'_,T> {
1021 ReadGuard(GenericLockedLazy::init_then_read_lock(unsafe{as_static(&self.__private)}))
1022 }
1023 #[inline(always)]
1024 pub fn fast_read(&self) -> Option<ReadGuard<'_,T>> {
1032 GenericLockedLazy::fast_init_then_read_lock(unsafe{as_static(&self.__private)}).map(ReadGuard)
1033 }
1034 #[inline(always)]
1035 pub fn try_read(&self) -> Result<ReadGuard<'_,T>,AccessError> {
1037 GenericLockedLazy::try_read_lock(unsafe{as_static(&self.__private)}).map(ReadGuard)
1038 }
1039 #[inline(always)]
1040 pub fn fast_try_read(&self) -> Option<Result<ReadGuard<'_,T>,AccessError>> {
1043 GenericLockedLazy::fast_try_read_lock(unsafe{as_static(&self.__private)}).map(|r| r.map(ReadGuard))
1044 }
1045 #[inline(always)]
1046 pub fn write(&self) -> WriteGuard<'_,T> {
1053 WriteGuard(GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)}))
1054 }
1055 #[inline(always)]
1056 pub fn fast_write(&self) -> Option<WriteGuard<'_,T>> {
1064 GenericLockedLazy::fast_init_then_write_lock(unsafe{as_static(&self.__private)}).map(WriteGuard)
1065 }
1066 #[inline(always)]
1067 pub fn try_write(&self) -> Result<WriteGuard<'_,T>,AccessError> {
1069 GenericLockedLazy::try_write_lock(unsafe{as_static(&self.__private)}).map(WriteGuard)
1070 }
1071 #[inline(always)]
1072 pub fn fast_try_write(&self) ->
1075 Option<Result<WriteGuard<'_,T>,AccessError>> {
1076 GenericLockedLazy::fast_try_write_lock(unsafe{as_static(&self.__private)}).map(|r| r.map(WriteGuard))
1077 }
1078 #[inline(always)]
1079 pub fn init(&self) -> Phase {
1081 let l = GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)});
1082 Phased::phase(&l)
1083 }
1084 }
1085
1086 };
1087 (@lock_global $tp:ident, $checker:ident, $data:ty,$gdw:ident,$gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1088
1089 use super::inited;
1090
1091 impl<T, G> $tp<T, G>
1092 where G: 'static + Generator<T>,
1094 T: 'static,
1095 $(G:$trg, T:Send,)?
1096 $(T:$tr,)?
1097 {
1098 #[inline(always)]
1099 pub fn read(&'static self) -> ReadGuard<'static,T> {
1105 if inited::global_inited_hint() {
1106 let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
1107 assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
1108 ReadGuard(l)
1109 } else {
1110 ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
1111 }
1112 }
1113 #[inline(always)]
1120 pub fn fast_read(&'static self) -> Option<ReadGuard<'static,T>> {
1121 if inited::global_inited_hint() {
1122 let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
1123 if let Some(l) = &l {
1124 assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
1125 }
1126 l
1127 } else {
1128 GenericLockedLazy::fast_init_then_read_lock(&self.__private)
1129 }.map(ReadGuard)
1130 }
1131 #[inline(always)]
1132 pub fn try_read(&'static self) -> Result<ReadGuard<'static,T>,AccessError> {
1134 if inited::global_inited_hint() {
1135 let l = unsafe{GenericLockedLazy::read_lock_unchecked(&self.__private)};
1136 let p = Phased::phase(&l);
1137 if <$checker::<G>>::initialized_is_accessible(p) {
1138 Ok(l)
1139 } else {
1140 Err(AccessError{phase:p})
1141 }
1142 } else {
1143 GenericLockedLazy::try_read_lock(&self.__private)
1144 }.map(ReadGuard)
1145 }
1146 #[inline(always)]
1149 pub fn fast_try_read(&'static self) -> Option<Result<ReadGuard<'static,T>,AccessError>> {
1150 if inited::global_inited_hint() {
1151 let l = unsafe{GenericLockedLazy::fast_read_lock_unchecked(&self.__private)};
1152 l.map(|l| {
1153 let p = Phased::phase(&l);
1154 if <$checker::<G>>::initialized_is_accessible(p) {
1155 Ok(l)
1156 } else {
1157 Err(AccessError{phase:p})
1158 }
1159 })
1160 } else {
1161 GenericLockedLazy::fast_try_read_lock(&self.__private)
1162 }.map(|r| r.map(ReadGuard))
1163 }
1164 #[inline(always)]
1171 pub fn write(&'static self) -> WriteGuard<'static,T> {
1172 WriteGuard(if inited::global_inited_hint() {
1173 let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1174 assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(&l)));
1175 l
1176 } else {
1177 GenericLockedLazy::init_then_write_lock(&self.__private)
1178 })
1179 }
1180 #[inline(always)]
1188 pub fn fast_write(&'static self) -> Option<WriteGuard<'static,T>> {
1189 if inited::global_inited_hint() {
1190 let l = unsafe{GenericLockedLazy::fast_write_lock_unchecked(&self.__private)};
1191 if let Some(l) = &l {
1192 assert!(<$checker::<G>>::initialized_is_accessible(Phased::phase(l)));
1193 }
1194 l
1195 } else {
1196 GenericLockedLazy::fast_init_then_write_lock(&self.__private)
1197 }.map(WriteGuard)
1198 }
1199 #[inline(always)]
1201 pub fn try_write(&'static self) -> Result<WriteGuard<'static,T>,AccessError> {
1202 if inited::global_inited_hint() {
1203 let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1204 let p = Phased::phase(&l);
1205 if <$checker::<G>>::initialized_is_accessible(p) {
1206 Ok(l)
1207 } else {
1208 Err(AccessError{phase:p})
1209 }
1210 } else {
1211 GenericLockedLazy::try_write_lock(&self.__private)
1212 }.map(WriteGuard)
1213 }
1214 #[inline(always)]
1217 pub fn fast_try_write(&'static self) -> Option<Result<WriteGuard<'static,T>,AccessError>> {
1218 if inited::global_inited_hint() {
1219 let l = unsafe{GenericLockedLazy::fast_write_lock_unchecked(&self.__private)};
1220 l.map(|l| {
1221 let p = Phased::phase(&l);
1222 if <$checker::<G>>::initialized_is_accessible(p) {
1223 Ok(l)
1224 } else {
1225 Err(AccessError{phase:p})
1226 }
1227 })
1228 } else {
1229 GenericLockedLazy::fast_try_write_lock(&self.__private)
1230 }.map(|r| r.map(WriteGuard))
1231 }
1232 #[inline(always)]
1234 pub fn init(&'static self) -> Phase {
1235 let l = GenericLockedLazy::init_then_write_lock(&self.__private);
1236 Phased::phase(&l)
1237 }
1238 }
1239
1240 };
1241 (@prime_static $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1242 impl<T, G> $tp<T, G>
1243 where G: 'static + Generator<T>,
1245 T: 'static,
1246 $(G:$trg, T:Send,)?
1247 $(T:$tr,)?
1248 {
1249 #[inline(always)]
1250 pub fn primed_read_non_initializing(&'static self) ->
1253 Result<ReadGuard<'static,T>,ReadGuard<'static,T>> {
1254 let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
1255 let p = Phased::phase(&l);
1256 if <$checker::<G>>::is_accessible(p) {
1257 Ok(ReadGuard(l))
1258 } else {
1259 Err(ReadGuard(l))
1260 }
1261 }
1262 #[inline(always)]
1263 pub fn primed_read(&'static self) -> Result<ReadGuard<'static,T>,ReadGuard<'static,T>> {
1266 let l = unsafe {GenericLockedLazy::init_then_read_lock_unchecked(&self.__private)};
1267 let p = Phased::phase(&l);
1268 if <$checker::<G>>::is_accessible(p) {
1269 Ok(ReadGuard(l))
1270 } else {
1271 Err(ReadGuard(l))
1272 }
1273 }
1274 #[inline(always)]
1275 pub fn primed_write_non_initializing(&'static self) -> Result<WriteGuard<'static,T>,ReadGuard<'static,T>> {
1278 let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1279 let p = Phased::phase(&l);
1280 if <$checker::<G>>::is_accessible(p) {
1281 Ok(WriteGuard(l))
1282 } else {
1283 Err(ReadGuard(l.into()))
1284 }
1285 }
1286 #[inline(always)]
1287 pub fn primed_write(&'static self) -> Result<WriteGuard<'static,T>,ReadGuard<'static,T>> {
1291 let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(&self.__private)};
1292 let p = Phased::phase(&l);
1293 if <$checker::<G>>::is_accessible(p) {
1294 Ok(WriteGuard(l))
1295 } else {
1296 Err(ReadGuard(l.into()))
1297 }
1298 }
1299 }
1300 };
1301 (@prime_global $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1302 impl<T, G> $tp<T, G>
1303 where G: 'static + Generator<T>,
1305 T: 'static,
1306 $(G:$trg, T:Send,)?
1307 $(T:$tr,)?
1308 {
1309 #[inline(always)]
1310 pub fn primed_read_non_initializing(&'static self) ->
1313 Result<ReadGuard<'static,T>,ReadGuard<'static,T>> {
1314 let l = unsafe {GenericLockedLazy::read_lock_unchecked(&self.__private)};
1315 let p = Phased::phase(&l);
1316 if inited::global_inited_hint() {
1317 if <$checker::<G>>::initialized_is_accessible(p) {
1318 Ok(ReadGuard(l))
1319 } else {
1320 Err(ReadGuard(l))
1321 }
1322 } else {
1323 if <$checker::<G>>::is_accessible(p) {
1324 Ok(ReadGuard(l))
1325 } else {
1326 Err(ReadGuard(l))
1327 }
1328 }
1329 }
1330 #[inline(always)]
1331 pub fn primed_read(&'static self) -> Result<ReadGuard<'static,T>,ReadGuard<'static,T>> {
1334 let l = unsafe {GenericLockedLazy::init_then_read_lock_unchecked(&self.__private)};
1335 let p = Phased::phase(&l);
1336 if inited::global_inited_hint() {
1337 if <$checker::<G>>::initialized_is_accessible(p) {
1338 Ok(ReadGuard(l))
1339 } else {
1340 Err(ReadGuard(l))
1341 }
1342 } else {
1343 if <$checker::<G>>::is_accessible(p) {
1344 Ok(ReadGuard(l))
1345 } else {
1346 Err(ReadGuard(l))
1347 }
1348 }
1349 }
1350 #[inline(always)]
1351 pub fn primed_write_non_initializing(&'static self) -> Result<WriteGuard<'static,T>,ReadGuard<'static,T>> {
1354 let l = unsafe{GenericLockedLazy::write_lock_unchecked(&self.__private)};
1355 let p = Phased::phase(&l);
1356 if inited::global_inited_hint() {
1357 if <$checker::<G>>::initialized_is_accessible(p) {
1358 Ok(WriteGuard(l))
1359 } else {
1360 Err(ReadGuard(l.into()))
1361 }
1362 } else {
1363 if <$checker::<G>>::is_accessible(p) {
1364 Ok(WriteGuard(l))
1365 } else {
1366 Err(ReadGuard(l.into()))
1367 }
1368 }
1369 }
1370 #[inline(always)]
1371 pub fn primed_write(&'static self) -> Result<WriteGuard<'static,T>,ReadGuard<'static,T>> {
1375 let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(&self.__private)};
1376 let p = Phased::phase(&l);
1377 if inited::global_inited_hint() {
1378 if <$checker::<G>>::initialized_is_accessible(p) {
1379 Ok(WriteGuard(l))
1380 } else {
1381 Err(ReadGuard(l.into()))
1382 }
1383 } else {
1384 if <$checker::<G>>::is_accessible(p) {
1385 Ok(WriteGuard(l))
1386 } else {
1387 Err(ReadGuard(l.into()))
1388 }
1389 }
1390 }
1391 }
1392 };
1393 (@prime_thread_local $tp:ident,$checker:ident, $data:ty, $gdw: ident, $gd:ident$(,T: $tr: ident)?$(,G: $trg:ident)?) => {
1394 impl<T, G> $tp<T, G>
1395 where G: 'static + Generator<T>,
1397 T:'static,
1398 $(G:$trg, T:Send,)?
1399 $(T:$tr,)?
1400 {
1401 #[inline(always)]
1402 pub fn primed_read_non_initializing(&self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1405 let l = unsafe{GenericLockedLazy::read_lock_unchecked(as_static(&self.__private))};
1406 let p = Phased::phase(&l);
1407 if <$checker::<G>>::is_accessible(p) {
1408 Ok(ReadGuard(l))
1409 } else {
1410 Err(ReadGuard(l))
1411 }
1412 }
1413 #[inline(always)]
1414 pub fn primed_read(&self) -> Result<ReadGuard<'_,T>,ReadGuard<'_,T>> {
1417 let l = unsafe{GenericLockedLazy::init_then_read_lock_unchecked(as_static(&self.__private))};
1418 let p = Phased::phase(&l);
1419 if <$checker::<G>>::is_accessible(p) {
1420 Ok(ReadGuard(l))
1421 } else {
1422 Err(ReadGuard(l))
1423 }
1424 }
1425 #[inline(always)]
1426 pub fn primed_write_non_initializing(&self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1429 let l = unsafe{GenericLockedLazy::write_lock_unchecked(as_static(&self.__private))};
1430 let p = Phased::phase(&l);
1431 if <$checker::<G>>::is_accessible(p) {
1432 Ok(WriteGuard(l))
1433 } else {
1434 Err(ReadGuard(l.into()))
1435 }
1436 }
1437 #[inline(always)]
1438 pub fn primed_write(&self) -> Result<WriteGuard<'_,T>,ReadGuard<'_,T>> {
1441 let l = unsafe{GenericLockedLazy::init_then_write_lock_unchecked(as_static(&self.__private))};
1442 let p = Phased::phase(&l);
1443 if <$checker::<G>>::is_accessible(p) {
1444 Ok(WriteGuard(l))
1445 } else {
1446 Err(ReadGuard(l.into()))
1447 }
1448 }
1449 }
1450 };
1451 (@uninited $tp:ident, $man:ident$(<$x:ident>)?, $data:ty, $locker: ty$(,$safe:ident)?) => {
1452 impl<T, G> $tp<T, G> {
1453 #[inline(always)]
1454 pub const $($safe)? fn from_generator(f: G) -> Self {
1461 #[allow(unused_unsafe)]
1462 Self {
1463
1464 __private: unsafe{GenericLockedLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::INIT)},
1465 }
1466 }
1467 #[inline(always)]
1468 pub const $($safe)? fn from_generator_with_info(f: G, info: StaticInfo) -> Self {
1475 #[allow(unused_unsafe)]
1476 Self {
1477 __private: unsafe{GenericLockedLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::INIT,info)},
1478 }
1479 }
1480 }
1481 };
1482 (@prime $tp:ident, $man:ident$(<$x:ident>)?, $data:ty, $locker: ty $(,$safe:ident)?) => {
1483 impl<T, G> $tp<T, G> {
1484 #[inline(always)]
1485 pub const $($safe)? fn from_generator(v: T, f: G) -> Self {
1492 #[allow(unused_unsafe)]
1493 Self {
1494
1495 __private: unsafe{GenericLockedLazy::new(f, $man::new(<$locker>::new(Phase::empty())),<$data>::prime(v))},
1496 }
1497 }
1498 #[inline(always)]
1499 pub const $($safe)? fn from_generator_with_info(v: T, f: G, info: StaticInfo) -> Self {
1506 #[allow(unused_unsafe)]
1507 Self {
1508 __private: unsafe{GenericLockedLazy::new_with_info(f, $man::new(<$locker>::new(Phase::empty())), <$data>::prime(v),info)},
1509 }
1510 }
1511 }
1512 };
1513 (@proc $tp:ident, $man:ident$(<$x:ident>)?, $checker:ident, $data:ty, $locker: ty, $gdw: ident, $gd:ident $(,T: $tr: ident)?$(,G: $trg:ident)?
1514 ,$doc:literal $(cfg($attr:meta))? $(,$safe:ident)? $(,$static:lifetime)?) => {
1515 #[doc=$doc]
1516 $(#[cfg_attr(docsrs,doc(cfg($attr)))])?
1517 pub struct $tp<T, G = fn() -> T> {
1518 __private: GenericLockedLazy<$data, G, $man$(<$x>)?, $checker::<G>>,
1519 }
1520
1521 #[must_use="If unused the write lock is immediatly released"]
1522 #[derive(Debug)]
1523 pub struct WriteGuard<'a,T>(generic_lazy::WriteGuard<$gdw::<'a,$data>>);
1524
1525 #[must_use="If unused the write lock is immediatly released"]
1526 #[derive(Debug)]
1527 pub struct ReadGuard<'a,T>(generic_lazy::ReadGuard<$gd::<'a,$data>>);
1528
1529 impl<'a,T> Clone for ReadGuard<'a,T> {
1530 #[inline(always)]
1531 fn clone(&self) -> Self {
1532 Self(self.0.clone())
1533 }
1534 }
1535 impl<'a,T> From<WriteGuard<'a,T>> for ReadGuard<'a,T> {
1536 #[inline(always)]
1537 fn from(that:WriteGuard<'a,T>) -> Self {
1538 Self(that.0.into())
1539 }
1540 }
1541
1542 use core::ops::{Deref,DerefMut};
1543
1544 impl<'a,T> Deref for WriteGuard<'a,T>
1545 $(where T: $static)?
1546 {
1547 type Target = T;
1548 #[inline(always)]
1549 fn deref(&self) -> &T {
1550 &*self.0
1551 }
1552 }
1553 impl<'a,T> DerefMut for WriteGuard<'a,T>
1554 $(where T: $static)?
1555 {
1556 #[inline(always)]
1557 fn deref_mut(&mut self) -> &mut T {
1558 &mut *self.0
1559 }
1560 }
1561 impl<'a,T> Deref for ReadGuard<'a,T>
1562 $(where T: $static)?
1563 {
1564 type Target = T;
1565 #[inline(always)]
1566 fn deref(&self) -> &T {
1567 &*self.0
1568 }
1569 }
1570
1571 impl<'a, T> Phased for ReadGuard<'a,T>
1572 $(where T: $static)?
1573 {
1574 #[inline(always)]
1575 fn phase(this: &Self) -> Phase {
1576 Phased::phase(&this.0)
1577 }
1578 }
1579
1580 impl<'a, T> Phased for WriteGuard<'a,T>
1581 $(where T: $static)?
1582 {
1583 #[inline(always)]
1584 fn phase(this: &Self) -> Phase {
1585 Phased::phase(&this.0)
1586 }
1587 }
1588
1589 impl<T, G> Phased for $tp<T, G>
1590 where
1591 $(T: $static ,)?
1592 G: $($static +)? Generator<T>
1593 {
1594 #[inline(always)]
1595 fn phase(this: &Self) -> Phase {
1596 Phased::phase(&this.__private)
1597 }
1598 }
1599
1600 impl<T, G> $tp<T, G>
1601 where
1602 $(T: $static ,)?
1603 G: $($static +)? Generator<T>,
1604 $(G:$trg, T:Send,)?
1605 $(T:$tr,)?
1606 {
1607 #[inline(always)]
1608 pub fn phase(&$($static)? self) -> Phase {
1611 Phased::phase(&self.__private)
1612 }
1613 }
1614 };
1615}
1616
1617impl_mut_lazy! {locked_lazy:extend_locked_lazy, LockedLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1618"A mutable locked lazy that initialize its content on the first lock"}
1619
1620impl_mut_lazy! {global lesser_locked_lazy, LesserLockedLazy,SyncSequentializer<G>,InitializedChecker,UnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1621"The actual type of mutable statics attributed with [#[dynamic]](macro@crate::dynamic) \
1622\
1623The method [from_generator](Self::from_generator) is unsafe because this kind of static \
1624can only safely be used through this attribute macros."
1625}
1626
1627impl_mut_lazy! {primed_static primed_locked_lazy, PrimedLockedLazy,SyncSequentializer<G>,InitializedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1628"The actual type of mutable statics attributed with [#[dynamic(primed)]](macro@crate::dynamic)"}
1629
1630impl_mut_lazy! {global_primed_static primed_lesser_locked_lazy, PrimedLesserLockedLazy,SyncSequentializer<G>,InitializedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,
1631"The actual type of mutable statics attributed with [#[dynamic(primed)]](macro@crate::dynamic)"}
1632
1633impl_mut_lazy! {static locked_lazy_finalize,LockedLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedChecker,UnInited::<T>,SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard, T:Finaly,G:Sync,
1634"The actual type of mutable statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic)"
1635}
1636
1637impl_mut_lazy! {global lesser_locked_lazy_finalize,LesserLockedLazyFinalize,ExitSequentializer<G>,InitializedSoftFinalizedCheckerLesser,UnInited::<T>,SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Finaly, G:Sync,
1638"The actual type of mutable statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
1639\
1640The method [from_generator](Self::from_generator) is unsafe because this kind of static \
1641can only safely be used through this attribute macros."
1642}
1643impl_mut_lazy! {static locked_lazy_droped,LockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,DropedUnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
1644"The actual type of statics attributed with [#[dynamic(lazy,finalize)]](macro@crate::dynamic)"
1645}
1646
1647impl_mut_lazy! {global lesser_locked_lazy_droped,LesserLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedCheckerLesser,DropedUnInited::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,G:Sync,
1648"The actual type of mutable statics attributed with #[dynamic(drop)] \
1649\
1650The method (new)[Self::from_generator] is unsafe because this kind of static \
1651can only safely be used through this attribute macros."
1652}
1653
1654impl_mut_lazy! {primed_static primed_locked_lazy_droped,PrimedLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Uninit, G:Sync,
1655"The actual type of mutable statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic)"
1656}
1657
1658impl_mut_lazy! {global_primed_static global_primed_locked_lazy_droped,PrimedLesserLockedLazyDroped,ExitSequentializer<G>,InitializedHardFinalizedChecker,Primed::<T>, SyncPhaseLocker, SyncPhaseGuard, SyncReadPhaseGuard,T:Uninit, G:Sync,
1659"The actual type of mutable statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic)"
1660}
1661
1662impl_mut_lazy! {unsync_locked_lazy:extend_unsync_locked_lazy,UnSyncLockedLazy,UnSyncSequentializer<G>,InitializedChecker,UnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
1667"A RefCell that initializes its content on the first access"
1668}
1669
1670#[cfg(feature = "thread_local")]
1671impl_mut_lazy! {primed_thread_local unsync_primed_locked_lazy,UnSyncPrimedLockedLazy,UnSyncSequentializer<G>,InitializedChecker,Primed::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
1672"The actual type of mutable thread_local statics attributed with [#[dynamic(primed)]](macro@crate::dynamic) \
1673\
1674The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1675}
1676#[cfg(feature = "thread_local")]
1677impl_mut_lazy! {primed_thread_local unsync_primed_locked_lazy_droped,UnSyncPrimedLockedLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,Primed::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard, T:Uninit,
1678"The actual type of mutable thread_local statics attributed with [#[dynamic(primed,drop)]](macro@crate::dynamic) \
1679\
1680The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1681}
1682
1683#[cfg(feature = "thread_local")]
1684impl_mut_lazy! {thread_local unsync_locked_lazy_finalize,UnSyncLockedLazyFinalize,ThreadExitSequentializer<G>,InitializedSoftFinalizedTLChecker,UnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,T:Finaly,
1685"The actual type of mutable thread_local statics attributed with [#[dynamic(finalize)]](macro@crate::dynamic) \
1686\
1687The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1688}
1689#[cfg(feature = "thread_local")]
1690impl_mut_lazy! {thread_local unsync_locked_lazy_droped,UnSyncLockedLazyDroped,ThreadExitSequentializer<G>,InitializedHardFinalizedTLChecker,DropedUnInited::<T>,UnSyncPhaseLocker, UnSyncPhaseGuard,UnSyncReadPhaseGuard,
1691"The actual type of thread_local mutable statics attributed with [#[dynamic(drop)]](macro@crate::dynamic) \
1692\
1693The method [from_generator](Self::from_generator) is unsafe as the object must be a non mutable thread_local static." cfg(feature="thread_local")
1694}
1695
1696#[cfg(all(support_priority, not(feature = "test_no_global_lazy_hint")))]
1697mod inited {
1698
1699 use core::sync::atomic::{AtomicBool, Ordering};
1700
1701 static LAZY_INIT_ENSURED: AtomicBool = AtomicBool::new(false);
1702
1703 #[static_init_macro::constructor(__lazy_init_finished)]
1704 extern "C" fn mark_inited() {
1705 LAZY_INIT_ENSURED.store(true, Ordering::Release);
1706 }
1707
1708 #[inline(always)]
1709 pub(super) fn global_inited_hint() -> bool {
1710 LAZY_INIT_ENSURED.load(Ordering::Acquire)
1711 }
1712}
1713#[cfg(not(all(support_priority, not(feature = "test_no_global_lazy_hint"))))]
1714mod inited {
1715 #[inline(always)]
1716 pub(super) const fn global_inited_hint() -> bool {
1717 false
1718 }
1719}
1720
1721#[cfg(test)]
1722mod test_lazy {
1723 use super::Lazy;
1724 static _X: Lazy<u32, fn() -> u32> = Lazy::from_generator(|| 22);
1725
1726 #[test]
1727 fn test() {
1728 assert_eq!(*_X, 22);
1729 }
1730}
1731
1732#[cfg(feature = "test_no_global_lazy_hint")]
1733#[cfg(test)]
1734mod test_quasi_lazy {
1735 use super::LesserLazy;
1736 static _X: LesserLazy<u32, fn() -> u32> = unsafe { LesserLazy::from_generator(|| 22) };
1737 #[test]
1738 fn test() {
1739 assert_eq!(*_X, 22);
1740 }
1741}
1742#[cfg(all(test, feature = "thread_local"))]
1743mod test_local_lazy {
1744 use super::UnSyncLazy;
1745 #[thread_local]
1746 static _X: UnSyncLazy<u32, fn() -> u32> = UnSyncLazy::from_generator(|| 22);
1747 #[test]
1748 fn test() {
1749 assert_eq!(*_X, 22);
1750 }
1751}
1752#[cfg(test)]
1753mod test_lazy_finalize {
1754 use super::LazyFinalize;
1755 use crate::Finaly;
1756 #[derive(Debug)]
1757 struct A(u32);
1758 impl Finaly for A {
1759 fn finaly(&self) {}
1760 }
1761 static _X: LazyFinalize<A, fn() -> A> = unsafe { LazyFinalize::from_generator(|| A(22)) };
1762 #[test]
1763 fn test() {
1764 assert_eq!(_X.0, 22);
1765 }
1766}
1767#[cfg(feature = "test_no_global_lazy_hint")]
1768#[cfg(test)]
1769mod test_quasi_lazy_finalize {
1770 use super::LesserLazyFinalize;
1771 use crate::Finaly;
1772 #[derive(Debug)]
1773 struct A(u32);
1774 impl Finaly for A {
1775 fn finaly(&self) {}
1776 }
1777 static _X: LesserLazyFinalize<A, fn() -> A> =
1778 unsafe { LesserLazyFinalize::from_generator(|| A(22)) };
1779 #[test]
1780 fn test() {
1781 assert_eq!((*_X).0, 22);
1782 }
1783}
1784#[cfg(all(test, feature = "thread_local"))]
1785mod test_local_lazy_finalize {
1786 use super::UnSyncLazyFinalize;
1787 use crate::Finaly;
1788 #[derive(Debug)]
1789 struct A(u32);
1790 impl Finaly for A {
1791 fn finaly(&self) {}
1792 }
1793 #[thread_local]
1794 static _X: UnSyncLazyFinalize<A, fn() -> A> =
1795 unsafe { UnSyncLazyFinalize::from_generator(|| A(22)) };
1796 #[test]
1797 fn test() {
1798 assert_eq!(_X.0, 22);
1799 }
1800}
1801#[cfg(all(test, feature = "thread_local"))]
1802mod test_droped_local_lazy_finalize {
1803 use super::UnSyncLazyDroped;
1804 #[derive(Debug)]
1805 struct A(u32);
1806 #[thread_local]
1807 static _X: UnSyncLazyDroped<A> = unsafe { UnSyncLazyDroped::from_generator(|| A(22)) };
1808 #[test]
1809 fn test() {
1810 assert_eq!(_X.0, 22);
1811 }
1812}
1813
1814#[cfg(test)]
1815mod test_mut_lazy {
1816 use super::LockedLazy;
1817 static _X: LockedLazy<u32, fn() -> u32> = LockedLazy::from_generator(|| 22);
1818 #[test]
1819 fn test() {
1820 assert_eq!(*_X.read(), 22);
1821 *_X.write() = 33;
1822 assert_eq!(*_X.read(), 33);
1823 }
1824}
1825
1826#[cfg(test)]
1827mod test_primed_mut_lazy_droped {
1828 use super::PrimedLockedLazyDroped;
1829 use crate::Uninit;
1830 #[derive(Debug)]
1831 struct A(u32);
1832 impl Uninit for A {
1833 fn uninit(&mut self) {
1834 self.0 = 0
1835 }
1836 }
1837 static _X: PrimedLockedLazyDroped<A> = PrimedLockedLazyDroped::from_generator(A(42), || A(22));
1838 #[test]
1839 fn test() {
1840 assert_eq!(_X.primed_read_non_initializing().unwrap_err().0, 42);
1841 assert_eq!(_X.read().0, 22);
1842 _X.write().0 = 33;
1843 assert_eq!(_X.read().0, 33);
1844 }
1845}
1846
1847#[cfg(test)]
1848mod test_primed_mut_lazy {
1849 use super::PrimedLockedLazy;
1850 static _X: PrimedLockedLazy<u32> = PrimedLockedLazy::from_generator(42, || 22);
1851 #[test]
1852 fn test() {
1853 assert_eq!(*_X.primed_read_non_initializing().unwrap_err(), 42);
1854 assert_eq!(*_X.read(), 22);
1855 *_X.write() = 33;
1856 assert_eq!(*_X.read(), 33);
1857 }
1858}
1859
1860#[cfg(feature = "test_no_global_lazy_hint")]
1861#[cfg(test)]
1862mod test_quasi_mut_lazy {
1863 use super::LesserLockedLazy;
1864 static _X: LesserLockedLazy<u32, fn() -> u32> =
1865 unsafe { LesserLockedLazy::from_generator(|| 22) };
1866 #[test]
1867 fn test() {
1868 assert_eq!(*_X.read(), 22);
1869 *_X.write() = 33;
1870 assert_eq!(*_X.read(), 33);
1871 }
1872}
1873#[cfg(test)]
1874mod test_mut_lazy_finalize {
1875 use super::LockedLazyFinalize;
1876 use crate::Finaly;
1877 #[derive(Debug)]
1878 struct A(u32);
1879 impl Finaly for A {
1880 fn finaly(&self) {}
1881 }
1882 static _X: LockedLazyFinalize<A, fn() -> A> = LockedLazyFinalize::from_generator(|| A(22));
1883 #[test]
1884 fn test() {
1885 assert!((*_X.read()).0 == 22);
1886 *_X.write() = A(33);
1887 assert_eq!((*_X.read()).0, 33);
1888 }
1889}
1890#[cfg(feature = "test_no_global_lazy_hint")]
1891#[cfg(test)]
1892mod test_quasi_mut_lazy_finalize {
1893 use super::LesserLockedLazyFinalize;
1894 use crate::Finaly;
1895 #[derive(Debug)]
1896 struct A(u32);
1897 impl Finaly for A {
1898 fn finaly(&self) {}
1899 }
1900 static _X: LesserLockedLazyFinalize<A, fn() -> A> =
1901 unsafe { LesserLockedLazyFinalize::from_generator(|| A(22)) };
1902 #[test]
1903 fn test() {
1904 assert!((*_X.read()).0 == 22);
1905 *_X.write() = A(33);
1906 assert_eq!((*_X.read()).0, 33);
1907 }
1908}
1909#[cfg(test)]
1910mod test_mut_lazy_dropped {
1911 use super::LockedLazyDroped;
1912 static _X: LockedLazyDroped<u32, fn() -> u32> = LockedLazyDroped::from_generator(|| 22);
1913 #[test]
1914 fn test() {
1915 assert_eq!(*_X.read(), 22);
1916 *_X.write() = 33;
1917 assert_eq!(*_X.read(), 33);
1918 }
1919}
1920#[cfg(feature = "test_no_global_lazy_hint")]
1921#[cfg(test)]
1922mod test_quasi_mut_lazy_dropped {
1923 use super::LesserLockedLazyDroped;
1924 static _X: LesserLockedLazyDroped<u32, fn() -> u32> =
1925 unsafe { LesserLockedLazyDroped::from_generator(|| 22) };
1926 #[test]
1927 fn test() {
1928 assert_eq!(*_X.read(), 22);
1929 *_X.write() = 33;
1930 assert_eq!(*_X.read(), 33);
1931 }
1932}
1933#[cfg(test)]
1934#[cfg(feature = "thread_local")]
1935mod test_unsync_mut_lazy {
1936 use super::UnSyncLockedLazy;
1937 #[thread_local]
1938 static _X: UnSyncLockedLazy<u32, fn() -> u32> = UnSyncLockedLazy::from_generator(|| 22);
1939 #[test]
1940 fn test() {
1941 assert_eq!(*_X.read(), 22);
1942 *_X.write() = 33;
1943 assert_eq!(*_X.read(), 33);
1944 }
1945}
1946
1947#[cfg(test)]
1948#[cfg(feature = "thread_local")]
1949mod test_unsync_mut_primed_lazy {
1950 use super::UnSyncPrimedLockedLazy;
1951 #[thread_local]
1952 static _X: UnSyncPrimedLockedLazy<u32> =
1953 unsafe { UnSyncPrimedLockedLazy::from_generator(42, || 22) };
1954 #[test]
1955 fn test() {
1956 assert_eq!(*_X.primed_read_non_initializing().unwrap_err(), 42);
1957 assert_eq!(*_X.read(), 22);
1958 *_X.write() = 33;
1959 assert_eq!(*_X.read(), 33);
1960 }
1961}
1962#[cfg(test)]
1963#[cfg(feature = "thread_local")]
1964mod test_unsync_mut_primed_lazy_droped {
1965 use super::UnSyncPrimedLockedLazyDroped;
1966 use crate::Uninit;
1967 #[derive(Debug)]
1968 struct A(u32);
1969 impl Uninit for A {
1970 fn uninit(&mut self) {
1971 self.0 = 0
1972 }
1973 }
1974 #[thread_local]
1975 static _X: UnSyncPrimedLockedLazyDroped<A> =
1976 unsafe { UnSyncPrimedLockedLazyDroped::from_generator(A(42), || A(22)) };
1977 #[test]
1978 fn test() {
1979 assert_eq!(_X.primed_read_non_initializing().unwrap_err().0, 42);
1980 assert_eq!(_X.read().0, 22);
1981 _X.write().0 = 33;
1982 assert_eq!(_X.read().0, 33);
1983 }
1984}
1985
1986#[cfg(test)]
1987#[cfg(feature = "thread_local")]
1988mod test_unsync_mut_lazy_finalize {
1989 use super::UnSyncLockedLazyFinalize;
1990 use crate::Finaly;
1991 #[derive(Debug)]
1992 struct A(u32);
1993 impl Finaly for A {
1994 fn finaly(&self) {}
1995 }
1996 #[thread_local]
1997 static _X: UnSyncLockedLazyFinalize<A, fn() -> A> =
1998 unsafe { UnSyncLockedLazyFinalize::from_generator(|| A(22)) };
1999 #[test]
2000 fn test() {
2001 assert!((*_X.read()).0 == 22);
2002 *_X.write() = A(33);
2003 assert_eq!((*_X.read()).0, 33);
2004 }
2005}
2006#[cfg(test)]
2007#[cfg(feature = "thread_local")]
2008mod test_unsync_mut_lazy_droped {
2009 use super::UnSyncLockedLazyDroped;
2010 #[thread_local]
2011 static _X: UnSyncLockedLazyDroped<u32, fn() -> u32> =
2012 unsafe { UnSyncLockedLazyDroped::from_generator(|| 22) };
2013 #[test]
2014 fn test() {
2015 assert_eq!(*_X.read(), 22);
2016 *_X.write() = 33;
2017 assert_eq!(*_X.read(), 33);
2018 }
2019}
2020
2021#[inline(always)]
2022unsafe fn as_static<T>(v: &T) -> &'static T {
2025 &*(v as *const _)
2026}