|
1 | 1 | use crate::cell::UnsafeCell;
|
2 |
| -use crate::fmt; |
3 | 2 | use crate::mem::ManuallyDrop;
|
4 | 3 | use crate::ops::Deref;
|
5 | 4 | use crate::panic::{RefUnwindSafe, UnwindSafe};
|
6 | 5 | use crate::sync::Once;
|
| 6 | +use crate::{fmt, ptr}; |
7 | 7 |
|
8 | 8 | use super::once::ExclusiveState;
|
9 | 9 |
|
@@ -69,6 +69,42 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
|
69 | 69 | LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
|
70 | 70 | }
|
71 | 71 |
|
| 72 | + /// Consumes this `LazyLock` returning the stored value. |
| 73 | + /// |
| 74 | + /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise. |
| 75 | + /// |
| 76 | + /// # Examples |
| 77 | + /// |
| 78 | + /// ``` |
| 79 | + /// #![feature(lazy_cell)] |
| 80 | + /// #![feature(lazy_cell_consume)] |
| 81 | + /// |
| 82 | + /// use std::sync::LazyLock; |
| 83 | + /// |
| 84 | + /// let hello = "Hello, World!".to_string(); |
| 85 | + /// |
| 86 | + /// let lazy = LazyLock::new(|| hello.to_uppercase()); |
| 87 | + /// |
| 88 | + /// assert_eq!(&*lazy, "HELLO, WORLD!"); |
| 89 | + /// assert_eq!(LazyLock::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string())); |
| 90 | + /// ``` |
| 91 | + #[unstable(feature = "lazy_cell_consume", issue = "109736")] |
| 92 | + pub fn into_inner(mut this: Self) -> Result<T, F> { |
| 93 | + let state = this.once.state(); |
| 94 | + match state { |
| 95 | + ExclusiveState::Poisoned => panic!("LazyLock instance has previously been poisoned"), |
| 96 | + state => { |
| 97 | + let this = ManuallyDrop::new(this); |
| 98 | + let data = unsafe { ptr::read(&this.data) }.into_inner(); |
| 99 | + match state { |
| 100 | + ExclusiveState::Incomplete => Err(ManuallyDrop::into_inner(unsafe { data.f })), |
| 101 | + ExclusiveState::Complete => Ok(ManuallyDrop::into_inner(unsafe { data.value })), |
| 102 | + ExclusiveState::Poisoned => unreachable!(), |
| 103 | + } |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + |
72 | 108 | /// Forces the evaluation of this lazy value and
|
73 | 109 | /// returns a reference to result. This is equivalent
|
74 | 110 | /// to the `Deref` impl, but is explicit.
|
|
0 commit comments