Add Lazy{Cell,Lock}::into_inner
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
This commit is contained in:
parent
660c966ff9
commit
d9256f94a9
@ -63,6 +63,34 @@ pub const fn new(f: F) -> LazyCell<T, F> {
|
||||
LazyCell { state: UnsafeCell::new(State::Uninit(f)) }
|
||||
}
|
||||
|
||||
/// Consumes this `LazyCell` returning the stored value.
|
||||
///
|
||||
/// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(lazy_cell)]
|
||||
/// #![feature(lazy_cell_consume)]
|
||||
///
|
||||
/// use std::cell::LazyCell;
|
||||
///
|
||||
/// let hello = "Hello, World!".to_string();
|
||||
///
|
||||
/// let lazy = LazyCell::new(|| hello.to_uppercase());
|
||||
///
|
||||
/// assert_eq!(&*lazy, "HELLO, WORLD!");
|
||||
/// assert_eq!(LazyCell::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
|
||||
/// ```
|
||||
#[unstable(feature = "lazy_cell_consume", issue = "109736")]
|
||||
pub fn into_inner(this: Self) -> Result<T, F> {
|
||||
match this.state.into_inner() {
|
||||
State::Init(data) => Ok(data),
|
||||
State::Uninit(f) => Err(f),
|
||||
State::Poisoned => panic!("LazyCell instance has previously been poisoned"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Forces the evaluation of this lazy value and returns a reference to
|
||||
/// the result.
|
||||
///
|
||||
|
@ -1,9 +1,9 @@
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::fmt;
|
||||
use crate::mem::ManuallyDrop;
|
||||
use crate::ops::Deref;
|
||||
use crate::panic::{RefUnwindSafe, UnwindSafe};
|
||||
use crate::sync::Once;
|
||||
use crate::{fmt, ptr};
|
||||
|
||||
use super::once::ExclusiveState;
|
||||
|
||||
@ -69,6 +69,42 @@ pub const fn new(f: F) -> LazyLock<T, F> {
|
||||
LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
|
||||
}
|
||||
|
||||
/// Consumes this `LazyLock` returning the stored value.
|
||||
///
|
||||
/// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(lazy_cell)]
|
||||
/// #![feature(lazy_cell_consume)]
|
||||
///
|
||||
/// use std::sync::LazyLock;
|
||||
///
|
||||
/// let hello = "Hello, World!".to_string();
|
||||
///
|
||||
/// let lazy = LazyLock::new(|| hello.to_uppercase());
|
||||
///
|
||||
/// assert_eq!(&*lazy, "HELLO, WORLD!");
|
||||
/// assert_eq!(LazyLock::into_inner(lazy).ok(), Some("HELLO, WORLD!".to_string()));
|
||||
/// ```
|
||||
#[unstable(feature = "lazy_cell_consume", issue = "109736")]
|
||||
pub fn into_inner(mut this: Self) -> Result<T, F> {
|
||||
let state = this.once.state();
|
||||
match state {
|
||||
ExclusiveState::Poisoned => panic!("LazyLock instance has previously been poisoned"),
|
||||
state => {
|
||||
let this = ManuallyDrop::new(this);
|
||||
let data = unsafe { ptr::read(&this.data) }.into_inner();
|
||||
match state {
|
||||
ExclusiveState::Incomplete => Err(ManuallyDrop::into_inner(unsafe { data.f })),
|
||||
ExclusiveState::Complete => Ok(ManuallyDrop::into_inner(unsafe { data.value })),
|
||||
ExclusiveState::Poisoned => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Forces the evaluation of this lazy value and
|
||||
/// returns a reference to result. This is equivalent
|
||||
/// to the `Deref` impl, but is explicit.
|
||||
|
Loading…
Reference in New Issue
Block a user