about summary refs log tree commit diff
path: root/src/liballoc/rc.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-23 20:26:58 +0000
committerbors <bors@rust-lang.org>2014-11-23 20:26:58 +0000
commit4e5259503cd8aac9905c7ac6d68d0c4caab1d28c (patch)
tree9d93d055fa5aa82480c4b5771aba4cca5efdfc9b /src/liballoc/rc.rs
parent220b99b148559e8996a1dbd279e8ca190bf94b2e (diff)
parentd6b023a46750d6c2df919908bd0f1460d3d9c8a6 (diff)
downloadrust-4e5259503cd8aac9905c7ac6d68d0c4caab1d28c.tar.gz
rust-4e5259503cd8aac9905c7ac6d68d0c4caab1d28c.zip
auto merge of #19242 : jakub-/rust/roll-up, r=jakub-
Diffstat (limited to 'src/liballoc/rc.rs')
-rw-r--r--src/liballoc/rc.rs49
1 files changed, 46 insertions, 3 deletions
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 501f915461a..df84ac9aec9 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -213,6 +213,16 @@ impl<T> Rc<T> {
     }
 }
 
+/// Get the number of weak references to this value.
+#[inline]
+#[experimental]
+pub fn weak_count<T>(this: &Rc<T>) -> uint { this.weak() - 1 }
+
+/// Get the number of strong references to this value.
+#[inline]
+#[experimental]
+pub fn strong_count<T>(this: &Rc<T>) -> uint { this.strong() }
+
 /// Returns true if the `Rc` currently has unique ownership.
 ///
 /// Unique ownership means that there are no other `Rc` or `Weak` values
@@ -220,8 +230,7 @@ impl<T> Rc<T> {
 #[inline]
 #[experimental]
 pub fn is_unique<T>(rc: &Rc<T>) -> bool {
-    // note that we hold both a strong and a weak reference
-    rc.strong() == 1 && rc.weak() == 1
+    weak_count(rc) == 0 && strong_count(rc) == 1
 }
 
 /// Unwraps the contained value if the `Rc` has unique ownership.
@@ -489,7 +498,7 @@ impl<T> RcBoxPtr<T> for Weak<T> {
 #[cfg(test)]
 #[allow(experimental)]
 mod tests {
-    use super::{Rc, Weak};
+    use super::{Rc, Weak, weak_count, strong_count};
     use std::cell::RefCell;
     use std::option::{Option, Some, None};
     use std::result::{Err, Ok};
@@ -567,6 +576,40 @@ mod tests {
     }
 
     #[test]
+    fn test_strong_count() {
+        let a = Rc::new(0u32);
+        assert!(strong_count(&a) == 1);
+        let w = a.downgrade();
+        assert!(strong_count(&a) == 1);
+        let b = w.upgrade().expect("upgrade of live rc failed");
+        assert!(strong_count(&b) == 2);
+        assert!(strong_count(&a) == 2);
+        drop(w);
+        drop(a);
+        assert!(strong_count(&b) == 1);
+        let c = b.clone();
+        assert!(strong_count(&b) == 2);
+        assert!(strong_count(&c) == 2);
+    }
+
+    #[test]
+    fn test_weak_count() {
+        let a = Rc::new(0u32);
+        assert!(strong_count(&a) == 1);
+        assert!(weak_count(&a) == 0);
+        let w = a.downgrade();
+        assert!(strong_count(&a) == 1);
+        assert!(weak_count(&a) == 1);
+        drop(w);
+        assert!(strong_count(&a) == 1);
+        assert!(weak_count(&a) == 0);
+        let c = a.clone();
+        assert!(strong_count(&a) == 2);
+        assert!(weak_count(&a) == 0);
+        drop(c);
+    }
+
+    #[test]
     fn try_unwrap() {
         let x = Rc::new(3u);
         assert_eq!(super::try_unwrap(x), Ok(3u));