pin_init/
unique.rs

1use super::*;
2use core::ops::{Deref, DerefMut};
3#[cfg(feature = "alloc_try_pin_with")]
4use core::alloc::AllocError;
5
6/// An uniquely owned `Rc`.
7///
8/// Useful for constructing `Rc`, since we are certain that when `Rc` is
9/// initially created, there is an unique reference. Once initially mutation
10/// is done, it can be convert to `Rc` with `shareable()`.
11#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
12#[repr(transparent)]
13pub struct UniqueRc<T: ?Sized>(Rc<T>);
14
15impl<T> UniqueRc<T> {
16    /// Constructs a new `UniqueRc`.
17    #[cfg(feature = "alloc_pin_with")]
18    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
19    #[inline]
20    pub fn new(data: T) -> Self {
21        UniqueRc(Rc::new(data))
22    }
23
24    /// Try to constructs a new `UniqueRc`.
25    #[cfg(feature = "alloc_try_pin_with")]
26    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
27    #[inline]
28    pub fn try_new(data: T) -> Result<Self, AllocError> {
29        Ok(UniqueRc(Rc::try_new(data)?))
30    }
31
32    /// Convert to a shareable [`Rc<T>`].
33    #[inline]
34    pub fn shareable(x: Self) -> Rc<T> {
35        x.0
36    }
37
38    /// Convert to a shareable [`Pin<Rc<T>>`].
39    #[inline]
40    pub fn shareable_pin(x: Pin<Self>) -> Pin<Rc<T>> {
41        unsafe { Pin::new_unchecked(Pin::into_inner_unchecked(x).0) }
42    }
43
44    /// Constructs a new `UniqueRc` with uninitialized contents.
45    #[inline]
46    pub fn new_uninit() -> UniqueRc<MaybeUninit<T>> {
47        UniqueRc::new(MaybeUninit::uninit())
48    }
49}
50
51impl<T> UniqueRc<MaybeUninit<T>> {
52    /// Convert to an initialized Rc.
53    ///
54    /// # Safety
55    ///
56    /// This function is unsafe as this is equivalent to [`MaybeUninit::assume_init`].
57    #[inline]
58    pub unsafe fn assume_init(self) -> UniqueRc<T> {
59        unsafe { core::mem::transmute(self) }
60    }
61}
62
63impl<T> Deref for UniqueRc<T> {
64    type Target = T;
65    #[inline]
66    fn deref(&self) -> &T {
67        &*self.0
68    }
69}
70
71impl<T> DerefMut for UniqueRc<T> {
72    #[inline]
73    fn deref_mut(&mut self) -> &mut T {
74        let ptr = Rc::as_ptr(&self.0) as *mut T;
75        // SAFETY: We know this is unqiuely owned.
76        unsafe { &mut *ptr }
77    }
78}
79
80impl<T> From<UniqueRc<T>> for Pin<UniqueRc<T>> {
81    fn from(x: UniqueRc<T>) -> Pin<UniqueRc<T>> {
82        // SAFETY: stable address
83        unsafe { Pin::new_unchecked(x) }
84    }
85}
86
87/// An uniquely owned `Arc`.
88///
89/// Useful for constructing `Arc`, since we are certain that when `Arc` is
90/// initially created, there is an unique reference. Once initially mutation
91/// is done, it can be convert to `Arc` with `shareable()`.
92#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
93#[repr(transparent)]
94pub struct UniqueArc<T: ?Sized>(Arc<T>);
95
96impl<T> UniqueArc<T> {
97    /// Constructs a new `UniqueArc`.
98    #[cfg(feature = "alloc_pin_with")]
99    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_pin_with")))]
100    #[inline]
101    pub fn new(data: T) -> Self {
102        UniqueArc(Arc::new(data))
103    }
104
105    /// Try to constructs a new `UniqueArc`.
106    #[cfg(feature = "alloc_try_pin_with")]
107    #[cfg_attr(doc_cfg, doc(cfg(feature = "alloc_try_pin_with")))]
108    #[inline]
109    pub fn try_new(data: T) -> Result<Self, AllocError> {
110        Ok(UniqueArc(Arc::try_new(data)?))
111    }
112
113    /// Convert to a shareable [`Arc<T>`].
114    #[inline]
115    pub fn shareable(x: Self) -> Arc<T> {
116        x.0
117    }
118
119    /// Convert to a shareable [`Pin<Arc<T>>`].
120    #[inline]
121    pub fn shareable_pin(x: Pin<Self>) -> Pin<Arc<T>> {
122        unsafe { Pin::new_unchecked(Pin::into_inner_unchecked(x).0) }
123    }
124
125    /// Constructs a new `UniqueArc` with uninitialized contents.
126    #[inline]
127    pub fn new_uninit() -> UniqueArc<MaybeUninit<T>> {
128        UniqueArc::new(MaybeUninit::uninit())
129    }
130}
131
132impl<T> UniqueArc<MaybeUninit<T>> {
133    /// Convert to an initialized Arc.
134    ///
135    /// # Safety
136    ///
137    /// This function is unsafe as this is equivalent to [`MaybeUninit::assume_init`].
138    #[inline]
139    pub unsafe fn assume_init(self) -> UniqueArc<T> {
140        unsafe { core::mem::transmute(self) }
141    }
142}
143
144impl<T> Deref for UniqueArc<T> {
145    type Target = T;
146    #[inline]
147    fn deref(&self) -> &T {
148        &*self.0
149    }
150}
151
152impl<T> DerefMut for UniqueArc<T> {
153    #[inline]
154    fn deref_mut(&mut self) -> &mut T {
155        let ptr = Arc::as_ptr(&self.0) as *mut T;
156        // SAFETY: We know this is unqiuely owned.
157        unsafe { &mut *ptr }
158    }
159}
160
161impl<T> From<UniqueArc<T>> for Pin<UniqueArc<T>> {
162    fn from(x: UniqueArc<T>) -> Pin<UniqueArc<T>> {
163        // SAFETY: stable address
164        unsafe { Pin::new_unchecked(x) }
165    }
166}