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
77
78
79
80
81
82
83
84
85
86
87
88
|
use once_cell::unsync::OnceCell;
use std::cell::Cell;
use std::fmt::Debug;
use std::ops::Deref;
pub trait Eval<Tgt> {
fn eval(self) -> Tgt;
}
/// A value which is initialized from a `Src` on the first access.
pub struct Lazy<Src, Tgt> {
/// Exactly one of `src` of `tgt` must be set at a given time.
/// Once `src` is unset and `tgt` is set, we never go back.
src: Cell<Option<Src>>,
tgt: OnceCell<Tgt>,
}
impl<Src, Tgt> Lazy<Src, Tgt>
where
Src: Eval<Tgt>,
{
/// Creates a new lazy value with the given initializing value.
pub fn new(src: Src) -> Self {
Lazy {
src: Cell::new(Some(src)),
tgt: OnceCell::new(),
}
}
/// Creates a new lazy value with the given already-initialized value.
pub fn new_completed(tgt: Tgt) -> Self {
let lazy = Lazy {
src: Cell::new(None),
tgt: OnceCell::new(),
};
let _ = lazy.tgt.set(tgt);
lazy
}
pub fn force(&self) -> &Tgt {
self.tgt.get_or_init(|| {
let src = self.src.take().unwrap();
src.eval()
})
}
pub fn get_mut(&mut self) -> &mut Tgt {
self.force();
self.tgt.get_mut().unwrap()
}
pub fn into_inner(self) -> Tgt {
self.force();
self.tgt.into_inner().unwrap()
}
}
impl<Src, Tgt> Deref for Lazy<Src, Tgt>
where
Src: Eval<Tgt>,
{
type Target = Tgt;
fn deref(&self) -> &Self::Target {
self.force()
}
}
/// This implementation evaluates before cloning, because we can't clone the contents of a `Cell`.
impl<Src, Tgt> Clone for Lazy<Src, Tgt>
where
Src: Eval<Tgt>,
Tgt: Clone,
{
fn clone(&self) -> Self {
Self::new_completed(self.force().clone())
}
}
impl<Src, Tgt> Debug for Lazy<Src, Tgt>
where
Tgt: Debug,
{
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(tgt) = self.tgt.get() {
fmt.debug_tuple("Lazy@Init").field(tgt).finish()
} else {
fmt.debug_tuple("Lazy@Uninit").finish()
}
}
}
|