1ef40d7f6Sopenharmony_ci//! # Overview
2ef40d7f6Sopenharmony_ci//!
3ef40d7f6Sopenharmony_ci//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and [`sync::OnceCell`]. A `OnceCell`
4ef40d7f6Sopenharmony_ci//! might store arbitrary non-`Copy` types, can be assigned to at most once and provides direct access
5ef40d7f6Sopenharmony_ci//! to the stored contents. The core API looks *roughly* like this (and there's much more inside, read on!):
6ef40d7f6Sopenharmony_ci//!
7ef40d7f6Sopenharmony_ci//! ```rust,ignore
8ef40d7f6Sopenharmony_ci//! impl<T> OnceCell<T> {
9ef40d7f6Sopenharmony_ci//!     const fn new() -> OnceCell<T> { ... }
10ef40d7f6Sopenharmony_ci//!     fn set(&self, value: T) -> Result<(), T> { ... }
11ef40d7f6Sopenharmony_ci//!     fn get(&self) -> Option<&T> { ... }
12ef40d7f6Sopenharmony_ci//! }
13ef40d7f6Sopenharmony_ci//! ```
14ef40d7f6Sopenharmony_ci//!
15ef40d7f6Sopenharmony_ci//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires only a shared reference.
16ef40d7f6Sopenharmony_ci//! Because of the single assignment restriction `get` can return a `&T` instead of `Ref<T>`
17ef40d7f6Sopenharmony_ci//! or `MutexGuard<T>`.
18ef40d7f6Sopenharmony_ci//!
19ef40d7f6Sopenharmony_ci//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait), while the `unsync` one is not.
20ef40d7f6Sopenharmony_ci//!
21ef40d7f6Sopenharmony_ci//! [`unsync::OnceCell`]: unsync/struct.OnceCell.html
22ef40d7f6Sopenharmony_ci//! [`sync::OnceCell`]: sync/struct.OnceCell.html
23ef40d7f6Sopenharmony_ci//! [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
24ef40d7f6Sopenharmony_ci//! [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
25ef40d7f6Sopenharmony_ci//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
26ef40d7f6Sopenharmony_ci//!
27ef40d7f6Sopenharmony_ci//! # Recipes
28ef40d7f6Sopenharmony_ci//!
29ef40d7f6Sopenharmony_ci//! `OnceCell` might be useful for a variety of patterns.
30ef40d7f6Sopenharmony_ci//!
31ef40d7f6Sopenharmony_ci//! ## Safe Initialization of Global Data
32ef40d7f6Sopenharmony_ci//!
33ef40d7f6Sopenharmony_ci//! ```rust
34ef40d7f6Sopenharmony_ci//! use std::{env, io};
35ef40d7f6Sopenharmony_ci//!
36ef40d7f6Sopenharmony_ci//! use once_cell::sync::OnceCell;
37ef40d7f6Sopenharmony_ci//!
38ef40d7f6Sopenharmony_ci//! #[derive(Debug)]
39ef40d7f6Sopenharmony_ci//! pub struct Logger {
40ef40d7f6Sopenharmony_ci//!     // ...
41ef40d7f6Sopenharmony_ci//! }
42ef40d7f6Sopenharmony_ci//! static INSTANCE: OnceCell<Logger> = OnceCell::new();
43ef40d7f6Sopenharmony_ci//!
44ef40d7f6Sopenharmony_ci//! impl Logger {
45ef40d7f6Sopenharmony_ci//!     pub fn global() -> &'static Logger {
46ef40d7f6Sopenharmony_ci//!         INSTANCE.get().expect("logger is not initialized")
47ef40d7f6Sopenharmony_ci//!     }
48ef40d7f6Sopenharmony_ci//!
49ef40d7f6Sopenharmony_ci//!     fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
50ef40d7f6Sopenharmony_ci//!        // ...
51ef40d7f6Sopenharmony_ci//! #      Ok(Logger {})
52ef40d7f6Sopenharmony_ci//!     }
53ef40d7f6Sopenharmony_ci//! }
54ef40d7f6Sopenharmony_ci//!
55ef40d7f6Sopenharmony_ci//! fn main() {
56ef40d7f6Sopenharmony_ci//!     let logger = Logger::from_cli(env::args()).unwrap();
57ef40d7f6Sopenharmony_ci//!     INSTANCE.set(logger).unwrap();
58ef40d7f6Sopenharmony_ci//!     // use `Logger::global()` from now on
59ef40d7f6Sopenharmony_ci//! }
60ef40d7f6Sopenharmony_ci//! ```
61ef40d7f6Sopenharmony_ci//!
62ef40d7f6Sopenharmony_ci//! ## Lazy Initialized Global Data
63ef40d7f6Sopenharmony_ci//!
64ef40d7f6Sopenharmony_ci//! This is essentially the `lazy_static!` macro, but without a macro.
65ef40d7f6Sopenharmony_ci//!
66ef40d7f6Sopenharmony_ci//! ```rust
67ef40d7f6Sopenharmony_ci//! use std::{sync::Mutex, collections::HashMap};
68ef40d7f6Sopenharmony_ci//!
69ef40d7f6Sopenharmony_ci//! use once_cell::sync::OnceCell;
70ef40d7f6Sopenharmony_ci//!
71ef40d7f6Sopenharmony_ci//! fn global_data() -> &'static Mutex<HashMap<i32, String>> {
72ef40d7f6Sopenharmony_ci//!     static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
73ef40d7f6Sopenharmony_ci//!     INSTANCE.get_or_init(|| {
74ef40d7f6Sopenharmony_ci//!         let mut m = HashMap::new();
75ef40d7f6Sopenharmony_ci//!         m.insert(13, "Spica".to_string());
76ef40d7f6Sopenharmony_ci//!         m.insert(74, "Hoyten".to_string());
77ef40d7f6Sopenharmony_ci//!         Mutex::new(m)
78ef40d7f6Sopenharmony_ci//!     })
79ef40d7f6Sopenharmony_ci//! }
80ef40d7f6Sopenharmony_ci//! ```
81ef40d7f6Sopenharmony_ci//!
82ef40d7f6Sopenharmony_ci//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to streamline this pattern:
83ef40d7f6Sopenharmony_ci//!
84ef40d7f6Sopenharmony_ci//! ```rust
85ef40d7f6Sopenharmony_ci//! use std::{sync::Mutex, collections::HashMap};
86ef40d7f6Sopenharmony_ci//! use once_cell::sync::Lazy;
87ef40d7f6Sopenharmony_ci//!
88ef40d7f6Sopenharmony_ci//! static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
89ef40d7f6Sopenharmony_ci//!     let mut m = HashMap::new();
90ef40d7f6Sopenharmony_ci//!     m.insert(13, "Spica".to_string());
91ef40d7f6Sopenharmony_ci//!     m.insert(74, "Hoyten".to_string());
92ef40d7f6Sopenharmony_ci//!     Mutex::new(m)
93ef40d7f6Sopenharmony_ci//! });
94ef40d7f6Sopenharmony_ci//!
95ef40d7f6Sopenharmony_ci//! fn main() {
96ef40d7f6Sopenharmony_ci//!     println!("{:?}", GLOBAL_DATA.lock().unwrap());
97ef40d7f6Sopenharmony_ci//! }
98ef40d7f6Sopenharmony_ci//! ```
99ef40d7f6Sopenharmony_ci//!
100ef40d7f6Sopenharmony_ci//! Note that the variable that holds `Lazy` is declared as `static`, *not*
101ef40d7f6Sopenharmony_ci//! `const`. This is important: using `const` instead compiles, but works wrong.
102ef40d7f6Sopenharmony_ci//!
103ef40d7f6Sopenharmony_ci//! [`sync::Lazy`]: sync/struct.Lazy.html
104ef40d7f6Sopenharmony_ci//! [`unsync::Lazy`]: unsync/struct.Lazy.html
105ef40d7f6Sopenharmony_ci//!
106ef40d7f6Sopenharmony_ci//! ## General purpose lazy evaluation
107ef40d7f6Sopenharmony_ci//!
108ef40d7f6Sopenharmony_ci//! Unlike `lazy_static!`, `Lazy` works with local variables.
109ef40d7f6Sopenharmony_ci//!
110ef40d7f6Sopenharmony_ci//! ```rust
111ef40d7f6Sopenharmony_ci//! use once_cell::unsync::Lazy;
112ef40d7f6Sopenharmony_ci//!
113ef40d7f6Sopenharmony_ci//! fn main() {
114ef40d7f6Sopenharmony_ci//!     let ctx = vec![1, 2, 3];
115ef40d7f6Sopenharmony_ci//!     let thunk = Lazy::new(|| {
116ef40d7f6Sopenharmony_ci//!         ctx.iter().sum::<i32>()
117ef40d7f6Sopenharmony_ci//!     });
118ef40d7f6Sopenharmony_ci//!     assert_eq!(*thunk, 6);
119ef40d7f6Sopenharmony_ci//! }
120ef40d7f6Sopenharmony_ci//! ```
121ef40d7f6Sopenharmony_ci//!
122ef40d7f6Sopenharmony_ci//! If you need a lazy field in a struct, you probably should use `OnceCell`
123ef40d7f6Sopenharmony_ci//! directly, because that will allow you to access `self` during initialization.
124ef40d7f6Sopenharmony_ci//!
125ef40d7f6Sopenharmony_ci//! ```rust
126ef40d7f6Sopenharmony_ci//! use std::{fs, path::PathBuf};
127ef40d7f6Sopenharmony_ci//!
128ef40d7f6Sopenharmony_ci//! use once_cell::unsync::OnceCell;
129ef40d7f6Sopenharmony_ci//!
130ef40d7f6Sopenharmony_ci//! struct Ctx {
131ef40d7f6Sopenharmony_ci//!     config_path: PathBuf,
132ef40d7f6Sopenharmony_ci//!     config: OnceCell<String>,
133ef40d7f6Sopenharmony_ci//! }
134ef40d7f6Sopenharmony_ci//!
135ef40d7f6Sopenharmony_ci//! impl Ctx {
136ef40d7f6Sopenharmony_ci//!     pub fn get_config(&self) -> Result<&str, std::io::Error> {
137ef40d7f6Sopenharmony_ci//!         let cfg = self.config.get_or_try_init(|| {
138ef40d7f6Sopenharmony_ci//!             fs::read_to_string(&self.config_path)
139ef40d7f6Sopenharmony_ci//!         })?;
140ef40d7f6Sopenharmony_ci//!         Ok(cfg.as_str())
141ef40d7f6Sopenharmony_ci//!     }
142ef40d7f6Sopenharmony_ci//! }
143ef40d7f6Sopenharmony_ci//! ```
144ef40d7f6Sopenharmony_ci//!
145ef40d7f6Sopenharmony_ci//! ## Lazily Compiled Regex
146ef40d7f6Sopenharmony_ci//!
147ef40d7f6Sopenharmony_ci//! This is a `regex!` macro which takes a string literal and returns an
148ef40d7f6Sopenharmony_ci//! *expression* that evaluates to a `&'static Regex`:
149ef40d7f6Sopenharmony_ci//!
150ef40d7f6Sopenharmony_ci//! ```
151ef40d7f6Sopenharmony_ci//! macro_rules! regex {
152ef40d7f6Sopenharmony_ci//!     ($re:literal $(,)?) => {{
153ef40d7f6Sopenharmony_ci//!         static RE: once_cell::sync::OnceCell<regex::Regex> = once_cell::sync::OnceCell::new();
154ef40d7f6Sopenharmony_ci//!         RE.get_or_init(|| regex::Regex::new($re).unwrap())
155ef40d7f6Sopenharmony_ci//!     }};
156ef40d7f6Sopenharmony_ci//! }
157ef40d7f6Sopenharmony_ci//! ```
158ef40d7f6Sopenharmony_ci//!
159ef40d7f6Sopenharmony_ci//! This macro can be useful to avoid the "compile regex on every loop iteration" problem.
160ef40d7f6Sopenharmony_ci//!
161ef40d7f6Sopenharmony_ci//! ## Runtime `include_bytes!`
162ef40d7f6Sopenharmony_ci//!
163ef40d7f6Sopenharmony_ci//! The `include_bytes` macro is useful to include test resources, but it slows
164ef40d7f6Sopenharmony_ci//! down test compilation a lot. An alternative is to load the resources at
165ef40d7f6Sopenharmony_ci//! runtime:
166ef40d7f6Sopenharmony_ci//!
167ef40d7f6Sopenharmony_ci//! ```
168ef40d7f6Sopenharmony_ci//! use std::path::Path;
169ef40d7f6Sopenharmony_ci//!
170ef40d7f6Sopenharmony_ci//! use once_cell::sync::OnceCell;
171ef40d7f6Sopenharmony_ci//!
172ef40d7f6Sopenharmony_ci//! pub struct TestResource {
173ef40d7f6Sopenharmony_ci//!     path: &'static str,
174ef40d7f6Sopenharmony_ci//!     cell: OnceCell<Vec<u8>>,
175ef40d7f6Sopenharmony_ci//! }
176ef40d7f6Sopenharmony_ci//!
177ef40d7f6Sopenharmony_ci//! impl TestResource {
178ef40d7f6Sopenharmony_ci//!     pub const fn new(path: &'static str) -> TestResource {
179ef40d7f6Sopenharmony_ci//!         TestResource { path, cell: OnceCell::new() }
180ef40d7f6Sopenharmony_ci//!     }
181ef40d7f6Sopenharmony_ci//!     pub fn bytes(&self) -> &[u8] {
182ef40d7f6Sopenharmony_ci//!         self.cell.get_or_init(|| {
183ef40d7f6Sopenharmony_ci//!             let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
184ef40d7f6Sopenharmony_ci//!             let path = Path::new(dir.as_str()).join(self.path);
185ef40d7f6Sopenharmony_ci//!             std::fs::read(&path).unwrap_or_else(|_err| {
186ef40d7f6Sopenharmony_ci//!                 panic!("failed to load test resource: {}", path.display())
187ef40d7f6Sopenharmony_ci//!             })
188ef40d7f6Sopenharmony_ci//!         }).as_slice()
189ef40d7f6Sopenharmony_ci//!     }
190ef40d7f6Sopenharmony_ci//! }
191ef40d7f6Sopenharmony_ci//!
192ef40d7f6Sopenharmony_ci//! static TEST_IMAGE: TestResource = TestResource::new("test_data/lena.png");
193ef40d7f6Sopenharmony_ci//!
194ef40d7f6Sopenharmony_ci//! #[test]
195ef40d7f6Sopenharmony_ci//! fn test_sobel_filter() {
196ef40d7f6Sopenharmony_ci//!     let rgb: &[u8] = TEST_IMAGE.bytes();
197ef40d7f6Sopenharmony_ci//!     // ...
198ef40d7f6Sopenharmony_ci//! # drop(rgb);
199ef40d7f6Sopenharmony_ci//! }
200ef40d7f6Sopenharmony_ci//! ```
201ef40d7f6Sopenharmony_ci//!
202ef40d7f6Sopenharmony_ci//! ## `lateinit`
203ef40d7f6Sopenharmony_ci//!
204ef40d7f6Sopenharmony_ci//! `LateInit` type for delayed initialization. It is reminiscent of Kotlin's
205ef40d7f6Sopenharmony_ci//! `lateinit` keyword and allows construction of cyclic data structures:
206ef40d7f6Sopenharmony_ci//!
207ef40d7f6Sopenharmony_ci//!
208ef40d7f6Sopenharmony_ci//! ```
209ef40d7f6Sopenharmony_ci//! use once_cell::sync::OnceCell;
210ef40d7f6Sopenharmony_ci//!
211ef40d7f6Sopenharmony_ci//! pub struct LateInit<T> { cell: OnceCell<T> }
212ef40d7f6Sopenharmony_ci//!
213ef40d7f6Sopenharmony_ci//! impl<T> LateInit<T> {
214ef40d7f6Sopenharmony_ci//!     pub fn init(&self, value: T) {
215ef40d7f6Sopenharmony_ci//!         assert!(self.cell.set(value).is_ok())
216ef40d7f6Sopenharmony_ci//!     }
217ef40d7f6Sopenharmony_ci//! }
218ef40d7f6Sopenharmony_ci//!
219ef40d7f6Sopenharmony_ci//! impl<T> Default for LateInit<T> {
220ef40d7f6Sopenharmony_ci//!     fn default() -> Self { LateInit { cell: OnceCell::default() } }
221ef40d7f6Sopenharmony_ci//! }
222ef40d7f6Sopenharmony_ci//!
223ef40d7f6Sopenharmony_ci//! impl<T> std::ops::Deref for LateInit<T> {
224ef40d7f6Sopenharmony_ci//!     type Target = T;
225ef40d7f6Sopenharmony_ci//!     fn deref(&self) -> &T {
226ef40d7f6Sopenharmony_ci//!         self.cell.get().unwrap()
227ef40d7f6Sopenharmony_ci//!     }
228ef40d7f6Sopenharmony_ci//! }
229ef40d7f6Sopenharmony_ci//!
230ef40d7f6Sopenharmony_ci//! #[derive(Default)]
231ef40d7f6Sopenharmony_ci//! struct A<'a> {
232ef40d7f6Sopenharmony_ci//!     b: LateInit<&'a B<'a>>,
233ef40d7f6Sopenharmony_ci//! }
234ef40d7f6Sopenharmony_ci//!
235ef40d7f6Sopenharmony_ci//! #[derive(Default)]
236ef40d7f6Sopenharmony_ci//! struct B<'a> {
237ef40d7f6Sopenharmony_ci//!     a: LateInit<&'a A<'a>>
238ef40d7f6Sopenharmony_ci//! }
239ef40d7f6Sopenharmony_ci//!
240ef40d7f6Sopenharmony_ci//!
241ef40d7f6Sopenharmony_ci//! fn build_cycle() {
242ef40d7f6Sopenharmony_ci//!     let a = A::default();
243ef40d7f6Sopenharmony_ci//!     let b = B::default();
244ef40d7f6Sopenharmony_ci//!     a.b.init(&b);
245ef40d7f6Sopenharmony_ci//!     b.a.init(&a);
246ef40d7f6Sopenharmony_ci//!
247ef40d7f6Sopenharmony_ci//!     let _a = &a.b.a.b.a;
248ef40d7f6Sopenharmony_ci//! }
249ef40d7f6Sopenharmony_ci//! ```
250ef40d7f6Sopenharmony_ci//!
251ef40d7f6Sopenharmony_ci//! # Comparison with std
252ef40d7f6Sopenharmony_ci//!
253ef40d7f6Sopenharmony_ci//! |`!Sync` types         | Access Mode            | Drawbacks                                     |
254ef40d7f6Sopenharmony_ci//! |----------------------|------------------------|-----------------------------------------------|
255ef40d7f6Sopenharmony_ci//! |`Cell<T>`             | `T`                    | requires `T: Copy` for `get`                  |
256ef40d7f6Sopenharmony_ci//! |`RefCell<T>`          | `RefMut<T>` / `Ref<T>` | may panic at runtime                          |
257ef40d7f6Sopenharmony_ci//! |`unsync::OnceCell<T>` | `&T`                   | assignable only once                          |
258ef40d7f6Sopenharmony_ci//!
259ef40d7f6Sopenharmony_ci//! |`Sync` types          | Access Mode            | Drawbacks                                     |
260ef40d7f6Sopenharmony_ci//! |----------------------|------------------------|-----------------------------------------------|
261ef40d7f6Sopenharmony_ci//! |`AtomicT`             | `T`                    | works only with certain `Copy` types          |
262ef40d7f6Sopenharmony_ci//! |`Mutex<T>`            | `MutexGuard<T>`        | may deadlock at runtime, may block the thread |
263ef40d7f6Sopenharmony_ci//! |`sync::OnceCell<T>`   | `&T`                   | assignable only once, may block the thread    |
264ef40d7f6Sopenharmony_ci//!
265ef40d7f6Sopenharmony_ci//! Technically, calling `get_or_init` will also cause a panic or a deadlock if it recursively calls
266ef40d7f6Sopenharmony_ci//! itself. However, because the assignment can happen only once, such cases should be more rare than
267ef40d7f6Sopenharmony_ci//! equivalents with `RefCell` and `Mutex`.
268ef40d7f6Sopenharmony_ci//!
269ef40d7f6Sopenharmony_ci//! # Minimum Supported `rustc` Version
270ef40d7f6Sopenharmony_ci//!
271ef40d7f6Sopenharmony_ci//! This crate's minimum supported `rustc` version is `1.56.0`.
272ef40d7f6Sopenharmony_ci//!
273ef40d7f6Sopenharmony_ci//! If only the `std` feature is enabled, MSRV will be updated conservatively, supporting at least latest 8 versions of the compiler.
274ef40d7f6Sopenharmony_ci//! When using other features, like `parking_lot`, MSRV might be updated more frequently, up to the latest stable.
275ef40d7f6Sopenharmony_ci//! In both cases, increasing MSRV is *not* considered a semver-breaking change.
276ef40d7f6Sopenharmony_ci//!
277ef40d7f6Sopenharmony_ci//! # Implementation details
278ef40d7f6Sopenharmony_ci//!
279ef40d7f6Sopenharmony_ci//! The implementation is based on the [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/)
280ef40d7f6Sopenharmony_ci//! and [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and [`std::sync::Once`]. In some sense,
281ef40d7f6Sopenharmony_ci//! `once_cell` just streamlines and unifies those APIs.
282ef40d7f6Sopenharmony_ci//!
283ef40d7f6Sopenharmony_ci//! To implement a sync flavor of `OnceCell`, this crates uses either a custom
284ef40d7f6Sopenharmony_ci//! re-implementation of `std::sync::Once` or `parking_lot::Mutex`. This is
285ef40d7f6Sopenharmony_ci//! controlled by the `parking_lot` feature (disabled by default). Performance
286ef40d7f6Sopenharmony_ci//! is the same for both cases, but the `parking_lot` based `OnceCell<T>` is
287ef40d7f6Sopenharmony_ci//! smaller by up to 16 bytes.
288ef40d7f6Sopenharmony_ci//!
289ef40d7f6Sopenharmony_ci//! This crate uses `unsafe`.
290ef40d7f6Sopenharmony_ci//!
291ef40d7f6Sopenharmony_ci//! [`std::sync::Once`]: https://doc.rust-lang.org/std/sync/struct.Once.html
292ef40d7f6Sopenharmony_ci//!
293ef40d7f6Sopenharmony_ci//! # F.A.Q.
294ef40d7f6Sopenharmony_ci//!
295ef40d7f6Sopenharmony_ci//! **Should I use lazy_static or once_cell?**
296ef40d7f6Sopenharmony_ci//!
297ef40d7f6Sopenharmony_ci//! To the first approximation, `once_cell` is both more flexible and more convenient than `lazy_static`
298ef40d7f6Sopenharmony_ci//! and should be preferred.
299ef40d7f6Sopenharmony_ci//!
300ef40d7f6Sopenharmony_ci//! Unlike `once_cell`, `lazy_static` supports spinlock-based implementation of blocking which works with
301ef40d7f6Sopenharmony_ci//! `#![no_std]`.
302ef40d7f6Sopenharmony_ci//!
303ef40d7f6Sopenharmony_ci//! `lazy_static` has received significantly more real world testing, but `once_cell` is also a widely
304ef40d7f6Sopenharmony_ci//! used crate.
305ef40d7f6Sopenharmony_ci//!
306ef40d7f6Sopenharmony_ci//! **Should I use the sync or unsync flavor?**
307ef40d7f6Sopenharmony_ci//!
308ef40d7f6Sopenharmony_ci//! Because Rust compiler checks thread safety for you, it's impossible to accidentally use `unsync` where
309ef40d7f6Sopenharmony_ci//! `sync` is required. So, use `unsync` in single-threaded code and `sync` in multi-threaded. It's easy
310ef40d7f6Sopenharmony_ci//! to switch between the two if code becomes multi-threaded later.
311ef40d7f6Sopenharmony_ci//!
312ef40d7f6Sopenharmony_ci//! At the moment, `unsync` has an additional benefit that reentrant initialization causes a panic, which
313ef40d7f6Sopenharmony_ci//! might be easier to debug than a deadlock.
314ef40d7f6Sopenharmony_ci//!
315ef40d7f6Sopenharmony_ci//! **Does this crate support async?**
316ef40d7f6Sopenharmony_ci//!
317ef40d7f6Sopenharmony_ci//! No, but you can use [`async_once_cell`](https://crates.io/crates/async_once_cell) instead.
318ef40d7f6Sopenharmony_ci//!
319ef40d7f6Sopenharmony_ci//! **Can I bring my own mutex?**
320ef40d7f6Sopenharmony_ci//!
321ef40d7f6Sopenharmony_ci//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to allow just that.
322ef40d7f6Sopenharmony_ci//!
323ef40d7f6Sopenharmony_ci//! # Related crates
324ef40d7f6Sopenharmony_ci//!
325ef40d7f6Sopenharmony_ci//! * [double-checked-cell](https://github.com/niklasf/double-checked-cell)
326ef40d7f6Sopenharmony_ci//! * [lazy-init](https://crates.io/crates/lazy-init)
327ef40d7f6Sopenharmony_ci//! * [lazycell](https://crates.io/crates/lazycell)
328ef40d7f6Sopenharmony_ci//! * [mitochondria](https://crates.io/crates/mitochondria)
329ef40d7f6Sopenharmony_ci//! * [lazy_static](https://crates.io/crates/lazy_static)
330ef40d7f6Sopenharmony_ci//! * [async_once_cell](https://crates.io/crates/async_once_cell)
331ef40d7f6Sopenharmony_ci//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring your own mutex)
332ef40d7f6Sopenharmony_ci//!
333ef40d7f6Sopenharmony_ci//! Most of this crate's functionality is available in `std` in nightly Rust.
334ef40d7f6Sopenharmony_ci//! See the [tracking issue](https://github.com/rust-lang/rust/issues/74465).
335ef40d7f6Sopenharmony_ci
336ef40d7f6Sopenharmony_ci#![cfg_attr(not(feature = "std"), no_std)]
337ef40d7f6Sopenharmony_ci
338ef40d7f6Sopenharmony_ci#[cfg(feature = "alloc")]
339ef40d7f6Sopenharmony_ciextern crate alloc;
340ef40d7f6Sopenharmony_ci
341ef40d7f6Sopenharmony_ci#[cfg(all(feature = "critical-section", not(feature = "std")))]
342ef40d7f6Sopenharmony_ci#[path = "imp_cs.rs"]
343ef40d7f6Sopenharmony_cimod imp;
344ef40d7f6Sopenharmony_ci
345ef40d7f6Sopenharmony_ci#[cfg(all(feature = "std", feature = "parking_lot"))]
346ef40d7f6Sopenharmony_ci#[path = "imp_pl.rs"]
347ef40d7f6Sopenharmony_cimod imp;
348ef40d7f6Sopenharmony_ci
349ef40d7f6Sopenharmony_ci#[cfg(all(feature = "std", not(feature = "parking_lot")))]
350ef40d7f6Sopenharmony_ci#[path = "imp_std.rs"]
351ef40d7f6Sopenharmony_cimod imp;
352ef40d7f6Sopenharmony_ci
353ef40d7f6Sopenharmony_ci/// Single-threaded version of `OnceCell`.
354ef40d7f6Sopenharmony_cipub mod unsync {
355ef40d7f6Sopenharmony_ci    use core::{
356ef40d7f6Sopenharmony_ci        cell::{Cell, UnsafeCell},
357ef40d7f6Sopenharmony_ci        fmt, mem,
358ef40d7f6Sopenharmony_ci        ops::{Deref, DerefMut},
359ef40d7f6Sopenharmony_ci        panic::{RefUnwindSafe, UnwindSafe},
360ef40d7f6Sopenharmony_ci    };
361ef40d7f6Sopenharmony_ci
362ef40d7f6Sopenharmony_ci    use super::unwrap_unchecked;
363ef40d7f6Sopenharmony_ci
364ef40d7f6Sopenharmony_ci    /// A cell which can be written to only once. It is not thread safe.
365ef40d7f6Sopenharmony_ci    ///
366ef40d7f6Sopenharmony_ci    /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&`
367ef40d7f6Sopenharmony_ci    /// references to the contents.
368ef40d7f6Sopenharmony_ci    ///
369ef40d7f6Sopenharmony_ci    /// [`std::cell::RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
370ef40d7f6Sopenharmony_ci    ///
371ef40d7f6Sopenharmony_ci    /// # Example
372ef40d7f6Sopenharmony_ci    /// ```
373ef40d7f6Sopenharmony_ci    /// use once_cell::unsync::OnceCell;
374ef40d7f6Sopenharmony_ci    ///
375ef40d7f6Sopenharmony_ci    /// let cell = OnceCell::new();
376ef40d7f6Sopenharmony_ci    /// assert!(cell.get().is_none());
377ef40d7f6Sopenharmony_ci    ///
378ef40d7f6Sopenharmony_ci    /// let value: &String = cell.get_or_init(|| {
379ef40d7f6Sopenharmony_ci    ///     "Hello, World!".to_string()
380ef40d7f6Sopenharmony_ci    /// });
381ef40d7f6Sopenharmony_ci    /// assert_eq!(value, "Hello, World!");
382ef40d7f6Sopenharmony_ci    /// assert!(cell.get().is_some());
383ef40d7f6Sopenharmony_ci    /// ```
384ef40d7f6Sopenharmony_ci    pub struct OnceCell<T> {
385ef40d7f6Sopenharmony_ci        // Invariant: written to at most once.
386ef40d7f6Sopenharmony_ci        inner: UnsafeCell<Option<T>>,
387ef40d7f6Sopenharmony_ci    }
388ef40d7f6Sopenharmony_ci
389ef40d7f6Sopenharmony_ci    // Similarly to a `Sync` bound on `sync::OnceCell`, we can use
390ef40d7f6Sopenharmony_ci    // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`,
391ef40d7f6Sopenharmony_ci    // by initializing the cell in closure and extracting the value in the
392ef40d7f6Sopenharmony_ci    // `Drop`.
393ef40d7f6Sopenharmony_ci    impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
394ef40d7f6Sopenharmony_ci    impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
395ef40d7f6Sopenharmony_ci
396ef40d7f6Sopenharmony_ci    impl<T> Default for OnceCell<T> {
397ef40d7f6Sopenharmony_ci        fn default() -> Self {
398ef40d7f6Sopenharmony_ci            Self::new()
399ef40d7f6Sopenharmony_ci        }
400ef40d7f6Sopenharmony_ci    }
401ef40d7f6Sopenharmony_ci
402ef40d7f6Sopenharmony_ci    impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
403ef40d7f6Sopenharmony_ci        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
404ef40d7f6Sopenharmony_ci            match self.get() {
405ef40d7f6Sopenharmony_ci                Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
406ef40d7f6Sopenharmony_ci                None => f.write_str("OnceCell(Uninit)"),
407ef40d7f6Sopenharmony_ci            }
408ef40d7f6Sopenharmony_ci        }
409ef40d7f6Sopenharmony_ci    }
410ef40d7f6Sopenharmony_ci
411ef40d7f6Sopenharmony_ci    impl<T: Clone> Clone for OnceCell<T> {
412ef40d7f6Sopenharmony_ci        fn clone(&self) -> OnceCell<T> {
413ef40d7f6Sopenharmony_ci            match self.get() {
414ef40d7f6Sopenharmony_ci                Some(value) => OnceCell::with_value(value.clone()),
415ef40d7f6Sopenharmony_ci                None => OnceCell::new(),
416ef40d7f6Sopenharmony_ci            }
417ef40d7f6Sopenharmony_ci        }
418ef40d7f6Sopenharmony_ci
419ef40d7f6Sopenharmony_ci        fn clone_from(&mut self, source: &Self) {
420ef40d7f6Sopenharmony_ci            match (self.get_mut(), source.get()) {
421ef40d7f6Sopenharmony_ci                (Some(this), Some(source)) => this.clone_from(source),
422ef40d7f6Sopenharmony_ci                _ => *self = source.clone(),
423ef40d7f6Sopenharmony_ci            }
424ef40d7f6Sopenharmony_ci        }
425ef40d7f6Sopenharmony_ci    }
426ef40d7f6Sopenharmony_ci
427ef40d7f6Sopenharmony_ci    impl<T: PartialEq> PartialEq for OnceCell<T> {
428ef40d7f6Sopenharmony_ci        fn eq(&self, other: &Self) -> bool {
429ef40d7f6Sopenharmony_ci            self.get() == other.get()
430ef40d7f6Sopenharmony_ci        }
431ef40d7f6Sopenharmony_ci    }
432ef40d7f6Sopenharmony_ci
433ef40d7f6Sopenharmony_ci    impl<T: Eq> Eq for OnceCell<T> {}
434ef40d7f6Sopenharmony_ci
435ef40d7f6Sopenharmony_ci    impl<T> From<T> for OnceCell<T> {
436ef40d7f6Sopenharmony_ci        fn from(value: T) -> Self {
437ef40d7f6Sopenharmony_ci            OnceCell::with_value(value)
438ef40d7f6Sopenharmony_ci        }
439ef40d7f6Sopenharmony_ci    }
440ef40d7f6Sopenharmony_ci
441ef40d7f6Sopenharmony_ci    impl<T> OnceCell<T> {
442ef40d7f6Sopenharmony_ci        /// Creates a new empty cell.
443ef40d7f6Sopenharmony_ci        pub const fn new() -> OnceCell<T> {
444ef40d7f6Sopenharmony_ci            OnceCell { inner: UnsafeCell::new(None) }
445ef40d7f6Sopenharmony_ci        }
446ef40d7f6Sopenharmony_ci
447ef40d7f6Sopenharmony_ci        /// Creates a new initialized cell.
448ef40d7f6Sopenharmony_ci        pub const fn with_value(value: T) -> OnceCell<T> {
449ef40d7f6Sopenharmony_ci            OnceCell { inner: UnsafeCell::new(Some(value)) }
450ef40d7f6Sopenharmony_ci        }
451ef40d7f6Sopenharmony_ci
452ef40d7f6Sopenharmony_ci        /// Gets a reference to the underlying value.
453ef40d7f6Sopenharmony_ci        ///
454ef40d7f6Sopenharmony_ci        /// Returns `None` if the cell is empty.
455ef40d7f6Sopenharmony_ci        #[inline]
456ef40d7f6Sopenharmony_ci        pub fn get(&self) -> Option<&T> {
457ef40d7f6Sopenharmony_ci            // Safe due to `inner`'s invariant
458ef40d7f6Sopenharmony_ci            unsafe { &*self.inner.get() }.as_ref()
459ef40d7f6Sopenharmony_ci        }
460ef40d7f6Sopenharmony_ci
461ef40d7f6Sopenharmony_ci        /// Gets a mutable reference to the underlying value.
462ef40d7f6Sopenharmony_ci        ///
463ef40d7f6Sopenharmony_ci        /// Returns `None` if the cell is empty.
464ef40d7f6Sopenharmony_ci        ///
465ef40d7f6Sopenharmony_ci        /// This method is allowed to violate the invariant of writing to a `OnceCell`
466ef40d7f6Sopenharmony_ci        /// at most once because it requires `&mut` access to `self`. As with all
467ef40d7f6Sopenharmony_ci        /// interior mutability, `&mut` access permits arbitrary modification:
468ef40d7f6Sopenharmony_ci        ///
469ef40d7f6Sopenharmony_ci        /// ```
470ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
471ef40d7f6Sopenharmony_ci        ///
472ef40d7f6Sopenharmony_ci        /// let mut cell: OnceCell<u32> = OnceCell::new();
473ef40d7f6Sopenharmony_ci        /// cell.set(92).unwrap();
474ef40d7f6Sopenharmony_ci        /// *cell.get_mut().unwrap() = 93;
475ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get(), Some(&93));
476ef40d7f6Sopenharmony_ci        /// ```
477ef40d7f6Sopenharmony_ci        #[inline]
478ef40d7f6Sopenharmony_ci        pub fn get_mut(&mut self) -> Option<&mut T> {
479ef40d7f6Sopenharmony_ci            // Safe because we have unique access
480ef40d7f6Sopenharmony_ci            unsafe { &mut *self.inner.get() }.as_mut()
481ef40d7f6Sopenharmony_ci        }
482ef40d7f6Sopenharmony_ci
483ef40d7f6Sopenharmony_ci        /// Sets the contents of this cell to `value`.
484ef40d7f6Sopenharmony_ci        ///
485ef40d7f6Sopenharmony_ci        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
486ef40d7f6Sopenharmony_ci        /// full.
487ef40d7f6Sopenharmony_ci        ///
488ef40d7f6Sopenharmony_ci        /// # Example
489ef40d7f6Sopenharmony_ci        /// ```
490ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
491ef40d7f6Sopenharmony_ci        ///
492ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
493ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_none());
494ef40d7f6Sopenharmony_ci        ///
495ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.set(92), Ok(()));
496ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.set(62), Err(62));
497ef40d7f6Sopenharmony_ci        ///
498ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_some());
499ef40d7f6Sopenharmony_ci        /// ```
500ef40d7f6Sopenharmony_ci        pub fn set(&self, value: T) -> Result<(), T> {
501ef40d7f6Sopenharmony_ci            match self.try_insert(value) {
502ef40d7f6Sopenharmony_ci                Ok(_) => Ok(()),
503ef40d7f6Sopenharmony_ci                Err((_, value)) => Err(value),
504ef40d7f6Sopenharmony_ci            }
505ef40d7f6Sopenharmony_ci        }
506ef40d7f6Sopenharmony_ci
507ef40d7f6Sopenharmony_ci        /// Like [`set`](Self::set), but also returns a reference to the final cell value.
508ef40d7f6Sopenharmony_ci        ///
509ef40d7f6Sopenharmony_ci        /// # Example
510ef40d7f6Sopenharmony_ci        /// ```
511ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
512ef40d7f6Sopenharmony_ci        ///
513ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
514ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_none());
515ef40d7f6Sopenharmony_ci        ///
516ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.try_insert(92), Ok(&92));
517ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
518ef40d7f6Sopenharmony_ci        ///
519ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_some());
520ef40d7f6Sopenharmony_ci        /// ```
521ef40d7f6Sopenharmony_ci        pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
522ef40d7f6Sopenharmony_ci            if let Some(old) = self.get() {
523ef40d7f6Sopenharmony_ci                return Err((old, value));
524ef40d7f6Sopenharmony_ci            }
525ef40d7f6Sopenharmony_ci
526ef40d7f6Sopenharmony_ci            let slot = unsafe { &mut *self.inner.get() };
527ef40d7f6Sopenharmony_ci            // This is the only place where we set the slot, no races
528ef40d7f6Sopenharmony_ci            // due to reentrancy/concurrency are possible, and we've
529ef40d7f6Sopenharmony_ci            // checked that slot is currently `None`, so this write
530ef40d7f6Sopenharmony_ci            // maintains the `inner`'s invariant.
531ef40d7f6Sopenharmony_ci            *slot = Some(value);
532ef40d7f6Sopenharmony_ci            Ok(unsafe { unwrap_unchecked(slot.as_ref()) })
533ef40d7f6Sopenharmony_ci        }
534ef40d7f6Sopenharmony_ci
535ef40d7f6Sopenharmony_ci        /// Gets the contents of the cell, initializing it with `f`
536ef40d7f6Sopenharmony_ci        /// if the cell was empty.
537ef40d7f6Sopenharmony_ci        ///
538ef40d7f6Sopenharmony_ci        /// # Panics
539ef40d7f6Sopenharmony_ci        ///
540ef40d7f6Sopenharmony_ci        /// If `f` panics, the panic is propagated to the caller, and the cell
541ef40d7f6Sopenharmony_ci        /// remains uninitialized.
542ef40d7f6Sopenharmony_ci        ///
543ef40d7f6Sopenharmony_ci        /// It is an error to reentrantly initialize the cell from `f`. Doing
544ef40d7f6Sopenharmony_ci        /// so results in a panic.
545ef40d7f6Sopenharmony_ci        ///
546ef40d7f6Sopenharmony_ci        /// # Example
547ef40d7f6Sopenharmony_ci        /// ```
548ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
549ef40d7f6Sopenharmony_ci        ///
550ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
551ef40d7f6Sopenharmony_ci        /// let value = cell.get_or_init(|| 92);
552ef40d7f6Sopenharmony_ci        /// assert_eq!(value, &92);
553ef40d7f6Sopenharmony_ci        /// let value = cell.get_or_init(|| unreachable!());
554ef40d7f6Sopenharmony_ci        /// assert_eq!(value, &92);
555ef40d7f6Sopenharmony_ci        /// ```
556ef40d7f6Sopenharmony_ci        pub fn get_or_init<F>(&self, f: F) -> &T
557ef40d7f6Sopenharmony_ci        where
558ef40d7f6Sopenharmony_ci            F: FnOnce() -> T,
559ef40d7f6Sopenharmony_ci        {
560ef40d7f6Sopenharmony_ci            enum Void {}
561ef40d7f6Sopenharmony_ci            match self.get_or_try_init(|| Ok::<T, Void>(f())) {
562ef40d7f6Sopenharmony_ci                Ok(val) => val,
563ef40d7f6Sopenharmony_ci                Err(void) => match void {},
564ef40d7f6Sopenharmony_ci            }
565ef40d7f6Sopenharmony_ci        }
566ef40d7f6Sopenharmony_ci
567ef40d7f6Sopenharmony_ci        /// Gets the contents of the cell, initializing it with `f` if
568ef40d7f6Sopenharmony_ci        /// the cell was empty. If the cell was empty and `f` failed, an
569ef40d7f6Sopenharmony_ci        /// error is returned.
570ef40d7f6Sopenharmony_ci        ///
571ef40d7f6Sopenharmony_ci        /// # Panics
572ef40d7f6Sopenharmony_ci        ///
573ef40d7f6Sopenharmony_ci        /// If `f` panics, the panic is propagated to the caller, and the cell
574ef40d7f6Sopenharmony_ci        /// remains uninitialized.
575ef40d7f6Sopenharmony_ci        ///
576ef40d7f6Sopenharmony_ci        /// It is an error to reentrantly initialize the cell from `f`. Doing
577ef40d7f6Sopenharmony_ci        /// so results in a panic.
578ef40d7f6Sopenharmony_ci        ///
579ef40d7f6Sopenharmony_ci        /// # Example
580ef40d7f6Sopenharmony_ci        /// ```
581ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
582ef40d7f6Sopenharmony_ci        ///
583ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
584ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
585ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_none());
586ef40d7f6Sopenharmony_ci        /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
587ef40d7f6Sopenharmony_ci        ///     Ok(92)
588ef40d7f6Sopenharmony_ci        /// });
589ef40d7f6Sopenharmony_ci        /// assert_eq!(value, Ok(&92));
590ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get(), Some(&92))
591ef40d7f6Sopenharmony_ci        /// ```
592ef40d7f6Sopenharmony_ci        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
593ef40d7f6Sopenharmony_ci        where
594ef40d7f6Sopenharmony_ci            F: FnOnce() -> Result<T, E>,
595ef40d7f6Sopenharmony_ci        {
596ef40d7f6Sopenharmony_ci            if let Some(val) = self.get() {
597ef40d7f6Sopenharmony_ci                return Ok(val);
598ef40d7f6Sopenharmony_ci            }
599ef40d7f6Sopenharmony_ci            let val = f()?;
600ef40d7f6Sopenharmony_ci            // Note that *some* forms of reentrant initialization might lead to
601ef40d7f6Sopenharmony_ci            // UB (see `reentrant_init` test). I believe that just removing this
602ef40d7f6Sopenharmony_ci            // `assert`, while keeping `set/get` would be sound, but it seems
603ef40d7f6Sopenharmony_ci            // better to panic, rather than to silently use an old value.
604ef40d7f6Sopenharmony_ci            assert!(self.set(val).is_ok(), "reentrant init");
605ef40d7f6Sopenharmony_ci            Ok(unsafe { unwrap_unchecked(self.get()) })
606ef40d7f6Sopenharmony_ci        }
607ef40d7f6Sopenharmony_ci
608ef40d7f6Sopenharmony_ci        /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
609ef40d7f6Sopenharmony_ci        ///
610ef40d7f6Sopenharmony_ci        /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
611ef40d7f6Sopenharmony_ci        ///
612ef40d7f6Sopenharmony_ci        /// # Examples
613ef40d7f6Sopenharmony_ci        ///
614ef40d7f6Sopenharmony_ci        /// ```
615ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
616ef40d7f6Sopenharmony_ci        ///
617ef40d7f6Sopenharmony_ci        /// let mut cell: OnceCell<String> = OnceCell::new();
618ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.take(), None);
619ef40d7f6Sopenharmony_ci        ///
620ef40d7f6Sopenharmony_ci        /// let mut cell = OnceCell::new();
621ef40d7f6Sopenharmony_ci        /// cell.set("hello".to_string()).unwrap();
622ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.take(), Some("hello".to_string()));
623ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get(), None);
624ef40d7f6Sopenharmony_ci        /// ```
625ef40d7f6Sopenharmony_ci        ///
626ef40d7f6Sopenharmony_ci        /// This method is allowed to violate the invariant of writing to a `OnceCell`
627ef40d7f6Sopenharmony_ci        /// at most once because it requires `&mut` access to `self`. As with all
628ef40d7f6Sopenharmony_ci        /// interior mutability, `&mut` access permits arbitrary modification:
629ef40d7f6Sopenharmony_ci        ///
630ef40d7f6Sopenharmony_ci        /// ```
631ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
632ef40d7f6Sopenharmony_ci        ///
633ef40d7f6Sopenharmony_ci        /// let mut cell: OnceCell<u32> = OnceCell::new();
634ef40d7f6Sopenharmony_ci        /// cell.set(92).unwrap();
635ef40d7f6Sopenharmony_ci        /// cell = OnceCell::new();
636ef40d7f6Sopenharmony_ci        /// ```
637ef40d7f6Sopenharmony_ci        pub fn take(&mut self) -> Option<T> {
638ef40d7f6Sopenharmony_ci            mem::replace(self, Self::default()).into_inner()
639ef40d7f6Sopenharmony_ci        }
640ef40d7f6Sopenharmony_ci
641ef40d7f6Sopenharmony_ci        /// Consumes the `OnceCell`, returning the wrapped value.
642ef40d7f6Sopenharmony_ci        ///
643ef40d7f6Sopenharmony_ci        /// Returns `None` if the cell was empty.
644ef40d7f6Sopenharmony_ci        ///
645ef40d7f6Sopenharmony_ci        /// # Examples
646ef40d7f6Sopenharmony_ci        ///
647ef40d7f6Sopenharmony_ci        /// ```
648ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
649ef40d7f6Sopenharmony_ci        ///
650ef40d7f6Sopenharmony_ci        /// let cell: OnceCell<String> = OnceCell::new();
651ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.into_inner(), None);
652ef40d7f6Sopenharmony_ci        ///
653ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
654ef40d7f6Sopenharmony_ci        /// cell.set("hello".to_string()).unwrap();
655ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
656ef40d7f6Sopenharmony_ci        /// ```
657ef40d7f6Sopenharmony_ci        pub fn into_inner(self) -> Option<T> {
658ef40d7f6Sopenharmony_ci            // Because `into_inner` takes `self` by value, the compiler statically verifies
659ef40d7f6Sopenharmony_ci            // that it is not currently borrowed. So it is safe to move out `Option<T>`.
660ef40d7f6Sopenharmony_ci            self.inner.into_inner()
661ef40d7f6Sopenharmony_ci        }
662ef40d7f6Sopenharmony_ci    }
663ef40d7f6Sopenharmony_ci
664ef40d7f6Sopenharmony_ci    /// A value which is initialized on the first access.
665ef40d7f6Sopenharmony_ci    ///
666ef40d7f6Sopenharmony_ci    /// # Example
667ef40d7f6Sopenharmony_ci    /// ```
668ef40d7f6Sopenharmony_ci    /// use once_cell::unsync::Lazy;
669ef40d7f6Sopenharmony_ci    ///
670ef40d7f6Sopenharmony_ci    /// let lazy: Lazy<i32> = Lazy::new(|| {
671ef40d7f6Sopenharmony_ci    ///     println!("initializing");
672ef40d7f6Sopenharmony_ci    ///     92
673ef40d7f6Sopenharmony_ci    /// });
674ef40d7f6Sopenharmony_ci    /// println!("ready");
675ef40d7f6Sopenharmony_ci    /// println!("{}", *lazy);
676ef40d7f6Sopenharmony_ci    /// println!("{}", *lazy);
677ef40d7f6Sopenharmony_ci    ///
678ef40d7f6Sopenharmony_ci    /// // Prints:
679ef40d7f6Sopenharmony_ci    /// //   ready
680ef40d7f6Sopenharmony_ci    /// //   initializing
681ef40d7f6Sopenharmony_ci    /// //   92
682ef40d7f6Sopenharmony_ci    /// //   92
683ef40d7f6Sopenharmony_ci    /// ```
684ef40d7f6Sopenharmony_ci    pub struct Lazy<T, F = fn() -> T> {
685ef40d7f6Sopenharmony_ci        cell: OnceCell<T>,
686ef40d7f6Sopenharmony_ci        init: Cell<Option<F>>,
687ef40d7f6Sopenharmony_ci    }
688ef40d7f6Sopenharmony_ci
689ef40d7f6Sopenharmony_ci    impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
690ef40d7f6Sopenharmony_ci
691ef40d7f6Sopenharmony_ci    impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
692ef40d7f6Sopenharmony_ci        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
693ef40d7f6Sopenharmony_ci            f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
694ef40d7f6Sopenharmony_ci        }
695ef40d7f6Sopenharmony_ci    }
696ef40d7f6Sopenharmony_ci
697ef40d7f6Sopenharmony_ci    impl<T, F> Lazy<T, F> {
698ef40d7f6Sopenharmony_ci        /// Creates a new lazy value with the given initializing function.
699ef40d7f6Sopenharmony_ci        ///
700ef40d7f6Sopenharmony_ci        /// # Example
701ef40d7f6Sopenharmony_ci        /// ```
702ef40d7f6Sopenharmony_ci        /// # fn main() {
703ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::Lazy;
704ef40d7f6Sopenharmony_ci        ///
705ef40d7f6Sopenharmony_ci        /// let hello = "Hello, World!".to_string();
706ef40d7f6Sopenharmony_ci        ///
707ef40d7f6Sopenharmony_ci        /// let lazy = Lazy::new(|| hello.to_uppercase());
708ef40d7f6Sopenharmony_ci        ///
709ef40d7f6Sopenharmony_ci        /// assert_eq!(&*lazy, "HELLO, WORLD!");
710ef40d7f6Sopenharmony_ci        /// # }
711ef40d7f6Sopenharmony_ci        /// ```
712ef40d7f6Sopenharmony_ci        pub const fn new(init: F) -> Lazy<T, F> {
713ef40d7f6Sopenharmony_ci            Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
714ef40d7f6Sopenharmony_ci        }
715ef40d7f6Sopenharmony_ci
716ef40d7f6Sopenharmony_ci        /// Consumes this `Lazy` returning the stored value.
717ef40d7f6Sopenharmony_ci        ///
718ef40d7f6Sopenharmony_ci        /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
719ef40d7f6Sopenharmony_ci        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
720ef40d7f6Sopenharmony_ci            let cell = this.cell;
721ef40d7f6Sopenharmony_ci            let init = this.init;
722ef40d7f6Sopenharmony_ci            cell.into_inner().ok_or_else(|| {
723ef40d7f6Sopenharmony_ci                init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned"))
724ef40d7f6Sopenharmony_ci            })
725ef40d7f6Sopenharmony_ci        }
726ef40d7f6Sopenharmony_ci    }
727ef40d7f6Sopenharmony_ci
728ef40d7f6Sopenharmony_ci    impl<T, F: FnOnce() -> T> Lazy<T, F> {
729ef40d7f6Sopenharmony_ci        /// Forces the evaluation of this lazy value and returns a reference to
730ef40d7f6Sopenharmony_ci        /// the result.
731ef40d7f6Sopenharmony_ci        ///
732ef40d7f6Sopenharmony_ci        /// This is equivalent to the `Deref` impl, but is explicit.
733ef40d7f6Sopenharmony_ci        ///
734ef40d7f6Sopenharmony_ci        /// # Example
735ef40d7f6Sopenharmony_ci        /// ```
736ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::Lazy;
737ef40d7f6Sopenharmony_ci        ///
738ef40d7f6Sopenharmony_ci        /// let lazy = Lazy::new(|| 92);
739ef40d7f6Sopenharmony_ci        ///
740ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::force(&lazy), &92);
741ef40d7f6Sopenharmony_ci        /// assert_eq!(&*lazy, &92);
742ef40d7f6Sopenharmony_ci        /// ```
743ef40d7f6Sopenharmony_ci        pub fn force(this: &Lazy<T, F>) -> &T {
744ef40d7f6Sopenharmony_ci            this.cell.get_or_init(|| match this.init.take() {
745ef40d7f6Sopenharmony_ci                Some(f) => f(),
746ef40d7f6Sopenharmony_ci                None => panic!("Lazy instance has previously been poisoned"),
747ef40d7f6Sopenharmony_ci            })
748ef40d7f6Sopenharmony_ci        }
749ef40d7f6Sopenharmony_ci
750ef40d7f6Sopenharmony_ci        /// Forces the evaluation of this lazy value and returns a mutable reference to
751ef40d7f6Sopenharmony_ci        /// the result.
752ef40d7f6Sopenharmony_ci        ///
753ef40d7f6Sopenharmony_ci        /// This is equivalent to the `DerefMut` impl, but is explicit.
754ef40d7f6Sopenharmony_ci        ///
755ef40d7f6Sopenharmony_ci        /// # Example
756ef40d7f6Sopenharmony_ci        /// ```
757ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::Lazy;
758ef40d7f6Sopenharmony_ci        ///
759ef40d7f6Sopenharmony_ci        /// let mut lazy = Lazy::new(|| 92);
760ef40d7f6Sopenharmony_ci        ///
761ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::force_mut(&mut lazy), &92);
762ef40d7f6Sopenharmony_ci        /// assert_eq!(*lazy, 92);
763ef40d7f6Sopenharmony_ci        /// ```
764ef40d7f6Sopenharmony_ci        pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
765ef40d7f6Sopenharmony_ci            Self::force(this);
766ef40d7f6Sopenharmony_ci            Self::get_mut(this).unwrap_or_else(|| unreachable!())
767ef40d7f6Sopenharmony_ci        }
768ef40d7f6Sopenharmony_ci
769ef40d7f6Sopenharmony_ci        /// Gets the reference to the result of this lazy value if
770ef40d7f6Sopenharmony_ci        /// it was initialized, otherwise returns `None`.
771ef40d7f6Sopenharmony_ci        ///
772ef40d7f6Sopenharmony_ci        /// # Example
773ef40d7f6Sopenharmony_ci        /// ```
774ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::Lazy;
775ef40d7f6Sopenharmony_ci        ///
776ef40d7f6Sopenharmony_ci        /// let lazy = Lazy::new(|| 92);
777ef40d7f6Sopenharmony_ci        ///
778ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get(&lazy), None);
779ef40d7f6Sopenharmony_ci        /// assert_eq!(&*lazy, &92);
780ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get(&lazy), Some(&92));
781ef40d7f6Sopenharmony_ci        /// ```
782ef40d7f6Sopenharmony_ci        pub fn get(this: &Lazy<T, F>) -> Option<&T> {
783ef40d7f6Sopenharmony_ci            this.cell.get()
784ef40d7f6Sopenharmony_ci        }
785ef40d7f6Sopenharmony_ci
786ef40d7f6Sopenharmony_ci        /// Gets the mutable reference to the result of this lazy value if
787ef40d7f6Sopenharmony_ci        /// it was initialized, otherwise returns `None`.
788ef40d7f6Sopenharmony_ci        ///
789ef40d7f6Sopenharmony_ci        /// # Example
790ef40d7f6Sopenharmony_ci        /// ```
791ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::Lazy;
792ef40d7f6Sopenharmony_ci        ///
793ef40d7f6Sopenharmony_ci        /// let mut lazy = Lazy::new(|| 92);
794ef40d7f6Sopenharmony_ci        ///
795ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get_mut(&mut lazy), None);
796ef40d7f6Sopenharmony_ci        /// assert_eq!(*lazy, 92);
797ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92));
798ef40d7f6Sopenharmony_ci        /// ```
799ef40d7f6Sopenharmony_ci        pub fn get_mut(this: &mut Lazy<T, F>) -> Option<&mut T> {
800ef40d7f6Sopenharmony_ci            this.cell.get_mut()
801ef40d7f6Sopenharmony_ci        }
802ef40d7f6Sopenharmony_ci    }
803ef40d7f6Sopenharmony_ci
804ef40d7f6Sopenharmony_ci    impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
805ef40d7f6Sopenharmony_ci        type Target = T;
806ef40d7f6Sopenharmony_ci        fn deref(&self) -> &T {
807ef40d7f6Sopenharmony_ci            Lazy::force(self)
808ef40d7f6Sopenharmony_ci        }
809ef40d7f6Sopenharmony_ci    }
810ef40d7f6Sopenharmony_ci
811ef40d7f6Sopenharmony_ci    impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
812ef40d7f6Sopenharmony_ci        fn deref_mut(&mut self) -> &mut T {
813ef40d7f6Sopenharmony_ci            Lazy::force(self);
814ef40d7f6Sopenharmony_ci            self.cell.get_mut().unwrap_or_else(|| unreachable!())
815ef40d7f6Sopenharmony_ci        }
816ef40d7f6Sopenharmony_ci    }
817ef40d7f6Sopenharmony_ci
818ef40d7f6Sopenharmony_ci    impl<T: Default> Default for Lazy<T> {
819ef40d7f6Sopenharmony_ci        /// Creates a new lazy value using `Default` as the initializing function.
820ef40d7f6Sopenharmony_ci        fn default() -> Lazy<T> {
821ef40d7f6Sopenharmony_ci            Lazy::new(T::default)
822ef40d7f6Sopenharmony_ci        }
823ef40d7f6Sopenharmony_ci    }
824ef40d7f6Sopenharmony_ci}
825ef40d7f6Sopenharmony_ci
826ef40d7f6Sopenharmony_ci/// Thread-safe, blocking version of `OnceCell`.
827ef40d7f6Sopenharmony_ci#[cfg(any(feature = "std", feature = "critical-section"))]
828ef40d7f6Sopenharmony_cipub mod sync {
829ef40d7f6Sopenharmony_ci    use core::{
830ef40d7f6Sopenharmony_ci        cell::Cell,
831ef40d7f6Sopenharmony_ci        fmt, mem,
832ef40d7f6Sopenharmony_ci        ops::{Deref, DerefMut},
833ef40d7f6Sopenharmony_ci        panic::RefUnwindSafe,
834ef40d7f6Sopenharmony_ci    };
835ef40d7f6Sopenharmony_ci
836ef40d7f6Sopenharmony_ci    use super::{imp::OnceCell as Imp, unwrap_unchecked};
837ef40d7f6Sopenharmony_ci
838ef40d7f6Sopenharmony_ci    /// A thread-safe cell which can be written to only once.
839ef40d7f6Sopenharmony_ci    ///
840ef40d7f6Sopenharmony_ci    /// `OnceCell` provides `&` references to the contents without RAII guards.
841ef40d7f6Sopenharmony_ci    ///
842ef40d7f6Sopenharmony_ci    /// Reading a non-`None` value out of `OnceCell` establishes a
843ef40d7f6Sopenharmony_ci    /// happens-before relationship with a corresponding write. For example, if
844ef40d7f6Sopenharmony_ci    /// thread A initializes the cell with `get_or_init(f)`, and thread B
845ef40d7f6Sopenharmony_ci    /// subsequently reads the result of this call, B also observes all the side
846ef40d7f6Sopenharmony_ci    /// effects of `f`.
847ef40d7f6Sopenharmony_ci    ///
848ef40d7f6Sopenharmony_ci    /// # Example
849ef40d7f6Sopenharmony_ci    /// ```
850ef40d7f6Sopenharmony_ci    /// use once_cell::sync::OnceCell;
851ef40d7f6Sopenharmony_ci    ///
852ef40d7f6Sopenharmony_ci    /// static CELL: OnceCell<String> = OnceCell::new();
853ef40d7f6Sopenharmony_ci    /// assert!(CELL.get().is_none());
854ef40d7f6Sopenharmony_ci    ///
855ef40d7f6Sopenharmony_ci    /// std::thread::spawn(|| {
856ef40d7f6Sopenharmony_ci    ///     let value: &String = CELL.get_or_init(|| {
857ef40d7f6Sopenharmony_ci    ///         "Hello, World!".to_string()
858ef40d7f6Sopenharmony_ci    ///     });
859ef40d7f6Sopenharmony_ci    ///     assert_eq!(value, "Hello, World!");
860ef40d7f6Sopenharmony_ci    /// }).join().unwrap();
861ef40d7f6Sopenharmony_ci    ///
862ef40d7f6Sopenharmony_ci    /// let value: Option<&String> = CELL.get();
863ef40d7f6Sopenharmony_ci    /// assert!(value.is_some());
864ef40d7f6Sopenharmony_ci    /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
865ef40d7f6Sopenharmony_ci    /// ```
866ef40d7f6Sopenharmony_ci    pub struct OnceCell<T>(Imp<T>);
867ef40d7f6Sopenharmony_ci
868ef40d7f6Sopenharmony_ci    impl<T> Default for OnceCell<T> {
869ef40d7f6Sopenharmony_ci        fn default() -> OnceCell<T> {
870ef40d7f6Sopenharmony_ci            OnceCell::new()
871ef40d7f6Sopenharmony_ci        }
872ef40d7f6Sopenharmony_ci    }
873ef40d7f6Sopenharmony_ci
874ef40d7f6Sopenharmony_ci    impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
875ef40d7f6Sopenharmony_ci        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
876ef40d7f6Sopenharmony_ci            match self.get() {
877ef40d7f6Sopenharmony_ci                Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
878ef40d7f6Sopenharmony_ci                None => f.write_str("OnceCell(Uninit)"),
879ef40d7f6Sopenharmony_ci            }
880ef40d7f6Sopenharmony_ci        }
881ef40d7f6Sopenharmony_ci    }
882ef40d7f6Sopenharmony_ci
883ef40d7f6Sopenharmony_ci    impl<T: Clone> Clone for OnceCell<T> {
884ef40d7f6Sopenharmony_ci        fn clone(&self) -> OnceCell<T> {
885ef40d7f6Sopenharmony_ci            match self.get() {
886ef40d7f6Sopenharmony_ci                Some(value) => Self::with_value(value.clone()),
887ef40d7f6Sopenharmony_ci                None => Self::new(),
888ef40d7f6Sopenharmony_ci            }
889ef40d7f6Sopenharmony_ci        }
890ef40d7f6Sopenharmony_ci
891ef40d7f6Sopenharmony_ci        fn clone_from(&mut self, source: &Self) {
892ef40d7f6Sopenharmony_ci            match (self.get_mut(), source.get()) {
893ef40d7f6Sopenharmony_ci                (Some(this), Some(source)) => this.clone_from(source),
894ef40d7f6Sopenharmony_ci                _ => *self = source.clone(),
895ef40d7f6Sopenharmony_ci            }
896ef40d7f6Sopenharmony_ci        }
897ef40d7f6Sopenharmony_ci    }
898ef40d7f6Sopenharmony_ci
899ef40d7f6Sopenharmony_ci    impl<T> From<T> for OnceCell<T> {
900ef40d7f6Sopenharmony_ci        fn from(value: T) -> Self {
901ef40d7f6Sopenharmony_ci            Self::with_value(value)
902ef40d7f6Sopenharmony_ci        }
903ef40d7f6Sopenharmony_ci    }
904ef40d7f6Sopenharmony_ci
905ef40d7f6Sopenharmony_ci    impl<T: PartialEq> PartialEq for OnceCell<T> {
906ef40d7f6Sopenharmony_ci        fn eq(&self, other: &OnceCell<T>) -> bool {
907ef40d7f6Sopenharmony_ci            self.get() == other.get()
908ef40d7f6Sopenharmony_ci        }
909ef40d7f6Sopenharmony_ci    }
910ef40d7f6Sopenharmony_ci
911ef40d7f6Sopenharmony_ci    impl<T: Eq> Eq for OnceCell<T> {}
912ef40d7f6Sopenharmony_ci
913ef40d7f6Sopenharmony_ci    impl<T> OnceCell<T> {
914ef40d7f6Sopenharmony_ci        /// Creates a new empty cell.
915ef40d7f6Sopenharmony_ci        pub const fn new() -> OnceCell<T> {
916ef40d7f6Sopenharmony_ci            OnceCell(Imp::new())
917ef40d7f6Sopenharmony_ci        }
918ef40d7f6Sopenharmony_ci
919ef40d7f6Sopenharmony_ci        /// Creates a new initialized cell.
920ef40d7f6Sopenharmony_ci        pub const fn with_value(value: T) -> OnceCell<T> {
921ef40d7f6Sopenharmony_ci            OnceCell(Imp::with_value(value))
922ef40d7f6Sopenharmony_ci        }
923ef40d7f6Sopenharmony_ci
924ef40d7f6Sopenharmony_ci        /// Gets the reference to the underlying value.
925ef40d7f6Sopenharmony_ci        ///
926ef40d7f6Sopenharmony_ci        /// Returns `None` if the cell is empty, or being initialized. This
927ef40d7f6Sopenharmony_ci        /// method never blocks.
928ef40d7f6Sopenharmony_ci        pub fn get(&self) -> Option<&T> {
929ef40d7f6Sopenharmony_ci            if self.0.is_initialized() {
930ef40d7f6Sopenharmony_ci                // Safe b/c value is initialized.
931ef40d7f6Sopenharmony_ci                Some(unsafe { self.get_unchecked() })
932ef40d7f6Sopenharmony_ci            } else {
933ef40d7f6Sopenharmony_ci                None
934ef40d7f6Sopenharmony_ci            }
935ef40d7f6Sopenharmony_ci        }
936ef40d7f6Sopenharmony_ci
937ef40d7f6Sopenharmony_ci        /// Gets the reference to the underlying value, blocking the current
938ef40d7f6Sopenharmony_ci        /// thread until it is set.
939ef40d7f6Sopenharmony_ci        ///
940ef40d7f6Sopenharmony_ci        /// ```
941ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
942ef40d7f6Sopenharmony_ci        ///
943ef40d7f6Sopenharmony_ci        /// let mut cell = std::sync::Arc::new(OnceCell::new());
944ef40d7f6Sopenharmony_ci        /// let t = std::thread::spawn({
945ef40d7f6Sopenharmony_ci        ///     let cell = std::sync::Arc::clone(&cell);
946ef40d7f6Sopenharmony_ci        ///     move || cell.set(92).unwrap()
947ef40d7f6Sopenharmony_ci        /// });
948ef40d7f6Sopenharmony_ci        ///
949ef40d7f6Sopenharmony_ci        /// // Returns immediately, but might return None.
950ef40d7f6Sopenharmony_ci        /// let _value_or_none = cell.get();
951ef40d7f6Sopenharmony_ci        ///
952ef40d7f6Sopenharmony_ci        /// // Will return 92, but might block until the other thread does `.set`.
953ef40d7f6Sopenharmony_ci        /// let value: &u32 = cell.wait();
954ef40d7f6Sopenharmony_ci        /// assert_eq!(*value, 92);
955ef40d7f6Sopenharmony_ci        /// t.join().unwrap();
956ef40d7f6Sopenharmony_ci        /// ```
957ef40d7f6Sopenharmony_ci        #[cfg(feature = "std")]
958ef40d7f6Sopenharmony_ci        pub fn wait(&self) -> &T {
959ef40d7f6Sopenharmony_ci            if !self.0.is_initialized() {
960ef40d7f6Sopenharmony_ci                self.0.wait()
961ef40d7f6Sopenharmony_ci            }
962ef40d7f6Sopenharmony_ci            debug_assert!(self.0.is_initialized());
963ef40d7f6Sopenharmony_ci            // Safe b/c of the wait call above and the fact that we didn't
964ef40d7f6Sopenharmony_ci            // relinquish our borrow.
965ef40d7f6Sopenharmony_ci            unsafe { self.get_unchecked() }
966ef40d7f6Sopenharmony_ci        }
967ef40d7f6Sopenharmony_ci
968ef40d7f6Sopenharmony_ci        /// Gets the mutable reference to the underlying value.
969ef40d7f6Sopenharmony_ci        ///
970ef40d7f6Sopenharmony_ci        /// Returns `None` if the cell is empty.
971ef40d7f6Sopenharmony_ci        ///
972ef40d7f6Sopenharmony_ci        /// This method is allowed to violate the invariant of writing to a `OnceCell`
973ef40d7f6Sopenharmony_ci        /// at most once because it requires `&mut` access to `self`. As with all
974ef40d7f6Sopenharmony_ci        /// interior mutability, `&mut` access permits arbitrary modification:
975ef40d7f6Sopenharmony_ci        ///
976ef40d7f6Sopenharmony_ci        /// ```
977ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
978ef40d7f6Sopenharmony_ci        ///
979ef40d7f6Sopenharmony_ci        /// let mut cell: OnceCell<u32> = OnceCell::new();
980ef40d7f6Sopenharmony_ci        /// cell.set(92).unwrap();
981ef40d7f6Sopenharmony_ci        /// cell = OnceCell::new();
982ef40d7f6Sopenharmony_ci        /// ```
983ef40d7f6Sopenharmony_ci        #[inline]
984ef40d7f6Sopenharmony_ci        pub fn get_mut(&mut self) -> Option<&mut T> {
985ef40d7f6Sopenharmony_ci            self.0.get_mut()
986ef40d7f6Sopenharmony_ci        }
987ef40d7f6Sopenharmony_ci
988ef40d7f6Sopenharmony_ci        /// Get the reference to the underlying value, without checking if the
989ef40d7f6Sopenharmony_ci        /// cell is initialized.
990ef40d7f6Sopenharmony_ci        ///
991ef40d7f6Sopenharmony_ci        /// # Safety
992ef40d7f6Sopenharmony_ci        ///
993ef40d7f6Sopenharmony_ci        /// Caller must ensure that the cell is in initialized state, and that
994ef40d7f6Sopenharmony_ci        /// the contents are acquired by (synchronized to) this thread.
995ef40d7f6Sopenharmony_ci        #[inline]
996ef40d7f6Sopenharmony_ci        pub unsafe fn get_unchecked(&self) -> &T {
997ef40d7f6Sopenharmony_ci            self.0.get_unchecked()
998ef40d7f6Sopenharmony_ci        }
999ef40d7f6Sopenharmony_ci
1000ef40d7f6Sopenharmony_ci        /// Sets the contents of this cell to `value`.
1001ef40d7f6Sopenharmony_ci        ///
1002ef40d7f6Sopenharmony_ci        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
1003ef40d7f6Sopenharmony_ci        /// full.
1004ef40d7f6Sopenharmony_ci        ///
1005ef40d7f6Sopenharmony_ci        /// # Example
1006ef40d7f6Sopenharmony_ci        ///
1007ef40d7f6Sopenharmony_ci        /// ```
1008ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
1009ef40d7f6Sopenharmony_ci        ///
1010ef40d7f6Sopenharmony_ci        /// static CELL: OnceCell<i32> = OnceCell::new();
1011ef40d7f6Sopenharmony_ci        ///
1012ef40d7f6Sopenharmony_ci        /// fn main() {
1013ef40d7f6Sopenharmony_ci        ///     assert!(CELL.get().is_none());
1014ef40d7f6Sopenharmony_ci        ///
1015ef40d7f6Sopenharmony_ci        ///     std::thread::spawn(|| {
1016ef40d7f6Sopenharmony_ci        ///         assert_eq!(CELL.set(92), Ok(()));
1017ef40d7f6Sopenharmony_ci        ///     }).join().unwrap();
1018ef40d7f6Sopenharmony_ci        ///
1019ef40d7f6Sopenharmony_ci        ///     assert_eq!(CELL.set(62), Err(62));
1020ef40d7f6Sopenharmony_ci        ///     assert_eq!(CELL.get(), Some(&92));
1021ef40d7f6Sopenharmony_ci        /// }
1022ef40d7f6Sopenharmony_ci        /// ```
1023ef40d7f6Sopenharmony_ci        pub fn set(&self, value: T) -> Result<(), T> {
1024ef40d7f6Sopenharmony_ci            match self.try_insert(value) {
1025ef40d7f6Sopenharmony_ci                Ok(_) => Ok(()),
1026ef40d7f6Sopenharmony_ci                Err((_, value)) => Err(value),
1027ef40d7f6Sopenharmony_ci            }
1028ef40d7f6Sopenharmony_ci        }
1029ef40d7f6Sopenharmony_ci
1030ef40d7f6Sopenharmony_ci        /// Like [`set`](Self::set), but also returns a reference to the final cell value.
1031ef40d7f6Sopenharmony_ci        ///
1032ef40d7f6Sopenharmony_ci        /// # Example
1033ef40d7f6Sopenharmony_ci        ///
1034ef40d7f6Sopenharmony_ci        /// ```
1035ef40d7f6Sopenharmony_ci        /// use once_cell::unsync::OnceCell;
1036ef40d7f6Sopenharmony_ci        ///
1037ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
1038ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_none());
1039ef40d7f6Sopenharmony_ci        ///
1040ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.try_insert(92), Ok(&92));
1041ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
1042ef40d7f6Sopenharmony_ci        ///
1043ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_some());
1044ef40d7f6Sopenharmony_ci        /// ```
1045ef40d7f6Sopenharmony_ci        pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
1046ef40d7f6Sopenharmony_ci            let mut value = Some(value);
1047ef40d7f6Sopenharmony_ci            let res = self.get_or_init(|| unsafe { unwrap_unchecked(value.take()) });
1048ef40d7f6Sopenharmony_ci            match value {
1049ef40d7f6Sopenharmony_ci                None => Ok(res),
1050ef40d7f6Sopenharmony_ci                Some(value) => Err((res, value)),
1051ef40d7f6Sopenharmony_ci            }
1052ef40d7f6Sopenharmony_ci        }
1053ef40d7f6Sopenharmony_ci
1054ef40d7f6Sopenharmony_ci        /// Gets the contents of the cell, initializing it with `f` if the cell
1055ef40d7f6Sopenharmony_ci        /// was empty.
1056ef40d7f6Sopenharmony_ci        ///
1057ef40d7f6Sopenharmony_ci        /// Many threads may call `get_or_init` concurrently with different
1058ef40d7f6Sopenharmony_ci        /// initializing functions, but it is guaranteed that only one function
1059ef40d7f6Sopenharmony_ci        /// will be executed.
1060ef40d7f6Sopenharmony_ci        ///
1061ef40d7f6Sopenharmony_ci        /// # Panics
1062ef40d7f6Sopenharmony_ci        ///
1063ef40d7f6Sopenharmony_ci        /// If `f` panics, the panic is propagated to the caller, and the cell
1064ef40d7f6Sopenharmony_ci        /// remains uninitialized.
1065ef40d7f6Sopenharmony_ci        ///
1066ef40d7f6Sopenharmony_ci        /// It is an error to reentrantly initialize the cell from `f`. The
1067ef40d7f6Sopenharmony_ci        /// exact outcome is unspecified. Current implementation deadlocks, but
1068ef40d7f6Sopenharmony_ci        /// this may be changed to a panic in the future.
1069ef40d7f6Sopenharmony_ci        ///
1070ef40d7f6Sopenharmony_ci        /// # Example
1071ef40d7f6Sopenharmony_ci        /// ```
1072ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
1073ef40d7f6Sopenharmony_ci        ///
1074ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
1075ef40d7f6Sopenharmony_ci        /// let value = cell.get_or_init(|| 92);
1076ef40d7f6Sopenharmony_ci        /// assert_eq!(value, &92);
1077ef40d7f6Sopenharmony_ci        /// let value = cell.get_or_init(|| unreachable!());
1078ef40d7f6Sopenharmony_ci        /// assert_eq!(value, &92);
1079ef40d7f6Sopenharmony_ci        /// ```
1080ef40d7f6Sopenharmony_ci        pub fn get_or_init<F>(&self, f: F) -> &T
1081ef40d7f6Sopenharmony_ci        where
1082ef40d7f6Sopenharmony_ci            F: FnOnce() -> T,
1083ef40d7f6Sopenharmony_ci        {
1084ef40d7f6Sopenharmony_ci            enum Void {}
1085ef40d7f6Sopenharmony_ci            match self.get_or_try_init(|| Ok::<T, Void>(f())) {
1086ef40d7f6Sopenharmony_ci                Ok(val) => val,
1087ef40d7f6Sopenharmony_ci                Err(void) => match void {},
1088ef40d7f6Sopenharmony_ci            }
1089ef40d7f6Sopenharmony_ci        }
1090ef40d7f6Sopenharmony_ci
1091ef40d7f6Sopenharmony_ci        /// Gets the contents of the cell, initializing it with `f` if
1092ef40d7f6Sopenharmony_ci        /// the cell was empty. If the cell was empty and `f` failed, an
1093ef40d7f6Sopenharmony_ci        /// error is returned.
1094ef40d7f6Sopenharmony_ci        ///
1095ef40d7f6Sopenharmony_ci        /// # Panics
1096ef40d7f6Sopenharmony_ci        ///
1097ef40d7f6Sopenharmony_ci        /// If `f` panics, the panic is propagated to the caller, and
1098ef40d7f6Sopenharmony_ci        /// the cell remains uninitialized.
1099ef40d7f6Sopenharmony_ci        ///
1100ef40d7f6Sopenharmony_ci        /// It is an error to reentrantly initialize the cell from `f`.
1101ef40d7f6Sopenharmony_ci        /// The exact outcome is unspecified. Current implementation
1102ef40d7f6Sopenharmony_ci        /// deadlocks, but this may be changed to a panic in the future.
1103ef40d7f6Sopenharmony_ci        ///
1104ef40d7f6Sopenharmony_ci        /// # Example
1105ef40d7f6Sopenharmony_ci        /// ```
1106ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
1107ef40d7f6Sopenharmony_ci        ///
1108ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
1109ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
1110ef40d7f6Sopenharmony_ci        /// assert!(cell.get().is_none());
1111ef40d7f6Sopenharmony_ci        /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
1112ef40d7f6Sopenharmony_ci        ///     Ok(92)
1113ef40d7f6Sopenharmony_ci        /// });
1114ef40d7f6Sopenharmony_ci        /// assert_eq!(value, Ok(&92));
1115ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get(), Some(&92))
1116ef40d7f6Sopenharmony_ci        /// ```
1117ef40d7f6Sopenharmony_ci        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
1118ef40d7f6Sopenharmony_ci        where
1119ef40d7f6Sopenharmony_ci            F: FnOnce() -> Result<T, E>,
1120ef40d7f6Sopenharmony_ci        {
1121ef40d7f6Sopenharmony_ci            // Fast path check
1122ef40d7f6Sopenharmony_ci            if let Some(value) = self.get() {
1123ef40d7f6Sopenharmony_ci                return Ok(value);
1124ef40d7f6Sopenharmony_ci            }
1125ef40d7f6Sopenharmony_ci
1126ef40d7f6Sopenharmony_ci            self.0.initialize(f)?;
1127ef40d7f6Sopenharmony_ci
1128ef40d7f6Sopenharmony_ci            // Safe b/c value is initialized.
1129ef40d7f6Sopenharmony_ci            debug_assert!(self.0.is_initialized());
1130ef40d7f6Sopenharmony_ci            Ok(unsafe { self.get_unchecked() })
1131ef40d7f6Sopenharmony_ci        }
1132ef40d7f6Sopenharmony_ci
1133ef40d7f6Sopenharmony_ci        /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
1134ef40d7f6Sopenharmony_ci        ///
1135ef40d7f6Sopenharmony_ci        /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
1136ef40d7f6Sopenharmony_ci        ///
1137ef40d7f6Sopenharmony_ci        /// # Examples
1138ef40d7f6Sopenharmony_ci        ///
1139ef40d7f6Sopenharmony_ci        /// ```
1140ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
1141ef40d7f6Sopenharmony_ci        ///
1142ef40d7f6Sopenharmony_ci        /// let mut cell: OnceCell<String> = OnceCell::new();
1143ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.take(), None);
1144ef40d7f6Sopenharmony_ci        ///
1145ef40d7f6Sopenharmony_ci        /// let mut cell = OnceCell::new();
1146ef40d7f6Sopenharmony_ci        /// cell.set("hello".to_string()).unwrap();
1147ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.take(), Some("hello".to_string()));
1148ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.get(), None);
1149ef40d7f6Sopenharmony_ci        /// ```
1150ef40d7f6Sopenharmony_ci        ///
1151ef40d7f6Sopenharmony_ci        /// This method is allowed to violate the invariant of writing to a `OnceCell`
1152ef40d7f6Sopenharmony_ci        /// at most once because it requires `&mut` access to `self`. As with all
1153ef40d7f6Sopenharmony_ci        /// interior mutability, `&mut` access permits arbitrary modification:
1154ef40d7f6Sopenharmony_ci        ///
1155ef40d7f6Sopenharmony_ci        /// ```
1156ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
1157ef40d7f6Sopenharmony_ci        ///
1158ef40d7f6Sopenharmony_ci        /// let mut cell: OnceCell<u32> = OnceCell::new();
1159ef40d7f6Sopenharmony_ci        /// cell.set(92).unwrap();
1160ef40d7f6Sopenharmony_ci        /// cell = OnceCell::new();
1161ef40d7f6Sopenharmony_ci        /// ```
1162ef40d7f6Sopenharmony_ci        pub fn take(&mut self) -> Option<T> {
1163ef40d7f6Sopenharmony_ci            mem::replace(self, Self::default()).into_inner()
1164ef40d7f6Sopenharmony_ci        }
1165ef40d7f6Sopenharmony_ci
1166ef40d7f6Sopenharmony_ci        /// Consumes the `OnceCell`, returning the wrapped value. Returns
1167ef40d7f6Sopenharmony_ci        /// `None` if the cell was empty.
1168ef40d7f6Sopenharmony_ci        ///
1169ef40d7f6Sopenharmony_ci        /// # Examples
1170ef40d7f6Sopenharmony_ci        ///
1171ef40d7f6Sopenharmony_ci        /// ```
1172ef40d7f6Sopenharmony_ci        /// use once_cell::sync::OnceCell;
1173ef40d7f6Sopenharmony_ci        ///
1174ef40d7f6Sopenharmony_ci        /// let cell: OnceCell<String> = OnceCell::new();
1175ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.into_inner(), None);
1176ef40d7f6Sopenharmony_ci        ///
1177ef40d7f6Sopenharmony_ci        /// let cell = OnceCell::new();
1178ef40d7f6Sopenharmony_ci        /// cell.set("hello".to_string()).unwrap();
1179ef40d7f6Sopenharmony_ci        /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
1180ef40d7f6Sopenharmony_ci        /// ```
1181ef40d7f6Sopenharmony_ci        #[inline]
1182ef40d7f6Sopenharmony_ci        pub fn into_inner(self) -> Option<T> {
1183ef40d7f6Sopenharmony_ci            self.0.into_inner()
1184ef40d7f6Sopenharmony_ci        }
1185ef40d7f6Sopenharmony_ci    }
1186ef40d7f6Sopenharmony_ci
1187ef40d7f6Sopenharmony_ci    /// A value which is initialized on the first access.
1188ef40d7f6Sopenharmony_ci    ///
1189ef40d7f6Sopenharmony_ci    /// This type is thread-safe and can be used in statics.
1190ef40d7f6Sopenharmony_ci    ///
1191ef40d7f6Sopenharmony_ci    /// # Example
1192ef40d7f6Sopenharmony_ci    ///
1193ef40d7f6Sopenharmony_ci    /// ```
1194ef40d7f6Sopenharmony_ci    /// use std::collections::HashMap;
1195ef40d7f6Sopenharmony_ci    ///
1196ef40d7f6Sopenharmony_ci    /// use once_cell::sync::Lazy;
1197ef40d7f6Sopenharmony_ci    ///
1198ef40d7f6Sopenharmony_ci    /// static HASHMAP: Lazy<HashMap<i32, String>> = Lazy::new(|| {
1199ef40d7f6Sopenharmony_ci    ///     println!("initializing");
1200ef40d7f6Sopenharmony_ci    ///     let mut m = HashMap::new();
1201ef40d7f6Sopenharmony_ci    ///     m.insert(13, "Spica".to_string());
1202ef40d7f6Sopenharmony_ci    ///     m.insert(74, "Hoyten".to_string());
1203ef40d7f6Sopenharmony_ci    ///     m
1204ef40d7f6Sopenharmony_ci    /// });
1205ef40d7f6Sopenharmony_ci    ///
1206ef40d7f6Sopenharmony_ci    /// fn main() {
1207ef40d7f6Sopenharmony_ci    ///     println!("ready");
1208ef40d7f6Sopenharmony_ci    ///     std::thread::spawn(|| {
1209ef40d7f6Sopenharmony_ci    ///         println!("{:?}", HASHMAP.get(&13));
1210ef40d7f6Sopenharmony_ci    ///     }).join().unwrap();
1211ef40d7f6Sopenharmony_ci    ///     println!("{:?}", HASHMAP.get(&74));
1212ef40d7f6Sopenharmony_ci    ///
1213ef40d7f6Sopenharmony_ci    ///     // Prints:
1214ef40d7f6Sopenharmony_ci    ///     //   ready
1215ef40d7f6Sopenharmony_ci    ///     //   initializing
1216ef40d7f6Sopenharmony_ci    ///     //   Some("Spica")
1217ef40d7f6Sopenharmony_ci    ///     //   Some("Hoyten")
1218ef40d7f6Sopenharmony_ci    /// }
1219ef40d7f6Sopenharmony_ci    /// ```
1220ef40d7f6Sopenharmony_ci    pub struct Lazy<T, F = fn() -> T> {
1221ef40d7f6Sopenharmony_ci        cell: OnceCell<T>,
1222ef40d7f6Sopenharmony_ci        init: Cell<Option<F>>,
1223ef40d7f6Sopenharmony_ci    }
1224ef40d7f6Sopenharmony_ci
1225ef40d7f6Sopenharmony_ci    impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
1226ef40d7f6Sopenharmony_ci        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1227ef40d7f6Sopenharmony_ci            f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
1228ef40d7f6Sopenharmony_ci        }
1229ef40d7f6Sopenharmony_ci    }
1230ef40d7f6Sopenharmony_ci
1231ef40d7f6Sopenharmony_ci    // We never create a `&F` from a `&Lazy<T, F>` so it is fine to not impl
1232ef40d7f6Sopenharmony_ci    // `Sync` for `F`. We do create a `&mut Option<F>` in `force`, but this is
1233ef40d7f6Sopenharmony_ci    // properly synchronized, so it only happens once so it also does not
1234ef40d7f6Sopenharmony_ci    // contribute to this impl.
1235ef40d7f6Sopenharmony_ci    unsafe impl<T, F: Send> Sync for Lazy<T, F> where OnceCell<T>: Sync {}
1236ef40d7f6Sopenharmony_ci    // auto-derived `Send` impl is OK.
1237ef40d7f6Sopenharmony_ci
1238ef40d7f6Sopenharmony_ci    impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
1239ef40d7f6Sopenharmony_ci
1240ef40d7f6Sopenharmony_ci    impl<T, F> Lazy<T, F> {
1241ef40d7f6Sopenharmony_ci        /// Creates a new lazy value with the given initializing
1242ef40d7f6Sopenharmony_ci        /// function.
1243ef40d7f6Sopenharmony_ci        pub const fn new(f: F) -> Lazy<T, F> {
1244ef40d7f6Sopenharmony_ci            Lazy { cell: OnceCell::new(), init: Cell::new(Some(f)) }
1245ef40d7f6Sopenharmony_ci        }
1246ef40d7f6Sopenharmony_ci
1247ef40d7f6Sopenharmony_ci        /// Consumes this `Lazy` returning the stored value.
1248ef40d7f6Sopenharmony_ci        ///
1249ef40d7f6Sopenharmony_ci        /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
1250ef40d7f6Sopenharmony_ci        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
1251ef40d7f6Sopenharmony_ci            let cell = this.cell;
1252ef40d7f6Sopenharmony_ci            let init = this.init;
1253ef40d7f6Sopenharmony_ci            cell.into_inner().ok_or_else(|| {
1254ef40d7f6Sopenharmony_ci                init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned"))
1255ef40d7f6Sopenharmony_ci            })
1256ef40d7f6Sopenharmony_ci        }
1257ef40d7f6Sopenharmony_ci    }
1258ef40d7f6Sopenharmony_ci
1259ef40d7f6Sopenharmony_ci    impl<T, F: FnOnce() -> T> Lazy<T, F> {
1260ef40d7f6Sopenharmony_ci        /// Forces the evaluation of this lazy value and
1261ef40d7f6Sopenharmony_ci        /// returns a reference to the result. This is equivalent
1262ef40d7f6Sopenharmony_ci        /// to the `Deref` impl, but is explicit.
1263ef40d7f6Sopenharmony_ci        ///
1264ef40d7f6Sopenharmony_ci        /// # Example
1265ef40d7f6Sopenharmony_ci        /// ```
1266ef40d7f6Sopenharmony_ci        /// use once_cell::sync::Lazy;
1267ef40d7f6Sopenharmony_ci        ///
1268ef40d7f6Sopenharmony_ci        /// let lazy = Lazy::new(|| 92);
1269ef40d7f6Sopenharmony_ci        ///
1270ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::force(&lazy), &92);
1271ef40d7f6Sopenharmony_ci        /// assert_eq!(&*lazy, &92);
1272ef40d7f6Sopenharmony_ci        /// ```
1273ef40d7f6Sopenharmony_ci        pub fn force(this: &Lazy<T, F>) -> &T {
1274ef40d7f6Sopenharmony_ci            this.cell.get_or_init(|| match this.init.take() {
1275ef40d7f6Sopenharmony_ci                Some(f) => f(),
1276ef40d7f6Sopenharmony_ci                None => panic!("Lazy instance has previously been poisoned"),
1277ef40d7f6Sopenharmony_ci            })
1278ef40d7f6Sopenharmony_ci        }
1279ef40d7f6Sopenharmony_ci
1280ef40d7f6Sopenharmony_ci        /// Forces the evaluation of this lazy value and
1281ef40d7f6Sopenharmony_ci        /// returns a mutable reference to the result. This is equivalent
1282ef40d7f6Sopenharmony_ci        /// to the `Deref` impl, but is explicit.
1283ef40d7f6Sopenharmony_ci        ///
1284ef40d7f6Sopenharmony_ci        /// # Example
1285ef40d7f6Sopenharmony_ci        /// ```
1286ef40d7f6Sopenharmony_ci        /// use once_cell::sync::Lazy;
1287ef40d7f6Sopenharmony_ci        ///
1288ef40d7f6Sopenharmony_ci        /// let mut lazy = Lazy::new(|| 92);
1289ef40d7f6Sopenharmony_ci        ///
1290ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92);
1291ef40d7f6Sopenharmony_ci        /// ```
1292ef40d7f6Sopenharmony_ci        pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
1293ef40d7f6Sopenharmony_ci            Self::force(this);
1294ef40d7f6Sopenharmony_ci            Self::get_mut(this).unwrap_or_else(|| unreachable!())
1295ef40d7f6Sopenharmony_ci        }
1296ef40d7f6Sopenharmony_ci
1297ef40d7f6Sopenharmony_ci        /// Gets the reference to the result of this lazy value if
1298ef40d7f6Sopenharmony_ci        /// it was initialized, otherwise returns `None`.
1299ef40d7f6Sopenharmony_ci        ///
1300ef40d7f6Sopenharmony_ci        /// # Example
1301ef40d7f6Sopenharmony_ci        /// ```
1302ef40d7f6Sopenharmony_ci        /// use once_cell::sync::Lazy;
1303ef40d7f6Sopenharmony_ci        ///
1304ef40d7f6Sopenharmony_ci        /// let lazy = Lazy::new(|| 92);
1305ef40d7f6Sopenharmony_ci        ///
1306ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get(&lazy), None);
1307ef40d7f6Sopenharmony_ci        /// assert_eq!(&*lazy, &92);
1308ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get(&lazy), Some(&92));
1309ef40d7f6Sopenharmony_ci        /// ```
1310ef40d7f6Sopenharmony_ci        pub fn get(this: &Lazy<T, F>) -> Option<&T> {
1311ef40d7f6Sopenharmony_ci            this.cell.get()
1312ef40d7f6Sopenharmony_ci        }
1313ef40d7f6Sopenharmony_ci
1314ef40d7f6Sopenharmony_ci        /// Gets the reference to the result of this lazy value if
1315ef40d7f6Sopenharmony_ci        /// it was initialized, otherwise returns `None`.
1316ef40d7f6Sopenharmony_ci        ///
1317ef40d7f6Sopenharmony_ci        /// # Example
1318ef40d7f6Sopenharmony_ci        /// ```
1319ef40d7f6Sopenharmony_ci        /// use once_cell::sync::Lazy;
1320ef40d7f6Sopenharmony_ci        ///
1321ef40d7f6Sopenharmony_ci        /// let mut lazy = Lazy::new(|| 92);
1322ef40d7f6Sopenharmony_ci        ///
1323ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get_mut(&mut lazy), None);
1324ef40d7f6Sopenharmony_ci        /// assert_eq!(&*lazy, &92);
1325ef40d7f6Sopenharmony_ci        /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92));
1326ef40d7f6Sopenharmony_ci        /// ```
1327ef40d7f6Sopenharmony_ci        pub fn get_mut(this: &mut Lazy<T, F>) -> Option<&mut T> {
1328ef40d7f6Sopenharmony_ci            this.cell.get_mut()
1329ef40d7f6Sopenharmony_ci        }
1330ef40d7f6Sopenharmony_ci    }
1331ef40d7f6Sopenharmony_ci
1332ef40d7f6Sopenharmony_ci    impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
1333ef40d7f6Sopenharmony_ci        type Target = T;
1334ef40d7f6Sopenharmony_ci        fn deref(&self) -> &T {
1335ef40d7f6Sopenharmony_ci            Lazy::force(self)
1336ef40d7f6Sopenharmony_ci        }
1337ef40d7f6Sopenharmony_ci    }
1338ef40d7f6Sopenharmony_ci
1339ef40d7f6Sopenharmony_ci    impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
1340ef40d7f6Sopenharmony_ci        fn deref_mut(&mut self) -> &mut T {
1341ef40d7f6Sopenharmony_ci            Lazy::force(self);
1342ef40d7f6Sopenharmony_ci            self.cell.get_mut().unwrap_or_else(|| unreachable!())
1343ef40d7f6Sopenharmony_ci        }
1344ef40d7f6Sopenharmony_ci    }
1345ef40d7f6Sopenharmony_ci
1346ef40d7f6Sopenharmony_ci    impl<T: Default> Default for Lazy<T> {
1347ef40d7f6Sopenharmony_ci        /// Creates a new lazy value using `Default` as the initializing function.
1348ef40d7f6Sopenharmony_ci        fn default() -> Lazy<T> {
1349ef40d7f6Sopenharmony_ci            Lazy::new(T::default)
1350ef40d7f6Sopenharmony_ci        }
1351ef40d7f6Sopenharmony_ci    }
1352ef40d7f6Sopenharmony_ci
1353ef40d7f6Sopenharmony_ci    /// ```compile_fail
1354ef40d7f6Sopenharmony_ci    /// struct S(*mut ());
1355ef40d7f6Sopenharmony_ci    /// unsafe impl Sync for S {}
1356ef40d7f6Sopenharmony_ci    ///
1357ef40d7f6Sopenharmony_ci    /// fn share<T: Sync>(_: &T) {}
1358ef40d7f6Sopenharmony_ci    /// share(&once_cell::sync::OnceCell::<S>::new());
1359ef40d7f6Sopenharmony_ci    /// ```
1360ef40d7f6Sopenharmony_ci    ///
1361ef40d7f6Sopenharmony_ci    /// ```compile_fail
1362ef40d7f6Sopenharmony_ci    /// struct S(*mut ());
1363ef40d7f6Sopenharmony_ci    /// unsafe impl Sync for S {}
1364ef40d7f6Sopenharmony_ci    ///
1365ef40d7f6Sopenharmony_ci    /// fn share<T: Sync>(_: &T) {}
1366ef40d7f6Sopenharmony_ci    /// share(&once_cell::sync::Lazy::<S>::new(|| unimplemented!()));
1367ef40d7f6Sopenharmony_ci    /// ```
1368ef40d7f6Sopenharmony_ci    fn _dummy() {}
1369ef40d7f6Sopenharmony_ci}
1370ef40d7f6Sopenharmony_ci
1371ef40d7f6Sopenharmony_ci#[cfg(feature = "race")]
1372ef40d7f6Sopenharmony_cipub mod race;
1373ef40d7f6Sopenharmony_ci
1374ef40d7f6Sopenharmony_ci// Remove once MSRV is at least 1.58.
1375ef40d7f6Sopenharmony_ci#[inline]
1376ef40d7f6Sopenharmony_ciunsafe fn unwrap_unchecked<T>(val: Option<T>) -> T {
1377ef40d7f6Sopenharmony_ci    match val {
1378ef40d7f6Sopenharmony_ci        Some(value) => value,
1379ef40d7f6Sopenharmony_ci        None => {
1380ef40d7f6Sopenharmony_ci            debug_assert!(false);
1381ef40d7f6Sopenharmony_ci            core::hint::unreachable_unchecked()
1382ef40d7f6Sopenharmony_ci        }
1383ef40d7f6Sopenharmony_ci    }
1384ef40d7f6Sopenharmony_ci}
1385