1#[macro_export]
7macro_rules! singleton_token {
8($(#[$meta: meta])* $vis: vis $id: ident) => {
9 $crate::paste! {
10 $vis use [<__ $id _mod__ >]::$id;
11 #[allow(nonstandard_style)]
12 mod [<__ $id _mod__ >] {
13 use core::{convert::Infallible, sync::atomic::AtomicBool};
14 use $crate::SingletonUnavailable;
15 static AVAILABLE: AtomicBool = AtomicBool::new(true);
16
17 $(#[$meta])*
18 pub struct $id(());
19 impl $crate::core::UnscopedToken for $id {
20 type ConstructionError = SingletonUnavailable;
21 fn try_new() -> Result<Self, Self::ConstructionError> {
22 if AVAILABLE.swap(false, core::sync::atomic::Ordering::Relaxed) {
23 Ok($id(()))
24 } else {
25 Err(SingletonUnavailable)
26 }
27 }
28 }
29 impl ::core::ops::Drop for $id {
30 fn drop(&mut self) {
31 AVAILABLE.store(true, core::sync::atomic::Ordering::Relaxed);
32 }
33 }
34 impl $crate::core::TokenTrait for $id {
35 type ComparisonMaySpuriouslyEq = $crate::core::False;
36 type RunError = SingletonUnavailable;
37 type Identifier = ();
38 type ComparisonError = Infallible;
39 fn with_token<R, F: FnOnce(Self)->R>(f: F) -> Result<R, Self::RunError> {
40 Self::try_new().map(f)
41 }
42 fn identifier(&self) -> Self::Identifier {
43 self.0
44 }
45 fn compare(&self, _: &Self::Identifier) -> Result<(), Self::ComparisonError> {
46 Ok(())
47 }
48 }
49 impl ::core::ops::Drop for $id {
50 fn drop(&mut self) {
51 AVAILABLE.store(true, core::sync::atomic::Ordering::Relaxed);
52 }
53 }
54 }
55 }
56};
57($($(#[$meta: meta])* $vis: vis $id: ident),*) => {
58 $($crate::singleton_token!($(#[$meta])* $vis $id);)*
59}
60}
61
62#[macro_export]
68macro_rules! unsafe_token {
69($(#[$meta: meta])* $vis: vis $id: ident) => {
70 $crate::paste! {
71 $vis use [<__ $id _mod__ >]::$id;
72 #[allow(nonstandard_style)]
73 mod [<__ $id _mod__ >] {
74 use core::convert::Infallible;
75 use $crate::core::UnscopedToken;
76
77 $(#[$meta])*
78 pub struct $id(());
79 impl UnscopedToken for $id {
80 type ConstructionError = Infallible;
81 fn try_new() -> Result<Self, Self::ConstructionError> {
82 Ok(Self(()))
83 }
84 }
85 impl $crate::core::TokenTrait for $id {
86 type ComparisonMaySpuriouslyEq = $crate::core::True;
87 type RunError = Infallible;
88 type Identifier = ();
89 type ComparisonError = Infallible;
90 type Branded<'a> = Self;
91 fn with_token<R, F: FnOnce(Self)->R>(f: F) -> Result<R, Self::RunError> {
92 Ok(f(Self::new()))
93 }
94 fn identifier(&self) -> Self::Identifier {
95 self.0
96 }
97 fn compare(&self, _: &Self::Identifier) -> Result<(), Self::ComparisonError> {
98 Ok(())
99 }
100 }
101 }
102 }
103};
104($($(#[$meta: meta])* $vis: vis $id: ident),*) => {
105 $($crate::unsafe_token!($(#[$meta])* $vis $id);)*
106}
107}
108pub use token::token;
109#[cfg(any(feature = "debug", debug_assertions))]
110mod token {
111 pub use crate::runtime_token as token;
112}
113#[cfg(not(any(feature = "debug", debug_assertions)))]
114mod token {
115 pub use crate::unsafe_token as token;
116}
117
118#[derive(Debug, Clone, Copy)]
120pub struct SingletonUnavailable;
121impl ::core::fmt::Display for SingletonUnavailable {
122 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
123 write!(f, "{:?}", self)
124 }
125}