]> git.lizzy.rs Git - rust.git/blobdiff - src/liballoc/arc.rs
std: Add AsRef/AsMut impls to Box/Rc/Arc
[rust.git] / src / liballoc / arc.rs
index bb2daa2a1d74274e2a52ecb162f3a9752dcf2937..f66f1f13dcb238195b870da826bcf169a3e52713 100644 (file)
@@ -73,6 +73,7 @@
 
 use core::sync::atomic;
 use core::sync::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
+use core::borrow;
 use core::fmt;
 use core::cmp::Ordering;
 use core::mem::{align_of_val, size_of_val};
@@ -136,7 +137,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 /// Weak pointers will not keep the data inside of the `Arc` alive, and can be
 /// used to break cycles between `Arc` pointers.
 #[unsafe_no_drop_flag]
-#[unstable(feature = "arc_weak", reason = "needs FCP", issue = "27718")]
+#[stable(feature = "arc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
@@ -200,7 +201,6 @@ pub fn new(data: T) -> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_unique)]
     /// use std::sync::Arc;
     ///
     /// let x = Arc::new(3);
@@ -211,10 +211,12 @@ pub fn new(data: T) -> Arc<T> {
     /// assert_eq!(Arc::try_unwrap(x), Err(Arc::new(4)));
     /// ```
     #[inline]
-    #[unstable(feature = "arc_unique", reason = "needs FCP", issue = "27718")]
+    #[stable(feature = "arc_unique", since = "1.4.0")]
     pub fn try_unwrap(this: Self) -> Result<T, Self> {
         // See `drop` for why all these atomics are like this
-        if this.inner().strong.compare_and_swap(1, 0, Release) != 1 { return Err(this) }
+        if this.inner().strong.compare_and_swap(1, 0, Release) != 1 {
+            return Err(this)
+        }
 
         atomic::fence(Acquire);
 
@@ -237,14 +239,13 @@ impl<T: ?Sized> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_weak)]
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
     ///
     /// let weak_five = Arc::downgrade(&five);
     /// ```
-    #[unstable(feature = "arc_weak", reason = "needs FCP", issue = "27718")]
+    #[stable(feature = "arc_weak", since = "1.4.0")]
     pub fn downgrade(this: &Self) -> Weak<T> {
         loop {
             // This Relaxed is OK because we're checking the value in the CAS
@@ -252,7 +253,9 @@ pub fn downgrade(this: &Self) -> Weak<T> {
             let cur = this.inner().weak.load(Relaxed);
 
             // check if the weak counter is currently "locked"; if so, spin.
-            if cur == usize::MAX { continue }
+            if cur == usize::MAX {
+                continue
+            }
 
             // NOTE: this code currently ignores the possibility of overflow
             // into usize::MAX; in general both Rc and Arc need to be adjusted
@@ -269,14 +272,16 @@ pub fn downgrade(this: &Self) -> Weak<T> {
 
     /// Get the number of weak references to this value.
     #[inline]
-    #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", issue = "27718")]
+    #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
+               issue = "28356")]
     pub fn weak_count(this: &Self) -> usize {
         this.inner().weak.load(SeqCst) - 1
     }
 
     /// Get the number of strong references to this value.
     #[inline]
-    #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy", issue = "27718")]
+    #[unstable(feature = "arc_counts", reason = "not clearly useful, and racy",
+               issue = "28356")]
     pub fn strong_count(this: &Self) -> usize {
         this.inner().strong.load(SeqCst)
     }
@@ -302,7 +307,9 @@ unsafe fn drop_slow(&mut self) {
 
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            deallocate(ptr as *mut u8, size_of_val(&*ptr), align_of_val(&*ptr))
+            deallocate(ptr as *mut u8,
+                       size_of_val(&*ptr),
+                       align_of_val(&*ptr))
         }
     }
 }
@@ -347,7 +354,9 @@ fn clone(&self) -> Arc<T> {
         // We abort because such a program is incredibly degenerate, and we
         // don't care to support it.
         if old_size > MAX_REFCOUNT {
-            unsafe { abort(); }
+            unsafe {
+                abort();
+            }
         }
 
         Arc { _ptr: self._ptr }
@@ -365,7 +374,8 @@ fn deref(&self) -> &T {
 }
 
 impl<T: Clone> Arc<T> {
-    #[unstable(feature = "arc_unique", reason = "renamed to Arc::make_mut", issue = "27718")]
+    #[unstable(feature = "arc_make_unique", reason = "renamed to Arc::make_mut",
+               issue = "27718")]
     #[deprecated(since = "1.4.0", reason = "renamed to Arc::make_mut")]
     pub fn make_unique(this: &mut Self) -> &mut T {
         Arc::make_mut(this)
@@ -380,7 +390,6 @@ pub fn make_unique(this: &mut Self) -> &mut T {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_unique)]
     /// use std::sync::Arc;
     ///
     /// let mut data = Arc::new(5);
