poly_once/
transform_once.rs

1//! Parameterized once cell with transformation support.
2//!
3//! This module provides the [`TOnce<P, T>`] type, a thread-safe cell that stores
4//! a parameter of type `P` and transforms it into a value of type `T` on first access.
5//! This is useful when you need to defer expensive initialization that requires
6//! input data, or when the initialization parameters are known at construction
7//! but the computation should be lazy.
8//!
9//! The key difference from `Once<T>` is that `TOnce<P, T>` stores the parameter
10//! until initialization, then replaces it with the computed value. This allows
11//! for more flexible initialization patterns where the initialization logic
12//! needs access to stored state.
13//!
14//! Like `Once`, it uses atomic operations for the fast path and futex-based
15//! synchronization for the slow path.
16
17use core::cell::UnsafeCell;
18use core::future::Future;
19use core::sync::atomic::Ordering;
20use core::{fmt, mem};
21
22use super::state::OnceLock;
23use crate::state::OnceGuard;
24
25/// Internal enum to hold either the parameter or the initialized value.
26union TOnceState<P, T> {
27   pending: mem::ManuallyDrop<P>,
28   init: mem::ManuallyDrop<T>,
29}
30
31impl<P, T> TOnceState<P, T> {
32   #[inline(always)]
33   const fn pending(value: P) -> Self {
34      Self {
35         pending: mem::ManuallyDrop::new(value),
36      }
37   }
38   #[inline(always)]
39   const fn init(value: T) -> Self {
40      Self {
41         init: mem::ManuallyDrop::new(value),
42      }
43   }
44   #[inline(always)]
45   unsafe fn drop_pending(&mut self) -> P {
46      mem::ManuallyDrop::take(unsafe { &mut self.pending })
47   }
48
49   #[inline(always)]
50   unsafe fn drop_init(&mut self) -> T {
51      mem::ManuallyDrop::take(unsafe { &mut self.init })
52   }
53}
54
55struct EditSanitizer<'a, P, T> {
56   state: &'a mut TOnceState<P, T>,
57   guard: OnceGuard<'a>,
58   taken: bool,
59}
60
61impl<'a, P, T> EditSanitizer<'a, P, T> {
62   #[inline(always)]
63   fn new(state: &'a UnsafeCell<TOnceState<P, T>>, guard: OnceGuard<'a>) -> Self {
64      Self {
65         state: unsafe { &mut *state.get() },
66         taken: false,
67         guard,
68      }
69   }
70
71   #[inline(always)]
72   unsafe fn take_parameter(&mut self) -> P {
73      debug_assert!(!self.taken, "Parameter already taken");
74      self.taken = true;
75      unsafe { self.state.drop_pending() }
76   }
77   #[inline(always)]
78   unsafe fn ref_parameter(&self) -> &P {
79      unsafe { &self.state.pending }
80   }
81   #[inline(always)]
82   unsafe fn commit(self, value: T) -> &'a mut T {
83      unsafe {
84         if !self.taken {
85            _ = self.state.drop_pending();
86         }
87         *self.state = TOnceState::init(value);
88         self.guard.commit_forgotten();
89         let ptr = self.state as *mut TOnceState<P, T>;
90         mem::forget(self);
91         &mut (*ptr).init
92      }
93   }
94}
95
96#[cfg(debug_assertions)]
97impl<P, T> Drop for EditSanitizer<'_, P, T> {
98   #[inline(always)]
99   fn drop(&mut self) {
100      assert!(!self.taken, "Parameter taken on return, no value in cell");
101   }
102}
103
104/// A thread-safe cell which can be written to only once using a parameterized initializer.
105///
106/// This structure provides safe initialization for values that might be accessed
107/// concurrently by multiple threads. It ensures that the initialization logic
108/// runs only once, even if multiple threads attempt to initialize the value simultaneously.
109///
110/// It uses atomic operations and `parking_lot`'s futex-based synchronization for
111/// efficient blocking when necessary.
112pub struct TOnce<P, T> {
113   value: UnsafeCell<TOnceState<P, T>>,
114   lock: OnceLock,
115}
116
117impl<P, T> TOnce<P, T> {
118   /// Creates a new, uninitialized `TOnce` cell with the given parameter.
119   #[inline]
120   #[must_use]
121   pub const fn new(param: P) -> Self {
122      Self {
123         lock: OnceLock::new(),
124         value: UnsafeCell::new(TOnceState::pending(param)),
125      }
126   }
127
128   /// Creates a new `TOnce` cell that is already initialized with the given value, bypassing the parameter.
129   #[inline]
130   #[must_use]
131   pub const fn with_value(value: T) -> Self {
132      Self {
133         lock: OnceLock::done(),
134         value: UnsafeCell::new(TOnceState::init(value)),
135      }
136   }
137
138   /// Checks if the cell has been initialized.
139   ///
140   /// This method never blocks.
141   #[inline]
142   pub fn is_done(&self) -> bool {
143      self.lock.is_done(Ordering::Relaxed)
144   }
145
146   /// Returns a reference to the contained value if initialized.
147   ///
148   /// Returns `None` if the cell is uninitialized or currently being initialized.
149   /// This method never blocks.
150   #[inline]
151   pub fn get(&self) -> Option<&T> {
152      if self.is_done() {
153         // SAFETY: is_done() returned true, so the value is initialized.
154         Some(unsafe { self.get_unchecked() })
155      } else {
156         None
157      }
158   }
159
160   /// Returns a mutable reference to the contained value if initialized.
161   ///
162   /// Returns `None` if the cell is uninitialized or currently being initialized.
163   /// This method requires exclusive access (`&mut self`) and never blocks.
164   #[inline]
165   pub fn get_mut(&mut self) -> Option<&mut T> {
166      if self.is_done() {
167         // SAFETY: is_done() returned true and we have exclusive access (`&mut self`).
168         Some(unsafe { self.get_unchecked_mut() })
169      } else {
170         None
171      }
172   }
173
174   /// Attempts to initialize the cell with `value` without blocking, ignoring the parameter.
175   ///
176   /// - If the cell is uninitialized and not locked, initializes it with `value` and returns `Ok(&value)`.
177   /// - If the cell is already initialized, returns `Err(value)`.
178   /// - If the cell is currently locked by another thread, returns `Err(value)`.
179   #[inline]
180   pub fn try_set(&self, value: T) -> Result<&T, T> {
181      let Some(guard) = self.lock.try_lock() else {
182         return Err(value);
183      };
184      // SAFETY: We hold the lock, so we have exclusive access to initialize the value.
185      unsafe {
186         let edit = EditSanitizer::new(&self.value, guard);
187         let v = edit.commit(value);
188         Ok(v)
189      }
190   }
191
192   /// Replaces the cell's value, returning the old value if initialized.
193   ///
194   /// - If uninitialized, discards the parameter, sets the value to `value` and returns `None`.
195   /// - If initialized, replaces the existing value with `value` and returns the old value.
196   ///
197   /// Requires exclusive access (`&mut self`), so it never blocks.
198   #[inline]
199   pub fn replace_mut(&mut self, value: T) -> Option<T> {
200      if self.lock.set_done() {
201         // Was uninitialized, now set to done. Replace with the new value.
202         unsafe {
203            mem::replace(self.value.get_mut(), TOnceState::init(value)).drop_pending();
204         }
205         None
206      } else {
207         // Was already initialized. Replace the existing value.
208         Some(unsafe { mem::replace(self.get_unchecked_mut(), value) })
209      }
210   }
211
212   /// Gets a mutable reference, initializing with `value` if needed.
213   ///
214   /// - If initialized, returns a mutable reference to the existing value.
215   /// - If uninitialized, discards the parameter, initializes it with `value` and returns a mutable reference.
216   ///
217   /// Requires exclusive access (`&mut self`), so it never blocks.
218   #[inline]
219   pub fn get_mut_or_set(&mut self, value: T) -> &mut T {
220      if self.lock.set_done() {
221         // Was uninitialized, now set to done. Replace with the new value.
222         unsafe {
223            mem::replace(self.value.get_mut(), TOnceState::init(value)).drop_pending();
224         }
225      }
226      // SAFETY: The cell is guaranteed to be initialized here, either previously
227      // or by the call above, and we have exclusive access.
228      unsafe { self.get_unchecked_mut() }
229   }
230
231   /// Gets a mutable reference, initializing with `Default::default()` if needed.
232   ///
233   /// - If initialized, returns a mutable reference to the existing value.
234   /// - If uninitialized, discards the parameter, initializes it with `T::default()` and returns a mutable reference.
235   ///
236   /// Requires exclusive access (`&mut self`), so it never blocks.
237   #[inline]
238   pub fn get_mut_or_default(&mut self) -> &mut T
239   where
240      T: Default,
241   {
242      if self.lock.set_done() {
243         // Was uninitialized, now set to done. Replace with the default value.
244         unsafe {
245            mem::replace(self.value.get_mut(), TOnceState::init(T::default())).drop_pending();
246         }
247      }
248      // SAFETY: The cell is guaranteed to be initialized here, either previously
249      // or by the call above, and we have exclusive access.
250      unsafe { self.get_unchecked_mut() }
251   }
252
253   /// Returns a reference to the value without checking if it's initialized.
254   ///
255   /// # Safety
256   ///
257   /// Calling this method on an uninitialized `TOnce` cell is *undefined behavior*.
258   /// The caller must ensure the cell is initialized, e.g., by calling `is_done()` or `get()`.
259   #[inline]
260   pub unsafe fn get_unchecked(&self) -> &T {
261      debug_assert!(self.is_done(), "get_unchecked called on uninitialized Once");
262      // SAFETY: The caller guarantees that the cell is initialized.
263      unsafe { &(*self.value.get()).init }
264   }
265
266   /// Returns a mutable reference to the value without checking if it's initialized.
267   ///
268   /// # Safety
269   ///
270   /// Calling this method on an uninitialized `TOnce` cell is *undefined behavior*.
271   /// The caller must ensure the cell is initialized and that they have exclusive access.
272   #[inline]
273   pub unsafe fn get_unchecked_mut(&mut self) -> &mut T {
274      debug_assert!(
275         self.is_done(),
276         "get_unchecked_mut called on uninitialized Once"
277      );
278      // SAFETY: The caller guarantees that the cell is initialized and we have exclusive access.
279      unsafe { &mut (*self.value.get()).init }
280   }
281
282   /// Takes the value out of the cell, leaving it uninitialized with the given parameter.
283   ///
284   /// Returns `Some(value)` if the cell was initialized, `None` otherwise.
285   /// Requires exclusive access (`&mut self`), so it never blocks.
286   #[inline]
287   pub fn take(&mut self, param: P) -> Result<T, P> {
288      if !self.lock.set_uninit() {
289         return Err(param);
290      }
291      let mut mref = mem::replace(self.value.get_mut(), TOnceState::pending(param));
292      Ok(unsafe { mref.drop_init() })
293   }
294
295   /// Initializes the cell with `value`, ignoring the parameter. Blocks if another thread is initializing.
296   ///
297   /// - If uninitialized, discards the parameter, initializes it with `value` and returns `Ok(())`.
298   /// - If already initialized, returns `Err(value)`.
299   ///
300   /// Guarantees the cell is initialized upon return, but not necessarily with `value`
301   /// if another thread completed initialization first.
302   #[inline]
303   pub fn set(&self, value: T) -> Result<(), T> {
304      match self.try_insert(value) {
305         Ok(_) => Ok(()), // Successfully inserted our value
306         Err((_current_value, original_value)) => Err(original_value), // Already initialized by someone else
307      }
308   }
309
310   /// Initializes the cell with `value` if uninitialized, returning a reference. Blocks if needed.
311   ///
312   /// - If uninitialized, discards the parameter, initializes with `value` and returns `Ok(&value)`.
313   /// - If already initialized, returns `Err((&current_value, value))`.
314   ///
315   /// Guarantees the cell is initialized upon return.
316   #[inline]
317   pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
318      // `get_or_init` ensures initialization. We use `value` only if the cell was empty.
319      let mut value_opt = Some(value);
320      let res_ref = self.get_or_init(|_p| value_opt.take().unwrap());
321      match value_opt {
322         None => Ok(res_ref), // Our value was used for initialization
323         Some(original_value) => Err((res_ref, original_value)), // Someone else initialized it first
324      }
325   }
326
327   /// Gets the value, initializing with `f(param)` if needed. Blocks if needed.
328   ///
329   /// - If initialized, returns a reference to the existing value.
330   /// - If uninitialized, calls `f(param)`, stores the result, and returns a reference.
331   ///
332   /// If multiple threads call this concurrently, only one `f(param)` execution happens.
333   #[inline]
334   pub fn get_or_init<F>(&self, f: F) -> &T
335   where
336      F: FnOnce(P) -> T,
337   {
338      if let Some(value) = self.get() {
339         return value;
340      }
341      // Cold path: needs initialization
342      self.initialize(f);
343      // SAFETY: initialize ensures the value is now initialized.
344      unsafe { self.get_unchecked() }
345   }
346
347   /// Gets a mutable reference, initializing with `f(param)` if needed.
348   ///
349   /// - If initialized, returns a mutable reference to the existing value.
350   /// - If uninitialized, calls `f(param)`, stores the result, and returns a mutable reference.
351   ///
352   /// Requires exclusive access (`&mut self`), so it never blocks.
353   #[inline]
354   pub fn get_mut_or_init<F>(&mut self, f: F) -> &mut T
355   where
356      F: FnOnce(P) -> T,
357   {
358      if self.is_done() {
359         // Already initialized.
360      } else if let Some(guard) = self.lock.try_lock() {
361         // We got the lock (because is_done was false and no one else had it). Initialize it.
362         // SAFETY: We hold the lock, exclusive access to initialize.
363         unsafe {
364            let mut edit = EditSanitizer::new(&self.value, guard);
365            let value = f(edit.take_parameter());
366            edit.commit(value);
367         }
368      } else {
369         // This case should theoretically not happen with &mut self,
370         // as try_lock should succeed if !is_done().
371         // If it did, it implies a logic error or unexpected concurrent access.
372         unreachable!("Could not lock for init despite having exclusive access");
373      }
374
375      // SAFETY: The cell is guaranteed to be initialized now, and we have exclusive access.
376      unsafe { self.get_unchecked_mut() }
377   }
378
379   /// Gets the value, initializing with fallible `f(param)` if needed. Blocks if needed.
380   ///
381   /// - If initialized, returns `Ok(&value)`.
382   /// - If uninitialized, calls `f(param)`:
383   ///     - On `Ok(value)`, initializes the cell and returns `Ok(&value)`.
384   ///     - On `Err(e)`, returns `Err(e)` and leaves the cell uninitialized.
385   ///
386   /// If multiple threads call this concurrently, only one `f(param)` execution happens.
387   pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
388   where
389      F: FnOnce(&P) -> Result<T, E>,
390   {
391      if let Some(value) = self.get() {
392         return Ok(value);
393      }
394      // Cold path: needs initialization attempt
395      self.try_initialize(f)?;
396      // If try_initialize succeeded, it's now initialized.
397      debug_assert!(self.is_done());
398      // SAFETY: try_initialize succeeded, so the value is initialized.
399      Ok(unsafe { self.get_unchecked() })
400   }
401
402   /// Gets a mutable reference, initializing with fallible `f(param)` if needed.
403   ///
404   /// - If initialized, returns `Ok(&mut value)`.
405   /// - If uninitialized, calls `f(param)`:
406   ///     - On `Ok(value)`, initializes the cell and returns `Ok(&mut value)`.
407   ///     - On `Err(e)`, returns `Err(e)` and leaves the cell uninitialized.
408   ///
409   /// Requires exclusive access (`&mut self`), so it never blocks (initialization happens inline).
410   pub fn get_mut_or_try_init<F, E>(&mut self, f: F) -> Result<&mut T, E>
411   where
412      F: FnOnce(&P) -> Result<T, E>,
413   {
414      if let Some(guard) = self.lock.try_lock() {
415         // We got the lock. Try to initialize.
416         unsafe {
417            let edit = EditSanitizer::new(&self.value, guard);
418            let value = f(edit.ref_parameter())?;
419            edit.commit(value);
420         }
421      }
422      // SAFETY: The cell is guaranteed to be initialized now (or we returned Err),
423      // and we have exclusive access.
424      Ok(unsafe { self.get_unchecked_mut() })
425   }
426
427   /// Gets the value, initializing asynchronously with `f(param)` if needed. Blocks if needed.
428   ///
429   /// - If initialized, returns a reference to the existing value.
430   /// - If uninitialized, awaits `f(param)`, stores the result, and returns a reference.
431   ///
432   /// If multiple tasks call this concurrently, only one `f(param)` execution happens.
433   #[inline]
434   pub async fn get_or_init_async<F, Fut>(&self, f: F) -> &T
435   where
436      F: FnOnce(&P) -> Fut,
437      Fut: Future<Output = T>,
438   {
439      if let Some(value) = self.get() {
440         return value;
441      }
442      // Cold path: needs async initialization
443      self.initialize_async(f).await;
444      // SAFETY: initialize_async ensures the value is now initialized.
445      unsafe { self.get_unchecked() }
446   }
447
448   /// Gets a mutable reference, initializing asynchronously with `f(param)` if needed.
449   ///
450   /// - If initialized, returns a mutable reference to the existing value.
451   /// - If uninitialized, awaits `f(param)`, stores the result, and returns a mutable reference.
452   ///
453   /// Requires exclusive access (`&mut self`), so it never blocks (initialization happens inline).
454   #[inline]
455   pub async fn get_mut_or_init_async<F, Fut>(&mut self, f: F) -> &mut T
456   where
457      F: FnOnce(&P) -> Fut,
458      Fut: Future<Output = T>,
459   {
460      if let Some(guard) = self.lock.try_lock() {
461         // We got the lock. Try to initialize.
462         unsafe {
463            let edit = EditSanitizer::new(&self.value, guard);
464            let value = f(edit.ref_parameter()).await;
465            edit.commit(value);
466         }
467      }
468      // SAFETY: The cell is guaranteed to be initialized now (or we returned Err),
469      // and we have exclusive access.
470      unsafe { self.get_unchecked_mut() }
471   }
472
473   /// Gets the value, initializing asynchronously with fallible `f(param)` if needed. Blocks if needed.
474   ///
475   /// - If initialized, returns `Ok(&value)`.
476   /// - If uninitialized, awaits `f(param)`:
477   ///     - On `Ok(value)`, initializes the cell and returns `Ok(&value)`.
478   ///     - On `Err(e)`, returns `Err(e)` and leaves the cell uninitialized.
479   ///
480   /// If multiple tasks call this concurrently, only one `f(param)` execution happens.
481   pub async fn get_or_try_init_async<F, Fut, E>(&self, f: F) -> Result<&T, E>
482   where
483      F: FnOnce(&P) -> Fut,
484      Fut: Future<Output = Result<T, E>>,
485   {
486      if let Some(value) = self.get() {
487         return Ok(value);
488      }
489      // Cold path: needs async initialization attempt
490      self.try_initialize_async(f).await?;
491      // If try_initialize_async succeeded, it's now initialized.
492      debug_assert!(self.is_done());
493      // SAFETY: try_initialize_async succeeded, so the value is initialized.
494      Ok(unsafe { self.get_unchecked() })
495   }
496
497   /// Gets a mutable reference, initializing asynchronously with fallible `f(param)` if needed.
498   ///
499   /// - If initialized, returns `Ok(&mut value)`.
500   /// - If uninitialized, awaits `f(param)`:
501   ///     - On `Ok(value)`, initializes the cell and returns `Ok(&mut value)`.
502   ///     - On `Err(e)`, returns `Err(e)` and leaves the cell uninitialized.
503   ///
504   /// Requires exclusive access (`&mut self`), so it never blocks (initialization happens inline).
505   pub async fn get_mut_or_try_init_async<F, Fut, E>(&mut self, f: F) -> Result<&mut T, E>
506   where
507      F: FnOnce(&P) -> Fut,
508      Fut: Future<Output = Result<T, E>>,
509   {
510      if let Some(guard) = self.lock.try_lock() {
511         // We got the lock. Try to initialize.
512         unsafe {
513            let edit = EditSanitizer::new(&self.value, guard);
514            let value = f(edit.ref_parameter()).await?;
515            edit.commit(value);
516         }
517      }
518
519      // SAFETY: The cell is guaranteed to be initialized now (or we returned Err),
520      // and we have exclusive access.
521      Ok(unsafe { self.get_unchecked_mut() })
522   }
523
524   // --- Internal Initialization Helpers ---
525
526   /// Cold path for `get_or_init_async`. Acquires lock asynchronously and awaits initializer.
527   #[cold]
528   async fn initialize_async<F, Fut>(&self, f: F)
529   where
530      F: FnOnce(&P) -> Fut,
531      Fut: Future<Output = T>,
532   {
533      let Some(guard) = self.lock.lock_async().await else {
534         return; // Another task initialized it while we waited
535      };
536      // SAFETY: We hold the lock, exclusive access to initialize the value.
537      unsafe {
538         let edit = EditSanitizer::new(&self.value, guard);
539         let value = f(edit.ref_parameter()).await;
540         edit.commit(value);
541      }
542   }
543
544   /// Cold path for `get_or_try_init_async`. Acquires lock asynchronously and awaits fallible initializer.
545   #[cold]
546   async fn try_initialize_async<Fn, Fut, E>(&self, f: Fn) -> Result<(), E>
547   where
548      Fn: FnOnce(&P) -> Fut,
549      Fut: Future<Output = Result<T, E>>,
550   {
551      let Some(guard) = self.lock.lock_async().await else {
552         return Ok(()); // Another task initialized it while we waited
553      };
554      unsafe {
555         let edit = EditSanitizer::new(&self.value, guard);
556         let value = f(edit.ref_parameter()).await?;
557         edit.commit(value);
558      }
559      Ok(())
560   }
561
562   /// Cold path for `get_or_init`. Acquires lock and calls initializer.
563   #[cold]
564   fn initialize<F>(&self, f: F)
565   where
566      F: FnOnce(P) -> T,
567   {
568      let Some(guard) = self.lock.lock() else {
569         return; // Another thread initialized it while we waited for the lock
570      };
571      // SAFETY: We hold the lock, exclusive access to initialize the value.
572      unsafe {
573         let mut edit = EditSanitizer::new(&self.value, guard);
574         let value = f(edit.take_parameter());
575         edit.commit(value);
576      }
577   }
578
579   /// Cold path for `get_or_try_init`. Acquires lock and calls fallible initializer.
580   #[cold]
581   fn try_initialize<F, E>(&self, f: F) -> Result<(), E>
582   where
583      F: FnOnce(&P) -> Result<T, E>,
584   {
585      let Some(guard) = self.lock.lock() else {
586         return Ok(()); // Another thread initialized it while we waited for the lock
587      };
588      unsafe {
589         let edit = EditSanitizer::new(&self.value, guard);
590         let value = f(edit.ref_parameter())?;
591         edit.commit(value);
592      }
593      Ok(())
594   }
595}
596
597// --- Trait Implementations ---
598
599impl<P, T> From<Option<T>> for TOnce<P, T>
600where
601   P: Default,
602{
603   /// Creates an initialized `TOnce` from `Some(value)` or an uninitialized one from `None` with a default parameter.
604   fn from(value: Option<T>) -> Self {
605      match value {
606         Some(value) => Self::with_value(value),
607         None => Self::new(P::default()),
608      }
609   }
610}
611
612impl<P, T> From<Result<T, P>> for TOnce<P, T> {
613   /// Creates an initialized `TOnce` from `Ok(value)` or an uninitialized one from `Err(param)` with the parameter.
614   fn from(value: Result<T, P>) -> Self {
615      match value {
616         Ok(value) => Self::with_value(value),
617         Err(param) => Self::new(param),
618      }
619   }
620}
621
622// SAFETY:
623// `&TOnce<P, T>` is `Sync` if `&T` is `Sync` (requiring `T: Sync`)
624// and if the initialization mechanism is thread-safe (which it is).
625// `T: Send` is also required because a value provided by one thread
626// might be read or dropped by another.
627// `P: Sync` is required because the parameter might be accessed by multiple threads.
628unsafe impl<P: Sync + Send, T: Send> Sync for TOnce<P, T> {}
629// SAFETY:
630// `TOnce<P, T>` is `Send` if both `P` and `T` are `Send`, as the ownership of both
631// can be transferred across threads via initialization or `take()`.
632unsafe impl<P: Send, T: Send> Send for TOnce<P, T> {}
633
634impl<P: Default, T> Default for TOnce<P, T> {
635   /// Creates a new, uninitialized `TOnce` cell with default parameter.
636   #[inline]
637   fn default() -> Self {
638      Self::new(P::default())
639   }
640}
641
642impl<P, T: fmt::Display> fmt::Display for TOnce<P, T> {
643   fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
644      match self.get() {
645         Some(v) => fmt::Display::fmt(v, f),
646         None => f.write_str("<uninit>"),
647      }
648   }
649}
650
651impl<P, T: fmt::Debug> fmt::Debug for TOnce<P, T> {
652   fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
653      let mut d = f.debug_tuple("Once");
654      match self.get() {
655         Some(v) => d.field(v),
656         None => d.field(&format_args!("<uninit>")),
657      };
658      d.finish()
659   }
660}
661
662impl<P: Clone, T: Clone> Clone for TOnce<P, T> {
663   /// Clones the `TOnce` cell.
664   ///
665   /// If the original cell is initialized, the clone will be initialized
666   /// with a cloned value. If the original is uninitialized, the clone
667   /// will also be uninitialized with a cloned parameter.
668   #[inline]
669   fn clone(&self) -> Self {
670      if let Some(value) = self.get() {
671         Self::with_value(value.clone())
672      } else {
673         let Some(_guard) = self.lock.lock() else {
674            return Self::with_value(
675               self
676                  .get()
677                  .expect("is_done() was false but value is init")
678                  .clone(),
679            );
680         };
681         Self::new(unsafe { (*(*self.value.get()).pending).clone() })
682      }
683   }
684}
685
686impl<T> From<T> for TOnce<(), T> {
687   /// Creates a new, initialized `TOnce` cell from the given value.
688   #[inline]
689   fn from(value: T) -> Self {
690      Self::with_value(value)
691   }
692}
693
694impl<P, T: PartialEq> PartialEq for TOnce<P, T> {
695   /// Checks if two `TOnce` cells are equal.
696   ///
697   /// They are equal if both are uninitialized, or if both are initialized
698   /// and their contained values are equal according to `PartialEq`.
699   #[inline]
700   fn eq(&self, other: &Self) -> bool {
701      self.get() == other.get()
702   }
703}
704
705impl<P, T: Eq> Eq for TOnce<P, T> {}
706
707impl<P, T> Drop for TOnce<P, T> {
708   #[inline]
709   fn drop(&mut self) {
710      unsafe {
711         if self.is_done() {
712            self.value.get_mut().drop_init();
713         } else {
714            self.value.get_mut().drop_pending();
715         }
716      }
717   }
718}