1#[macro_export]
2macro_rules! singleton_manual {
3 (
4 $([$($trait_bound:tt)+])?
5 $type:ident$(<$($inner_gen:ty),+>)?
6 $([$($outer_gen:ty),+])?
7 $(where [$($where_bound:tt)+])?
8 $(with [$($param_gen:ty),+])?
9 ) => {
10 static mut __INSTANCE: *mut $type$(<$($param_gen),+>)? = std::ptr::null_mut();
11
12 impl$(<$($trait_bound)+>)? singleton_attr::traits::Singleton for $type$(<$($outer_gen),+>)?
13 $(where $($where_bound)+)? {
14 #[inline]
15 fn init_instance(instance: Self) {
16 unsafe {
17 __INSTANCE = std::alloc::alloc(std::alloc::Layout::new::<Self>()) as *mut Self;
18 std::ptr::write_volatile(__INSTANCE, instance);
19 }
20 }
21
22 #[inline]
23 fn get_instance() -> &'static mut Self {
24 unsafe {
25 if __INSTANCE.is_null() {
26 Self::init_instance(Self::default());
27 }
28 &mut *__INSTANCE
29 }
30 }
31 }
32
33 impl$(<$($trait_bound)+>)? Drop for $type$(<$($outer_gen),+>)?
34 $(where $($where_bound)+)? {
35 fn drop(&mut self) {
36 unsafe { std::alloc::dealloc(__INSTANCE as *mut u8, std::alloc::Layout::new::<Self>()); }
37 }
38 }
39 };
40}
41
42#[macro_export]
43macro_rules! singleton_safe_manual {
44 (
45 $([$($trait_bound:tt)+])?
46 $type:ident$(<$($inner_gen:ty),+>)?
47 $([$($outer_gen:ty),+])?
48 $(where [$($where_bound:tt)+])?
49 $(with [$($param_gen:ty),+])?
50 ) => {
51 const _: () = {
52 static mut __INSTANCE: Option<std::sync::Arc<std::sync::Mutex<$type$(<$($param_gen),+>)?>>> = None;
53
54 impl$(<$($trait_bound)+>)? singleton_attr::traits::SafeSingleton for $type$(<$($outer_gen),+>)?
55 $(where $($where_bound)+)? {
56 #[inline]
57 fn init_instance(instance: Self) {
58 unsafe {
59 __INSTANCE = Some(std::sync::Arc::new(std::sync::Mutex::new(instance)));
60 }
61 }
62
63 #[inline]
64 fn get_instance() -> std::sync::LockResult<std::sync::MutexGuard<'static, Self>> {
65 unsafe {
66 if let None = __INSTANCE {
67 Self::init_instance(Self::default());
68 }
69
70 __INSTANCE.as_ref().unwrap().lock()
71 }
72 }
73 }
74 };
75 };
76}