1use core::{
16 fmt::Debug,
17 hash::Hash,
18 marker::PhantomData,
19 mem::{ManuallyDrop, MaybeUninit},
20 ptr::NonNull,
21 sync::atomic::{AtomicPtr, AtomicUsize, Ordering},
22};
23
24use crate::{
25 unreachable_unchecked, vtable::HasDropVt, AnonymRef, AnonymRefMut, Dyn, IStable, IntoDyn,
26};
27
28use super::{
29 vec::{ptr_add, ptr_diff, Vec, VecInner},
30 AllocPtr, AllocSlice, DefaultAllocator, IAlloc,
31};
32
33#[crate::stabby]
35pub struct Arc<T, Alloc: IAlloc = super::DefaultAllocator> {
36 ptr: AllocPtr<T, Alloc>,
37}
38unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Arc<T, Alloc> {}
40unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for Arc<T, Alloc> {}
42const USIZE_TOP_BIT: usize = 1 << (core::mem::size_of::<usize>() as i32 * 8 - 1);
43
44#[cfg(not(stabby_default_alloc = "disabled"))]
45impl<T> Arc<T> {
46 pub unsafe fn make<
61 F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
62 >(
63 constructor: F,
64 ) -> Result<Self, Arc<MaybeUninit<T>>> {
65 unsafe { Self::make_in(constructor, super::DefaultAllocator::new()) }
67 }
68 pub fn new(value: T) -> Self {
73 Self::new_in(value, DefaultAllocator::new())
74 }
75}
76
77impl<T, Alloc: IAlloc> Arc<T, Alloc> {
78 #[allow(clippy::type_complexity)]
94 pub unsafe fn try_make_in<
95 F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
96 >(
97 constructor: F,
98 mut alloc: Alloc,
99 ) -> Result<Self, Result<Arc<MaybeUninit<T>, Alloc>, (F, Alloc)>> {
100 let mut ptr = match AllocPtr::alloc(&mut alloc) {
101 Some(mut ptr) => {
102 let prefix = unsafe { ptr.prefix_mut() };
104 prefix.alloc.write(alloc);
105 prefix.strong = AtomicUsize::new(1);
106 prefix.weak = AtomicUsize::new(1);
107 ptr
108 }
109 None => return Err(Err((constructor, alloc))),
110 };
111 constructor(unsafe { ptr.as_mut() }).map_or_else(
113 |()| Err(Ok(Arc { ptr })),
114 |_| {
115 Ok(Self {
116 ptr: unsafe { ptr.assume_init() },
118 })
119 },
120 )
121 }
122 pub fn try_new_in(value: T, alloc: Alloc) -> Result<Self, (T, Alloc)> {
126 let this = unsafe {
128 Self::try_make_in(
129 |slot: &mut core::mem::MaybeUninit<T>| {
130 Ok(slot.write(core::ptr::read(&value)))
132 },
133 alloc,
134 )
135 };
136 match this {
137 Ok(this) => {
138 core::mem::forget(value);
139 Ok(this)
140 }
141 Err(Err((_, a))) => Err((value, a)),
142 Err(Ok(_)) => unsafe { unreachable_unchecked!() },
144 }
145 }
146 pub unsafe fn make_in<
159 F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
160 >(
161 constructor: F,
162 alloc: Alloc,
163 ) -> Result<Self, Arc<MaybeUninit<T>, Alloc>> {
164 Self::try_make_in(constructor, alloc).map_err(|e| match e {
165 Ok(uninit) => uninit,
166 Err(_) => panic!("Allocation failed"),
167 })
168 }
169 pub fn new_in(value: T, alloc: Alloc) -> Self {
174 let this = unsafe { Self::make_in(move |slot| Ok(slot.write(value)), alloc) };
176 unsafe { this.unwrap_unchecked() }
178 }
179
180 pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
184 let inner = this.ptr;
185 core::mem::forget(this);
186 inner
187 }
188 pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
192 Self { ptr: this }
193 }
194
195 pub fn get_mut(this: &mut Self) -> Option<&mut T> {
197 if Self::is_unique(this) {
198 Some(unsafe { Self::get_mut_unchecked(this) })
199 } else {
200 None
201 }
202 }
203
204 #[rustversion::attr(since(1.86), const)]
209 pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
210 unsafe { this.ptr.ptr.as_mut() }
211 }
212
213 pub fn strong_count(this: &Self) -> usize {
215 unsafe { this.ptr.prefix() }.strong.load(Ordering::Relaxed)
216 }
217 pub unsafe fn increment_strong_count(this: *const T) -> usize {
221 let ptr: AllocPtr<T, Alloc> = AllocPtr {
222 ptr: NonNull::new_unchecked(this.cast_mut()),
223 marker: core::marker::PhantomData,
224 };
225 unsafe { ptr.prefix() }
226 .strong
227 .fetch_add(1, Ordering::Relaxed)
228 }
229 pub fn weak_count(this: &Self) -> usize {
231 unsafe { this.ptr.prefix() }.weak.load(Ordering::Relaxed)
232 }
233 pub fn increment_weak_count(this: &Self) -> usize {
235 unsafe { this.ptr.prefix() }
236 .weak
237 .fetch_add(1, Ordering::Relaxed)
238 }
239
240 pub fn make_mut(&mut self) -> &mut T
242 where
243 T: Clone,
244 Alloc: Clone,
245 {
246 if !Self::is_unique(self) {
247 *self = Self::new_in(
248 T::clone(self),
249 unsafe { self.ptr.prefix().alloc.assume_init_ref() }.clone(),
250 );
251 }
252 unsafe { Self::get_mut_unchecked(self) }
253 }
254
255 pub fn make_mut_and_get_alloc(&mut self) -> (&mut T, &Alloc)
257 where
258 T: Clone,
259 Alloc: Clone,
260 {
261 if !Self::is_unique(self) {
262 *self = Self::new_in(
263 T::clone(self),
264 unsafe { self.ptr.prefix().alloc.assume_init_ref() }.clone(),
265 );
266 }
267 let (prefix, inner) = unsafe { self.ptr.split_mut() };
268 (inner, unsafe { prefix.alloc.assume_init_ref() })
269 }
270
271 pub fn is_unique(this: &Self) -> bool {
273 Self::strong_count(this) == 1 && Self::weak_count(this) == 1
274 }
275 pub fn try_into_inner(this: Self) -> Result<T, Self> {
279 if !Self::is_unique(&this) {
280 Err(this)
281 } else {
282 let ret = unsafe { core::ptr::read(&*this) };
283 _ = unsafe { Weak::<T, Alloc>::from_raw(Arc::into_raw(this)) };
284 Ok(ret)
285 }
286 }
287
288 pub fn downgrade(this: &Self) -> Weak<T, Alloc> {
290 this.into()
291 }
292 #[rustversion::since(1.73)]
293 pub const fn allocator(this: &Self) -> &Alloc {
295 unsafe { this.ptr.prefix().alloc.assume_init_ref() }
296 }
297 #[rustversion::before(1.73)]
298 pub fn allocator(this: &Self) -> &Alloc {
300 unsafe { this.ptr.prefix().alloc.assume_init_ref() }
301 }
302}
303impl<T, Alloc: IAlloc> Drop for Arc<T, Alloc> {
304 fn drop(&mut self) {
305 if unsafe { self.ptr.prefix() }
306 .strong
307 .fetch_sub(1, Ordering::Relaxed)
308 != 1
309 {
310 return;
311 }
312 unsafe {
313 core::ptr::drop_in_place(self.ptr.as_mut());
314 _ = Weak::<T, Alloc>::from_raw(self.ptr);
315 }
316 }
317}
318impl<T, Alloc: IAlloc> Clone for Arc<T, Alloc> {
319 fn clone(&self) -> Self {
320 unsafe { self.ptr.prefix() }
321 .strong
322 .fetch_add(1, Ordering::Relaxed);
323 Self { ptr: self.ptr }
324 }
325}
326impl<T, Alloc: IAlloc> core::ops::Deref for Arc<T, Alloc> {
327 type Target = T;
328 fn deref(&self) -> &Self::Target {
329 unsafe { self.ptr.as_ref() }
330 }
331}
332
333#[crate::stabby]
335pub struct Weak<T, Alloc: IAlloc = super::DefaultAllocator> {
336 ptr: AllocPtr<T, Alloc>,
337}
338unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Weak<T, Alloc> {}
340unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for Weak<T, Alloc> {}
342impl<T, Alloc: IAlloc> From<&Arc<T, Alloc>> for Arc<T, Alloc> {
343 fn from(value: &Arc<T, Alloc>) -> Self {
344 value.clone()
345 }
346}
347impl<T, Alloc: IAlloc> From<&Weak<T, Alloc>> for Weak<T, Alloc> {
348 fn from(value: &Weak<T, Alloc>) -> Self {
349 value.clone()
350 }
351}
352impl<T, Alloc: IAlloc> From<&Arc<T, Alloc>> for Weak<T, Alloc> {
353 fn from(value: &Arc<T, Alloc>) -> Self {
354 unsafe { value.ptr.prefix() }
355 .weak
356 .fetch_add(1, Ordering::Relaxed);
357 Self { ptr: value.ptr }
358 }
359}
360impl<T, Alloc: IAlloc> Weak<T, Alloc> {
361 pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
365 let inner = this.ptr;
366 core::mem::forget(this);
367 inner
368 }
369 pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
373 Self { ptr: this }
374 }
375 pub fn upgrade(&self) -> Option<Arc<T, Alloc>> {
377 let strong = &unsafe { self.ptr.prefix() }.strong;
378 let count = strong.fetch_or(USIZE_TOP_BIT, Ordering::Acquire);
379 match count {
380 0 | USIZE_TOP_BIT => {
381 strong.store(0, Ordering::Release);
382 None
383 }
384 _ => {
385 strong.fetch_add(1, Ordering::Release);
386 strong.fetch_and(!USIZE_TOP_BIT, Ordering::Release);
387 Some(Arc { ptr: self.ptr })
388 }
389 }
390 }
391}
392impl<T, Alloc: IAlloc> Clone for Weak<T, Alloc> {
393 fn clone(&self) -> Self {
394 unsafe { self.ptr.prefix() }
395 .weak
396 .fetch_add(1, Ordering::Relaxed);
397 Self { ptr: self.ptr }
398 }
399}
400impl<T, Alloc: IAlloc> Drop for Weak<T, Alloc> {
401 fn drop(&mut self) {
402 if unsafe { self.ptr.prefix() }
403 .weak
404 .fetch_sub(1, Ordering::Relaxed)
405 != 1
406 {
407 return;
408 }
409 unsafe {
410 let mut alloc = self.ptr.prefix().alloc.assume_init_read();
411 self.ptr.free(&mut alloc)
412 }
413 }
414}
415
416#[crate::stabby]
420pub struct ArcSlice<T, Alloc: IAlloc = super::DefaultAllocator> {
421 pub(crate) inner: AllocSlice<T, Alloc>,
422}
423unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for ArcSlice<T, Alloc> {}
425unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for ArcSlice<T, Alloc> {}
427unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for WeakSlice<T, Alloc> {}
429unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for WeakSlice<T, Alloc> {}
431
432impl<T, Alloc: IAlloc> ArcSlice<T, Alloc> {
433 pub const fn len(&self) -> usize {
435 ptr_diff(self.inner.end, self.inner.start.ptr)
436 }
437 pub const fn is_empty(&self) -> bool {
439 self.len() == 0
440 }
441 pub const fn as_slice(&self) -> &[T] {
443 let start = self.inner.start;
444 unsafe { core::slice::from_raw_parts(start.ptr.as_ptr(), self.len()) }
445 }
446 pub fn as_slice_mut(&mut self) -> Option<&mut [T]> {
448 (ArcSlice::strong_count(self) == 1 && ArcSlice::weak_count(self) == 1)
449 .then(|| unsafe { self.as_slice_mut_unchecked() })
450 }
451 #[rustversion::attr(since(1.86), const)]
455 pub unsafe fn as_slice_mut_unchecked(&mut self) -> &mut [T] {
456 let start = self.inner.start;
457 unsafe { core::slice::from_raw_parts_mut(start.ptr.as_ptr(), self.len()) }
458 }
459 pub fn strong_count(this: &Self) -> usize {
461 unsafe { this.inner.start.prefix().strong.load(Ordering::Relaxed) }
462 }
463 pub fn weak_count(this: &Self) -> usize {
465 unsafe { this.inner.start.prefix().weak.load(Ordering::Relaxed) }
466 }
467 pub fn is_unique(this: &Self) -> bool {
469 Self::strong_count(this) == 1 && Self::weak_count(this) == 1
470 }
471 pub const fn into_raw(this: Self) -> AllocSlice<T, Alloc> {
475 let inner = this.inner;
476 core::mem::forget(this);
477 inner
478 }
479 pub const unsafe fn from_raw(this: AllocSlice<T, Alloc>) -> Self {
484 Self { inner: this }
485 }
486}
487impl<T, Alloc: IAlloc> core::ops::Deref for ArcSlice<T, Alloc> {
488 type Target = [T];
489 fn deref(&self) -> &Self::Target {
490 self.as_slice()
491 }
492}
493impl<T, Alloc: IAlloc> Clone for ArcSlice<T, Alloc> {
494 fn clone(&self) -> Self {
495 unsafe { self.inner.start.prefix() }
496 .strong
497 .fetch_add(1, Ordering::Relaxed);
498 Self { inner: self.inner }
499 }
500}
501impl<T, Alloc: IAlloc> From<Arc<T, Alloc>> for ArcSlice<T, Alloc> {
502 fn from(mut value: Arc<T, Alloc>) -> Self {
503 unsafe { value.ptr.prefix_mut() }.capacity = AtomicUsize::new(1);
504 Self {
505 inner: AllocSlice {
506 start: value.ptr,
507 end: ptr_add(value.ptr.ptr, 1),
508 },
509 }
510 }
511}
512impl<T: Copy, Alloc: IAlloc + Default> From<&[T]> for ArcSlice<T, Alloc> {
513 fn from(value: &[T]) -> Self {
514 Vec::from(value).into()
515 }
516}
517impl<T, Alloc: IAlloc> From<Vec<T, Alloc>> for ArcSlice<T, Alloc> {
518 fn from(value: Vec<T, Alloc>) -> Self {
519 let (mut slice, capacity, mut alloc) = value.into_raw_components();
520 if capacity != 0 {
521 unsafe {
522 slice.start.prefix_mut().strong = AtomicUsize::new(1);
523 slice.start.prefix_mut().weak = AtomicUsize::new(1);
524 slice.start.prefix_mut().capacity = AtomicUsize::new(capacity);
525 slice.start.prefix_mut().alloc.write(alloc);
526 }
527 Self {
528 inner: AllocSlice {
529 start: slice.start,
530 end: slice.end,
531 },
532 }
533 } else {
534 let mut start = AllocPtr::alloc_array(&mut alloc, 0).expect("Allocation failed");
535 unsafe {
536 start.prefix_mut().strong = AtomicUsize::new(1);
537 start.prefix_mut().weak = AtomicUsize::new(1);
538 start.prefix_mut().capacity = if core::mem::size_of::<T>() != 0 {
539 AtomicUsize::new(0)
540 } else {
541 AtomicUsize::new(ptr_diff(
542 core::mem::transmute::<usize, NonNull<u8>>(usize::MAX),
543 start.ptr.cast::<u8>(),
544 ))
545 };
546 slice.start.prefix_mut().alloc.write(alloc);
547 }
548 Self {
549 inner: AllocSlice {
550 start,
551 end: ptr_add(start.ptr.cast::<u8>(), slice.len()).cast(),
552 },
553 }
554 }
555 }
556}
557impl<T, Alloc: IAlloc> TryFrom<ArcSlice<T, Alloc>> for Vec<T, Alloc> {
558 type Error = ArcSlice<T, Alloc>;
559 fn try_from(value: ArcSlice<T, Alloc>) -> Result<Self, Self::Error> {
560 if core::mem::size_of::<T>() == 0 || !ArcSlice::is_unique(&value) {
561 Err(value)
562 } else {
563 unsafe {
564 let ret = Vec {
565 inner: VecInner {
566 start: value.inner.start,
567 end: value.inner.end,
568 capacity: ptr_add(
569 value.inner.start.ptr,
570 value.inner.start.prefix().capacity.load(Ordering::Relaxed),
571 ),
572 alloc: value.inner.start.prefix().alloc.assume_init_read(),
573 },
574 };
575 core::mem::forget(value);
576 Ok(ret)
577 }
578 }
579 }
580}
581impl<T: Eq, Alloc: IAlloc> Eq for ArcSlice<T, Alloc> {}
582impl<T: PartialEq, Alloc: IAlloc> PartialEq for ArcSlice<T, Alloc> {
583 fn eq(&self, other: &Self) -> bool {
584 self.as_slice() == other.as_slice()
585 }
586}
587impl<T: Ord, Alloc: IAlloc> Ord for ArcSlice<T, Alloc> {
588 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
589 self.as_slice().cmp(other.as_slice())
590 }
591}
592impl<T: PartialOrd, Alloc: IAlloc> PartialOrd for ArcSlice<T, Alloc> {
593 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
594 self.as_slice().partial_cmp(other.as_slice())
595 }
596}
597impl<T: Hash, Alloc: IAlloc> Hash for ArcSlice<T, Alloc> {
598 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
599 self.as_slice().hash(state)
600 }
601}
602impl<T, Alloc: IAlloc> Drop for ArcSlice<T, Alloc> {
603 fn drop(&mut self) {
604 if unsafe { self.inner.start.prefix() }
605 .strong
606 .fetch_sub(1, Ordering::Relaxed)
607 != 1
608 {
609 return;
610 }
611 unsafe { core::ptr::drop_in_place(self.as_slice_mut_unchecked()) }
612 _ = WeakSlice { inner: self.inner };
613 }
614}
615impl<T: Debug, Alloc: IAlloc> Debug for ArcSlice<T, Alloc> {
616 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
617 self.as_slice().fmt(f)
618 }
619}
620impl<T: core::fmt::LowerHex, Alloc: IAlloc> core::fmt::LowerHex for ArcSlice<T, Alloc> {
621 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
622 let mut first = true;
623 for item in self {
624 if !first {
625 f.write_str(":")?;
626 }
627 first = false;
628 core::fmt::LowerHex::fmt(item, f)?;
629 }
630 Ok(())
631 }
632}
633impl<T: core::fmt::UpperHex, Alloc: IAlloc> core::fmt::UpperHex for ArcSlice<T, Alloc> {
634 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
635 let mut first = true;
636 for item in self {
637 if !first {
638 f.write_str(":")?;
639 }
640 first = false;
641 core::fmt::UpperHex::fmt(item, f)?;
642 }
643 Ok(())
644 }
645}
646impl<'a, T, Alloc: IAlloc> IntoIterator for &'a ArcSlice<T, Alloc> {
647 type Item = &'a T;
648 type IntoIter = core::slice::Iter<'a, T>;
649 fn into_iter(self) -> Self::IntoIter {
650 self.as_slice().iter()
651 }
652}
653
654impl<T, Alloc: IAlloc + Default> FromIterator<T> for ArcSlice<T, Alloc> {
655 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
656 Vec::from_iter(iter).into()
657 }
658}
659
660#[crate::stabby]
662pub struct WeakSlice<T, Alloc: IAlloc = super::DefaultAllocator> {
663 pub(crate) inner: AllocSlice<T, Alloc>,
664}
665
666impl<T, Alloc: IAlloc> WeakSlice<T, Alloc> {
667 pub fn upgrade(&self) -> Option<ArcSlice<T, Alloc>> {
669 let strong = &unsafe { self.inner.start.prefix() }.strong;
670 let count = strong.fetch_or(USIZE_TOP_BIT, Ordering::Acquire);
671 match count {
672 0 | USIZE_TOP_BIT => {
673 strong.store(0, Ordering::Release);
674 None
675 }
676 _ => {
677 strong.fetch_add(1, Ordering::Release);
678 strong.fetch_and(!USIZE_TOP_BIT, Ordering::Release);
679 Some(ArcSlice { inner: self.inner })
680 }
681 }
682 }
683 pub fn force_upgrade(&self) -> ArcSlice<T, Alloc>
688 where
689 T: Copy,
690 {
691 let strong = &unsafe { self.inner.start.prefix() }.strong;
692 match strong.fetch_add(1, Ordering::Release) {
693 0 | USIZE_TOP_BIT => {
694 unsafe { self.inner.start.prefix() }
695 .weak
696 .fetch_add(1, Ordering::Relaxed);
697 }
698 _ => {}
699 }
700 ArcSlice { inner: self.inner }
701 }
702}
703impl<T, Alloc: IAlloc> Clone for WeakSlice<T, Alloc> {
704 fn clone(&self) -> Self {
705 unsafe { self.inner.start.prefix() }
706 .weak
707 .fetch_add(1, Ordering::Relaxed);
708 Self { inner: self.inner }
709 }
710}
711impl<T, Alloc: IAlloc> From<&ArcSlice<T, Alloc>> for ArcSlice<T, Alloc> {
712 fn from(value: &ArcSlice<T, Alloc>) -> Self {
713 value.clone()
714 }
715}
716impl<T, Alloc: IAlloc> From<&WeakSlice<T, Alloc>> for WeakSlice<T, Alloc> {
717 fn from(value: &WeakSlice<T, Alloc>) -> Self {
718 value.clone()
719 }
720}
721impl<T, Alloc: IAlloc> From<&ArcSlice<T, Alloc>> for WeakSlice<T, Alloc> {
722 fn from(value: &ArcSlice<T, Alloc>) -> Self {
723 unsafe { value.inner.start.prefix() }
724 .weak
725 .fetch_add(1, Ordering::Relaxed);
726 Self { inner: value.inner }
727 }
728}
729impl<T, Alloc: IAlloc> Drop for WeakSlice<T, Alloc> {
730 fn drop(&mut self) {
731 if unsafe { self.inner.start.prefix() }
732 .weak
733 .fetch_sub(1, Ordering::Relaxed)
734 != 1
735 {
736 return;
737 }
738 let mut alloc = unsafe { self.inner.start.prefix().alloc.assume_init_read() };
739 unsafe { self.inner.start.free(&mut alloc) }
740 }
741}
742pub use super::string::{ArcStr, WeakStr};
743
744impl<T, Alloc: IAlloc> crate::IPtr for Arc<T, Alloc> {
745 unsafe fn as_ref(&self) -> AnonymRef<'_> {
746 AnonymRef {
747 ptr: self.ptr.ptr.cast(),
748 _marker: PhantomData,
749 }
750 }
751}
752impl<T, Alloc: IAlloc> crate::IPtrClone for Arc<T, Alloc> {
753 fn clone(this: &Self) -> Self {
754 this.clone()
755 }
756}
757
758impl<T, Alloc: IAlloc> crate::IPtrTryAsMut for Arc<T, Alloc> {
759 unsafe fn try_as_mut(&mut self) -> Option<AnonymRefMut<'_>> {
760 Self::is_unique(self).then(|| AnonymRefMut {
761 ptr: self.ptr.ptr.cast(),
762 _marker: PhantomData,
763 })
764 }
765}
766impl<T, Alloc: IAlloc> crate::IPtrOwned for Arc<T, Alloc> {
767 fn drop(
768 this: &mut core::mem::ManuallyDrop<Self>,
769 drop: unsafe extern "C" fn(AnonymRefMut<'_>),
770 ) {
771 if unsafe { this.ptr.prefix() }
772 .strong
773 .fetch_sub(1, Ordering::Relaxed)
774 != 1
775 {
776 return;
777 }
778 unsafe {
779 drop(AnonymRefMut {
780 ptr: this.ptr.ptr.cast(),
781 _marker: PhantomData,
782 });
783 _ = Weak::<T, Alloc>::from_raw(this.ptr);
784 }
785 }
786}
787
788impl<T, Alloc: IAlloc> IntoDyn for Arc<T, Alloc> {
789 type Anonymized = Arc<(), Alloc>;
790 type Target = T;
791 fn anonimize(self) -> Self::Anonymized {
792 let original_prefix = self.ptr.prefix_ptr();
793 let anonymized = unsafe { core::mem::transmute::<Self, Self::Anonymized>(self) };
794 let anonymized_prefix = anonymized.ptr.prefix_ptr();
795 assert_eq!(anonymized_prefix, original_prefix, "The allocation prefix was lost in anonimization, this is definitely a bug, please report it.");
796 anonymized
797 }
798}
799
800impl<T, Alloc: IAlloc> crate::IPtrOwned for Weak<T, Alloc> {
801 fn drop(
802 this: &mut core::mem::ManuallyDrop<Self>,
803 _drop: unsafe extern "C" fn(AnonymRefMut<'_>),
804 ) {
805 if unsafe { this.ptr.prefix() }
806 .weak
807 .fetch_sub(1, Ordering::Relaxed)
808 != 1
809 {
810 return;
811 }
812 unsafe {
813 _ = Weak::<T, Alloc>::from_raw(this.ptr);
814 }
815 }
816}
817
818impl<T, Alloc: IAlloc> crate::IPtrClone for Weak<T, Alloc> {
819 fn clone(this: &Self) -> Self {
820 this.clone()
821 }
822}
823
824impl<T, Alloc: IAlloc> IntoDyn for Weak<T, Alloc> {
825 type Anonymized = Weak<(), Alloc>;
826 type Target = T;
827 fn anonimize(self) -> Self::Anonymized {
828 let original_prefix = self.ptr.prefix_ptr();
829 let anonymized = unsafe { core::mem::transmute::<Self, Self::Anonymized>(self) };
830 let anonymized_prefix = anonymized.ptr.prefix_ptr();
831 assert_eq!(anonymized_prefix, original_prefix, "The allocation prefix was lost in anonimization, this is definitely a bug, please report it.");
832 anonymized
833 }
834}
835
836impl<'a, Vt: HasDropVt, Alloc: IAlloc> From<&'a Dyn<'a, Arc<(), Alloc>, Vt>>
837 for Dyn<'a, Weak<(), Alloc>, Vt>
838{
839 fn from(value: &'a Dyn<'a, Arc<(), Alloc>, Vt>) -> Self {
840 Self {
841 ptr: ManuallyDrop::new(Arc::downgrade(&value.ptr)),
842 vtable: value.vtable,
843 unsend: core::marker::PhantomData,
844 }
845 }
846}
847impl<'a, Vt: HasDropVt + IStable, Alloc: IAlloc> Dyn<'a, Weak<(), Alloc>, Vt> {
848 pub fn upgrade(self) -> crate::option::Option<Dyn<'a, Arc<(), Alloc>, Vt>> {
850 let Some(ptr) = self.ptr.upgrade() else {
851 return crate::option::Option::None();
852 };
853 crate::option::Option::Some(Dyn {
854 ptr: ManuallyDrop::new(ptr),
855 vtable: self.vtable,
856 unsend: core::marker::PhantomData,
857 })
858 }
859}
860
861#[crate::stabby]
862pub struct AtomicArc<T, Alloc: IAlloc> {
864 ptr: AtomicPtr<T>,
865 alloc: core::marker::PhantomData<*const Alloc>,
866}
867unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for AtomicArc<T, Alloc> {}
869unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for AtomicArc<T, Alloc> {}
871
872impl<T, Alloc: IAlloc> Drop for AtomicArc<T, Alloc> {
873 fn drop(&mut self) {
874 let ptr = self.ptr.load(Ordering::Relaxed);
875 if let Some(ptr) = NonNull::new(ptr) {
876 unsafe {
877 Arc::<T, Alloc>::from_raw(AllocPtr {
878 ptr,
879 marker: PhantomData,
880 })
881 };
882 }
883 }
884}
885
886type MaybeArc<T, Alloc> = Option<Arc<T, Alloc>>;
887impl<T, Alloc: IAlloc> AtomicArc<T, Alloc> {
888 pub const fn new(value: MaybeArc<T, Alloc>) -> Self {
890 Self {
891 ptr: AtomicPtr::new(unsafe {
892 core::mem::transmute::<Option<Arc<T, Alloc>>, *mut T>(value)
893 }),
894 alloc: PhantomData,
895 }
896 }
897 pub fn load(&self, order: Ordering) -> MaybeArc<T, Alloc> {
899 let ptr = NonNull::new(self.ptr.load(order))?;
900 unsafe {
901 Arc::<T, Alloc>::increment_strong_count(ptr.as_ptr());
902 Some(Arc::from_raw(AllocPtr {
903 ptr,
904 marker: PhantomData,
905 }))
906 }
907 }
908 pub fn store(&self, value: MaybeArc<T, Alloc>, order: Ordering) {
910 let ptr = value.map_or(core::ptr::null_mut(), |value| Arc::into_raw(value).as_ptr());
911 self.ptr.store(ptr, order)
912 }
913 pub fn is(
917 &self,
918 current: Option<&Arc<T, Alloc>>,
919 order: Ordering,
920 ) -> Result<(), MaybeArc<T, Alloc>> {
921 let ptr = NonNull::new(self.ptr.load(order));
922 match (ptr, current) {
923 (None, None) => Ok(()),
924 (None, _) => Err(None),
925 (Some(ptr), Some(current)) if core::ptr::eq(ptr.as_ptr(), current.ptr.as_ptr()) => {
926 Ok(())
927 }
928 (Some(ptr), _) => unsafe {
929 Arc::<T, Alloc>::increment_strong_count(ptr.as_ptr());
930 Err(Some(Arc::from_raw(AllocPtr {
931 ptr,
932 marker: PhantomData,
933 })))
934 },
935 }
936 }
937 pub fn compare_exchange(
941 &self,
942 current: Option<&Arc<T, Alloc>>,
943 new: MaybeArc<T, Alloc>,
944 success: Ordering,
945 failure: Ordering,
946 ) -> Result<MaybeArc<T, Alloc>, MaybeArc<T, Alloc>> {
947 let current = current.map_or(core::ptr::null_mut(), |value| value.ptr.ptr.as_ptr());
948 let new = new.map_or(core::ptr::null_mut(), |value| Arc::into_raw(value).as_ptr());
949 match self.ptr.compare_exchange(current, new, success, failure) {
950 Ok(ptr) => Ok(NonNull::new(ptr).map(|ptr| unsafe {
951 Arc::from_raw(AllocPtr {
952 ptr,
953 marker: PhantomData,
954 })
955 })),
956 Err(ptr) => Err(NonNull::new(ptr).map(|ptr| unsafe {
957 Arc::<T, Alloc>::increment_strong_count(ptr.as_ptr());
958 Arc::from_raw(AllocPtr {
959 ptr,
960 marker: PhantomData,
961 })
962 })),
963 }
964 }
965}
966
967#[cfg(feature = "serde")]
968mod serde_impl {
969 use super::*;
970 use crate::alloc::IAlloc;
971 use serde::{Deserialize, Serialize};
972 impl<T: Serialize, Alloc: IAlloc> Serialize for ArcSlice<T, Alloc> {
973 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
974 where
975 S: serde::Serializer,
976 {
977 let slice: &[T] = self;
978 slice.serialize(serializer)
979 }
980 }
981 impl<'a, T: Deserialize<'a>, Alloc: IAlloc + Default> Deserialize<'a> for ArcSlice<T, Alloc> {
982 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
983 where
984 D: serde::Deserializer<'a>,
985 {
986 crate::alloc::vec::Vec::deserialize(deserializer).map(Into::into)
987 }
988 }
989 impl<Alloc: IAlloc> Serialize for ArcStr<Alloc> {
990 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
991 where
992 S: serde::Serializer,
993 {
994 let slice: &str = self;
995 slice.serialize(serializer)
996 }
997 }
998 impl<'a, Alloc: IAlloc + Default> Deserialize<'a> for ArcStr<Alloc> {
999 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1000 where
1001 D: serde::Deserializer<'a>,
1002 {
1003 crate::alloc::string::String::deserialize(deserializer).map(Into::into)
1004 }
1005 }
1006}