1use crate::VmResult;
2
3#[cfg(feature = "std")]
4type OnceCellImp<T> = once_cell::sync::OnceCell<T>;
5
6#[cfg(not(feature = "std"))]
7struct OnceCellImp<T>(once_cell::race::OnceBox<T>);
8
9#[cfg(not(feature = "std"))]
10impl<T> OnceCellImp<T> {
11 pub const fn new() -> Self {
12 Self(once_cell::race::OnceBox::new())
13 }
14
15 pub fn get_or_init<F>(&self, f: F) -> &T
16 where
17 F: FnOnce() -> T,
18 {
19 self.0.get_or_init(|| alloc::boxed::Box::new(f()))
20 }
21
22 pub fn get_or_try_init<F>(&self, f: F) -> VmResult<&T>
23 where
24 F: FnOnce() -> VmResult<T>,
25 {
26 self.0.get_or_try_init(|| Ok(alloc::boxed::Box::new(f()?)))
27 }
28}
29
30pub struct OnceCell<T>(OnceCellImp<T>);
31
32#[allow(unused)]
33impl<T> OnceCell<T> {
34 pub const fn new() -> Self {
35 Self(OnceCellImp::new())
36 }
37
38 pub fn get_or_init<F>(&self, f: F) -> &T
39 where
40 F: FnOnce() -> T,
41 {
42 self.0.get_or_init(f)
43 }
44
45 pub fn get_or_try_init<F>(&self, f: F) -> VmResult<&T>
46 where
47 F: FnOnce() -> VmResult<T>,
48 {
49 self.0.get_or_try_init(f)
50 }
51}
52
53impl<T> Default for OnceCell<T> {
54 fn default() -> Self {
55 Self::new()
56 }
57}