diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2021-04-07 13:07:06 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-07 13:07:06 +0200 |
| commit | 505846ec07c1303369358a1c3358c7d7ee0ca12e (patch) | |
| tree | 54841e777a4af849b43003dcdb19b4e22e781a17 /library/alloc/src | |
| parent | 1c158b6a8b440f826d952c3a8f42bdc3f77a5ac1 (diff) | |
| parent | a591d7ab9004f5b653b6f135c4a79bd3104a44a4 (diff) | |
| download | rust-505846ec07c1303369358a1c3358c7d7ee0ca12e.tar.gz rust-505846ec07c1303369358a1c3358c7d7ee0ca12e.zip | |
Rollup merge of #83476 - mystor:rc_mutate_strong_count, r=m-ou-se
Add strong_count mutation methods to Rc The corresponding methods were stabilized on `Arc` in #79285 (tracking: #71983). This patch implements and stabilizes identical methods on the `Rc` types as well.
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/rc.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 2ee5e6c791c..c81ababf151 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -910,6 +910,73 @@ impl<T: ?Sized> Rc<T> { this.inner().strong() } + /// Increments the strong reference count on the `Rc<T>` associated with the + /// provided pointer by one. + /// + /// # Safety + /// + /// The pointer must have been obtained through `Rc::into_raw`, and the + /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// least 1) for the duration of this method. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let five = Rc::new(5); + /// + /// unsafe { + /// let ptr = Rc::into_raw(five); + /// Rc::increment_strong_count(ptr); + /// + /// let five = Rc::from_raw(ptr); + /// assert_eq!(2, Rc::strong_count(&five)); + /// } + /// ``` + #[inline] + #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] + pub unsafe fn increment_strong_count(ptr: *const T) { + // Retain Rc, but don't touch refcount by wrapping in ManuallyDrop + let rc = unsafe { mem::ManuallyDrop::new(Rc::<T>::from_raw(ptr)) }; + // Now increase refcount, but don't drop new refcount either + let _rc_clone: mem::ManuallyDrop<_> = rc.clone(); + } + + /// Decrements the strong reference count on the `Rc<T>` associated with the + /// provided pointer by one. + /// + /// # Safety + /// + /// The pointer must have been obtained through `Rc::into_raw`, and the + /// associated `Rc` instance must be valid (i.e. the strong count must be at + /// least 1) when invoking this method. This method can be used to release + /// the final `Rc` and backing storage, but **should not** be called after + /// the final `Rc` has been released. + /// + /// # Examples + /// + /// ``` + /// use std::rc::Rc; + /// + /// let five = Rc::new(5); + /// + /// unsafe { + /// let ptr = Rc::into_raw(five); + /// Rc::increment_strong_count(ptr); + /// + /// let five = Rc::from_raw(ptr); + /// assert_eq!(2, Rc::strong_count(&five)); + /// Rc::decrement_strong_count(ptr); + /// assert_eq!(1, Rc::strong_count(&five)); + /// } + /// ``` + #[inline] + #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] + pub unsafe fn decrement_strong_count(ptr: *const T) { + unsafe { mem::drop(Rc::from_raw(ptr)) }; + } + /// Returns `true` if there are no other `Rc` or [`Weak`] pointers to /// this allocation. #[inline] |
