1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
//! This crate provides functionality for thread-safe and non-thread-safe lazy //! evaluation in Rust. It also provides functionality for generically working //! with thunks of a given type. //! //! Three different owned thunk types are provided, implementing `Lazy`, //! `LazyRef`, and `LazyMut`: //! * `Thunk`: a non thread-safe thunk. //! * `AtomicThunk`: a thread-safe thunk, which implements `Send + Sync`. //! * `Strict`: a strict, non-deferred thunk which always immediately //! evaluates whatever computation it's given, intended for genericity over //! strictness. //! //! In addition, two shared thunk types are provided, implementing `LazyRef` //! and `LazyShared`: //! * `RcThunk`: a reference-counted thunk type. This is a wrapper over `Thunk`. //! * `ArcThunk`: an atomically reference-counted thunk type. This is a wrapper //! over `AtomicThunk`. #![cfg_attr(test, feature(test))] #![feature(fnbox)] #![feature(untagged_unions)] extern crate unreachable; #[cfg(test)] extern crate test; use std::ops::{Deref, DerefMut}; pub mod strict; pub mod sync; pub mod unsync; pub use strict::Strict; pub use sync::{AtomicThunk, ArcThunk}; pub use unsync::{Thunk, RcThunk}; /// The `Lazy` trait abstracts thunks which have exactly the same lifetimes /// as the types they defer computation of. pub trait LazyRef : Deref + Sized where Self::Target: Into<Self> + Sized { /// Construct a thunk with a precomputed value. This means /// forcing the thunk is a no-op. #[inline] fn computed(t: Self::Target) -> Self { t.into() } /// Defer a computation stored as a `FnOnce` closure. Unwrapping/dereferencing /// will force the computation of the closure. The supplied closure must live /// as long as the type which the thunk computes. fn defer<'a, F: FnOnce() -> Self::Target + 'a>(F) -> Self where Self::Target: 'a; /// Manually force a thunk's computation. fn force(&self); } /// The `LazyMut` trait abstracts mutable references to lazily computed values. pub trait LazyMut: From<<Self as Deref>::Target> + LazyRef + DerefMut where Self::Target: Sized { } /// The `Lazy` trait abstracts owned, lazily computed values. pub trait Lazy: LazyMut where Self::Target: Sized { /// Unwrap a thunk into its inner value. This forces the thunk. fn unwrap(self) -> Self::Target; }