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};
9
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12
13use crate::iterator_as_exact_size_iterator::IteratorAsExactSizeIterator;
14use crate::{AllocError, HeaderSlice};
15
16use super::{Arc, ArcInner};
17
18#[repr(transparent)]
42pub struct UniqueArc<T: ?Sized>(Arc<T>);
43
44unsafe impl<T: ?Sized + Send> Send for UniqueArc<T> {}
47unsafe impl<T: ?Sized + Sync> Sync for UniqueArc<T> {}
48
49impl<T> UniqueArc<T> {
50 #[inline]
51 pub fn new(data: T) -> Self {
53 UniqueArc(Arc::new(data))
54 }
55
56 #[inline]
60 pub fn try_new(data: T) -> Result<Self, AllocError> {
61 Arc::try_new(data).map(UniqueArc)
62 }
63
64 #[inline]
66 pub fn new_uninit() -> UniqueArc<MaybeUninit<T>> {
67 let inner = unsafe {
72 Arc::<MaybeUninit<T>>::allocate_for_layout(Layout::new::<MaybeUninit<T>>(), |mem| {
73 mem as *mut ArcInner<MaybeUninit<T>>
74 })
75 };
76
77 UniqueArc(Arc {
78 p: inner,
79 phantom: PhantomData,
80 })
81 }
82
83 #[inline]
87 pub fn try_new_uninit() -> Result<UniqueArc<MaybeUninit<T>>, AllocError> {
88 let inner = unsafe {
90 Arc::<MaybeUninit<T>>::try_allocate_for_layout(
91 Layout::new::<MaybeUninit<T>>(),
92 |mem| mem as *mut ArcInner<MaybeUninit<T>>,
93 )?
94 };
95
96 Ok(UniqueArc(Arc {
97 p: inner,
98 phantom: PhantomData,
99 }))
100 }
101
102 pub fn into_inner(this: Self) -> T {
104 let this = ManuallyDrop::new(this.0);
106 debug_assert!(
107 this.is_unique(),
108 "attempted to call `.into_inner()` on a `UniqueArc` with a non-zero ref count",
109 );
110
111 unsafe { Box::from_raw(this.ptr()).data }
115 }
116}
117
118impl<T: ?Sized> UniqueArc<T> {
119 #[inline]
121 pub fn shareable(self) -> Arc<T> {
122 self.0
123 }
124
125 pub(crate) unsafe fn from_arc(arc: Arc<T>) -> Self {
134 debug_assert_eq!(Arc::count(&arc), 1);
135 Self(arc)
136 }
137
138 pub(crate) unsafe fn from_arc_ref(arc: &mut Arc<T>) -> &mut Self {
146 debug_assert_eq!(Arc::count(arc), 1);
147
148 &mut *(arc as *mut Arc<T> as *mut UniqueArc<T>)
151 }
152}
153
154impl<T> UniqueArc<MaybeUninit<T>> {
155 pub fn write(&mut self, val: T) -> &mut T {
157 unsafe {
158 let ptr = self.as_mut_ptr() as *mut T;
160
161 ptr.write(val);
163
164 &mut *ptr
166 }
167 }
168
169 pub fn as_mut_ptr(&mut self) -> *mut MaybeUninit<T> {
171 unsafe { &mut (*self.0.ptr()).data }
172 }
173
174 #[inline]
182 pub unsafe fn assume_init(this: Self) -> UniqueArc<T> {
183 UniqueArc(Arc {
184 p: ManuallyDrop::new(this).0.p.cast(),
185 phantom: PhantomData,
186 })
187 }
188}
189
190impl<T> UniqueArc<[MaybeUninit<T>]> {
191 pub fn new_uninit_slice(len: usize) -> Self {
193 let arc: Arc<HeaderSlice<(), [MaybeUninit<T>]>> =
198 UniqueArc::from_header_and_uninit_slice((), len).0;
199 let arc: Arc<[MaybeUninit<T>]> = arc.into();
200 UniqueArc(arc)
201 }
202
203 pub fn try_new_uninit_slice(len: usize) -> Result<Self, AllocError> {
207 let arc: Arc<HeaderSlice<(), [MaybeUninit<T>]>> =
208 UniqueArc::try_from_header_and_uninit_slice((), len)?.0;
209 let arc: Arc<[MaybeUninit<T>]> = arc.into();
210 Ok(UniqueArc(arc))
211 }
212
213 #[inline]
217 pub unsafe fn assume_init_slice(Self(this): Self) -> UniqueArc<[T]> {
218 UniqueArc(this.assume_init())
219 }
220}
221
222impl<H, T> UniqueArc<HeaderSlice<H, [MaybeUninit<T>]>> {
223 #[inline]
226 pub fn from_header_and_uninit_slice(header: H, len: usize) -> Self {
227 let inner = Arc::<HeaderSlice<H, [MaybeUninit<T>]>>::allocate_for_header_and_slice(len);
228
229 unsafe {
230 let dst = addr_of_mut!((*inner.as_ptr()).data.header);
232
233 ptr::write(dst, header);
235 }
236
237 Self(Arc {
240 p: inner,
241 phantom: PhantomData,
242 })
243 }
244
245 #[inline]
249 pub fn try_from_header_and_uninit_slice(header: H, len: usize) -> Result<Self, AllocError> {
250 let inner =
251 Arc::<HeaderSlice<H, [MaybeUninit<T>]>>::try_allocate_for_header_and_slice(len)?;
252
253 unsafe {
254 let dst = addr_of_mut!((*inner.as_ptr()).data.header);
256
257 ptr::write(dst, header);
259 }
260
261 Ok(Self(Arc {
264 p: inner,
265 phantom: PhantomData,
266 }))
267 }
268
269 #[inline]
273 pub unsafe fn assume_init_slice_with_header(self) -> UniqueArc<HeaderSlice<H, [T]>> {
274 unsafe { core::mem::transmute(self) }
275 }
276}
277
278impl<T: ?Sized> TryFrom<Arc<T>> for UniqueArc<T> {
279 type Error = Arc<T>;
280
281 fn try_from(arc: Arc<T>) -> Result<Self, Self::Error> {
282 Arc::try_unique(arc)
283 }
284}
285
286impl<T: ?Sized> Deref for UniqueArc<T> {
287 type Target = T;
288
289 #[inline]
290 fn deref(&self) -> &T {
291 &self.0
292 }
293}
294
295impl<T: ?Sized> DerefMut for UniqueArc<T> {
296 #[inline]
297 fn deref_mut(&mut self) -> &mut T {
298 unsafe { &mut (*self.0.ptr()).data }
300 }
301}
302
303impl<A> FromIterator<A> for UniqueArc<[A]> {
304 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
305 let iter = iter.into_iter();
306 let (lower, upper) = iter.size_hint();
307 let arc: Arc<[A]> = if Some(lower) == upper {
308 let iter = IteratorAsExactSizeIterator::new(iter);
309 Arc::from_header_and_iter((), iter).into()
310 } else {
311 let vec = iter.collect::<Vec<_>>();
312 Arc::from(vec)
313 };
314 unsafe { UniqueArc::from_arc(arc) }
316 }
317}
318
319#[cfg(feature = "unsize")]
325unsafe impl<T, U: ?Sized> unsize::CoerciblePtr<U> for UniqueArc<T> {
326 type Pointee = T;
327 type Output = UniqueArc<U>;
328
329 fn as_sized_ptr(&mut self) -> *mut T {
330 unsize::CoerciblePtr::<U>::as_sized_ptr(&mut self.0)
332 }
333
334 unsafe fn replace_ptr(self, new: *mut U) -> UniqueArc<U> {
335 let inner = ManuallyDrop::new(self);
337 UniqueArc(ptr::read(&inner.0).replace_ptr(new))
338 }
339}
340
341#[cfg(feature = "serde")]
342impl<'de, T: Deserialize<'de>> Deserialize<'de> for UniqueArc<T> {
343 fn deserialize<D>(deserializer: D) -> Result<UniqueArc<T>, D::Error>
344 where
345 D: ::serde::de::Deserializer<'de>,
346 {
347 T::deserialize(deserializer).map(UniqueArc::new)
348 }
349}
350
351#[cfg(feature = "serde")]
352impl<T: Serialize> Serialize for UniqueArc<T> {
353 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
354 where
355 S: ::serde::ser::Serializer,
356 {
357 (**self).serialize(serializer)
358 }
359}
360
361#[cfg(test)]
362mod tests {
363 use crate::{Arc, HeaderSliceWithLengthUnchecked, HeaderWithLength, UniqueArc};
364 use core::{convert::TryFrom, mem::MaybeUninit};
365
366 #[test]
367 fn unique_into_inner() {
368 let unique = UniqueArc::new(10u64);
369 assert_eq!(UniqueArc::into_inner(unique), 10);
370 }
371
372 #[test]
373 fn try_new() {
374 let unique = UniqueArc::try_new(10u64).unwrap();
375 assert_eq!(UniqueArc::into_inner(unique), 10);
376 }
377
378 #[test]
379 fn try_new_uninit() {
380 let mut arc: UniqueArc<MaybeUninit<_>> = UniqueArc::try_new_uninit().unwrap();
381 arc.write(999);
382
383 let arc = unsafe { UniqueArc::assume_init(arc) };
384 assert_eq!(*arc, 999);
385 }
386
387 #[test]
388 fn try_new_uninit_slice() {
389 let mut arc: UniqueArc<[MaybeUninit<u16>]> = UniqueArc::try_new_uninit_slice(3).unwrap();
390 arc.fill(MaybeUninit::new(2));
391 let arc = unsafe { UniqueArc::assume_init_slice(arc) }.shareable();
392 assert_eq!(&*arc, [2, 2, 2]);
393 }
394
395 #[test]
396 fn try_from_header_and_uninit_slice() {
397 let mut uarc: UniqueArc<HeaderSliceWithLengthUnchecked<u8, MaybeUninit<u16>>> =
398 UniqueArc::try_from_header_and_uninit_slice(HeaderWithLength::new(1, 3), 3).unwrap();
399 uarc.slice.fill(MaybeUninit::new(2));
400 let arc = unsafe { uarc.assume_init_slice_with_header() }.shareable();
401 assert_eq!(arc.header.header, 1);
402 assert_eq!(&arc.slice, [2, 2, 2]);
403 }
404
405 #[test]
406 fn try_from_arc() {
407 let x = Arc::new(10_000);
408 let y = x.clone();
409
410 assert!(UniqueArc::try_from(x).is_err());
411 assert_eq!(
412 UniqueArc::into_inner(UniqueArc::try_from(y).unwrap()),
413 10_000,
414 );
415 }
416
417 #[test]
418 #[allow(deprecated)]
419 fn maybeuninit_smoke() {
420 let mut arc: UniqueArc<MaybeUninit<_>> = UniqueArc::new_uninit();
421 arc.write(999);
422
423 let arc = unsafe { UniqueArc::assume_init(arc) };
424 assert_eq!(*arc, 999);
425 }
426
427 #[test]
428 fn from_header_and_uninit_slice() {
429 let mut uarc: UniqueArc<HeaderSliceWithLengthUnchecked<u8, MaybeUninit<u16>>> =
430 UniqueArc::from_header_and_uninit_slice(HeaderWithLength::new(1, 3), 3);
431 uarc.slice.fill(MaybeUninit::new(2));
432 let arc = unsafe { uarc.assume_init_slice_with_header() }.shareable();
433 assert!(arc.is_unique());
434 let arcs = [
437 arc.clone(),
438 arc.clone(),
439 arc.clone(),
440 arc.clone(),
441 arc.clone(),
442 ];
443 let thin = Arc::into_thin(arc.clone());
445 assert_eq!(7, Arc::count(&arc));
446 assert_eq!(arc.header.header, 1);
448 assert_eq!(&arc.slice, [2, 2, 2]);
449 assert_eq!(thin.header.header, 1);
450 assert_eq!(&thin.slice, [2, 2, 2]);
451
452 drop(arcs);
455 drop(thin);
456 assert!(arc.is_unique());
457 assert_eq!(arc.header.header, 1);
458 assert_eq!(&arc.slice, [2, 2, 2]);
459 }
460}