]> git.proxmox.com Git - rustc.git/blame - vendor/once_cell/src/lib.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / vendor / once_cell / src / lib.rs
CommitLineData
e1599b0c
XL
1/*!
2# Overview
3
f035d41b
XL
4`once_cell` provides two new cell-like types, [`unsync::OnceCell`] and [`sync::OnceCell`]. A `OnceCell`
5might store arbitrary non-`Copy` types, can be assigned to at most once and provides direct access
6to the stored contents. In a nutshell, the API looks *roughly* like this:
e1599b0c
XL
7
8```rust,ignore
9impl<T> OnceCell<T> {
10 fn new() -> OnceCell<T> { ... }
11 fn set(&self, value: T) -> Result<(), T> { ... }
12 fn get(&self) -> Option<&T> { ... }
13}
14```
15
f035d41b
XL
16Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires only a shared reference.
17Because of the single assignment restriction `get` can return a `&T` instead of `Ref<T>`
e1599b0c
XL
18or `MutexGuard<T>`.
19
f035d41b 20The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait), while the `unsync` one is not.
e1599b0c 21
f035d41b
XL
22[`unsync::OnceCell`]: unsync/struct.OnceCell.html
23[`sync::OnceCell`]: sync/struct.ONceCell.html
24[`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
25[`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
e1599b0c
XL
26[`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
27
28# Patterns
29
30`OnceCell` might be useful for a variety of patterns.
31
32## Safe Initialization of global data
33
34```rust
35use std::{env, io};
36
37use once_cell::sync::OnceCell;
38
39#[derive(Debug)]
40pub struct Logger {
41 // ...
42}
43static INSTANCE: OnceCell<Logger> = OnceCell::new();
44
45impl Logger {
46 pub fn global() -> &'static Logger {
47 INSTANCE.get().expect("logger is not initialized")
48 }
49
50 fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
51 // ...
52# Ok(Logger {})
53 }
54}
55
56fn main() {
57 let logger = Logger::from_cli(env::args()).unwrap();
58 INSTANCE.set(logger).unwrap();
59 // use `Logger::global()` from now on
60}
61```
62
63## Lazy initialized global data
64
f035d41b 65This is essentially the `lazy_static!` macro, but without a macro.
e1599b0c
XL
66
67```rust
68use std::{sync::Mutex, collections::HashMap};
69
70use once_cell::sync::OnceCell;
71
72fn global_data() -> &'static Mutex<HashMap<i32, String>> {
73 static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
74 INSTANCE.get_or_init(|| {
75 let mut m = HashMap::new();
76 m.insert(13, "Spica".to_string());
77 m.insert(74, "Hoyten".to_string());
78 Mutex::new(m)
79 })
80}
81```
82
f035d41b 83There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to streamline this pattern:
e1599b0c
XL
84
85```rust
86use std::{sync::Mutex, collections::HashMap};
87use once_cell::sync::Lazy;
88
89static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
90 let mut m = HashMap::new();
91 m.insert(13, "Spica".to_string());
92 m.insert(74, "Hoyten".to_string());
93 Mutex::new(m)
94});
95
96fn main() {
97 println!("{:?}", GLOBAL_DATA.lock().unwrap());
98}
99```
100
f035d41b
XL
101[`sync::Lazy`]: sync/struct.Lazy.html
102[`unsync::Lazy`]: unsync/struct.Lazy.html
103
e1599b0c
XL
104## General purpose lazy evaluation
105
106Unlike `lazy_static!`, `Lazy` works with local variables.
107
108```rust
109use once_cell::unsync::Lazy;
110
111fn main() {
112 let ctx = vec![1, 2, 3];
113 let thunk = Lazy::new(|| {
114 ctx.iter().sum::<i32>()
115 });
116 assert_eq!(*thunk, 6);
117}
118```
119
120If you need a lazy field in a struct, you probably should use `OnceCell`
121directly, because that will allow you to access `self` during initialization.
122
123```rust
124use std::{fs, path::PathBuf};
125
126use once_cell::unsync::OnceCell;
127
128struct Ctx {
129 config_path: PathBuf,
130 config: OnceCell<String>,
131}
132
133impl Ctx {
134 pub fn get_config(&self) -> Result<&str, std::io::Error> {
135 let cfg = self.config.get_or_try_init(|| {
136 fs::read_to_string(&self.config_path)
137 })?;
138 Ok(cfg.as_str())
139 }
140}
141```
142
143## Building block
144
145Naturally, it is possible to build other abstractions on top of `OnceCell`.
146For example, this is a `regex!` macro which takes a string literal and returns an
147*expression* that evaluates to a `&'static Regex`:
148
149```
150macro_rules! regex {
151 ($re:literal $(,)?) => {{
152 static RE: once_cell::sync::OnceCell<regex::Regex> = once_cell::sync::OnceCell::new();
153 RE.get_or_init(|| regex::Regex::new($re).unwrap())
154 }};
155}
156```
157
f035d41b 158This macro can be useful to avoid the "compile regex on every loop iteration" problem.
e1599b0c
XL
159
160# Comparison with std
161
162|`!Sync` types | Access Mode | Drawbacks |
163|----------------------|------------------------|-----------------------------------------------|
164|`Cell<T>` | `T` | requires `T: Copy` for `get` |
f035d41b 165|`RefCell<T>` | `RefMut<T>` / `Ref<T>` | may panic at runtime |
e1599b0c
XL
166|`unsync::OnceCell<T>` | `&T` | assignable only once |
167
168|`Sync` types | Access Mode | Drawbacks |
169|----------------------|------------------------|-----------------------------------------------|
170|`AtomicT` | `T` | works only with certain `Copy` types |
171|`Mutex<T>` | `MutexGuard<T>` | may deadlock at runtime, may block the thread |
172|`sync::OnceCell<T>` | `&T` | assignable only once, may block the thread |
173
174Technically, calling `get_or_init` will also cause a panic or a deadlock if it recursively calls
175itself. However, because the assignment can happen only once, such cases should be more rare than
176equivalents with `RefCell` and `Mutex`.
177
178# Minimum Supported `rustc` Version
179
f035d41b
XL
180This crate's minimum supported `rustc` version is `1.31.1` (or `1.36.0` with the
181`parking_lot` feature enabled).
e1599b0c 182
f035d41b 183If only the `std` feature is enabled, MSRV will be updated conservatively.
e1599b0c
XL
184When using other features, like `parking_lot`, MSRV might be updated more frequently, up to the latest stable.
185In both cases, increasing MSRV is *not* considered a semver-breaking change.
186
187# Implementation details
188
f035d41b
XL
189The implementation is based on the [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/)
190and [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and [`std::sync::Once`]. In some sense,
e1599b0c
XL
191`once_cell` just streamlines and unifies those APIs.
192
193To implement a sync flavor of `OnceCell`, this crates uses either a custom re-implementation of
194`std::sync::Once` or `parking_lot::Mutex`. This is controlled by the `parking_lot` feature, which
f035d41b 195is enabled by default. Performance is the same for both cases, but the `parking_lot` based `OnceCell<T>`
e1599b0c
XL
196is smaller by up to 16 bytes.
197
f035d41b
XL
198This crate uses `unsafe`.
199
200[`std::sync::Once`]: https://doc.rust-lang.org/std/sync/struct.Once.html
e1599b0c
XL
201
202# F.A.Q.
203
204**Should I use lazy_static or once_cell?**
205
206To the first approximation, `once_cell` is both more flexible and more convenient than `lazy_static`
207and should be preferred.
208
209Unlike `once_cell`, `lazy_static` supports spinlock-based implementation of blocking which works with
210`#![no_std]`.
211
212`lazy_static` has received significantly more real world testing, but `once_cell` is also a widely
213used crate.
214
f035d41b 215**Should I use the sync or unsync flavor?**
e1599b0c
XL
216
217Because Rust compiler checks thread safety for you, it's impossible to accidentally use `unsync` where
218`sync` is required. So, use `unsync` in single-threaded code and `sync` in multi-threaded. It's easy
219to switch between the two if code becomes multi-threaded later.
220
221At the moment, `unsync` has an additional benefit that reentrant initialization causes a panic, which
222might be easier to debug than a deadlock.
223
224# Related crates
225
226* [double-checked-cell](https://github.com/niklasf/double-checked-cell)
227* [lazy-init](https://crates.io/crates/lazy-init)
228* [lazycell](https://crates.io/crates/lazycell)
229* [mitochondria](https://crates.io/crates/mitochondria)
230* [lazy_static](https://crates.io/crates/lazy_static)
231
232*/
233
234#![cfg_attr(not(feature = "std"), no_std)]
235
236#[cfg(feature = "std")]
237#[cfg(feature = "parking_lot")]
238#[path = "imp_pl.rs"]
239mod imp;
240
241#[cfg(feature = "std")]
242#[cfg(not(feature = "parking_lot"))]
243#[path = "imp_std.rs"]
244mod imp;
245
246pub mod unsync {
247 use core::{
248 cell::{Cell, UnsafeCell},
f035d41b
XL
249 fmt, mem,
250 ops::{Deref, DerefMut},
e1599b0c
XL
251 };
252
253 #[cfg(feature = "std")]
254 use std::panic::{RefUnwindSafe, UnwindSafe};
255
f035d41b 256 /// A cell which can be written to only once. It is not thread safe.
e1599b0c 257 ///
f035d41b 258 /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&`
e1599b0c
XL
259 /// references to the contents.
260 ///
f035d41b
XL
261 /// [`std::cell::RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
262 ///
e1599b0c
XL
263 /// # Example
264 /// ```
265 /// use once_cell::unsync::OnceCell;
266 ///
267 /// let cell = OnceCell::new();
268 /// assert!(cell.get().is_none());
269 ///
270 /// let value: &String = cell.get_or_init(|| {
271 /// "Hello, World!".to_string()
272 /// });
273 /// assert_eq!(value, "Hello, World!");
274 /// assert!(cell.get().is_some());
275 /// ```
276 pub struct OnceCell<T> {
277 // Invariant: written to at most once.
278 inner: UnsafeCell<Option<T>>,
279 }
280
281 // Similarly to a `Sync` bound on `sync::OnceCell`, we can use
282 // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`,
283 // by initializing the cell in closure and extracting the value in the
284 // `Drop`.
285 #[cfg(feature = "std")]
286 impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
287 #[cfg(feature = "std")]
288 impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
289
290 impl<T> Default for OnceCell<T> {
291 fn default() -> Self {
292 Self::new()
293 }
294 }
295
296 impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
297 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
298 match self.get() {
299 Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
300 None => f.write_str("OnceCell(Uninit)"),
301 }
302 }
303 }
304
305 impl<T: Clone> Clone for OnceCell<T> {
306 fn clone(&self) -> OnceCell<T> {
307 let res = OnceCell::new();
308 if let Some(value) = self.get() {
309 match res.set(value.clone()) {
310 Ok(()) => (),
311 Err(_) => unreachable!(),
312 }
313 }
314 res
315 }
316 }
317
318 impl<T: PartialEq> PartialEq for OnceCell<T> {
319 fn eq(&self, other: &Self) -> bool {
320 self.get() == other.get()
321 }
322 }
323
324 impl<T: Eq> Eq for OnceCell<T> {}
325
326 impl<T> From<T> for OnceCell<T> {
327 fn from(value: T) -> Self {
328 OnceCell { inner: UnsafeCell::new(Some(value)) }
329 }
330 }
331
332 impl<T> OnceCell<T> {
333 /// Creates a new empty cell.
334 pub const fn new() -> OnceCell<T> {
335 OnceCell { inner: UnsafeCell::new(None) }
336 }
337
f035d41b 338 /// Gets a reference to the underlying value.
e1599b0c
XL
339 ///
340 /// Returns `None` if the cell is empty.
341 pub fn get(&self) -> Option<&T> {
342 // Safe due to `inner`'s invariant
343 unsafe { &*self.inner.get() }.as_ref()
344 }
345
f035d41b 346 /// Gets a mutable reference to the underlying value.
e1599b0c
XL
347 ///
348 /// Returns `None` if the cell is empty.
349 pub fn get_mut(&mut self) -> Option<&mut T> {
350 // Safe because we have unique access
351 unsafe { &mut *self.inner.get() }.as_mut()
352 }
353
354 /// Sets the contents of this cell to `value`.
355 ///
356 /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
357 /// full.
358 ///
359 /// # Example
360 /// ```
361 /// use once_cell::unsync::OnceCell;
362 ///
363 /// let cell = OnceCell::new();
364 /// assert!(cell.get().is_none());
365 ///
366 /// assert_eq!(cell.set(92), Ok(()));
367 /// assert_eq!(cell.set(62), Err(62));
368 ///
369 /// assert!(cell.get().is_some());
370 /// ```
371 pub fn set(&self, value: T) -> Result<(), T> {
372 let slot = unsafe { &*self.inner.get() };
373 if slot.is_some() {
374 return Err(value);
375 }
376 let slot = unsafe { &mut *self.inner.get() };
377 // This is the only place where we set the slot, no races
378 // due to reentrancy/concurrency are possible, and we've
379 // checked that slot is currently `None`, so this write
380 // maintains the `inner`'s invariant.
381 *slot = Some(value);
382 Ok(())
383 }
384
385 /// Gets the contents of the cell, initializing it with `f`
386 /// if the cell was empty.
387 ///
388 /// # Panics
389 ///
390 /// If `f` panics, the panic is propagated to the caller, and the cell
391 /// remains uninitialized.
392 ///
393 /// It is an error to reentrantly initialize the cell from `f`. Doing
394 /// so results in a panic.
395 ///
396 /// # Example
397 /// ```
398 /// use once_cell::unsync::OnceCell;
399 ///
400 /// let cell = OnceCell::new();
401 /// let value = cell.get_or_init(|| 92);
402 /// assert_eq!(value, &92);
403 /// let value = cell.get_or_init(|| unreachable!());
404 /// assert_eq!(value, &92);
405 /// ```
406 pub fn get_or_init<F>(&self, f: F) -> &T
407 where
408 F: FnOnce() -> T,
409 {
410 enum Void {}
411 match self.get_or_try_init(|| Ok::<T, Void>(f())) {
412 Ok(val) => val,
413 Err(void) => match void {},
414 }
415 }
416
417 /// Gets the contents of the cell, initializing it with `f` if
418 /// the cell was empty. If the cell was empty and `f` failed, an
419 /// error is returned.
420 ///
421 /// # Panics
422 ///
423 /// If `f` panics, the panic is propagated to the caller, and the cell
424 /// remains uninitialized.
425 ///
426 /// It is an error to reentrantly initialize the cell from `f`. Doing
427 /// so results in a panic.
428 ///
429 /// # Example
430 /// ```
431 /// use once_cell::unsync::OnceCell;
432 ///
433 /// let cell = OnceCell::new();
434 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
435 /// assert!(cell.get().is_none());
436 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
437 /// Ok(92)
438 /// });
439 /// assert_eq!(value, Ok(&92));
440 /// assert_eq!(cell.get(), Some(&92))
441 /// ```
442 pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
443 where
444 F: FnOnce() -> Result<T, E>,
445 {
446 if let Some(val) = self.get() {
447 return Ok(val);
448 }
449 let val = f()?;
f035d41b
XL
450 // Note that *some* forms of reentrant initialization might lead to
451 // UB (see `reentrant_init` test). I believe that just removing this
452 // `assert`, while keeping `set/get` would be sound, but it seems
453 // better to panic, rather than to silently use an old value.
e1599b0c
XL
454 assert!(self.set(val).is_ok(), "reentrant init");
455 Ok(self.get().unwrap())
456 }
457
f035d41b
XL
458 /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
459 ///
460 /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
461 ///
462 /// # Examples
463 ///
464 /// ```
465 /// use once_cell::unsync::OnceCell;
466 ///
467 /// let mut cell: OnceCell<String> = OnceCell::new();
468 /// assert_eq!(cell.take(), None);
469 ///
470 /// let mut cell = OnceCell::new();
471 /// cell.set("hello".to_string()).unwrap();
472 /// assert_eq!(cell.take(), Some("hello".to_string()));
473 /// assert_eq!(cell.get(), None);
474 /// ```
475 pub fn take(&mut self) -> Option<T> {
476 mem::replace(self, Self::default()).into_inner()
477 }
478
e1599b0c
XL
479 /// Consumes the `OnceCell`, returning the wrapped value.
480 ///
481 /// Returns `None` if the cell was empty.
482 ///
483 /// # Examples
484 ///
485 /// ```
486 /// use once_cell::unsync::OnceCell;
487 ///
488 /// let cell: OnceCell<String> = OnceCell::new();
489 /// assert_eq!(cell.into_inner(), None);
490 ///
491 /// let cell = OnceCell::new();
492 /// cell.set("hello".to_string()).unwrap();
493 /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
494 /// ```
495 pub fn into_inner(self) -> Option<T> {
496 // Because `into_inner` takes `self` by value, the compiler statically verifies
497 // that it is not currently borrowed. So it is safe to move out `Option<T>`.
498 self.inner.into_inner()
499 }
500 }
501
502 /// A value which is initialized on the first access.
503 ///
504 /// # Example
505 /// ```
506 /// use once_cell::unsync::Lazy;
507 ///
508 /// let lazy: Lazy<i32> = Lazy::new(|| {
509 /// println!("initializing");
510 /// 92
511 /// });
512 /// println!("ready");
513 /// println!("{}", *lazy);
514 /// println!("{}", *lazy);
515 ///
516 /// // Prints:
517 /// // ready
518 /// // initializing
519 /// // 92
520 /// // 92
521 /// ```
522 pub struct Lazy<T, F = fn() -> T> {
523 cell: OnceCell<T>,
524 init: Cell<Option<F>>,
525 }
526
527 #[cfg(feature = "std")]
528 impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
529
f035d41b 530 impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
e1599b0c
XL
531 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
532 f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
533 }
534 }
535
536 impl<T, F> Lazy<T, F> {
537 /// Creates a new lazy value with the given initializing function.
538 ///
539 /// # Example
540 /// ```
541 /// # fn main() {
542 /// use once_cell::unsync::Lazy;
543 ///
544 /// let hello = "Hello, World!".to_string();
545 ///
546 /// let lazy = Lazy::new(|| hello.to_uppercase());
547 ///
548 /// assert_eq!(&*lazy, "HELLO, WORLD!");
549 /// # }
550 /// ```
551 pub const fn new(init: F) -> Lazy<T, F> {
552 Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
553 }
554 }
555
556 impl<T, F: FnOnce() -> T> Lazy<T, F> {
557 /// Forces the evaluation of this lazy value and returns a reference to
558 /// the result.
559 ///
560 /// This is equivalent to the `Deref` impl, but is explicit.
561 ///
562 /// # Example
563 /// ```
564 /// use once_cell::unsync::Lazy;
565 ///
566 /// let lazy = Lazy::new(|| 92);
567 ///
568 /// assert_eq!(Lazy::force(&lazy), &92);
569 /// assert_eq!(&*lazy, &92);
570 /// ```
571 pub fn force(this: &Lazy<T, F>) -> &T {
572 this.cell.get_or_init(|| match this.init.take() {
573 Some(f) => f(),
574 None => panic!("Lazy instance has previously been poisoned"),
575 })
576 }
577 }
578
579 impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
580 type Target = T;
581 fn deref(&self) -> &T {
582 Lazy::force(self)
583 }
584 }
585
f035d41b
XL
586 impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
587 fn deref_mut(&mut self) -> &mut T {
588 Lazy::force(self);
589 self.cell.get_mut().unwrap_or_else(|| unreachable!())
590 }
591 }
592
e1599b0c
XL
593 impl<T: Default> Default for Lazy<T> {
594 /// Creates a new lazy value using `Default` as the initializing function.
595 fn default() -> Lazy<T> {
596 Lazy::new(T::default)
597 }
598 }
599}
600
601#[cfg(feature = "std")]
602pub mod sync {
f035d41b
XL
603 use std::{
604 cell::Cell,
605 fmt, mem,
606 ops::{Deref, DerefMut},
607 panic::RefUnwindSafe,
608 };
e1599b0c
XL
609
610 use crate::imp::OnceCell as Imp;
611
612 /// A thread-safe cell which can be written to only once.
613 ///
f035d41b
XL
614 /// `OnceCell` provides `&` references to the contents without RAII guards.
615 ///
616 /// Reading a non-`None` value out of `OnceCell` establishes a
617 /// happens-before relationship with a corresponding write. For example, if
618 /// thread A initializes the cell with `get_or_init(f)`, and thread B
619 /// subsequently reads the result of this call, B also observes all the side
620 /// effects of `f`.
e1599b0c
XL
621 ///
622 /// # Example
623 /// ```
624 /// use once_cell::sync::OnceCell;
625 ///
626 /// static CELL: OnceCell<String> = OnceCell::new();
627 /// assert!(CELL.get().is_none());
628 ///
629 /// std::thread::spawn(|| {
630 /// let value: &String = CELL.get_or_init(|| {
631 /// "Hello, World!".to_string()
632 /// });
633 /// assert_eq!(value, "Hello, World!");
634 /// }).join().unwrap();
635 ///
636 /// let value: Option<&String> = CELL.get();
637 /// assert!(value.is_some());
638 /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
639 /// ```
640 pub struct OnceCell<T>(Imp<T>);
641
642 impl<T> Default for OnceCell<T> {
643 fn default() -> OnceCell<T> {
644 OnceCell::new()
645 }
646 }
647
648 impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
649 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
650 match self.get() {
651 Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
652 None => f.write_str("OnceCell(Uninit)"),
653 }
654 }
655 }
656
657 impl<T: Clone> Clone for OnceCell<T> {
658 fn clone(&self) -> OnceCell<T> {
659 let res = OnceCell::new();
660 if let Some(value) = self.get() {
661 match res.set(value.clone()) {
662 Ok(()) => (),
663 Err(_) => unreachable!(),
664 }
665 }
666 res
667 }
668 }
669
670 impl<T> From<T> for OnceCell<T> {
671 fn from(value: T) -> Self {
672 let cell = Self::new();
673 cell.get_or_init(|| value);
674 cell
675 }
676 }
677
678 impl<T: PartialEq> PartialEq for OnceCell<T> {
679 fn eq(&self, other: &OnceCell<T>) -> bool {
680 self.get() == other.get()
681 }
682 }
683
684 impl<T: Eq> Eq for OnceCell<T> {}
685
686 impl<T> OnceCell<T> {
687 /// Creates a new empty cell.
688 pub const fn new() -> OnceCell<T> {
689 OnceCell(Imp::new())
690 }
691
692 /// Gets the reference to the underlying value.
693 ///
694 /// Returns `None` if the cell is empty, or being initialized. This
695 /// method never blocks.
696 pub fn get(&self) -> Option<&T> {
697 if self.0.is_initialized() {
f035d41b 698 // Safe b/c value is initialized.
e1599b0c
XL
699 Some(unsafe { self.get_unchecked() })
700 } else {
701 None
702 }
703 }
704
705 /// Gets the mutable reference to the underlying value.
706 ///
707 /// Returns `None` if the cell is empty.
708 pub fn get_mut(&mut self) -> Option<&mut T> {
f035d41b
XL
709 self.0.get_mut()
710 }
711
712 /// Get the reference to the underlying value, without checking if the
713 /// cell is initialized.
714 ///
715 /// # Safety
716 ///
717 /// Caller must ensure that the cell is in initialized state, and that
718 /// the contents are acquired by (synchronized to) this thread.
719 pub unsafe fn get_unchecked(&self) -> &T {
720 self.0.get_unchecked()
e1599b0c
XL
721 }
722
723 /// Sets the contents of this cell to `value`.
724 ///
725 /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
726 /// full.
727 ///
728 /// # Example
f035d41b 729 ///
e1599b0c
XL
730 /// ```
731 /// use once_cell::sync::OnceCell;
732 ///
733 /// static CELL: OnceCell<i32> = OnceCell::new();
734 ///
735 /// fn main() {
736 /// assert!(CELL.get().is_none());
737 ///
738 /// std::thread::spawn(|| {
739 /// assert_eq!(CELL.set(92), Ok(()));
740 /// }).join().unwrap();
741 ///
742 /// assert_eq!(CELL.set(62), Err(62));
743 /// assert_eq!(CELL.get(), Some(&92));
744 /// }
745 /// ```
746 pub fn set(&self, value: T) -> Result<(), T> {
747 let mut value = Some(value);
748 self.get_or_init(|| value.take().unwrap());
749 match value {
750 None => Ok(()),
751 Some(value) => Err(value),
752 }
753 }
754
755 /// Gets the contents of the cell, initializing it with `f` if the cell
756 /// was empty.
757 ///
758 /// Many threads may call `get_or_init` concurrently with different
759 /// initializing functions, but it is guaranteed that only one function
760 /// will be executed.
761 ///
762 /// # Panics
763 ///
764 /// If `f` panics, the panic is propagated to the caller, and the cell
765 /// remains uninitialized.
766 ///
767 /// It is an error to reentrantly initialize the cell from `f`. The
768 /// exact outcome is unspecified. Current implementation deadlocks, but
769 /// this may be changed to a panic in the future.
770 ///
771 /// # Example
772 /// ```
773 /// use once_cell::sync::OnceCell;
774 ///
775 /// let cell = OnceCell::new();
776 /// let value = cell.get_or_init(|| 92);
777 /// assert_eq!(value, &92);
778 /// let value = cell.get_or_init(|| unreachable!());
779 /// assert_eq!(value, &92);
780 /// ```
781 pub fn get_or_init<F>(&self, f: F) -> &T
782 where
783 F: FnOnce() -> T,
784 {
785 enum Void {}
786 match self.get_or_try_init(|| Ok::<T, Void>(f())) {
787 Ok(val) => val,
788 Err(void) => match void {},
789 }
790 }
791
792 /// Gets the contents of the cell, initializing it with `f` if
793 /// the cell was empty. If the cell was empty and `f` failed, an
794 /// error is returned.
795 ///
796 /// # Panics
797 ///
798 /// If `f` panics, the panic is propagated to the caller, and
799 /// the cell remains uninitialized.
800 ///
801 /// It is an error to reentrantly initialize the cell from `f`.
802 /// The exact outcome is unspecified. Current implementation
803 /// deadlocks, but this may be changed to a panic in the future.
804 ///
805 /// # Example
806 /// ```
807 /// use once_cell::sync::OnceCell;
808 ///
809 /// let cell = OnceCell::new();
810 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
811 /// assert!(cell.get().is_none());
812 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
813 /// Ok(92)
814 /// });
815 /// assert_eq!(value, Ok(&92));
816 /// assert_eq!(cell.get(), Some(&92))
817 /// ```
818 pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
819 where
820 F: FnOnce() -> Result<T, E>,
821 {
822 // Fast path check
823 if let Some(value) = self.get() {
824 return Ok(value);
825 }
826 self.0.initialize(f)?;
827
f035d41b 828 // Safe b/c value is initialized.
e1599b0c
XL
829 debug_assert!(self.0.is_initialized());
830 Ok(unsafe { self.get_unchecked() })
831 }
832
f035d41b
XL
833 /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
834 ///
835 /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
836 ///
837 /// # Examples
838 ///
839 /// ```
840 /// use once_cell::sync::OnceCell;
841 ///
842 /// let mut cell: OnceCell<String> = OnceCell::new();
843 /// assert_eq!(cell.take(), None);
844 ///
845 /// let mut cell = OnceCell::new();
846 /// cell.set("hello".to_string()).unwrap();
847 /// assert_eq!(cell.take(), Some("hello".to_string()));
848 /// assert_eq!(cell.get(), None);
849 /// ```
850 pub fn take(&mut self) -> Option<T> {
851 mem::replace(self, Self::default()).into_inner()
852 }
853
e1599b0c
XL
854 /// Consumes the `OnceCell`, returning the wrapped value. Returns
855 /// `None` if the cell was empty.
856 ///
857 /// # Examples
858 ///
859 /// ```
860 /// use once_cell::sync::OnceCell;
861 ///
862 /// let cell: OnceCell<String> = OnceCell::new();
863 /// assert_eq!(cell.into_inner(), None);
864 ///
865 /// let cell = OnceCell::new();
866 /// cell.set("hello".to_string()).unwrap();
867 /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
868 /// ```
869 pub fn into_inner(self) -> Option<T> {
f035d41b 870 self.0.into_inner()
e1599b0c
XL
871 }
872 }
873
874 /// A value which is initialized on the first access.
875 ///
f035d41b 876 /// This type is thread-safe and can be used in statics.
e1599b0c
XL
877 ///
878 /// # Example
f035d41b 879 ///
e1599b0c
XL
880 /// ```
881 /// use std::collections::HashMap;
882 ///
883 /// use once_cell::sync::Lazy;
884 ///
885 /// static HASHMAP: Lazy<HashMap<i32, String>> = Lazy::new(|| {
886 /// println!("initializing");
887 /// let mut m = HashMap::new();
888 /// m.insert(13, "Spica".to_string());
889 /// m.insert(74, "Hoyten".to_string());
890 /// m
891 /// });
892 ///
893 /// fn main() {
894 /// println!("ready");
895 /// std::thread::spawn(|| {
896 /// println!("{:?}", HASHMAP.get(&13));
897 /// }).join().unwrap();
898 /// println!("{:?}", HASHMAP.get(&74));
899 ///
900 /// // Prints:
901 /// // ready
902 /// // initializing
903 /// // Some("Spica")
904 /// // Some("Hoyten")
905 /// }
906 /// ```
907 pub struct Lazy<T, F = fn() -> T> {
908 cell: OnceCell<T>,
909 init: Cell<Option<F>>,
910 }
911
f035d41b 912 impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
e1599b0c
XL
913 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
914 f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
915 }
916 }
917
918 // We never create a `&F` from a `&Lazy<T, F>` so it is fine
919 // to not impl `Sync` for `F`
920 // we do create a `&mut Option<F>` in `force`, but this is
921 // properly synchronized, so it only happens once
922 // so it also does not contribute to this impl.
923 unsafe impl<T, F: Send> Sync for Lazy<T, F> where OnceCell<T>: Sync {}
924 // auto-derived `Send` impl is OK.
925
926 #[cfg(feature = "std")]
927 impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
928
929 impl<T, F> Lazy<T, F> {
930 /// Creates a new lazy value with the given initializing
931 /// function.
932 pub const fn new(f: F) -> Lazy<T, F> {
933 Lazy { cell: OnceCell::new(), init: Cell::new(Some(f)) }
934 }
935 }
936
937 impl<T, F: FnOnce() -> T> Lazy<T, F> {
938 /// Forces the evaluation of this lazy value and
f035d41b 939 /// returns a reference to the result. This is equivalent
e1599b0c
XL
940 /// to the `Deref` impl, but is explicit.
941 ///
942 /// # Example
943 /// ```
944 /// use once_cell::sync::Lazy;
945 ///
946 /// let lazy = Lazy::new(|| 92);
947 ///
948 /// assert_eq!(Lazy::force(&lazy), &92);
949 /// assert_eq!(&*lazy, &92);
950 /// ```
951 pub fn force(this: &Lazy<T, F>) -> &T {
952 this.cell.get_or_init(|| match this.init.take() {
953 Some(f) => f(),
954 None => panic!("Lazy instance has previously been poisoned"),
955 })
956 }
957 }
958
f035d41b 959 impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
e1599b0c
XL
960 type Target = T;
961 fn deref(&self) -> &T {
962 Lazy::force(self)
963 }
964 }
965
f035d41b
XL
966 impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
967 fn deref_mut(&mut self) -> &mut T {
968 Lazy::force(self);
969 self.cell.get_mut().unwrap_or_else(|| unreachable!())
970 }
971 }
972
e1599b0c
XL
973 impl<T: Default> Default for Lazy<T> {
974 /// Creates a new lazy value using `Default` as the initializing function.
975 fn default() -> Lazy<T> {
976 Lazy::new(T::default)
977 }
978 }
979
980 /// ```compile_fail
981 /// struct S(*mut ());
982 /// unsafe impl Sync for S {}
983 ///
984 /// fn share<T: Sync>(_: &T) {}
985 /// share(&once_cell::sync::OnceCell::<S>::new());
986 /// ```
987 ///
988 /// ```compile_fail
989 /// struct S(*mut ());
990 /// unsafe impl Sync for S {}
991 ///
992 /// fn share<T: Sync>(_: &T) {}
993 /// share(&once_cell::sync::Lazy::<S>::new(|| unimplemented!()));
994 /// ```
995 fn _dummy() {}
996}