lazy_static::lazy_static! [] [src]

macro_rules! lazy_static {
    ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV, $(#[$attr])* static ref $N : $T = $e; $($t)*);
    };
    ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB, $(#[$attr])* static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident, $(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY, $VIS, $(#[$attr])*, $N);
        impl ::std::ops::Deref for $N {
            type Target = $T;
            fn deref<'a>(&'a self) -> &'a $T {
                #[inline(always)]
                fn __static_ref_initialize() -> $T { $e }

                unsafe {
                    use std::sync::{Once, ONCE_INIT};

                    #[inline(always)]
                    fn require_sync<T: Sync>(_: &T) { }

                    #[inline(always)]
                    #[cfg(feature="nightly")]
                    unsafe fn __stability() -> &'static $T {
                        use std::cell::UnsafeCell;

                        struct SyncCell(UnsafeCell<Option<$T>>);
                        unsafe impl Sync for SyncCell {}

                        static DATA: SyncCell = SyncCell(UnsafeCell::new(None));
                        static ONCE: Once = ONCE_INIT;
                        ONCE.call_once(|| {
                            *DATA.0.get() = Some(__static_ref_initialize());
                        });
                        match *DATA.0.get() {
                            Some(ref x) => x,
                            None => loop { /* unreachable */ },
                        }
                    }

                    #[inline(always)]
                    #[cfg(not(feature="nightly"))]
                    unsafe fn __stability() -> &'static $T {
                        use std::mem::transmute;

                        static mut DATA: *const $T = 0 as *const $T;
                        static mut ONCE: Once = ONCE_INIT;
                        ONCE.call_once(|| {
                            DATA = transmute::<Box<$T>, *const $T>(
                                Box::new(__static_ref_initialize()));
                        });
                        &*DATA
                    }

                    let static_ref = __stability();
                    require_sync(static_ref);
                    static_ref
                }
            }
        }
        lazy_static!($($t)*);
    };
    (MAKE TY, PUB, $(#[$attr:meta])*, $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        $(#[$attr])*
        pub struct $N {__private_field: ()}
        #[doc(hidden)]
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY, PRIV, $(#[$attr:meta])*, $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        $(#[$attr])*
        struct $N {__private_field: ()}
        #[doc(hidden)]
        static $N: $N = $N {__private_field: ()};
    };
    () => ()
}