@@ -397,7 +406,7 @@ pub fn make_unique(this: &mut Self) -> &mut T {
     ///
     /// ```
     #[inline]
-    #[unstable(feature = "arc_unique", reason = "needs FCP", issue = "27718")]
+    #[stable(feature = "arc_unique", since = "1.4.0")]
     pub fn make_mut(this: &mut Self) -> &mut T {
         // Note that we hold both a strong reference and a weak reference.
         // Thus, releasing our strong reference only will not, by itself, cause
@@ -459,7 +468,6 @@ impl<T: ?Sized> Arc<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_unique)]
     /// use std::sync::Arc;
     ///
     /// let mut x = Arc::new(3);
@@ -470,7 +478,7 @@ impl<T: ?Sized> Arc<T> {
     /// assert!(Arc::get_mut(&mut x).is_none());
     /// ```
     #[inline]
-    #[unstable(feature = "arc_unique", reason = "needs FCP", issue = "27718")]
+    #[stable(feature = "arc_unique", since = "1.4.0")]
     pub fn get_mut(this: &mut Self) -> Option<&mut T> {
         if this.is_unique() {
             // This unsafety is ok because we're guaranteed that the pointer
@@ -556,7 +564,9 @@ fn drop(&mut self) {
         // Because `fetch_sub` is already atomic, we do not need to synchronize
         // with other threads unless we are going to delete the object. This
         // same logic applies to the below `fetch_sub` to the `weak` count.
-        if self.inner().strong.fetch_sub(1, Release) != 1 { return }
+        if self.inner().strong.fetch_sub(1, Release) != 1 {
+            return
+        }
 
         // This fence is needed to prevent reordering of use of the data and
         // deletion of the data.  Because it is marked `Release`, the decreasing
@@ -578,7 +588,7 @@ fn drop(&mut self) {
         atomic::fence(Acquire);
 
         unsafe {
-            self.drop_slow()
+            self.drop_slow();
         }
     }
 }
@@ -594,7 +604,6 @@ impl<T: ?Sized> Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_weak)]
     /// use std::sync::Arc;
     ///
     /// let five = Arc::new(5);
@@ -603,7 +612,7 @@ impl<T: ?Sized> Weak<T> {
     ///
     /// let strong_five: Option<Arc<_>> = weak_five.upgrade();
     /// ```
-    #[unstable(feature = "arc_weak", reason = "needs FCP", issue = "27718")]
+    #[stable(feature = "arc_weak", since = "1.4.0")]
     pub fn upgrade(&self) -> Option<Arc<T>> {
         // We use a CAS loop to increment the strong count instead of a
         // fetch_add because once the count hits 0 it must never be above 0.
@@ -614,11 +623,15 @@ pub fn upgrade(&self) -> Option<Arc<T>> {
             // "stale" read of 0 is fine), and any other value is
             // confirmed via the CAS below.
             let n = inner.strong.load(Relaxed);
-            if n == 0 { return None }
+            if n == 0 {
+                return None
+            }
 
             // Relaxed is valid for the same reason it is on Arc's Clone impl
             let old = inner.strong.compare_and_swap(n, n + 1, Relaxed);
-            if old == n { return Some(Arc { _ptr: self._ptr }) }
+            if old == n {
+                return Some(Arc { _ptr: self._ptr })
+            }
         }
     }
 
@@ -629,7 +642,7 @@ fn inner(&self) -> &ArcInner<T> {
     }
 }
 
-#[unstable(feature = "arc_weak", reason = "needs FCP", issue = "27718")]
+#[stable(feature = "arc_weak", since = "1.4.0")]
 impl<T: ?Sized> Clone for Weak<T> {
     /// Makes a clone of the `Weak<T>`.
     ///
@@ -638,7 +651,6 @@ impl<T: ?Sized> Clone for Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_weak)]
     /// use std::sync::Arc;
     ///
     /// let weak_five = Arc::downgrade(&Arc::new(5));
