]> git.proxmox.com Git - rustc.git/blame - library/core/src/cell/lazy.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / library / core / src / cell / lazy.rs
CommitLineData
923072b8
FG
1use crate::cell::{Cell, OnceCell};
2use crate::fmt;
3use crate::ops::Deref;
4
5/// A value which is initialized on the first access.
6///
487cf647
FG
7/// For a thread-safe version of this struct, see [`std::sync::LazyLock`].
8///
9/// [`std::sync::LazyLock`]: ../../std/sync/struct.LazyLock.html
10///
923072b8
FG
11/// # Examples
12///
13/// ```
14/// #![feature(once_cell)]
15///
16/// use std::cell::LazyCell;
17///
18/// let lazy: LazyCell<i32> = LazyCell::new(|| {
19/// println!("initializing");
20/// 92
21/// });
22/// println!("ready");
23/// println!("{}", *lazy);
24/// println!("{}", *lazy);
25///
26/// // Prints:
27/// // ready
28/// // initializing
29/// // 92
30/// // 92
31/// ```
32#[unstable(feature = "once_cell", issue = "74465")]
33pub struct LazyCell<T, F = fn() -> T> {
34 cell: OnceCell<T>,
35 init: Cell<Option<F>>,
36}
37
f25598a0 38impl<T, F: FnOnce() -> T> LazyCell<T, F> {
923072b8
FG
39 /// Creates a new lazy value with the given initializing function.
40 ///
41 /// # Examples
42 ///
43 /// ```
44 /// #![feature(once_cell)]
45 ///
46 /// use std::cell::LazyCell;
47 ///
48 /// let hello = "Hello, World!".to_string();
49 ///
50 /// let lazy = LazyCell::new(|| hello.to_uppercase());
51 ///
52 /// assert_eq!(&*lazy, "HELLO, WORLD!");
53 /// ```
f25598a0 54 #[inline]
923072b8
FG
55 #[unstable(feature = "once_cell", issue = "74465")]
56 pub const fn new(init: F) -> LazyCell<T, F> {
57 LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) }
58 }
923072b8 59
923072b8
FG
60 /// Forces the evaluation of this lazy value and returns a reference to
61 /// the result.
62 ///
63 /// This is equivalent to the `Deref` impl, but is explicit.
64 ///
65 /// # Examples
66 ///
67 /// ```
68 /// #![feature(once_cell)]
69 ///
70 /// use std::cell::LazyCell;
71 ///
72 /// let lazy = LazyCell::new(|| 92);
73 ///
74 /// assert_eq!(LazyCell::force(&lazy), &92);
75 /// assert_eq!(&*lazy, &92);
76 /// ```
f25598a0 77 #[inline]
923072b8
FG
78 #[unstable(feature = "once_cell", issue = "74465")]
79 pub fn force(this: &LazyCell<T, F>) -> &T {
80 this.cell.get_or_init(|| match this.init.take() {
81 Some(f) => f(),
82 None => panic!("`Lazy` instance has previously been poisoned"),
83 })
84 }
85}
86
87#[unstable(feature = "once_cell", issue = "74465")]
88impl<T, F: FnOnce() -> T> Deref for LazyCell<T, F> {
89 type Target = T;
f25598a0 90 #[inline]
923072b8
FG
91 fn deref(&self) -> &T {
92 LazyCell::force(self)
93 }
94}
95
96#[unstable(feature = "once_cell", issue = "74465")]
97impl<T: Default> Default for LazyCell<T> {
98 /// Creates a new lazy value using `Default` as the initializing function.
f25598a0 99 #[inline]
923072b8
FG
100 fn default() -> LazyCell<T> {
101 LazyCell::new(T::default)
102 }
103}
104
105#[unstable(feature = "once_cell", issue = "74465")]
106impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
109 }
110}