Skip to main content

stabby_abi/alloc/
sync.rs

1//
2// Copyright (c) 2023 ZettaScale Technology
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7// which is available at https://www.apache.org/licenses/LICENSE-2.0
8//
9// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10//
11// Contributors:
12//   Pierre Avital, <pierre.avital@me.com>
13//
14
15use 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/// [`alloc::sync::Arc`](https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html), but ABI-stable.
34#[crate::stabby]
35pub struct Arc<T, Alloc: IAlloc = super::DefaultAllocator> {
36    ptr: AllocPtr<T, Alloc>,
37}
38// SAFETY: Same constraints as in `std`.
39unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Arc<T, Alloc> {}
40// SAFETY: Same constraints as in `std`.
41unsafe 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    /// Attempts to allocate [`Self`], initializing it with `constructor`.
47    ///
48    /// Note that the allocation may or may not be zeroed.
49    ///
50    /// If the allocation fails, the `constructor` will not be run.
51    ///
52    /// # Safety
53    /// `constructor` MUST return `Err(())` if it failed to initialize the passed argument.
54    ///
55    /// # Errors
56    /// Returns the uninitialized allocation if the constructor declares a failure.
57    ///
58    /// # Panics
59    /// If the allocator fails to provide an appropriate allocation.
60    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        // SAFETY: Ensured by parent fn
66        unsafe { Self::make_in(constructor, super::DefaultAllocator::new()) }
67    }
68    /// Attempts to allocate [`Self`] and store `value` in it.
69    ///
70    /// # Panics
71    /// If the allocator fails to provide an appropriate allocation.
72    pub fn new(value: T) -> Self {
73        Self::new_in(value, DefaultAllocator::new())
74    }
75}
76
77impl<T, Alloc: IAlloc> Arc<T, Alloc> {
78    /// Attempts to allocate [`Self`], initializing it with `constructor`.
79    ///
80    /// Note that the allocation may or may not be zeroed.
81    ///
82    /// If the `constructor` panics, the allocated memory will be leaked.
83    ///
84    /// # Errors
85    /// - Returns the `constructor` and the allocator in case of allocation failure.
86    /// - Returns the uninitialized allocated memory if `constructor` fails.
87    ///
88    /// # Safety
89    /// `constructor` MUST return `Err(())` if it failed to initialize the passed argument.
90    ///
91    /// # Notes
92    /// Note that the allocation may or may not be zeroed.
93    #[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                // SAFETY: `ptr` just got allocated via `AllocPtr::alloc`.
103                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        // SAFETY: We are the sole owners of `ptr`
112        constructor(unsafe { ptr.as_mut() }).map_or_else(
113            |()| Err(Ok(Arc { ptr })),
114            |_| {
115                Ok(Self {
116                    // SAFETY: `constructor` reported success.
117                    ptr: unsafe { ptr.assume_init() },
118                })
119            },
120        )
121    }
122    /// Attempts to allocate a [`Self`] and store `value` in it
123    /// # Errors
124    /// Returns `value` and the allocator in case of failure.
125    pub fn try_new_in(value: T, alloc: Alloc) -> Result<Self, (T, Alloc)> {
126        // SAFETY: `ctor` is a valid constructor, always initializing the value.
127        let this = unsafe {
128            Self::try_make_in(
129                |slot: &mut core::mem::MaybeUninit<T>| {
130                    // SAFETY: `value` will be forgotten if the allocation succeeds and `read` is called.
131                    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            // SAFETY: the constructor is infallible.
143            Err(Ok(_)) => unsafe { unreachable_unchecked!() },
144        }
145    }
146    /// Attempts to allocate [`Self`], initializing it with `constructor`.
147    ///
148    /// Note that the allocation may or may not be zeroed.
149    ///
150    /// # Errors
151    /// Returns the uninitialized allocated memory if `constructor` fails.
152    ///
153    /// # Safety
154    /// `constructor` MUST return `Err(())` if it failed to initialize the passed argument.
155    ///
156    /// # Panics
157    /// If the allocator fails to provide an appropriate allocation.
158    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    /// Attempts to allocate [`Self`] and store `value` in it.
170    ///
171    /// # Panics
172    /// If the allocator fails to provide an appropriate allocation.
173    pub fn new_in(value: T, alloc: Alloc) -> Self {
174        // SAFETY: `constructor` fits the spec.
175        let this = unsafe { Self::make_in(move |slot| Ok(slot.write(value)), alloc) };
176        // SAFETY: `constructor` is infallible.
177        unsafe { this.unwrap_unchecked() }
178    }
179
180    /// Returns the pointer to the inner raw allocation, leaking `this`.
181    ///
182    /// Note that the pointer may be dangling if `T` is zero-sized.
183    pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
184        let inner = this.ptr;
185        core::mem::forget(this);
186        inner
187    }
188    /// Constructs `Self` from a raw allocation.
189    /// # Safety
190    /// `this` MUST not be dangling, and have been obtained through [`Self::into_raw`].
191    pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
192        Self { ptr: this }
193    }
194
195    /// Provides a mutable reference to the internals if the strong and weak counts are both 1.
196    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    /// Provides a mutable reference to the internals without checking.
205    /// # Safety
206    /// If used carelessly, this can cause mutable references and immutable references to the same value to appear,
207    /// causing undefined behaviour.
208    #[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    /// Returns the strong count.
214    pub fn strong_count(this: &Self) -> usize {
215        unsafe { this.ptr.prefix() }.strong.load(Ordering::Relaxed)
216    }
217    /// Increments the strong count.
218    /// # Safety
219    /// `this` MUST be a valid pointer derived from `Self`
220    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    /// Returns the weak count. Note that all Arcs to a same value share a Weak, so the weak count can never be 0.
230    pub fn weak_count(this: &Self) -> usize {
231        unsafe { this.ptr.prefix() }.weak.load(Ordering::Relaxed)
232    }
233    /// Increments the weak count, returning its previous value.
234    pub fn increment_weak_count(this: &Self) -> usize {
235        unsafe { this.ptr.prefix() }
236            .weak
237            .fetch_add(1, Ordering::Relaxed)
238    }
239
240    /// Returns a mutable reference to this `Arc`'s value, cloning that value into a new `Arc` if [`Self::get_mut`] would have failed.
241    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    /// Returns a mutable reference to this `Arc`'s value, cloning that value into a new `Arc` if [`Self::get_mut`] would have failed.
256    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    /// Whether or not `this` is the sole owner of its data, including weak owners.
272    pub fn is_unique(this: &Self) -> bool {
273        Self::strong_count(this) == 1 && Self::weak_count(this) == 1
274    }
275    /// Attempts the value from the allocation, freeing said allocation.
276    /// # Errors
277    /// Returns `this` if it's not the sole owner of its value.
278    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    /// Constructs an additional [`Weak`] pointer to `this`.
289    pub fn downgrade(this: &Self) -> Weak<T, Alloc> {
290        this.into()
291    }
292    #[rustversion::since(1.73)]
293    /// Returns a reference to the allocator used to construct `this`
294    pub const fn allocator(this: &Self) -> &Alloc {
295        unsafe { this.ptr.prefix().alloc.assume_init_ref() }
296    }
297    #[rustversion::before(1.73)]
298    /// Returns a reference to the allocator used to construct `this`
299    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/// [`alloc::sync::Weak`](https://doc.rust-lang.org/stable/alloc/sync/struct.Weak.html), but ABI-stable.
334#[crate::stabby]
335pub struct Weak<T, Alloc: IAlloc = super::DefaultAllocator> {
336    ptr: AllocPtr<T, Alloc>,
337}
338// SAFETY: Same constraints as in `std`.
339unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Weak<T, Alloc> {}
340// SAFETY: Same constraints as in `std`.
341unsafe 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    /// Returns the pointer to the inner raw allocation, leaking `this`.
362    ///
363    /// Note that the pointer may be dangling if `T` is zero-sized.
364    pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
365        let inner = this.ptr;
366        core::mem::forget(this);
367        inner
368    }
369    /// Constructs `Self` from a raw allocation.
370    /// # Safety
371    /// `this` MUST not be dangling, and have been obtained through [`Self::into_raw`].
372    pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
373        Self { ptr: this }
374    }
375    /// Attempts to upgrade self into an Arc.
376    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/// A strong reference to a fixed size slice of elements.
417///
418/// Equivalent to `alloc::sync::Arc<[T]>`
419#[crate::stabby]
420pub struct ArcSlice<T, Alloc: IAlloc = super::DefaultAllocator> {
421    pub(crate) inner: AllocSlice<T, Alloc>,
422}
423// SAFETY: Same constraints as in `std`.
424unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for ArcSlice<T, Alloc> {}
425// SAFETY: Same constraints as in `std`.
426unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for ArcSlice<T, Alloc> {}
427// SAFETY: Same constraints as in `std`.
428unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for WeakSlice<T, Alloc> {}
429// SAFETY: Same constraints as in `std`.
430unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for WeakSlice<T, Alloc> {}
431
432impl<T, Alloc: IAlloc> ArcSlice<T, Alloc> {
433    /// Returns the number of elements in the slice.
434    pub const fn len(&self) -> usize {
435        ptr_diff(self.inner.end, self.inner.start.ptr)
436    }
437    /// Returns true if the slice is empty.
438    pub const fn is_empty(&self) -> bool {
439        self.len() == 0
440    }
441    /// Returns a borrow to the slice.
442    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    /// Returns a mutable borrow to the slice if no other references to it may exist.
447    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    /// Returns a mutable borrow to the slice.
452    /// # Safety
453    /// This can easily create aliased mutable references, which would be undefined behaviour.
454    #[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    /// Returns the strong count to the slice.
460    pub fn strong_count(this: &Self) -> usize {
461        unsafe { this.inner.start.prefix().strong.load(Ordering::Relaxed) }
462    }
463    /// Returns the weak count to the slice.
464    pub fn weak_count(this: &Self) -> usize {
465        unsafe { this.inner.start.prefix().weak.load(Ordering::Relaxed) }
466    }
467    /// Whether or not `this` is the sole owner of its data, including weak owners.
468    pub fn is_unique(this: &Self) -> bool {
469        Self::strong_count(this) == 1 && Self::weak_count(this) == 1
470    }
471    /// Returns the slice's raw representation, without altering the associated reference counts.
472    ///
473    /// Failing to reconstruct the `this` using [`Self::from_raw`] will result in the associated `this` being effectively leaked.
474    pub const fn into_raw(this: Self) -> AllocSlice<T, Alloc> {
475        let inner = this.inner;
476        core::mem::forget(this);
477        inner
478    }
479    /// Reconstructs an [`ArcSlice`] from its raw representation, without altering the associated reference counts.
480    ///
481    /// # Safety
482    /// `this` MUST have been obtained using [`Self::into_raw`], and not have been previously used to reconstruct an [`ArcSlice`].
483    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/// A weak reference counted slice.
661#[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    /// Return a strong reference to the slice if it hasn't been destroyed yet.
668    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    /// For types that are [`Copy`], the slice actually remains valid even after all strong references
684    /// have been dropped as long as at least a weak reference lives on.
685    ///
686    /// If you're using this, there are probably design issues in your program...
687    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    /// Attempts to upgrade a weak trait object to a strong one.
849    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]
862/// An owner of an [`Arc<T, Alloc>`] whose pointee can be atomically changed.
863pub struct AtomicArc<T, Alloc: IAlloc> {
864    ptr: AtomicPtr<T>,
865    alloc: core::marker::PhantomData<*const Alloc>,
866}
867// SAFETY: Same constraints as in `std`.
868unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for AtomicArc<T, Alloc> {}
869// SAFETY: Same constraints as in `std`.
870unsafe 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    /// Constructs a new [`AtomicArc`] set to the provided value.
889    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    /// Atomically load the current value.
898    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    /// Atomically store a new value.
909    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    /// Compares `self` with `current` by pointer.
914    /// # Errors
915    /// Returns the new value of `self` if it differs from `current`.
916    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    /// Replace the current value with the new value.
938    /// # Errors
939    /// If `current` no longer points to the same value as `self`, it
940    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}