Skip to content

Commit 35ad00d

Browse files
committed
alloc: Make deriving more friendly with Arc
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!
1 parent 823f805 commit 35ad00d

File tree

2 files changed

+54
-20
lines changed

2 files changed

+54
-20
lines changed

src/liballoc/arc.rs

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
use core::atomic;
1717
use core::clone::Clone;
1818
use core::fmt::{mod, Show};
19+
use core::cmp::{Eq, Ord, PartialEq, PartialOrd, Ordering};
20+
use core::default::Default;
1921
use core::kinds::{Sync, Send};
2022
use core::mem::{min_align_of, size_of, drop};
2123
use core::mem;
2224
use core::ops::{Drop, Deref};
2325
use core::option::{Some, None, Option};
24-
use core::ptr;
2526
use core::ptr::RawPtr;
27+
use core::ptr;
2628
use heap::deallocate;
2729

2830
/// An atomically reference counted wrapper for shared state.
@@ -92,16 +94,6 @@ impl<T: Sync + Send> Arc<T> {
9294
Arc { _ptr: unsafe { mem::transmute(x) } }
9395
}
9496

95-
#[inline]
96-
fn inner(&self) -> &ArcInner<T> {
97-
// This unsafety is ok because while this arc is alive we're guaranteed
98-
// that the inner pointer is valid. Furthermore, we know that the
99-
// `ArcInner` structure itself is `Sync` because the inner data is
100-
// `Sync` as well, so we're ok loaning out an immutable pointer to
101-
// these contents.
102-
unsafe { &*self._ptr }
103-
}
104-
10597
/// Downgrades a strong pointer to a weak pointer.
10698
///
10799
/// Weak pointers will not keep the data alive. Once all strong references
@@ -115,8 +107,20 @@ impl<T: Sync + Send> Arc<T> {
115107
}
116108
}
117109

110+
impl<T> Arc<T> {
111+
#[inline]
112+
fn inner(&self) -> &ArcInner<T> {
113+
// This unsafety is ok because while this arc is alive we're guaranteed
114+
// that the inner pointer is valid. Furthermore, we know that the
115+
// `ArcInner` structure itself is `Sync` because the inner data is
116+
// `Sync` as well, so we're ok loaning out an immutable pointer to
117+
// these contents.
118+
unsafe { &*self._ptr }
119+
}
120+
}
121+
118122
#[unstable = "waiting on stability of Clone"]
119-
impl<T: Sync + Send> Clone for Arc<T> {
123+
impl<T> Clone for Arc<T> {
120124
/// Duplicate an atomically reference counted wrapper.
121125
///
122126
/// The resulting two `Arc` objects will point to the same underlying data
@@ -141,19 +145,13 @@ impl<T: Sync + Send> Clone for Arc<T> {
141145
}
142146

143147
#[experimental = "Deref is experimental."]
144-
impl<T: Send + Sync> Deref<T> for Arc<T> {
148+
impl<T> Deref<T> for Arc<T> {
145149
#[inline]
146150
fn deref(&self) -> &T {
147151
&self.inner().data
148152
}
149153
}
150154

151-
impl<T: Send + Sync + Show> Show for Arc<T> {
152-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
153-
(**self).fmt(f)
154-
}
155-
}
156-
157155
impl<T: Send + Sync + Clone> Arc<T> {
158156
/// Acquires a mutable pointer to the inner contents by guaranteeing that
159157
/// the reference count is one (no sharing is possible).
@@ -279,6 +277,38 @@ impl<T: Sync + Send> Drop for Weak<T> {
279277
}
280278
}
281279

280+
#[unstable = "waiting on PartialEq"]
281+
impl<T: PartialEq> PartialEq for Arc<T> {
282+
fn eq(&self, other: &Arc<T>) -> bool { *(*self) == *(*other) }
283+
fn ne(&self, other: &Arc<T>) -> bool { *(*self) != *(*other) }
284+
}
285+
#[unstable = "waiting on PartialOrd"]
286+
impl<T: PartialOrd> PartialOrd for Arc<T> {
287+
fn partial_cmp(&self, other: &Arc<T>) -> Option<Ordering> {
288+
(**self).partial_cmp(&**other)
289+
}
290+
fn lt(&self, other: &Arc<T>) -> bool { *(*self) < *(*other) }
291+
fn le(&self, other: &Arc<T>) -> bool { *(*self) <= *(*other) }
292+
fn ge(&self, other: &Arc<T>) -> bool { *(*self) >= *(*other) }
293+
fn gt(&self, other: &Arc<T>) -> bool { *(*self) > *(*other) }
294+
}
295+
#[unstable = "waiting on Ord"]
296+
impl<T: Ord> Ord for Arc<T> {
297+
fn cmp(&self, other: &Arc<T>) -> Ordering { (**self).cmp(&**other) }
298+
}
299+
#[unstable = "waiting on Eq"]
300+
impl<T: Eq> Eq for Arc<T> {}
301+
302+
impl<T: fmt::Show> fmt::Show for Arc<T> {
303+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
304+
(**self).fmt(f)
305+
}
306+
}
307+
308+
impl<T: Default + Sync + Send> Default for Arc<T> {
309+
fn default() -> Arc<T> { Arc::new(Default::default()) }
310+
}
311+
282312
#[cfg(test)]
283313
#[allow(experimental)]
284314
mod tests {
@@ -440,4 +470,8 @@ mod tests {
440470
let a = Arc::new(5u32);
441471
assert!(format!("{}", a).as_slice() == "5")
442472
}
473+
474+
// Make sure deriving works with Arc<T>
475+
#[deriving(Eq, Ord, PartialEq, PartialOrd, Clone, Show, Default)]
476+
struct Foo { inner: Arc<int> }
443477
}

src/libserialize/serialize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ impl<E, D: Decoder<E>, T: Decodable<D, E>> Decodable<D, E> for RefCell<T> {
557557
}
558558
}
559559

560-
impl<E, S:Encoder<E>, T:Encodable<S, E>+Send+Sync> Encodable<S, E> for Arc<T> {
560+
impl<E, S:Encoder<E>, T:Encodable<S, E>> Encodable<S, E> for Arc<T> {
561561
fn encode(&self, s: &mut S) -> Result<(), E> {
562562
(**self).encode(s)
563563
}

0 commit comments

Comments
 (0)