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.inner which is available at
6// http://www.eclipse.org/legal/epl-2.inner, or the Apache License, Version 2.inner
7// which is available at https://www.apache.org/licenses/LICENSE-2.inner.
8//
9// SPDX-License-Identifier: EPL-2.inner OR Apache-2.inner
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::{unreachable_unchecked, vtable::HasDropVt, Dyn, IStable, IntoDyn};
25
26use super::{
27    vec::{ptr_add, ptr_diff, Vec, VecInner},
28    AllocPtr, AllocSlice, DefaultAllocator, IAlloc,
29};
30
31/// [`alloc::sync::Arc`](https://doc.rust-lang.org/stable/alloc/sync/struct.Arc.html), but ABI-stable.
32#[crate::stabby]
33pub struct Arc<T, Alloc: IAlloc = super::DefaultAllocator> {
34    ptr: AllocPtr<T, Alloc>,
35}
36// SAFETY: Same constraints as in `std`.
37unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Arc<T, Alloc> {}
38// SAFETY: Same constraints as in `std`.
39unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for Arc<T, Alloc> {}
40const USIZE_TOP_BIT: usize = 1 << (core::mem::size_of::<usize>() as i32 * 8 - 1);
41
42#[cfg(not(stabby_default_alloc = "disabled"))]
43impl<T> Arc<T> {
44    /// Attempts to allocate [`Self`], initializing it with `constructor`.
45    ///
46    /// Note that the allocation may or may not be zeroed.
47    ///
48    /// If the allocation fails, the `constructor` will not be run.
49    ///
50    /// # Safety
51    /// `constructor` MUST return `Err(())` if it failed to initialize the passed argument.
52    ///
53    /// # Errors
54    /// Returns the uninitialized allocation if the constructor declares a failure.
55    ///
56    /// # Panics
57    /// If the allocator fails to provide an appropriate allocation.
58    pub unsafe fn make<
59        F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
60    >(
61        constructor: F,
62    ) -> Result<Self, Arc<MaybeUninit<T>>> {
63        // SAFETY: Ensured by parent fn
64        unsafe { Self::make_in(constructor, super::DefaultAllocator::new()) }
65    }
66    /// Attempts to allocate [`Self`] and store `value` in it.
67    ///
68    /// # Panics
69    /// If the allocator fails to provide an appropriate allocation.
70    pub fn new(value: T) -> Self {
71        Self::new_in(value, DefaultAllocator::new())
72    }
73}
74
75impl<T, Alloc: IAlloc> Arc<T, Alloc> {
76    /// Attempts to allocate [`Self`], initializing it with `constructor`.
77    ///
78    /// Note that the allocation may or may not be zeroed.
79    ///
80    /// If the `constructor` panics, the allocated memory will be leaked.
81    ///
82    /// # Errors
83    /// - Returns the `constructor` and the allocator in case of allocation failure.
84    /// - Returns the uninitialized allocated memory if `constructor` fails.
85    ///
86    /// # Safety
87    /// `constructor` MUST return `Err(())` if it failed to initialize the passed argument.
88    ///
89    /// # Notes
90    /// Note that the allocation may or may not be zeroed.
91    #[allow(clippy::type_complexity)]
92    pub unsafe fn try_make_in<
93        F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
94    >(
95        constructor: F,
96        mut alloc: Alloc,
97    ) -> Result<Self, Result<Arc<MaybeUninit<T>, Alloc>, (F, Alloc)>> {
98        let mut ptr = match AllocPtr::alloc(&mut alloc) {
99            Some(mut ptr) => {
100                // SAFETY: `ptr` just got allocated via `AllocPtr::alloc`.
101                let prefix = unsafe { ptr.prefix_mut() };
102                prefix.alloc.write(alloc);
103                prefix.strong = AtomicUsize::new(1);
104                prefix.weak = AtomicUsize::new(1);
105                ptr
106            }
107            None => return Err(Err((constructor, alloc))),
108        };
109        // SAFETY: We are the sole owners of `ptr`
110        constructor(unsafe { ptr.as_mut() }).map_or_else(
111            |()| Err(Ok(Arc { ptr })),
112            |_| {
113                Ok(Self {
114                    // SAFETY: `constructor` reported success.
115                    ptr: unsafe { ptr.assume_init() },
116                })
117            },
118        )
119    }
120    /// Attempts to allocate a [`Self`] and store `value` in it
121    /// # Errors
122    /// Returns `value` and the allocator in case of failure.
123    pub fn try_new_in(value: T, alloc: Alloc) -> Result<Self, (T, Alloc)> {
124        // SAFETY: `ctor` is a valid constructor, always initializing the value.
125        let this = unsafe {
126            Self::try_make_in(
127                |slot: &mut core::mem::MaybeUninit<T>| {
128                    // SAFETY: `value` will be forgotten if the allocation succeeds and `read` is called.
129                    Ok(slot.write(core::ptr::read(&value)))
130                },
131                alloc,
132            )
133        };
134        match this {
135            Ok(this) => {
136                core::mem::forget(value);
137                Ok(this)
138            }
139            Err(Err((_, a))) => Err((value, a)),
140            // SAFETY: the constructor is infallible.
141            Err(Ok(_)) => unsafe { unreachable_unchecked!() },
142        }
143    }
144    /// Attempts to allocate [`Self`], initializing it with `constructor`.
145    ///
146    /// Note that the allocation may or may not be zeroed.
147    ///
148    /// # Errors
149    /// Returns the uninitialized allocated memory if `constructor` fails.
150    ///
151    /// # Safety
152    /// `constructor` MUST return `Err(())` if it failed to initialize the passed argument.
153    ///
154    /// # Panics
155    /// If the allocator fails to provide an appropriate allocation.
156    pub unsafe fn make_in<
157        F: for<'a> FnOnce(&'a mut core::mem::MaybeUninit<T>) -> Result<&'a mut T, ()>,
158    >(
159        constructor: F,
160        alloc: Alloc,
161    ) -> Result<Self, Arc<MaybeUninit<T>, Alloc>> {
162        Self::try_make_in(constructor, alloc).map_err(|e| match e {
163            Ok(uninit) => uninit,
164            Err(_) => panic!("Allocation failed"),
165        })
166    }
167    /// Attempts to allocate [`Self`] and store `value` in it.
168    ///
169    /// # Panics
170    /// If the allocator fails to provide an appropriate allocation.
171    pub fn new_in(value: T, alloc: Alloc) -> Self {
172        // SAFETY: `constructor` fits the spec.
173        let this = unsafe { Self::make_in(move |slot| Ok(slot.write(value)), alloc) };
174        // SAFETY: `constructor` is infallible.
175        unsafe { this.unwrap_unchecked() }
176    }
177
178    /// Returns the pointer to the inner raw allocation, leaking `this`.
179    ///
180    /// Note that the pointer may be dangling if `T` is zero-sized.
181    pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
182        let inner = this.ptr;
183        core::mem::forget(this);
184        inner
185    }
186    /// Constructs `Self` from a raw allocation.
187    /// # Safety
188    /// `this` MUST not be dangling, and have been obtained through [`Self::into_raw`].
189    pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
190        Self { ptr: this }
191    }
192
193    /// Provides a mutable reference to the internals if the strong and weak counts are both 1.
194    pub fn get_mut(this: &mut Self) -> Option<&mut T> {
195        if Self::is_unique(this) {
196            Some(unsafe { Self::get_mut_unchecked(this) })
197        } else {
198            None
199        }
200    }
201
202    /// Provides a mutable reference to the internals without checking.
203    /// # Safety
204    /// If used carelessly, this can cause mutable references and immutable references to the same value to appear,
205    /// causing undefined behaviour.
206    pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T {
207        unsafe { this.ptr.as_mut() }
208    }
209
210    /// Returns the strong count.
211    pub fn strong_count(this: &Self) -> usize {
212        unsafe { this.ptr.prefix() }.strong.load(Ordering::Relaxed)
213    }
214    /// Increments the strong count.
215    /// # Safety
216    /// `this` MUST be a valid pointer derived from `Self`
217    pub unsafe fn increment_strong_count(this: *const T) -> usize {
218        let ptr: AllocPtr<T, Alloc> = AllocPtr {
219            ptr: NonNull::new_unchecked(this.cast_mut()),
220            marker: core::marker::PhantomData,
221        };
222        unsafe { ptr.prefix() }
223            .strong
224            .fetch_add(1, Ordering::Relaxed)
225    }
226    /// Returns the weak count. Note that all Arcs to a same value share a Weak, so the weak count can never be 0.
227    pub fn weak_count(this: &Self) -> usize {
228        unsafe { this.ptr.prefix() }.weak.load(Ordering::Relaxed)
229    }
230    /// Increments the weak count, returning its previous value.
231    pub fn increment_weak_count(this: &Self) -> usize {
232        unsafe { this.ptr.prefix() }
233            .weak
234            .fetch_add(1, Ordering::Relaxed)
235    }
236
237    /// Returns a mutable reference to this `Arc`'s value, cloning that value into a new `Arc` if [`Self::get_mut`] would have failed.
238    pub fn make_mut(&mut self) -> &mut T
239    where
240        T: Clone,
241        Alloc: Clone,
242    {
243        if !Self::is_unique(self) {
244            *self = Self::new_in(
245                T::clone(self),
246                unsafe { self.ptr.prefix().alloc.assume_init_ref() }.clone(),
247            );
248        }
249        unsafe { Self::get_mut_unchecked(self) }
250    }
251
252    /// Whether or not `this` is the sole owner of its data, including weak owners.
253    pub fn is_unique(this: &Self) -> bool {
254        Self::strong_count(this) == 1 && Self::weak_count(this) == 1
255    }
256    /// Attempts the value from the allocation, freeing said allocation.
257    /// # Errors
258    /// Returns `this` if it's not the sole owner of its value.
259    pub fn try_into_inner(this: Self) -> Result<T, Self> {
260        if !Self::is_unique(&this) {
261            Err(this)
262        } else {
263            let ret = unsafe { core::ptr::read(&*this) };
264            _ = unsafe { Weak::<T, Alloc>::from_raw(Arc::into_raw(this)) };
265            Ok(ret)
266        }
267    }
268
269    /// Constructs an additional [`Weak`] pointer to `this`.
270    pub fn downgrade(this: &Self) -> Weak<T, Alloc> {
271        this.into()
272    }
273    #[rustversion::since(1.73)]
274    /// Returns a reference to the allocator used to construct `this`
275    pub const fn allocator(this: &Self) -> &Alloc {
276        unsafe { this.ptr.prefix().alloc.assume_init_ref() }
277    }
278    #[rustversion::before(1.73)]
279    /// Returns a reference to the allocator used to construct `this`
280    pub fn allocator(this: &Self) -> &Alloc {
281        unsafe { this.ptr.prefix().alloc.assume_init_ref() }
282    }
283}
284impl<T, Alloc: IAlloc> Drop for Arc<T, Alloc> {
285    fn drop(&mut self) {
286        if unsafe { self.ptr.prefix() }
287            .strong
288            .fetch_sub(1, Ordering::Relaxed)
289            != 1
290        {
291            return;
292        }
293        unsafe {
294            core::ptr::drop_in_place(self.ptr.as_mut());
295            _ = Weak::<T, Alloc>::from_raw(self.ptr);
296        }
297    }
298}
299impl<T, Alloc: IAlloc> Clone for Arc<T, Alloc> {
300    fn clone(&self) -> Self {
301        unsafe { self.ptr.prefix() }
302            .strong
303            .fetch_add(1, Ordering::Relaxed);
304        Self { ptr: self.ptr }
305    }
306}
307impl<T, Alloc: IAlloc> core::ops::Deref for Arc<T, Alloc> {
308    type Target = T;
309    fn deref(&self) -> &Self::Target {
310        unsafe { self.ptr.as_ref() }
311    }
312}
313
314/// [`alloc::sync::Weak`](https://doc.rust-lang.org/stable/alloc/sync/struct.Weak.html), but ABI-stable.
315#[crate::stabby]
316pub struct Weak<T, Alloc: IAlloc = super::DefaultAllocator> {
317    ptr: AllocPtr<T, Alloc>,
318}
319// SAFETY: Same constraints as in `std`.
320unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for Weak<T, Alloc> {}
321// SAFETY: Same constraints as in `std`.
322unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for Weak<T, Alloc> {}
323impl<T, Alloc: IAlloc> From<&Arc<T, Alloc>> for Arc<T, Alloc> {
324    fn from(value: &Arc<T, Alloc>) -> Self {
325        value.clone()
326    }
327}
328impl<T, Alloc: IAlloc> From<&Weak<T, Alloc>> for Weak<T, Alloc> {
329    fn from(value: &Weak<T, Alloc>) -> Self {
330        value.clone()
331    }
332}
333impl<T, Alloc: IAlloc> From<&Arc<T, Alloc>> for Weak<T, Alloc> {
334    fn from(value: &Arc<T, Alloc>) -> Self {
335        unsafe { value.ptr.prefix() }
336            .weak
337            .fetch_add(1, Ordering::Relaxed);
338        Self { ptr: value.ptr }
339    }
340}
341impl<T, Alloc: IAlloc> Weak<T, Alloc> {
342    /// Returns the pointer to the inner raw allocation, leaking `this`.
343    ///
344    /// Note that the pointer may be dangling if `T` is zero-sized.
345    pub const fn into_raw(this: Self) -> AllocPtr<T, Alloc> {
346        let inner = this.ptr;
347        core::mem::forget(this);
348        inner
349    }
350    /// Constructs `Self` from a raw allocation.
351    /// # Safety
352    /// `this` MUST not be dangling, and have been obtained through [`Self::into_raw`].
353    pub const unsafe fn from_raw(this: AllocPtr<T, Alloc>) -> Self {
354        Self { ptr: this }
355    }
356    /// Attempts to upgrade self into an Arc.
357    pub fn upgrade(&self) -> Option<Arc<T, Alloc>> {
358        let strong = &unsafe { self.ptr.prefix() }.strong;
359        let count = strong.fetch_or(USIZE_TOP_BIT, Ordering::Acquire);
360        match count {
361            0 | USIZE_TOP_BIT => {
362                strong.store(0, Ordering::Release);
363                None
364            }
365            _ => {
366                strong.fetch_add(1, Ordering::Release);
367                strong.fetch_and(!USIZE_TOP_BIT, Ordering::Release);
368                Some(Arc { ptr: self.ptr })
369            }
370        }
371    }
372}
373impl<T, Alloc: IAlloc> Clone for Weak<T, Alloc> {
374    fn clone(&self) -> Self {
375        unsafe { self.ptr.prefix() }
376            .weak
377            .fetch_add(1, Ordering::Relaxed);
378        Self { ptr: self.ptr }
379    }
380}
381impl<T, Alloc: IAlloc> Drop for Weak<T, Alloc> {
382    fn drop(&mut self) {
383        if unsafe { self.ptr.prefix() }
384            .weak
385            .fetch_sub(1, Ordering::Relaxed)
386            != 1
387        {
388            return;
389        }
390        unsafe {
391            let mut alloc = self.ptr.prefix().alloc.assume_init_read();
392            self.ptr.free(&mut alloc)
393        }
394    }
395}
396
397/// A strong reference to a fixed size slice of elements.
398///
399/// Equivalent to `alloc::sync::Arc<[T]>`
400#[crate::stabby]
401pub struct ArcSlice<T, Alloc: IAlloc = super::DefaultAllocator> {
402    pub(crate) inner: AllocSlice<T, Alloc>,
403}
404// SAFETY: Same constraints as in `std`.
405unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for ArcSlice<T, Alloc> {}
406// SAFETY: Same constraints as in `std`.
407unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for ArcSlice<T, Alloc> {}
408// SAFETY: Same constraints as in `std`.
409unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for WeakSlice<T, Alloc> {}
410// SAFETY: Same constraints as in `std`.
411unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for WeakSlice<T, Alloc> {}
412
413impl<T, Alloc: IAlloc> ArcSlice<T, Alloc> {
414    /// Returns the number of elements in the slice.
415    pub const fn len(&self) -> usize {
416        ptr_diff(self.inner.end, self.inner.start.ptr)
417    }
418    /// Returns true if the slice is empty.
419    pub const fn is_empty(&self) -> bool {
420        self.len() == 0
421    }
422    /// Returns a borrow to the slice.
423    pub fn as_slice(&self) -> &[T] {
424        let start = self.inner.start;
425        unsafe { core::slice::from_raw_parts(start.as_ptr(), self.len()) }
426    }
427    /// Returns a mutable borrow to the slice if no other references to it may exist.
428    pub fn as_slice_mut(&mut self) -> Option<&mut [T]> {
429        (ArcSlice::strong_count(self) == 1 && ArcSlice::weak_count(self) == 1)
430            .then(|| unsafe { self.as_slice_mut_unchecked() })
431    }
432    /// Returns a mutable borrow to the slice.
433    /// # Safety
434    /// This can easily create aliased mutable references, which would be undefined behaviour.
435    pub unsafe fn as_slice_mut_unchecked(&mut self) -> &mut [T] {
436        let start = self.inner.start;
437        unsafe { core::slice::from_raw_parts_mut(start.as_ptr(), self.len()) }
438    }
439    /// Returns the strong count to the slice.
440    pub fn strong_count(this: &Self) -> usize {
441        unsafe { this.inner.start.prefix().strong.load(Ordering::Relaxed) }
442    }
443    /// Returns the weak count to the slice.
444    pub fn weak_count(this: &Self) -> usize {
445        unsafe { this.inner.start.prefix().weak.load(Ordering::Relaxed) }
446    }
447    /// Whether or not `this` is the sole owner of its data, including weak owners.
448    pub fn is_unique(this: &Self) -> bool {
449        Self::strong_count(this) == 1 && Self::weak_count(this) == 1
450    }
451    /// Returns the slice's raw representation, without altering the associated reference counts.
452    ///
453    /// Failing to reconstruct the `this` using [`Self::from_raw`] will result in the associated `this` being effectively leaked.
454    pub const fn into_raw(this: Self) -> AllocSlice<T, Alloc> {
455        let inner = this.inner;
456        core::mem::forget(this);
457        inner
458    }
459    /// Reconstructs an [`ArcSlice`] from its raw representation, without altering the associated reference counts.
460    ///
461    /// # Safety
462    /// `this` MUST have been obtained using [`Self::into_raw`], and not have been previously used to reconstruct an [`ArcSlice`].
463    pub const unsafe fn from_raw(this: AllocSlice<T, Alloc>) -> Self {
464        Self { inner: this }
465    }
466}
467impl<T, Alloc: IAlloc> core::ops::Deref for ArcSlice<T, Alloc> {
468    type Target = [T];
469    fn deref(&self) -> &Self::Target {
470        self.as_slice()
471    }
472}
473impl<T, Alloc: IAlloc> Clone for ArcSlice<T, Alloc> {
474    fn clone(&self) -> Self {
475        unsafe { self.inner.start.prefix() }
476            .strong
477            .fetch_add(1, Ordering::Relaxed);
478        Self { inner: self.inner }
479    }
480}
481impl<T, Alloc: IAlloc> From<Arc<T, Alloc>> for ArcSlice<T, Alloc> {
482    fn from(mut value: Arc<T, Alloc>) -> Self {
483        unsafe { value.ptr.prefix_mut() }.capacity = AtomicUsize::new(1);
484        Self {
485            inner: AllocSlice {
486                start: value.ptr,
487                end: ptr_add(value.ptr.ptr, 1),
488            },
489        }
490    }
491}
492impl<T: Copy, Alloc: IAlloc + Default> From<&[T]> for ArcSlice<T, Alloc> {
493    fn from(value: &[T]) -> Self {
494        Vec::from(value).into()
495    }
496}
497impl<T, Alloc: IAlloc> From<Vec<T, Alloc>> for ArcSlice<T, Alloc> {
498    fn from(value: Vec<T, Alloc>) -> Self {
499        let (mut slice, capacity, mut alloc) = value.into_raw_components();
500        if capacity != 0 {
501            unsafe {
502                slice.start.prefix_mut().strong = AtomicUsize::new(1);
503                slice.start.prefix_mut().weak = AtomicUsize::new(1);
504                slice.start.prefix_mut().capacity = AtomicUsize::new(capacity);
505                slice.start.prefix_mut().alloc.write(alloc);
506            }
507            Self {
508                inner: AllocSlice {
509                    start: slice.start,
510                    end: slice.end,
511                },
512            }
513        } else {
514            let mut start = AllocPtr::alloc_array(&mut alloc, 0).expect("Allocation failed");
515            unsafe {
516                start.prefix_mut().strong = AtomicUsize::new(1);
517                start.prefix_mut().weak = AtomicUsize::new(1);
518                start.prefix_mut().capacity = if core::mem::size_of::<T>() != 0 {
519                    AtomicUsize::new(0)
520                } else {
521                    AtomicUsize::new(ptr_diff(
522                        core::mem::transmute::<usize, NonNull<u8>>(usize::MAX),
523                        start.ptr.cast::<u8>(),
524                    ))
525                };
526                slice.start.prefix_mut().alloc.write(alloc);
527            }
528            Self {
529                inner: AllocSlice {
530                    start,
531                    end: ptr_add(start.ptr.cast::<u8>(), slice.len()).cast(),
532                },
533            }
534        }
535    }
536}
537impl<T, Alloc: IAlloc> TryFrom<ArcSlice<T, Alloc>> for Vec<T, Alloc> {
538    type Error = ArcSlice<T, Alloc>;
539    fn try_from(value: ArcSlice<T, Alloc>) -> Result<Self, Self::Error> {
540        if core::mem::size_of::<T>() == 0 || !ArcSlice::is_unique(&value) {
541            Err(value)
542        } else {
543            unsafe {
544                let ret = Vec {
545                    inner: VecInner {
546                        start: value.inner.start,
547                        end: value.inner.end,
548                        capacity: ptr_add(
549                            value.inner.start.ptr,
550                            value.inner.start.prefix().capacity.load(Ordering::Relaxed),
551                        ),
552                        alloc: value.inner.start.prefix().alloc.assume_init_read(),
553                    },
554                };
555                core::mem::forget(value);
556                Ok(ret)
557            }
558        }
559    }
560}
561impl<T: Eq, Alloc: IAlloc> Eq for ArcSlice<T, Alloc> {}
562impl<T: PartialEq, Alloc: IAlloc> PartialEq for ArcSlice<T, Alloc> {
563    fn eq(&self, other: &Self) -> bool {
564        self.as_slice() == other.as_slice()
565    }
566}
567impl<T: Ord, Alloc: IAlloc> Ord for ArcSlice<T, Alloc> {
568    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
569        self.as_slice().cmp(other.as_slice())
570    }
571}
572impl<T: PartialOrd, Alloc: IAlloc> PartialOrd for ArcSlice<T, Alloc> {
573    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
574        self.as_slice().partial_cmp(other.as_slice())
575    }
576}
577impl<T: Hash, Alloc: IAlloc> Hash for ArcSlice<T, Alloc> {
578    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
579        self.as_slice().hash(state)
580    }
581}
582impl<T, Alloc: IAlloc> Drop for ArcSlice<T, Alloc> {
583    fn drop(&mut self) {
584        if unsafe { self.inner.start.prefix() }
585            .strong
586            .fetch_sub(1, Ordering::Relaxed)
587            != 1
588        {
589            return;
590        }
591        unsafe { core::ptr::drop_in_place(self.as_slice_mut_unchecked()) }
592        _ = WeakSlice { inner: self.inner };
593    }
594}
595impl<T: Debug, Alloc: IAlloc> Debug for ArcSlice<T, Alloc> {
596    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
597        self.as_slice().fmt(f)
598    }
599}
600impl<T: core::fmt::LowerHex, Alloc: IAlloc> core::fmt::LowerHex for ArcSlice<T, Alloc> {
601    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
602        let mut first = true;
603        for item in self {
604            if !first {
605                f.write_str(":")?;
606            }
607            first = false;
608            core::fmt::LowerHex::fmt(item, f)?;
609        }
610        Ok(())
611    }
612}
613impl<T: core::fmt::UpperHex, Alloc: IAlloc> core::fmt::UpperHex for ArcSlice<T, Alloc> {
614    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
615        let mut first = true;
616        for item in self {
617            if !first {
618                f.write_str(":")?;
619            }
620            first = false;
621            core::fmt::UpperHex::fmt(item, f)?;
622        }
623        Ok(())
624    }
625}
626impl<'a, T, Alloc: IAlloc> IntoIterator for &'a ArcSlice<T, Alloc> {
627    type Item = &'a T;
628    type IntoIter = core::slice::Iter<'a, T>;
629    fn into_iter(self) -> Self::IntoIter {
630        self.as_slice().iter()
631    }
632}
633
634impl<T, Alloc: IAlloc + Default> FromIterator<T> for ArcSlice<T, Alloc> {
635    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
636        Vec::from_iter(iter).into()
637    }
638}
639
640/// A weak reference counted slice.
641#[crate::stabby]
642pub struct WeakSlice<T, Alloc: IAlloc = super::DefaultAllocator> {
643    pub(crate) inner: AllocSlice<T, Alloc>,
644}
645
646impl<T, Alloc: IAlloc> WeakSlice<T, Alloc> {
647    /// Return a strong reference to the slice if it hasn't been destroyed yet.
648    pub fn upgrade(&self) -> Option<ArcSlice<T, Alloc>> {
649        let strong = &unsafe { self.inner.start.prefix() }.strong;
650        let count = strong.fetch_or(USIZE_TOP_BIT, Ordering::Acquire);
651        match count {
652            0 | USIZE_TOP_BIT => {
653                strong.store(0, Ordering::Release);
654                None
655            }
656            _ => {
657                strong.fetch_add(1, Ordering::Release);
658                strong.fetch_and(!USIZE_TOP_BIT, Ordering::Release);
659                Some(ArcSlice { inner: self.inner })
660            }
661        }
662    }
663    /// For types that are [`Copy`], the slice actually remains valid even after all strong references
664    /// have been dropped as long as at least a weak reference lives on.
665    ///
666    /// If you're using this, there are probably design issues in your program...
667    pub fn force_upgrade(&self) -> ArcSlice<T, Alloc>
668    where
669        T: Copy,
670    {
671        let strong = &unsafe { self.inner.start.prefix() }.strong;
672        match strong.fetch_add(1, Ordering::Release) {
673            0 | USIZE_TOP_BIT => {
674                unsafe { self.inner.start.prefix() }
675                    .weak
676                    .fetch_add(1, Ordering::Relaxed);
677            }
678            _ => {}
679        }
680        ArcSlice { inner: self.inner }
681    }
682}
683impl<T, Alloc: IAlloc> Clone for WeakSlice<T, Alloc> {
684    fn clone(&self) -> Self {
685        unsafe { self.inner.start.prefix() }
686            .weak
687            .fetch_add(1, Ordering::Relaxed);
688        Self { inner: self.inner }
689    }
690}
691impl<T, Alloc: IAlloc> From<&ArcSlice<T, Alloc>> for ArcSlice<T, Alloc> {
692    fn from(value: &ArcSlice<T, Alloc>) -> Self {
693        value.clone()
694    }
695}
696impl<T, Alloc: IAlloc> From<&WeakSlice<T, Alloc>> for WeakSlice<T, Alloc> {
697    fn from(value: &WeakSlice<T, Alloc>) -> Self {
698        value.clone()
699    }
700}
701impl<T, Alloc: IAlloc> From<&ArcSlice<T, Alloc>> for WeakSlice<T, Alloc> {
702    fn from(value: &ArcSlice<T, Alloc>) -> Self {
703        unsafe { value.inner.start.prefix() }
704            .weak
705            .fetch_add(1, Ordering::Relaxed);
706        Self { inner: value.inner }
707    }
708}
709impl<T, Alloc: IAlloc> Drop for WeakSlice<T, Alloc> {
710    fn drop(&mut self) {
711        if unsafe { self.inner.start.prefix() }
712            .weak
713            .fetch_sub(1, Ordering::Relaxed)
714            != 1
715        {
716            return;
717        }
718        let mut alloc = unsafe { self.inner.start.prefix().alloc.assume_init_read() };
719        unsafe { self.inner.start.free(&mut alloc) }
720    }
721}
722pub use super::string::{ArcStr, WeakStr};
723
724impl<T, Alloc: IAlloc> crate::IPtr for Arc<T, Alloc> {
725    unsafe fn as_ref<U: Sized>(&self) -> &U {
726        self.ptr.cast().as_ref()
727    }
728}
729impl<T, Alloc: IAlloc> crate::IPtrClone for Arc<T, Alloc> {
730    fn clone(this: &Self) -> Self {
731        this.clone()
732    }
733}
734
735impl<T, Alloc: IAlloc> crate::IPtrTryAsMut for Arc<T, Alloc> {
736    unsafe fn try_as_mut<U: Sized>(&mut self) -> Option<&mut U> {
737        Self::get_mut(self).map(|r| unsafe { core::mem::transmute::<&mut T, &mut U>(r) })
738    }
739}
740impl<T, Alloc: IAlloc> crate::IPtrOwned for Arc<T, Alloc> {
741    fn drop(this: &mut core::mem::ManuallyDrop<Self>, drop: unsafe extern "C" fn(&mut ())) {
742        if unsafe { this.ptr.prefix() }
743            .strong
744            .fetch_sub(1, Ordering::Relaxed)
745            != 1
746        {
747            return;
748        }
749        unsafe {
750            drop(this.ptr.cast().as_mut());
751            _ = Weak::<T, Alloc>::from_raw(this.ptr);
752        }
753    }
754}
755
756impl<T, Alloc: IAlloc> IntoDyn for Arc<T, Alloc> {
757    type Anonymized = Arc<(), Alloc>;
758    type Target = T;
759    fn anonimize(self) -> Self::Anonymized {
760        let original_prefix = self.ptr.prefix_ptr();
761        let anonymized = unsafe { core::mem::transmute::<Self, Self::Anonymized>(self) };
762        let anonymized_prefix = anonymized.ptr.prefix_ptr();
763        assert_eq!(anonymized_prefix, original_prefix, "The allocation prefix was lost in anonimization, this is definitely a bug, please report it.");
764        anonymized
765    }
766}
767
768impl<T, Alloc: IAlloc> crate::IPtrOwned for Weak<T, Alloc> {
769    fn drop(this: &mut core::mem::ManuallyDrop<Self>, drop: unsafe extern "C" fn(&mut ())) {
770        if unsafe { this.ptr.prefix() }
771            .strong
772            .fetch_sub(1, Ordering::Relaxed)
773            != 1
774        {
775            return;
776        }
777        unsafe {
778            drop(this.ptr.cast().as_mut());
779            _ = Weak::<T, Alloc>::from_raw(this.ptr);
780        }
781    }
782}
783
784impl<T, Alloc: IAlloc> crate::IPtrClone for Weak<T, Alloc> {
785    fn clone(this: &Self) -> Self {
786        this.clone()
787    }
788}
789
790impl<T, Alloc: IAlloc> IntoDyn for Weak<T, Alloc> {
791    type Anonymized = Weak<(), Alloc>;
792    type Target = T;
793    fn anonimize(self) -> Self::Anonymized {
794        let original_prefix = self.ptr.prefix_ptr();
795        let anonymized = unsafe { core::mem::transmute::<Self, Self::Anonymized>(self) };
796        let anonymized_prefix = anonymized.ptr.prefix_ptr();
797        assert_eq!(anonymized_prefix, original_prefix, "The allocation prefix was lost in anonimization, this is definitely a bug, please report it.");
798        anonymized
799    }
800}
801
802impl<'a, Vt: HasDropVt, Alloc: IAlloc> From<&'a Dyn<'a, Arc<(), Alloc>, Vt>>
803    for Dyn<'a, Weak<(), Alloc>, Vt>
804{
805    fn from(value: &'a Dyn<'a, Arc<(), Alloc>, Vt>) -> Self {
806        Self {
807            ptr: ManuallyDrop::new(Arc::downgrade(&value.ptr)),
808            vtable: value.vtable,
809            unsend: core::marker::PhantomData,
810        }
811    }
812}
813impl<'a, Vt: HasDropVt + IStable, Alloc: IAlloc> Dyn<'a, Weak<(), Alloc>, Vt> {
814    /// Attempts to upgrade a weak trait object to a strong one.
815    pub fn upgrade(self) -> crate::option::Option<Dyn<'a, Arc<(), Alloc>, Vt>> {
816        let Some(ptr) = self.ptr.upgrade() else {
817            return crate::option::Option::None();
818        };
819        crate::option::Option::Some(Dyn {
820            ptr: ManuallyDrop::new(ptr),
821            vtable: self.vtable,
822            unsend: core::marker::PhantomData,
823        })
824    }
825}
826
827#[crate::stabby]
828/// An owner of an [`Arc<T, Alloc>`] whose pointee can be atomically changed.
829pub struct AtomicArc<T, Alloc: IAlloc> {
830    ptr: AtomicPtr<T>,
831    alloc: core::marker::PhantomData<*const Alloc>,
832}
833// SAFETY: Same constraints as in `std`.
834unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Send for AtomicArc<T, Alloc> {}
835// SAFETY: Same constraints as in `std`.
836unsafe impl<T: Send + Sync, Alloc: IAlloc + Send + Sync> Sync for AtomicArc<T, Alloc> {}
837
838impl<T, Alloc: IAlloc> Drop for AtomicArc<T, Alloc> {
839    fn drop(&mut self) {
840        let ptr = self.ptr.load(Ordering::Relaxed);
841        if let Some(ptr) = NonNull::new(ptr) {
842            unsafe {
843                Arc::<T, Alloc>::from_raw(AllocPtr {
844                    ptr,
845                    marker: PhantomData,
846                })
847            };
848        }
849    }
850}
851
852type MaybeArc<T, Alloc> = Option<Arc<T, Alloc>>;
853impl<T, Alloc: IAlloc> AtomicArc<T, Alloc> {
854    /// Constructs a new [`AtomicArc`] set to the provided value.
855    pub const fn new(value: MaybeArc<T, Alloc>) -> Self {
856        Self {
857            ptr: AtomicPtr::new(unsafe {
858                core::mem::transmute::<Option<Arc<T, Alloc>>, *mut T>(value)
859            }),
860            alloc: PhantomData,
861        }
862    }
863    /// Atomically load the current value.
864    pub fn load(&self, order: Ordering) -> MaybeArc<T, Alloc> {
865        let ptr = NonNull::new(self.ptr.load(order))?;
866        unsafe {
867            Arc::<T, Alloc>::increment_strong_count(ptr.as_ptr());
868            Some(Arc::from_raw(AllocPtr {
869                ptr,
870                marker: PhantomData,
871            }))
872        }
873    }
874    /// Atomically store a new value.
875    pub fn store(&self, value: MaybeArc<T, Alloc>, order: Ordering) {
876        let ptr = value.map_or(core::ptr::null_mut(), |value| Arc::into_raw(value).as_ptr());
877        self.ptr.store(ptr, order)
878    }
879    /// Compares `self` with `current` by pointer.
880    /// # Errors
881    /// Returns the new value of `self` if it differs from `current`.
882    pub fn is(
883        &self,
884        current: Option<&Arc<T, Alloc>>,
885        order: Ordering,
886    ) -> Result<(), MaybeArc<T, Alloc>> {
887        let ptr = NonNull::new(self.ptr.load(order));
888        match (ptr, current) {
889            (None, None) => Ok(()),
890            (None, _) => Err(None),
891            (Some(ptr), Some(current)) if core::ptr::eq(ptr.as_ptr(), current.ptr.as_ptr()) => {
892                Ok(())
893            }
894            (Some(ptr), _) => unsafe {
895                Arc::<T, Alloc>::increment_strong_count(ptr.as_ptr());
896                Err(Some(Arc::from_raw(AllocPtr {
897                    ptr,
898                    marker: PhantomData,
899                })))
900            },
901        }
902    }
903    /// Replace the current value with the new value.
904    /// # Errors
905    /// If `current` no longer points to the same value as `self`, it
906    pub fn compare_exchange(
907        &self,
908        current: Option<&Arc<T, Alloc>>,
909        new: MaybeArc<T, Alloc>,
910        success: Ordering,
911        failure: Ordering,
912    ) -> Result<MaybeArc<T, Alloc>, MaybeArc<T, Alloc>> {
913        let current = current.map_or(core::ptr::null_mut(), |value| value.ptr.ptr.as_ptr());
914        let new = new.map_or(core::ptr::null_mut(), |value| Arc::into_raw(value).as_ptr());
915        match self.ptr.compare_exchange(current, new, success, failure) {
916            Ok(ptr) => Ok(NonNull::new(ptr).map(|ptr| unsafe {
917                Arc::from_raw(AllocPtr {
918                    ptr,
919                    marker: PhantomData,
920                })
921            })),
922            Err(ptr) => Err(NonNull::new(ptr).map(|ptr| unsafe {
923                Arc::<T, Alloc>::increment_strong_count(ptr.as_ptr());
924                Arc::from_raw(AllocPtr {
925                    ptr,
926                    marker: PhantomData,
927                })
928            })),
929        }
930    }
931}
932
933#[cfg(feature = "serde")]
934mod serde_impl {
935    use super::*;
936    use crate::alloc::IAlloc;
937    use serde::{Deserialize, Serialize};
938    impl<T: Serialize, Alloc: IAlloc> Serialize for ArcSlice<T, Alloc> {
939        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
940        where
941            S: serde::Serializer,
942        {
943            let slice: &[T] = self;
944            slice.serialize(serializer)
945        }
946    }
947    impl<'a, T: Deserialize<'a>, Alloc: IAlloc + Default> Deserialize<'a> for ArcSlice<T, Alloc> {
948        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
949        where
950            D: serde::Deserializer<'a>,
951        {
952            crate::alloc::vec::Vec::deserialize(deserializer).map(Into::into)
953        }
954    }
955    impl<Alloc: IAlloc> Serialize for ArcStr<Alloc> {
956        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
957        where
958            S: serde::Serializer,
959        {
960            let slice: &str = self;
961            slice.serialize(serializer)
962        }
963    }
964    impl<'a, Alloc: IAlloc + Default> Deserialize<'a> for ArcStr<Alloc> {
965        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
966        where
967            D: serde::Deserializer<'a>,
968        {
969            crate::alloc::string::String::deserialize(deserializer).map(Into::into)
970        }
971    }
972}