1
Fork 0

Implement Weak::{strong_count, weak_count}

This commit is contained in:
Jonas Schievink 2018-12-11 00:40:39 +01:00
parent 7425663011
commit 2fe3b3b486
2 changed files with 80 additions and 0 deletions

View file

@ -1284,6 +1284,40 @@ impl<T: ?Sized> Weak<T> {
}
}
/// Gets the number of strong (`Rc`) pointers pointing to this value.
///
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong()
} else {
0
}
}
/// Gets the number of `Weak` pointers pointing to this value.
///
/// If `self` was created using [`Weak::new`], this will return 0. If not,
/// the returned value is at least 1, since `self` still points to the
/// value.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "0")]
pub fn weak_count(&self) -> usize {
if let Some(inner) = self.inner() {
if inner.strong() > 0 {
inner.weak() - 1 // subtract the implicit weak ptr
} else {
inner.weak()
}
} else {
0
}
}
/// Return `None` when the pointer is dangling and there is no allocated `RcBox`,
/// i.e., this `Weak` was created by `Weak::new`
#[inline]
@ -1622,6 +1656,33 @@ mod tests {
drop(c);
}
#[test]
fn weak_counts() {
assert_eq!(Weak::weak_count(&Weak::<u64>::new()), 0);
assert_eq!(Weak::strong_count(&Weak::<u64>::new()), 0);
let a = Rc::new(0);
let w = Rc::downgrade(&a);
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), 1);
let w2 = w.clone();
assert_eq!(Weak::strong_count(&w), 1);
assert_eq!(Weak::weak_count(&w), 2);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), 2);
drop(w);
assert_eq!(Weak::strong_count(&w2), 1);
assert_eq!(Weak::weak_count(&w2), 1);
let a2 = a.clone();
assert_eq!(Weak::strong_count(&w2), 2);
assert_eq!(Weak::weak_count(&w2), 1);
drop(a2);
drop(a);
assert_eq!(Weak::strong_count(&w2), 0);
assert_eq!(Weak::weak_count(&w2), 1);
drop(w2);
}
#[test]
fn try_unwrap() {
let x = Rc::new(3);

View file

@ -1117,6 +1117,25 @@ impl<T: ?Sized> Weak<T> {
}
}
/// Gets the number of strong (`Arc`) pointers pointing to this value.
///
/// If `self` was created using [`Weak::new`], this will return 0.
///
/// [`Weak::new`]: #method.new
#[unstable(feature = "weak_counts", issue = "0")]
pub fn strong_count(&self) -> usize {
if let Some(inner) = self.inner() {
inner.strong.load(SeqCst)
} else {
0
}
}
// Due to the implicit weak pointer added when any strong pointers are
// around, we cannot implement `weak_count` correctly since it necessarily
// requires accessing the strong count and weak count in an unsynchronized
// fashion.
/// Return `None` when the pointer is dangling and there is no allocated `ArcInner`,
/// i.e., this `Weak` was created by `Weak::new`
#[inline]