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