1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use super::*;
use core::ops::{Deref, DerefMut};

/// An uniquely owned `Rc`.
///
/// Useful for constructing `Rc`, since we are certain that when `Rc` is
/// initially created, there is an unique reference. Once initially mutation
/// is done, it can be convert to `Rc` with `shareable()`.
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[repr(transparent)]
pub struct UniqueRc<T: ?Sized>(Rc<T>);

impl<T> UniqueRc<T> {
    /// Constructs a new `UniqueRc`.
    #[inline]
    pub fn new(data: T) -> Self {
        UniqueRc(Rc::new(data))
    }

    /// Convert to a shareable [`Rc<T>`].
    #[inline]
    pub fn shareable(x: Self) -> Rc<T> {
        x.0
    }

    /// Convert to a shareable [`Pin<Rc<T>>`].
    #[inline]
    pub fn shareable_pin(x: Pin<Self>) -> Pin<Rc<T>> {
        unsafe { Pin::new_unchecked(Pin::into_inner_unchecked(x).0) }
    }

    /// Constructs a new `UniqueRc` with uninitialized contents.
    #[inline]
    pub fn new_uninit() -> UniqueRc<MaybeUninit<T>> {
        UniqueRc::new(MaybeUninit::uninit())
    }
}

impl<T> UniqueRc<MaybeUninit<T>> {
    /// Convert to an initialized Rc.
    ///
    /// # Safety
    ///
    /// This function is unsafe as this is equivalent to [`MaybeUninit::assume_init`].
    #[inline]
    pub unsafe fn assume_init(self) -> UniqueRc<T> {
        unsafe { core::mem::transmute(self) }
    }
}

impl<T> Deref for UniqueRc<T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        &*self.0
    }
}

impl<T> DerefMut for UniqueRc<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        let ptr = Rc::as_ptr(&self.0) as *mut T;
        // SAFETY: We know this is unqiuely owned.
        unsafe { &mut *ptr }
    }
}

impl<T> From<UniqueRc<T>> for Pin<UniqueRc<T>> {
    fn from(x: UniqueRc<T>) -> Pin<UniqueRc<T>> {
        // SAFETY: stable address
        unsafe { Pin::new_unchecked(x) }
    }
}

/// An uniquely owned `Arc`.
///
/// Useful for constructing `Arc`, since we are certain that when `Arc` is
/// initially created, there is an unique reference. Once initially mutation
/// is done, it can be convert to `Arc` with `shareable()`.
#[cfg_attr(doc_cfg, doc(cfg(feature = "alloc")))]
#[repr(transparent)]
pub struct UniqueArc<T: ?Sized>(Arc<T>);

impl<T> UniqueArc<T> {
    /// Constructs a new `UniqueArc`.
    #[inline]
    pub fn new(data: T) -> Self {
        UniqueArc(Arc::new(data))
    }

    /// Convert to a shareable [`Arc<T>`].
    #[inline]
    pub fn shareable(x: Self) -> Arc<T> {
        x.0
    }

    /// Convert to a shareable [`Pin<Arc<T>>`].
    #[inline]
    pub fn shareable_pin(x: Pin<Self>) -> Pin<Arc<T>> {
        unsafe { Pin::new_unchecked(Pin::into_inner_unchecked(x).0) }
    }

    /// Constructs a new `UniqueArc` with uninitialized contents.
    #[inline]
    pub fn new_uninit() -> UniqueArc<MaybeUninit<T>> {
        UniqueArc::new(MaybeUninit::uninit())
    }
}

impl<T> UniqueArc<MaybeUninit<T>> {
    /// Convert to an initialized Arc.
    ///
    /// # Safety
    ///
    /// This function is unsafe as this is equivalent to [`MaybeUninit::assume_init`].
    #[inline]
    pub unsafe fn assume_init(self) -> UniqueArc<T> {
        unsafe { core::mem::transmute(self) }
    }
}

impl<T> Deref for UniqueArc<T> {
    type Target = T;
    #[inline]
    fn deref(&self) -> &T {
        &*self.0
    }
}

impl<T> DerefMut for UniqueArc<T> {
    #[inline]
    fn deref_mut(&mut self) -> &mut T {
        let ptr = Arc::as_ptr(&self.0) as *mut T;
        // SAFETY: We know this is unqiuely owned.
        unsafe { &mut *ptr }
    }
}

impl<T> From<UniqueArc<T>> for Pin<UniqueArc<T>> {
    fn from(x: UniqueArc<T>) -> Pin<UniqueArc<T>> {
        // SAFETY: stable address
        unsafe { Pin::new_unchecked(x) }
    }
}