@@ -35,7 +35,7 @@ use std::{
35
35
os:: fd:: { AsFd , AsRawFd } ,
36
36
panic:: UnwindSafe ,
37
37
pin:: Pin ,
38
- ptr:: { self , addr_of, addr_of_mut, slice_from_raw_parts_mut, write, NonNull }
38
+ ptr:: { self , addr_of, addr_of_mut, slice_from_raw_parts_mut, write, NonNull } ,
39
39
} ;
40
40
41
41
use core:: sync:: atomic:: AtomicUsize ;
@@ -1189,7 +1189,7 @@ impl<T: ?Sized> Trc<T> {
1189
1189
this. shared . as_ptr ( ) == other. shared . as_ptr ( )
1190
1190
}
1191
1191
1192
- /// Gets the raw pointer to the most inner layer of `Trc<T>`.
1192
+ /// Gets the raw pointer to the most inner layer of `Trc<T>`. This is only valid if there is are at least some strong references.
1193
1193
///
1194
1194
/// # Examples
1195
1195
/// ```
@@ -1698,8 +1698,6 @@ impl<T: Clone + ?Sized> FromIterator<T> for Trc<[T]> {
1698
1698
//impl<T: ?Sized + std::marker::Unsize<U>, U: ?Sized> std::ops::CoerceUnsized<Trc<U>> for Trc<T> {}
1699
1699
//impl<T: ?Sized> std::ops::Receiver for Trc<T> {}
1700
1700
1701
-
1702
-
1703
1701
impl < T : ?Sized > Drop for Weak < T > {
1704
1702
#[ inline]
1705
1703
fn drop ( & mut self ) {
@@ -1763,6 +1761,118 @@ impl<T: ?Sized> Weak<T> {
1763
1761
}
1764
1762
} )
1765
1763
}
1764
+
1765
+ /// Gets the raw pointer to the most inner layer of `Weak<T>`. This is only valid if there is are at least some strong references.
1766
+ ///
1767
+ /// # Examples
1768
+ /// ```
1769
+ /// use trc::Trc;
1770
+ /// use trc::Weak;
1771
+ ///
1772
+ /// let trc = Trc::new(100);
1773
+ /// let weak = Trc::downgrade(&trc);
1774
+ /// println!("{}", Trc::as_ptr(&trc) as usize)
1775
+ /// ```
1776
+ #[ inline]
1777
+ pub fn as_ptr ( this : & Self ) -> * const T {
1778
+ let sharedptr = NonNull :: as_ptr ( this. data ) ;
1779
+ unsafe { addr_of_mut ! ( ( * sharedptr) . data) }
1780
+ }
1781
+
1782
+ /// Converts a `Weak<T>` into `*const T`, without freeing the allocation.
1783
+ /// To avoid a memory leak, be sure to call `from_raw` to reclaim the allocation.
1784
+ ///
1785
+ /// # Examples
1786
+ /// ```
1787
+ /// use trc::Trc;
1788
+ /// use trc::Weak;
1789
+ ///
1790
+ /// let trc = Trc::new(100);
1791
+ /// let weak = Trc::downgrade(&trc);
1792
+ /// let ptr = Trc::into_raw(trc);
1793
+ ///
1794
+ /// assert_eq!(unsafe { *ptr }, 100);
1795
+ ///
1796
+ /// unsafe { Weak::from_raw(ptr) };
1797
+ /// ```
1798
+ pub fn into_raw ( this : Self ) -> * const T {
1799
+ let ptr = Self :: as_ptr ( & this) ;
1800
+
1801
+ forget ( this) ;
1802
+ ptr
1803
+ }
1804
+ }
1805
+
1806
+ impl < T > Weak < T > {
1807
+ /// Converts a `*const T` into `Weak<T>`. The caller must uphold the below safety constraints.
1808
+ /// To avoid a memory leak, be sure to call `from_raw` to reclaim the allocation.
1809
+ ///
1810
+ /// # Safety
1811
+ /// - The given pointer must be a valid pointer to `T` that came from `into_raw`.
1812
+ /// - After `from_raw`, the pointer must not be accessed.
1813
+ ///
1814
+ /// # Examples
1815
+ /// ```
1816
+ /// use trc::Trc;
1817
+ /// use trc::Weak;
1818
+ ///
1819
+ /// let weak = Trc::downgrade(&Trc::new(100));
1820
+ /// let ptr = Weak::into_raw(weak);
1821
+ ///
1822
+ /// assert_eq!(unsafe { *ptr }, 100);
1823
+ ///
1824
+ /// unsafe { Weak::from_raw(ptr) };
1825
+ ///
1826
+ /// let strong = Trc::new("hello".to_owned());
1827
+ ///
1828
+ /// let raw_1 = Weak::into_raw(Trc::downgrade(&strong));
1829
+ /// let raw_2 = Weak::into_raw(Trc::downgrade(&strong));
1830
+ ///
1831
+ /// assert_eq!(3, Trc::weak_count(&strong));
1832
+ ///
1833
+ /// assert_eq!("hello", &*Weak::upgrade(unsafe { &Weak::from_raw(raw_1) }).unwrap());
1834
+ /// assert_eq!(2, Trc::weak_count(&strong));
1835
+ ///
1836
+ /// drop(strong);
1837
+ ///
1838
+ /// // Decrement the last weak count.
1839
+ /// assert!( Weak::upgrade(unsafe {& Weak::from_raw(raw_2) }).is_none());
1840
+ /// ```
1841
+ pub unsafe fn from_raw ( ptr : * const T ) -> Self {
1842
+ let layout = Layout :: new :: < SharedTrcInternal < ( ) > > ( ) ;
1843
+ let n = layout. size ( ) ;
1844
+
1845
+ let data_ptr = ( ptr as * const u8 ) . sub ( n) as * mut SharedTrcInternal < T > ;
1846
+
1847
+ Weak {
1848
+ data : NonNull :: new_unchecked ( data_ptr) ,
1849
+ }
1850
+ }
1851
+
1852
+ /// Create a new, uninitialzed Weak<T>. Calling `Weak::upgrade` on this will always return `None.
1853
+ ///
1854
+ /// # Examples
1855
+ /// ```
1856
+ /// use trc::Weak;
1857
+ /// use core::mem::MaybeUninit;
1858
+ ///
1859
+ /// let weak: Weak<MaybeUninit<i32>> = Weak::new();
1860
+ ///
1861
+ /// assert!(Weak::upgrade(&weak).is_none());
1862
+ /// ```
1863
+ pub fn new ( ) -> Weak < MaybeUninit < T > > {
1864
+ let data = MaybeUninit :: < T > :: uninit ( ) ;
1865
+
1866
+ let shareddata = SharedTrcInternal {
1867
+ atomicref : AtomicUsize :: new ( 0 ) ,
1868
+ weakcount : AtomicUsize :: new ( 0 ) ,
1869
+ data,
1870
+ } ;
1871
+
1872
+ let sbx = Box :: new ( shareddata) ;
1873
+
1874
+ Weak { data : NonNull :: from ( Box :: leak ( sbx) ) }
1875
+ }
1766
1876
}
1767
1877
1768
1878
impl < T : ?Sized > Clone for Weak < T > {
0 commit comments