From 35ad00d2ec63432ff4a5b4a0def8c9eae46125b6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 17 Oct 2014 11:00:02 -0700 Subject: [PATCH] alloc: Make deriving more friendly with Arc This adds impls of Eq/Ord/PartialEq/PartialOrd/Show/Default to Arc, 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! --- src/liballoc/arc.rs | 72 ++++++++++++++++++++++++++--------- src/libserialize/serialize.rs | 2 +- 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 Arc { Arc { _ptr: unsafe { mem::transmute(x) } } } - #[inline] - fn inner(&self) -> &ArcInner { - // 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 Arc { } } +impl Arc { + #[inline] + fn inner(&self) -> &ArcInner { + // 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 Clone for Arc { +impl Clone for Arc { /// Duplicate an atomically reference counted wrapper. /// /// The resulting two `Arc` objects will point to the same underlying data @@ -141,19 +145,13 @@ impl Clone for Arc { } #[experimental = "Deref is experimental."] -impl Deref for Arc { +impl Deref for Arc { #[inline] fn deref(&self) -> &T { &self.inner().data } } -impl Show for Arc { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - (**self).fmt(f) - } -} - impl Arc { /// 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 Drop for Weak { } } +#[unstable = "waiting on PartialEq"] +impl PartialEq for Arc { + fn eq(&self, other: &Arc) -> bool { *(*self) == *(*other) } + fn ne(&self, other: &Arc) -> bool { *(*self) != *(*other) } +} +#[unstable = "waiting on PartialOrd"] +impl PartialOrd for Arc { + fn partial_cmp(&self, other: &Arc) -> Option { + (**self).partial_cmp(&**other) + } + fn lt(&self, other: &Arc) -> bool { *(*self) < *(*other) } + fn le(&self, other: &Arc) -> bool { *(*self) <= *(*other) } + fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) } + fn gt(&self, other: &Arc) -> bool { *(*self) > *(*other) } +} +#[unstable = "waiting on Ord"] +impl Ord for Arc { + fn cmp(&self, other: &Arc) -> Ordering { (**self).cmp(&**other) } +} +#[unstable = "waiting on Eq"] +impl Eq for Arc {} + +impl fmt::Show for Arc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (**self).fmt(f) + } +} + +impl Default for Arc { + fn default() -> Arc { 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 + #[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Default)] + struct Foo { inner: Arc } } 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, T: Decodable> Decodable for RefCell { } } -impl, T:Encodable+Send+Sync> Encodable for Arc { +impl, T:Encodable> Encodable for Arc { fn encode(&self, s: &mut S) -> Result<(), E> { (**self).encode(s) }