about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-10-28 08:01:52 +0000
committerbors <bors@rust-lang.org>2014-10-28 08:01:52 +0000
commitfaed6489dacf334a84fa890b385363bca0d865da (patch)
tree0d7a07246cdb36ff8455b644ce5e96a095ac0f2c
parent3f37e2efac1d04c7a3b17e5dde1453c1c0190eb1 (diff)
parent35ad00d2ec63432ff4a5b4a0def8c9eae46125b6 (diff)
downloadrust-faed6489dacf334a84fa890b385363bca0d865da.tar.gz
rust-faed6489dacf334a84fa890b385363bca0d865da.zip
auto merge of #18127 : alexcrichton/rust/deriving-arc, r=aturon
This adds impls of Eq/Ord/PartialEq/PartialOrd/Show/Default to Arc<T>, and it
also removes the `Send + Sync` bound on the `Clone` impl of Arc to make it more
deriving-friendly. The `Send + Sync` requirement is still enforce on
construction, of course!
-rw-r--r--src/liballoc/arc.rs72
-rw-r--r--src/libserialize/serialize.rs2
2 files changed, 54 insertions, 20 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 0e62fbb0144..cc6f2d76eaf 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -16,13 +16,15 @@
 use core::atomic;
 use core::clone::Clone;
 use core::fmt::{mod, Show};
+use core::cmp::{Eq, Ord, PartialEq, PartialOrd, Ordering};
+use core::default::Default;
 use core::kinds::{Sync, Send};
 use core::mem::{min_align_of, size_of, drop};
 use core::mem;
 use core::ops::{Drop, Deref};
 use core::option::{Some, None, Option};
-use core::ptr;
 use core::ptr::RawPtr;
+use core::ptr;
 use heap::deallocate;
 
 /// An atomically reference counted wrapper for shared state.
@@ -92,16 +94,6 @@ impl<T: Sync + Send> Arc<T> {
         Arc { _ptr: unsafe { mem::transmute(x) } }
     }
 
-    #[inline]
-    fn inner(&self) -> &ArcInner<T> {
-        // This unsafety is ok because while this arc is alive we're guaranteed
-        // that the inner pointer is valid. Furthermore, we know that the
-        // `ArcInner` structure itself is `Sync` because the inner data is
-        // `Sync` as well, so we're ok loaning out an immutable pointer to
-        // these contents.
-        unsafe { &*self._ptr }
-    }
-
     /// Downgrades a strong pointer to a weak pointer.
     ///
     /// Weak pointers will not keep the data alive. Once all strong references
@@ -115,8 +107,20 @@ impl<T: Sync + Send> Arc<T> {
     }
 }
 
+impl<T> Arc<T> {
+    #[inline]
+    fn inner(&self) -> &ArcInner<T> {
+        // This unsafety is ok because while this arc is alive we're guaranteed
+        // that the inner pointer is valid. Furthermore, we know that the
+        // `ArcInner` structure itself is `Sync` because the inner data is
+        // `Sync` as well, so we're ok loaning out an immutable pointer to
+        // these contents.
+        unsafe { &*self._ptr }
+    }
+}
+
 #[unstable = "waiting on stability of Clone"]
-impl<T: Sync + Send> Clone for Arc<T> {
+impl<T> Clone for Arc<T> {
     /// Duplicate an atomically reference counted wrapper.
     ///
     /// The resulting two `Arc` objects will point to the same underlying data
@@ -141,19 +145,13 @@ impl<T: Sync + Send> Clone for Arc<T> {
 }
 
 #[experimental = "Deref is experimental."]
-impl<T: Send + Sync> Deref<T> for Arc<T> {
+impl<T> Deref<T> for Arc<T> {
     #[inline]
     fn deref(&self) -> &T {
         &self.inner().data
     }
 }
 
-impl<T: Send + Sync + Show> Show for Arc<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        (**self).fmt(f)
-    }
-}
-
 impl<T: Send + Sync + Clone> Arc<T> {
     /// Acquires a mutable pointer to the inner contents by guaranteeing that
     /// the reference count is one (no sharing is possible).
@@ -279,6 +277,38 @@ impl<T: Sync + Send> Drop for Weak<T> {
     }
 }
 
+#[unstable = "waiting on PartialEq"]
+impl<T: PartialEq> PartialEq for Arc<T> {
+    fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
+    fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
+}
+#[unstable = "waiting on PartialOrd"]
+impl<T: PartialOrd> PartialOrd for Arc<T> {
+    fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
+        (**self).partial_cmp(&**other)
+    }
+    fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
+    fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
+    fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
+    fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
+}
+#[unstable = "waiting on Ord"]
+impl<T: Ord> Ord for Arc<T> {
+    fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
+}
+#[unstable = "waiting on Eq"]
+impl<T: Eq> Eq for Arc<T> {}
+
+impl<T: fmt::Show> fmt::Show for Arc<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        (**self).fmt(f)
+    }
+}
+
+impl<T: Default + Sync + Send> Default for Arc<T> {
+    fn default() -> Arc<T> { Arc::new(Default::default()) }
+}
+
 #[cfg(test)]
 #[allow(experimental)]
 mod tests {
@@ -440,4 +470,8 @@ mod tests {
         let a = Arc::new(5u32);
         assert!(format!("{}", a).as_slice() == "5")
     }
+
+    // Make sure deriving works with Arc<T>
+    #[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Default)]
+    struct Foo { inner: Arc<int> }
 }
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs
index 0a040fff40d..1cd1738e369 100644
--- a/src/libserialize/serialize.rs
+++ b/src/libserialize/serialize.rs
@@ -557,7 +557,7 @@ impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
     }
 }
 
-impl<E, S:Encoder<E>, T:Encodable<S, E>+Send+Sync> Encodable<S, E> for Arc<T> {
+impl<E, S:Encoder<E>, T:Encodable<S, E>> Encodable<S, E> for Arc<T> {
     fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }