#![warn(missing_docs, missing_debug_implementations)]
#![no_std]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "erasable")]
use erasable::{Erasable, ErasablePtr, ErasedPtr};
#[cfg(feature = "std")]
use std::{
io,
net::ToSocketAddrs,
panic::{RefUnwindSafe, UnwindSafe},
};
use {
alloc::{
rc::{self, Rc},
sync::{self, Arc},
},
core::{
borrow::Borrow,
cmp::Ordering,
fmt::{
self, Binary, Debug, Display, Formatter, LowerExp, LowerHex, Octal, Pointer, UpperExp,
UpperHex,
},
hash::{Hash, Hasher},
marker::PhantomData,
mem::ManuallyDrop,
ops::Deref,
ptr,
},
};
trait RawRc<T: ?Sized> {
type Weak;
fn as_raw(this: &Self) -> *const T;
unsafe fn clone_raw(this: *const T) -> Self;
unsafe fn downgrade_raw(this: *const T) -> Self::Weak;
}
impl<T: ?Sized> RawRc<T> for Arc<T> {
type Weak = sync::Weak<T>;
#[inline(always)]
fn as_raw(this: &Self) -> *const T {
Arc::into_raw(unsafe { ptr::read(this) })
}
#[inline(always)]
unsafe fn clone_raw(this: *const T) -> Self {
Arc::clone(&ManuallyDrop::new(Arc::from_raw(this)))
}
#[inline(always)]
unsafe fn downgrade_raw(this: *const T) -> sync::Weak<T> {
let this = ManuallyDrop::new(Arc::from_raw(this));
Arc::downgrade(&this)
}
}
impl<T: ?Sized> RawRc<T> for Rc<T> {
type Weak = rc::Weak<T>;
#[inline(always)]
fn as_raw(this: &Self) -> *const T {
Rc::into_raw(unsafe { ptr::read(this) })
}
#[inline(always)]
unsafe fn clone_raw(this: *const T) -> Self {
Rc::clone(&ManuallyDrop::new(Rc::from_raw(this)))
}
#[inline(always)]
unsafe fn downgrade_raw(this: *const T) -> rc::Weak<T> {
let this = ManuallyDrop::new(Rc::from_raw(this));
Rc::downgrade(&this)
}
}
macro_rules! doc_comment {
($doc:expr, $($tt:tt)*) => {
#[doc = $doc]
$($tt)*
};
}
macro_rules! rc_borrow {
($($(#[$m:meta])* $vis:vis struct $RcBorrow:ident = &$rc:ident::$Rc:ident;)*) => {$(
$(#[$m])*
$vis struct $RcBorrow<'a, T: ?Sized> {
raw: ptr::NonNull<T>,
marker: PhantomData<&'a $Rc<T>>
}
unsafe impl<'a, T: ?Sized> Send for $RcBorrow<'a, T> where &'a $Rc<T>: Send {}
unsafe impl<'a, T: ?Sized> Sync for $RcBorrow<'a, T> where &'a $Rc<T>: Sync {}
impl<'a, T: ?Sized> From<&'a $Rc<T>> for $RcBorrow<'a, T> {
fn from(v: &'a $Rc<T>) -> $RcBorrow<'a, T> {
let raw = <$Rc<T> as RawRc<T>>::as_raw(v);
$RcBorrow {
raw: unsafe { ptr::NonNull::new_unchecked(raw as *mut T) },
marker: PhantomData,
}
}
}
impl<'a, T: ?Sized> $RcBorrow<'a, T> {
$vis fn upgrade(this: Self) -> $Rc<T> {
unsafe { <$Rc<T> as RawRc<T>>::clone_raw(this.raw.as_ptr()) }
}
$vis fn to_weak(this: Self) -> $rc::Weak<T> {
unsafe { <$Rc<T> as RawRc<T>>::downgrade_raw(this.raw.as_ptr()) }
}
$vis fn downgrade(this: Self) -> &'a T {
unsafe { &*this.raw.as_ptr() }
}
$vis fn strong_count(this: Self) -> usize {
let rc = unsafe { ManuallyDrop::new($Rc::from_raw(Self::into_raw(this))) };
$Rc::strong_count(&rc)
}
$vis fn weak_count(this: Self) -> usize {
let rc = unsafe { ManuallyDrop::new($Rc::from_raw(Self::into_raw(this))) };
$Rc::weak_count(&rc)
}
$vis fn into_raw(this: Self) -> *const T {
ManuallyDrop::new(this).raw.as_ptr()
}
doc_comment! {
concat!("\
Construct a new `", stringify!($RcBorrow), "` from a raw pointer.
The raw pointer must have been previously returned by a call to
`",stringify!($RcBorrow),"<U>::into_raw` or `",stringify!($Rc),"<U>::as_raw`
where `U` must have the same size and alignment as `T`. This is trivially true
if `U` is `T`. Note that if `U` is not `T`, this is a pointer cast (transmute)
between the two types, and the types must be transmute-compatible."),
$vis unsafe fn from_raw(ptr: *const T) -> Self {
$RcBorrow {
raw: ptr::NonNull::new_unchecked(ptr as *mut T),
marker: PhantomData
}
}
}
}
#[cfg(feature = "erasable")]
unsafe impl<T: ?Sized> ErasablePtr for $RcBorrow<'_, T>
where
T: Erasable
{
#[inline(always)]
fn erase(this: Self) -> ErasedPtr {
T::erase(this.raw)
}
#[inline(always)]
unsafe fn unerase(this: ErasedPtr) -> Self {
$RcBorrow {
raw: T::unerase(this),
marker: PhantomData,
}
}
}
impl<T: ?Sized, U: ?Sized> AsRef<U> for $RcBorrow<'_, T>
where
T: AsRef<U>,
{
fn as_ref(&self) -> &U {
(**self).as_ref()
}
}
impl<T: ?Sized> Binary for $RcBorrow<'_, T>
where
T: Binary,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ?Sized> Borrow<T> for $RcBorrow<'_, T> {
fn borrow(&self) -> &T {
&**self
}
}
impl<T: ?Sized> Clone for $RcBorrow<'_, T> {
fn clone(&self) -> Self { *self }
}
impl<T: ?Sized> Copy for $RcBorrow<'_, T> {}
impl<T: ?Sized> Debug for $RcBorrow<'_, T>
where
T: Debug
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ?Sized> Deref for $RcBorrow<'_, T> {
type Target = T;
fn deref(&self) -> &T {
Self::downgrade(*self)
}
}
impl<T: ?Sized> Display for $RcBorrow<'_, T>
where
T: Display,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ?Sized> Eq for $RcBorrow<'_, T> where T: Eq {}
impl<T: ?Sized> Hash for $RcBorrow<'_, T>
where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
(**self).hash(state)
}
}
impl<T: ?Sized> LowerExp for $RcBorrow<'_, T>
where
T: LowerExp,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ?Sized> LowerHex for $RcBorrow<'_, T>
where
T: LowerHex,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ?Sized> Octal for $RcBorrow<'_, T>
where
T: Octal,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: Ord> Ord for $RcBorrow<'_, T>
where
T: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(**self).cmp(&**other)
}
}
impl<T: ?Sized, O> PartialEq<O> for $RcBorrow<'_, T>
where
O: Deref,
T: PartialEq<O::Target>,
{
fn eq(&self, other: &O) -> bool {
(**self).eq(&*other)
}
}
impl<T: ?Sized, O> PartialOrd<O> for $RcBorrow<'_, T>
where
O: Deref,
T: PartialOrd<O::Target>,
{
fn partial_cmp(&self, other: &O) -> Option<Ordering> {
(**self).partial_cmp(&*other)
}
}
impl<T: ?Sized> Pointer for $RcBorrow<'_, T>
where
T: Pointer,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
#[cfg(feature = "std")]
impl<T: ?Sized> ToSocketAddrs for $RcBorrow<'_, T>
where
T: ToSocketAddrs
{
type Iter = T::Iter;
fn to_socket_addrs(&self) -> io::Result<T::Iter> {
(**self).to_socket_addrs()
}
}
impl<T: ?Sized> Unpin for $RcBorrow<'_, T> {}
#[cfg(feature = "std")]
impl<T: ?Sized> UnwindSafe for $RcBorrow<'_, T> where T: RefUnwindSafe {}
impl<T: ?Sized> UpperExp for $RcBorrow<'_, T>
where
T: UpperExp,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
impl<T: ?Sized> UpperHex for $RcBorrow<'_, T>
where
T: UpperHex,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
(**self).fmt(f)
}
}
)*}
}
rc_borrow! {
#[repr(transparent)]
pub struct ArcBorrow = &sync::Arc;
#[repr(transparent)]
pub struct RcBorrow = &rc::Rc;
}