1use alloc::vec::Vec;
2use alloc::{alloc::Layout, boxed::Box};
3use core::convert::TryFrom;
4use core::iter::FromIterator;
5use core::marker::PhantomData;
6use core::mem::{ManuallyDrop, MaybeUninit};
7use core::ops::{Deref, DerefMut};
8use core::ptr::{self, addr_of_mut, NonNull};
9use core::sync::atomic::AtomicUsize;
10
11use crate::iterator_as_exact_size_iterator::IteratorAsExactSizeIterator;
12use crate::HeaderSlice;
13
14use super::{Arc, ArcInner};
15
16#[repr(transparent)]
40pub struct UniqueArc<T: ?Sized>(Arc<T>);
41
42unsafe impl<T: ?Sized + Send> Send for UniqueArc<T> {}
45unsafe impl<T: ?Sized + Sync> Sync for UniqueArc<T> {}
46
47impl<T> UniqueArc<T> {
48 #[inline]
49 pub fn new(data: T) -> Self {
51 UniqueArc(Arc::new(data))
52 }
53
54 #[inline]
56 pub fn new_uninit() -> UniqueArc<MaybeUninit<T>> {
57 unsafe {
58 let layout = Layout::new::<ArcInner<MaybeUninit<T>>>();
59 let ptr = alloc::alloc::alloc(layout);
60 let mut p = NonNull::new(ptr)
61 .unwrap_or_else(|| alloc::alloc::handle_alloc_error(layout))
62 .cast::<ArcInner<MaybeUninit<T>>>();
63 ptr::write(&mut p.as_mut().count, AtomicUsize::new(1));
64
65 UniqueArc(Arc {
66 p,
67 phantom: PhantomData,
68 })
69 }
70 }
71
72 pub fn into_inner(this: Self) -> T {
74 let this = ManuallyDrop::new(this.0);
76 debug_assert!(
77 this.is_unique(),
78 "attempted to call `.into_inner()` on a `UniqueArc` with a non-zero ref count",
79 );
80
81 unsafe { Box::from_raw(this.ptr()).data }
85 }
86}
87
88impl<T: ?Sized> UniqueArc<T> {
89 #[inline]
91 pub fn shareable(self) -> Arc<T> {
92 self.0
93 }
94
95 pub(crate) unsafe fn from_arc(arc: Arc<T>) -> Self {
104 debug_assert_eq!(Arc::count(&arc), 1);
105 Self(arc)
106 }
107
108 pub(crate) unsafe fn from_arc_ref(arc: &mut Arc<T>) -> &mut Self {
116 debug_assert_eq!(Arc::count(arc), 1);
117
118 &mut *(arc as *mut Arc<T> as *mut UniqueArc<T>)
121 }
122}
123
124impl<T> UniqueArc<MaybeUninit<T>> {
125 pub fn write(&mut self, val: T) -> &mut T {
127 unsafe {
128 let ptr = self.as_mut_ptr() as *mut T;
130
131 ptr.write(val);
133
134 &mut *ptr
136 }
137 }
138
139 pub fn as_mut_ptr(&mut self) -> *mut MaybeUninit<T> {
141 unsafe { &mut (*self.0.ptr()).data }
142 }
143
144 #[inline]
152 pub unsafe fn assume_init(this: Self) -> UniqueArc<T> {
153 UniqueArc(Arc {
154 p: ManuallyDrop::new(this).0.p.cast(),
155 phantom: PhantomData,
156 })
157 }
158}
159
160impl<T> UniqueArc<[MaybeUninit<T>]> {
161 pub fn new_uninit_slice(len: usize) -> Self {
163 let arc: Arc<HeaderSlice<(), [MaybeUninit<T>]>> =
168 UniqueArc::from_header_and_uninit_slice((), len).0;
169 let arc: Arc<[MaybeUninit<T>]> = arc.into();
170 UniqueArc(arc)
171 }
172
173 #[inline]
177 pub unsafe fn assume_init_slice(Self(this): Self) -> UniqueArc<[T]> {
178 UniqueArc(this.assume_init())
179 }
180}
181
182impl<H, T> UniqueArc<HeaderSlice<H, [MaybeUninit<T>]>> {
183 #[inline]
186 pub fn from_header_and_uninit_slice(header: H, len: usize) -> Self {
187 let inner = Arc::<HeaderSlice<H, [MaybeUninit<T>]>>::allocate_for_header_and_slice(len);
188
189 unsafe {
190 let dst = addr_of_mut!((*inner.as_ptr()).data.header);
192
193 ptr::write(dst, header);
195 }
196
197 Self(Arc {
200 p: inner,
201 phantom: PhantomData,
202 })
203 }
204
205 #[inline]
209 pub unsafe fn assume_init_slice_with_header(self) -> UniqueArc<HeaderSlice<H, [T]>> {
210 unsafe { core::mem::transmute(self) }
211 }
212}
213
214impl<T: ?Sized> TryFrom<Arc<T>> for UniqueArc<T> {
215 type Error = Arc<T>;
216
217 fn try_from(arc: Arc<T>) -> Result<Self, Self::Error> {
218 Arc::try_unique(arc)
219 }
220}
221
222impl<T: ?Sized> Deref for UniqueArc<T> {
223 type Target = T;
224
225 #[inline]
226 fn deref(&self) -> &T {
227 &self.0
228 }
229}
230
231impl<T: ?Sized> DerefMut for UniqueArc<T> {
232 #[inline]
233 fn deref_mut(&mut self) -> &mut T {
234 unsafe { &mut (*self.0.ptr()).data }
236 }
237}
238
239impl<A> FromIterator<A> for UniqueArc<[A]> {
240 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
241 let iter = iter.into_iter();
242 let (lower, upper) = iter.size_hint();
243 let arc: Arc<[A]> = if Some(lower) == upper {
244 let iter = IteratorAsExactSizeIterator::new(iter);
245 Arc::from_header_and_iter((), iter).into()
246 } else {
247 let vec = iter.collect::<Vec<_>>();
248 Arc::from(vec)
249 };
250 unsafe { UniqueArc::from_arc(arc) }
252 }
253}
254
255#[cfg(feature = "unsize")]
261unsafe impl<T, U: ?Sized> unsize::CoerciblePtr<U> for UniqueArc<T> {
262 type Pointee = T;
263 type Output = UniqueArc<U>;
264
265 fn as_sized_ptr(&mut self) -> *mut T {
266 unsize::CoerciblePtr::<U>::as_sized_ptr(&mut self.0)
268 }
269
270 unsafe fn replace_ptr(self, new: *mut U) -> UniqueArc<U> {
271 let inner = ManuallyDrop::new(self);
273 UniqueArc(ptr::read(&inner.0).replace_ptr(new))
274 }
275}
276
277#[cfg(test)]
278mod tests {
279 use crate::{Arc, HeaderSliceWithLength, HeaderWithLength, UniqueArc};
280 use core::{convert::TryFrom, mem::MaybeUninit};
281
282 #[test]
283 fn unique_into_inner() {
284 let unique = UniqueArc::new(10u64);
285 assert_eq!(UniqueArc::into_inner(unique), 10);
286 }
287
288 #[test]
289 fn try_from_arc() {
290 let x = Arc::new(10_000);
291 let y = x.clone();
292
293 assert!(UniqueArc::try_from(x).is_err());
294 assert_eq!(
295 UniqueArc::into_inner(UniqueArc::try_from(y).unwrap()),
296 10_000,
297 );
298 }
299
300 #[test]
301 #[allow(deprecated)]
302 fn maybeuninit_smoke() {
303 let mut arc: UniqueArc<MaybeUninit<_>> = UniqueArc::new_uninit();
304 arc.write(999);
305
306 let arc = unsafe { UniqueArc::assume_init(arc) };
307 assert_eq!(*arc, 999);
308 }
309
310 #[test]
311 fn from_header_and_uninit_slice() {
312 let mut uarc: UniqueArc<HeaderSliceWithLength<u8, [MaybeUninit<u16>]>> =
313 UniqueArc::from_header_and_uninit_slice(HeaderWithLength::new(1, 3), 3);
314 uarc.slice.fill(MaybeUninit::new(2));
315 let arc = unsafe { uarc.assume_init_slice_with_header() }.shareable();
316 assert!(arc.is_unique());
317 let arcs = [
320 arc.clone(),
321 arc.clone(),
322 arc.clone(),
323 arc.clone(),
324 arc.clone(),
325 ];
326 let thin = Arc::into_thin(arc.clone());
328 assert_eq!(7, Arc::count(&arc));
329 assert_eq!(arc.header.header, 1);
331 assert_eq!(&arc.slice, [2, 2, 2]);
332 assert_eq!(thin.header.header, 1);
333 assert_eq!(&thin.slice, [2, 2, 2]);
334
335 drop(arcs);
338 drop(thin);
339 assert!(arc.is_unique());
340 assert_eq!(arc.header.header, 1);
341 assert_eq!(&arc.slice, [2, 2, 2]);
342 }
343}