Rollup merge of #109026 - joshtriplett:rc-into-inner, r=dtolnay
Introduce `Rc::into_inner`, as a parallel to `Arc::into_inner` Unlike `Arc`, `Rc` doesn't have the same race condition to avoid, but maintaining an equivalent API still makes it easier to work with both `Rc` and `Arc`.
This commit is contained in:
commit
b28775cdcb
@ -681,6 +681,24 @@ impl<T> Rc<T> {
|
|||||||
Err(this)
|
Err(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the inner value, if the `Rc` has exactly one strong reference.
|
||||||
|
///
|
||||||
|
/// Otherwise, [`None`] is returned and the `Rc` is dropped.
|
||||||
|
///
|
||||||
|
/// This will succeed even if there are outstanding weak references.
|
||||||
|
///
|
||||||
|
/// If `Rc::into_inner` is called on every clone of this `Rc`,
|
||||||
|
/// it is guaranteed that exactly one of the calls returns the inner value.
|
||||||
|
/// This means in particular that the inner value is not dropped.
|
||||||
|
///
|
||||||
|
/// This is equivalent to `Rc::try_unwrap(...).ok()`. (Note that these are not equivalent for
|
||||||
|
/// `Arc`, due to race conditions that do not apply to `Rc`.)
|
||||||
|
#[inline]
|
||||||
|
#[unstable(feature = "rc_into_inner", issue = "106894")]
|
||||||
|
pub fn into_inner(this: Self) -> Option<T> {
|
||||||
|
Rc::try_unwrap(this).ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Rc<[T]> {
|
impl<T> Rc<[T]> {
|
||||||
|
@ -151,6 +151,21 @@ fn try_unwrap() {
|
|||||||
assert_eq!(Rc::try_unwrap(x), Ok(5));
|
assert_eq!(Rc::try_unwrap(x), Ok(5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn into_inner() {
|
||||||
|
let x = Rc::new(3);
|
||||||
|
assert_eq!(Rc::into_inner(x), Some(3));
|
||||||
|
|
||||||
|
let x = Rc::new(4);
|
||||||
|
let y = Rc::clone(&x);
|
||||||
|
assert_eq!(Rc::into_inner(x), None);
|
||||||
|
assert_eq!(Rc::into_inner(y), Some(4));
|
||||||
|
|
||||||
|
let x = Rc::new(5);
|
||||||
|
let _w = Rc::downgrade(&x);
|
||||||
|
assert_eq!(Rc::into_inner(x), Some(5));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn into_from_raw() {
|
fn into_from_raw() {
|
||||||
let x = Rc::new(Box::new("hello"));
|
let x = Rc::new(Box::new("hello"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user