kernel::lazy_static! [−] [src]

macro_rules! lazy_static {
    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV ALLOC static ref $N : $T = $e; $($t)*);
    };
    (pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB ALLOC static ref $N : $T = $e; $($t)*);
    };
    (static noalloc $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PRIV NOALLOC static ref $N : $T = $e; $($t)*);
    };
    (pub static noalloc $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(PUB NOALLOC static ref $N : $T = $e; $($t)*);
    };
    ($VIS:ident $ALLOC:ident static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
        lazy_static!(MAKE TY $VIS $N);
        lazy_static!(MAKE DEREF $ALLOC $N, $T, $e);
        lazy_static!($($t)*);
    };
    (MAKE TY PUB $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        pub struct $N {__private_field: ()}
        pub static $N: $N = $N {__private_field: ()};
    };
    (MAKE TY PRIV $N:ident) => {
        #[allow(missing_copy_implementations)]
        #[allow(non_camel_case_types)]
        #[allow(dead_code)]
        struct $N {__private_field: ()}
        static $N: $N = $N {__private_field: ()};
    };
    (MAKE DEREF ALLOC $N:ident, $T:ty, $e:expr) => {
        impl ::core::ops::Deref for $N {
            type Target = $T;
            fn deref<'a>(&'a self) -> &'a $T {
                use $crate::once::{Once, ONCE_INIT};
                use alloc::boxed::Box;
                use core::marker::Sync;

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

                static mut DATA: *const $T = 0 as *const $T;
                static ONCE: Once = ONCE_INIT;
                ONCE.call_once(|| {
                    let b = Box::new($e);
                    unsafe {
                        DATA = Box::into_raw(b);
                    }
                });
                unsafe {
                    require_sync(&*DATA);
                    &*DATA
                }
            }
        }
    };
    (MAKE DEREF NOALLOC $N:ident, $T:ty, $e:expr) => {
        impl ::core::ops::Deref for $N {
            type Target = $T;
            fn deref<'a>(&'a self) -> &'a $T {
                use $crate::once::{Once, ONCE_INIT};
                use core::option::Option::{self,Some,None};
                use core::marker::Sync;

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

                static mut DATA: Option<$T> = None;
                static ONCE: Once = ONCE_INIT;
                ONCE.call_once(|| {
                    let value = $e;
                    unsafe {
                        DATA = Some(value);
                    }
                });
                unsafe {
                    match DATA {
                        Some(ref static_ref) => {
                            require_sync(static_ref);
                            static_ref
                        },

                        None => panic!(concat!(stringify!($N), " was not lazy initialized"))
                    }
                }
            }
        }
    };
    () => ()
}