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 pub fn read(&$($static)? self) -> ReadGuard<'_,T> {
886 ReadGuard(GenericLockedLazy::init_then_read_lock(&self.__private))
887 }
888 #[inline(always)]
889 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 pub fn try_read(&$($static)? self) -> Result<ReadGuard<'_,T>,AccessError> {
901 GenericLockedLazy::try_read_lock(&self.__private).map(ReadGuard)
902 }
903 #[inline(always)]
904 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 pub fn write(&$($static)? self) -> WriteGuard<'_,T> {
916 WriteGuard(GenericLockedLazy::init_then_write_lock(&self.__private))
917 }
918 #[inline(always)]
919 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 pub fn try_write(&$($static)? self) -> Result<WriteGuard<'_,T>,AccessError> {
931 GenericLockedLazy::try_write_lock(&self.__private).map(WriteGuard)
932 }
933 #[inline(always)]
934 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 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 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 #[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 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 G: 'static + Generator<T>,
1001 T: 'static,
1002 $(G:$trg, T:Send,)?
1003 $(T:$tr,)?
1004 {
1005 #[inline(always)]
1006 pub fn read(&self) -> ReadGuard<'_,T> {
1013 ReadGuard(GenericLockedLazy::init_then_read_lock(unsafe{as_static(&self.__private)}))
1014 }
1015 #[inline(always)]
1016 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 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 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 pub fn write(&self) -> WriteGuard<'_,T> {
1045 WriteGuard(GenericLockedLazy::init_then_write_lock(unsafe{as_static(&self.__private)}))
1046 }
1047 #[inline(always)]
1048 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 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 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 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 G: 'static + Generator<T>,
1086 T: 'static,
1087 $(G:$trg, T:Send,)?
1088 $(T:$tr,)?
1089 {
1090 #[inline(always)]
1091 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 #[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 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 #[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 #[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 #[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 #[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 #[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 #[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 G: 'static + Generator<T>,
1237 T: 'static,
1238 $(G:$trg, T:Send,)?
1239 $(T:$tr,)?
1240 {
1241 #[inline(always)]
1242 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 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 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 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 G: 'static + Generator<T>,
1297 T: 'static,
1298 $(G:$trg, T:Send,)?
1299 $(T:$tr,)?
1300 {
1301 #[inline(always)]
1302 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 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 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 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 G: 'static + Generator<T>,
1389 T:'static,
1390 $(G:$trg, T:Send,)?
1391 $(T:$tr,)?
1392 {
1393 #[inline(always)]
1394 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 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 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 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 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 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 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 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 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
1654impl_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)]
2014unsafe fn as_static<T>(v: &T) -> &'static T {
2017 &*(v as *const _)
2018}