@@ -655,7 +667,9 @@ fn clone(&self) -> Weak<T> {
 
         // See comments in Arc::clone() for why we do this (for mem::forget).
         if old_size > MAX_REFCOUNT {
-            unsafe { abort(); }
+            unsafe {
+                abort();
+            }
         }
 
         return Weak { _ptr: self._ptr }
@@ -671,7 +685,6 @@ impl<T: ?Sized> Drop for Weak<T> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(arc_weak)]
     /// use std::sync::Arc;
     ///
     /// {
@@ -708,9 +721,11 @@ fn drop(&mut self) {
         // ref, which can only happen after the lock is released.
         if self.inner().weak.fetch_sub(1, Release) == 1 {
             atomic::fence(Acquire);
-            unsafe { deallocate(ptr as *mut u8,
-                                size_of_val(&*ptr),
-                                align_of_val(&*ptr)) }
+            unsafe {
+                deallocate(ptr as *mut u8,
+                           size_of_val(&*ptr),
+                           align_of_val(&*ptr))
+            }
         }
     }
 }
@@ -730,7 +745,9 @@ impl<T: ?Sized + PartialEq> PartialEq for Arc<T> {
     ///
     /// five == Arc::new(5);
     /// ```
-    fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
+    fn eq(&self, other: &Arc<T>) -> bool {
+        *(*self) == *(*other)
+    }
 
     /// Inequality for two `Arc<T>`s.
     ///
@@ -745,7 +762,9 @@ fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
     ///
     /// five != Arc::new(5);
     /// ```
-    fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
+    fn ne(&self, other: &Arc<T>) -> bool {
+        *(*self) != *(*other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + PartialOrd> PartialOrd for Arc<T> {
@@ -779,7 +798,9 @@ fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
     ///
     /// five < Arc::new(5);
     /// ```
-    fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
+    fn lt(&self, other: &Arc<T>) -> bool {
+        *(*self) < *(*other)
+    }
 
     /// 'Less-than or equal to' comparison for two `Arc<T>`s.
     ///
@@ -794,7 +815,9 @@ fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
     ///
     /// five <= Arc::new(5);
     /// ```
-    fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
+    fn le(&self, other: &Arc<T>) -> bool {
+        *(*self) <= *(*other)
+    }
 
     /// Greater-than comparison for two `Arc<T>`s.
     ///
@@ -809,7 +832,9 @@ fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
     ///
     /// five > Arc::new(5);
     /// ```
-    fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
+    fn gt(&self, other: &Arc<T>) -> bool {
+        *(*self) > *(*other)
+    }
 
     /// 'Greater-than or equal to' comparison for two `Arc<T>`s.
     ///
@@ -824,11 +849,15 @@ fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
     ///
     /// five >= Arc::new(5);
     /// ```
-    fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
+    fn ge(&self, other: &Arc<T>) -> bool {
+        *(*self) >= *(*other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Ord> Ord for Arc<T> {
-    fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
+    fn cmp(&self, other: &Arc<T>) -> Ordering {
+        (**self).cmp(&**other)
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + Eq> Eq for Arc<T> {}
@@ -857,7 +886,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Default> Default for Arc<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn default() -> Arc<T> { Arc::new(Default::default()) }
+    fn default() -> Arc<T> {
+        Arc::new(Default::default())
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1018,7 +1049,7 @@ fn test_dead() {
     #[test]
     fn weak_self_cyclic() {
         struct Cycle {
-            x: Mutex<Option<Weak<Cycle>>>
+            x: Mutex<Option<Weak<Cycle>>>,
         }
 
         let a = Arc::new(Cycle { x: Mutex::new(None) });
@@ -1098,7 +1129,9 @@ fn show_arc() {
 
     // Make sure deriving works with Arc<T>
     #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)]
-    struct Foo { inner: Arc<i32> }
+    struct Foo {
+        inner: Arc<i32>,
+    }
 
     #[test]
     fn test_unsized() {
@@ -1109,3 +1142,14 @@ fn test_unsized() {
         assert!(y.upgrade().is_none());
     }
 }
+
+impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
+    fn borrow(&self) -> &T {
+        &**self
+    }
+}
+
+#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
+impl<T: ?Sized> AsRef<T> for Arc<T> {
+    fn as_ref(&self) -> &T { &**self }
+}