singleton-attr 0.1.9

Simple to use singleton procedural attribute and derive macro
Documentation
#[macro_export]
macro_rules! singleton_manual {
    (
        $([$($trait_bound:tt)+])?
        $type:ident$(<$($inner_gen:ty),+>)?
        $([$($outer_gen:ty),+])?
        $(where [$($where_bound:tt)+])?
        $(with [$($param_gen:ty),+])?
    ) => {
        static mut __INSTANCE: *mut $type$(<$($param_gen),+>)? = std::ptr::null_mut();

        impl$(<$($trait_bound)+>)? singleton_attr::traits::Singleton for $type$(<$($outer_gen),+>)?
        $(where $($where_bound)+)? {
            #[inline]
            fn init_instance(instance: Self) {
                unsafe {
                    __INSTANCE = std::alloc::alloc(std::alloc::Layout::new::<Self>()) as *mut Self;
                    std::ptr::write_volatile(__INSTANCE, instance);
                }
            }

            #[inline]
            fn get_instance() -> &'static mut Self {
                unsafe {
                    if __INSTANCE.is_null() {
                        Self::init_instance(Self::default());
                    }
                    &mut *__INSTANCE
                }
            }
        }

        impl$(<$($trait_bound)+>)? Drop for $type$(<$($outer_gen),+>)?
        $(where $($where_bound)+)? {
            fn drop(&mut self) {
                unsafe { std::alloc::dealloc(__INSTANCE as *mut u8, std::alloc::Layout::new::<Self>()); }
            }
        }
    };
}

#[macro_export]
macro_rules! singleton_safe_manual {
    (
        $([$($trait_bound:tt)+])?
        $type:ident$(<$($inner_gen:ty),+>)?
        $([$($outer_gen:ty),+])?
        $(where [$($where_bound:tt)+])?
        $(with [$($param_gen:ty),+])?
    ) => {
        const _: () = {
            static mut __INSTANCE: Option<std::sync::Arc<std::sync::Mutex<$type$(<$($param_gen),+>)?>>> = None;

            impl$(<$($trait_bound)+>)? singleton_attr::traits::SafeSingleton for $type$(<$($outer_gen),+>)?
            $(where $($where_bound)+)? {
                #[inline]
                fn init_instance(instance: Self) {
                    unsafe {
                        __INSTANCE = Some(std::sync::Arc::new(std::sync::Mutex::new(instance)));
                    }
                }

                #[inline]
                fn get_instance() -> std::sync::LockResult<std::sync::MutexGuard<'static, Self>> {
                    unsafe {
                        if let None = __INSTANCE {
                            Self::init_instance(Self::default());
                        }

                        __INSTANCE.as_ref().unwrap().lock()
                    }
                }
            }
        };
    };
}