#[cfg(feature = "std")] pub(crate) use once_cell::sync::Lazy; #[cfg(not(feature = "std"))] pub(crate) use self::spin::Lazy; #[cfg(not(feature = "std"))] mod spin { //! This is the `once_cell::sync::Lazy` type, but modified to use our //! `spin::Once` type rather than `OnceCell`. This is used to replace //! `once_cell::sync::Lazy` on `no-std` builds. use crate::spin::Once; use core::{cell::Cell, fmt, ops::Deref}; /// Re-implementation of `once_cell::sync::Lazy` on top of `spin::Once` /// rather than `OnceCell`. /// /// This is used when the standard library is disabled. pub(crate) struct Lazy T> { cell: Once, init: Cell>, } impl fmt::Debug for Lazy { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Lazy") .field("cell", &self.cell) .field("init", &"..") .finish() } } // We never create a `&F` from a `&Lazy` so it is fine to not impl // `Sync` for `F`. We do create a `&mut Option` in `force`, but this is // properly synchronized, so it only happens once so it also does not // contribute to this impl. unsafe impl Sync for Lazy where Once: Sync {} // auto-derived `Send` impl is OK. impl Lazy { /// Creates a new lazy value with the given initializing function. pub(crate) const fn new(init: F) -> Lazy { Lazy { cell: Once::new(), init: Cell::new(Some(init)), } } } impl T> Lazy { /// Forces the evaluation of this lazy value and returns a reference to /// the result. /// /// This is equivalent to the `Deref` impl, but is explicit. pub(crate) fn force(this: &Lazy) -> &T { this.cell.call_once(|| match this.init.take() { Some(f) => f(), None => panic!("Lazy instance has previously been poisoned"), }) } } impl T> Deref for Lazy { type Target = T; fn deref(&self) -> &T { Lazy::force(self) } } impl Default for Lazy { /// Creates a new lazy value using `Default` as the initializing function. fn default() -> Lazy { Lazy::new(T::default) } } }