mod polyfill {
use core::ffi::CStr;
#[cfg(feature = "std")]
use std::{ffi::OsStr, path::Path};
use alloc::{rc::Rc, sync::Arc};
pub unsafe trait CloneToUninit {
fn rc_make_mut(rc: &mut Rc<Self>);
fn arc_make_mut(rc: &mut Arc<Self>);
}
macro_rules! impl_ {
($($({$($t:tt)*})? $Self:ty)*) => {$(
unsafe impl$(<$($t)*>)? CloneToUninit for $Self {
fn rc_make_mut(rc: &mut Rc<Self>) {
Rc::make_mut(rc);
}
fn arc_make_mut(rc: &mut Arc<Self>) {
Arc::make_mut(rc);
}
}
)*};
}
impl_! {
str CStr
{T: Clone} [T]
{T: Clone} T
}
#[cfg(feature = "std")]
impl_! {
OsStr Path
}
}
#[cfg(docsrs)]
use core::clone::CloneToUninit;
#[cfg(not(docsrs))]
use polyfill::CloneToUninit;
use alloc::{rc::Rc, sync::Arc};
use stable_deref_trait::StableDeref;
use core::{
ops::{Deref, DerefMut},
panic::{RefUnwindSafe, UnwindSafe},
};
pub trait UniqueExt: Deref {
type Unique;
fn get_unique(this: &mut Self) -> Option<&mut Self::Unique>;
fn make_unique(this: &mut Self) -> &mut Self::Unique
where
Self::Target: CloneToUninit;
}
impl<T: ?Sized> UniqueExt for Rc<T> {
type Unique = UniqueRc<T>;
fn get_unique(this: &mut Self) -> Option<&mut UniqueRc<T>> {
Rc::get_mut(this)
.is_some()
.then(|| unsafe { &mut *(this as *mut Rc<T> as *mut UniqueRc<T>) })
}
fn make_unique(this: &mut Self) -> &mut UniqueRc<T>
where
T: CloneToUninit,
{
#[cfg(not(docsrs))]
T::rc_make_mut(this);
#[cfg(docsrs)]
Rc::make_mut(this);
unsafe { &mut *(this as *mut Rc<T> as *mut UniqueRc<T>) }
}
}
impl<T: ?Sized> UniqueExt for Arc<T> {
type Unique = UniqueArc<T>;
fn get_unique(this: &mut Self) -> Option<&mut UniqueArc<T>> {
Arc::get_mut(this)
.is_some()
.then(|| unsafe { &mut *(this as *mut Arc<T> as *mut UniqueArc<T>) })
}
fn make_unique(this: &mut Self) -> &mut UniqueArc<T>
where
T: CloneToUninit,
{
#[cfg(not(docsrs))]
T::arc_make_mut(this);
#[cfg(docsrs)]
Arc::make_mut(this);
unsafe { &mut *(this as *mut Arc<T> as *mut UniqueArc<T>) }
}
}
#[repr(transparent)]
pub struct UniqueRc<T: ?Sized>(Rc<T>);
#[repr(transparent)]
pub struct UniqueArc<T: ?Sized>(Arc<T>);
impl<T: ?Sized> UnwindSafe for UniqueRc<T> where T: UnwindSafe {}
impl<T: ?Sized> RefUnwindSafe for UniqueRc<T> where T: RefUnwindSafe {}
impl<T: ?Sized> UnwindSafe for UniqueArc<T> where T: UnwindSafe {}
impl<T: ?Sized> RefUnwindSafe for UniqueArc<T> where T: RefUnwindSafe {}
unsafe impl<T: ?Sized> Send for UniqueRc<T> where T: Send {}
unsafe impl<T: ?Sized> Sync for UniqueRc<T> where T: Sync {}
unsafe impl<T: ?Sized> Send for UniqueArc<T> where T: Send {}
unsafe impl<T: ?Sized> Sync for UniqueArc<T> where T: Sync {}
impl<T: ?Sized> Deref for UniqueRc<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*Rc::as_ptr(&self.0) }
}
}
impl<T: ?Sized> DerefMut for UniqueRc<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *(Rc::as_ptr(&self.0) as *mut T) }
}
}
unsafe impl<T: ?Sized> StableDeref for UniqueRc<T> {}
impl<T: ?Sized> Deref for UniqueArc<T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*Arc::as_ptr(&self.0) }
}
}
impl<T: ?Sized> DerefMut for UniqueArc<T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *(Arc::as_ptr(&self.0) as *mut T) }
}
}
unsafe impl<T: ?Sized> StableDeref for UniqueArc<T> {}