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