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::{self, 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::{mdref, 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 const fn shareable(self) -> Arc<T> {
122 let this = ManuallyDrop::new(self);
123 unsafe { mem::transmute_copy(&mdref(&this).0) }
125 }
126
127 pub(crate) unsafe fn from_arc(arc: Arc<T>) -> Self {
136 debug_assert_eq!(Arc::count(&arc), 1);
137 Self(arc)
138 }
139
140 pub(crate) unsafe fn from_arc_ref(arc: &mut Arc<T>) -> &mut Self {
148 debug_assert_eq!(Arc::count(arc), 1);
149
150 &mut *(arc as *mut Arc<T> as *mut UniqueArc<T>)
153 }
154}
155
156impl<T> UniqueArc<MaybeUninit<T>> {
157 pub fn write(&mut self, val: T) -> &mut T {
159 unsafe {
160 let ptr = self.as_mut_ptr() as *mut T;
162
163 ptr.write(val);
165
166 &mut *ptr
168 }
169 }
170
171 pub const fn as_mut_ptr(&mut self) -> *mut MaybeUninit<T> {
173 unsafe { addr_of_mut!((*self.0.ptr()).data) }
174 }
175
176 #[inline]
184 pub const unsafe fn assume_init(this: Self) -> UniqueArc<T> {
185 let this = ManuallyDrop::new(this);
186 UniqueArc(Arc {
187 p: mdref(&this).0.p.cast(),
188 phantom: PhantomData,
189 })
190 }
191}
192
193impl<T> UniqueArc<[MaybeUninit<T>]> {
194 pub fn new_uninit_slice(len: usize) -> Self {
196 let arc: Arc<HeaderSlice<(), [MaybeUninit<T>]>> =
201 UniqueArc::from_header_and_uninit_slice((), len).0;
202 let arc: Arc<[MaybeUninit<T>]> = arc.into();
203 UniqueArc(arc)
204 }
205
206 pub fn try_new_uninit_slice(len: usize) -> Result<Self, AllocError> {
210 let arc: Arc<HeaderSlice<(), [MaybeUninit<T>]>> =
211 UniqueArc::try_from_header_and_uninit_slice((), len)?.0;
212 let arc: Arc<[MaybeUninit<T>]> = arc.into();
213 Ok(UniqueArc(arc))
214 }
215
216 #[inline]
220 pub const unsafe fn assume_init_slice(this: Self) -> UniqueArc<[T]> {
221 UniqueArc(this.shareable().assume_init())
222 }
223}
224
225impl<H, T> UniqueArc<HeaderSlice<H, [MaybeUninit<T>]>> {
226 #[inline]
229 pub fn from_header_and_uninit_slice(header: H, len: usize) -> Self {
230 let inner = Arc::<HeaderSlice<H, [MaybeUninit<T>]>>::allocate_for_header_and_slice(len);
231
232 unsafe {
233 let dst = addr_of_mut!((*inner.as_ptr()).data.header);
235
236 ptr::write(dst, header);
238 }
239
240 Self(Arc {
243 p: inner,
244 phantom: PhantomData,
245 })
246 }
247
248 #[inline]
252 pub fn try_from_header_and_uninit_slice(header: H, len: usize) -> Result<Self, AllocError> {
253 let inner =
254 Arc::<HeaderSlice<H, [MaybeUninit<T>]>>::try_allocate_for_header_and_slice(len)?;
255
256 unsafe {
257 let dst = addr_of_mut!((*inner.as_ptr()).data.header);
259
260 ptr::write(dst, header);
262 }
263
264 Ok(Self(Arc {
267 p: inner,
268 phantom: PhantomData,
269 }))
270 }
271
272 #[inline]
276 pub const unsafe fn assume_init_slice_with_header(self) -> UniqueArc<HeaderSlice<H, [T]>> {
277 unsafe { core::mem::transmute(self) }
278 }
279}
280
281impl<T: ?Sized> TryFrom<Arc<T>> for UniqueArc<T> {
282 type Error = Arc<T>;
283
284 fn try_from(arc: Arc<T>) -> Result<Self, Self::Error> {
285 Arc::try_unique(arc)
286 }
287}
288
289impl<T: ?Sized> Deref for UniqueArc<T> {
290 type Target = T;
291
292 #[inline]
293 fn deref(&self) -> &T {
294 &self.0
295 }
296}
297
298impl<T: ?Sized> DerefMut for UniqueArc<T> {
299 #[inline]
300 fn deref_mut(&mut self) -> &mut T {
301 unsafe { &mut (*self.0.ptr()).data }
303 }
304}
305
306impl<A> FromIterator<A> for UniqueArc<[A]> {
307 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
308 let iter = iter.into_iter();
309 let (lower, upper) = iter.size_hint();
310 let arc: Arc<[A]> = if Some(lower) == upper {
311 let iter = IteratorAsExactSizeIterator::new(iter);
312 Arc::from_header_and_iter((), iter).into()
313 } else {
314 let vec = iter.collect::<Vec<_>>();
315 Arc::from(vec)
316 };
317 unsafe { UniqueArc::from_arc(arc) }
319 }
320}
321
322#[cfg(feature = "unsize")]
328unsafe impl<T, U: ?Sized> unsize::CoerciblePtr<U> for UniqueArc<T> {
329 type Pointee = T;
330 type Output = UniqueArc<U>;
331
332 fn as_sized_ptr(&mut self) -> *mut T {
333 unsize::CoerciblePtr::<U>::as_sized_ptr(&mut self.0)
335 }
336
337 unsafe fn replace_ptr(self, new: *mut U) -> UniqueArc<U> {
338 let inner = ManuallyDrop::new(self);
340 UniqueArc(ptr::read(&inner.0).replace_ptr(new))
341 }
342}
343
344#[cfg(feature = "serde")]
345impl<'de, T: Deserialize<'de>> Deserialize<'de> for UniqueArc<T> {
346 fn deserialize<D>(deserializer: D) -> Result<UniqueArc<T>, D::Error>
347 where
348 D: ::serde::de::Deserializer<'de>,
349 {
350 T::deserialize(deserializer).map(UniqueArc::new)
351 }
352}
353
354#[cfg(feature = "serde")]
355impl<T: Serialize> Serialize for UniqueArc<T> {
356 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
357 where
358 S: ::serde::ser::Serializer,
359 {
360 (**self).serialize(serializer)
361 }
362}
363
364#[cfg(test)]
365mod tests {
366 use crate::{Arc, HeaderSliceWithLengthUnchecked, HeaderWithLength, UniqueArc};
367 use core::{convert::TryFrom, mem::MaybeUninit};
368
369 #[test]
370 fn unique_into_inner() {
371 let unique = UniqueArc::new(10u64);
372 assert_eq!(UniqueArc::into_inner(unique), 10);
373 }
374
375 #[test]
376 fn try_new() {
377 let unique = UniqueArc::try_new(10u64).unwrap();
378 assert_eq!(UniqueArc::into_inner(unique), 10);
379 }
380
381 #[test]
382 fn try_new_uninit() {
383 let mut arc: UniqueArc<MaybeUninit<_>> = UniqueArc::try_new_uninit().unwrap();
384 arc.write(999);
385
386 let arc = unsafe { UniqueArc::assume_init(arc) };
387 assert_eq!(*arc, 999);
388 }
389
390 #[test]
391 fn try_new_uninit_slice() {
392 let mut arc: UniqueArc<[MaybeUninit<u16>]> = UniqueArc::try_new_uninit_slice(3).unwrap();
393 arc.fill(MaybeUninit::new(2));
394 let arc = unsafe { UniqueArc::assume_init_slice(arc) }.shareable();
395 assert_eq!(&*arc, [2, 2, 2]);
396 }
397
398 #[test]
399 fn try_from_header_and_uninit_slice() {
400 let mut uarc: UniqueArc<HeaderSliceWithLengthUnchecked<u8, MaybeUninit<u16>>> =
401 UniqueArc::try_from_header_and_uninit_slice(HeaderWithLength::new(1, 3), 3).unwrap();
402 uarc.slice.fill(MaybeUninit::new(2));
403 let arc = unsafe { uarc.assume_init_slice_with_header() }.shareable();
404 assert_eq!(arc.header.header, 1);
405 assert_eq!(&arc.slice, [2, 2, 2]);
406 }
407
408 #[test]
409 fn try_from_arc() {
410 let x = Arc::new(10_000);
411 let y = x.clone();
412
413 assert!(UniqueArc::try_from(x).is_err());
414 assert_eq!(
415 UniqueArc::into_inner(UniqueArc::try_from(y).unwrap()),
416 10_000,
417 );
418 }
419
420 #[test]
421 #[allow(deprecated)]
422 fn maybeuninit_smoke() {
423 let mut arc: UniqueArc<MaybeUninit<_>> = UniqueArc::new_uninit();
424 arc.write(999);
425
426 let arc = unsafe { UniqueArc::assume_init(arc) };
427 assert_eq!(*arc, 999);
428 }
429
430 #[test]
431 fn from_header_and_uninit_slice() {
432 let mut uarc: UniqueArc<HeaderSliceWithLengthUnchecked<u8, MaybeUninit<u16>>> =
433 UniqueArc::from_header_and_uninit_slice(HeaderWithLength::new(1, 3), 3);
434 uarc.slice.fill(MaybeUninit::new(2));
435 let arc = unsafe { uarc.assume_init_slice_with_header() }.shareable();
436 assert!(arc.is_unique());
437 let arcs = [
440 arc.clone(),
441 arc.clone(),
442 arc.clone(),
443 arc.clone(),
444 arc.clone(),
445 ];
446 let thin = Arc::into_thin(arc.clone());
448 assert_eq!(7, Arc::count(&arc));
449 assert_eq!(arc.header.header, 1);
451 assert_eq!(&arc.slice, [2, 2, 2]);
452 assert_eq!(thin.header.header, 1);
453 assert_eq!(&thin.slice, [2, 2, 2]);
454
455 drop(arcs);
458 drop(thin);
459 assert!(arc.is_unique());
460 assert_eq!(arc.header.header, 1);
461 assert_eq!(&arc.slice, [2, 2, 2]);
462 }
463}