diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-05-15 18:06:22 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-05-15 19:18:09 -0400 |
| commit | 4702667a62be3286828e2c43094cbfbcfd26ad2a (patch) | |
| tree | 2951f5e2eaedde7a9df5a3e41007bb6e2edddaa5 /src/libstd | |
| parent | 8a15333c06b8ba491e1654c3fca3fa21d21def9b (diff) | |
| download | rust-4702667a62be3286828e2c43094cbfbcfd26ad2a.tar.gz rust-4702667a62be3286828e2c43094cbfbcfd26ad2a.zip | |
allow constructing Rc/RcMut from Const types too
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rc.rs | 108 |
1 files changed, 66 insertions, 42 deletions
diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs index cb0798f2a39..46f50eafec1 100644 --- a/src/libstd/rc.rs +++ b/src/libstd/rc.rs @@ -11,7 +11,11 @@ /** Task-local reference counted smart pointers Task-local reference counted smart pointers are an alternative to managed boxes with deterministic -destruction. They are restricted to containing `Owned` types in order to prevent cycles. +destruction. They are restricted to containing types that are either `Owned` or `Const` (or both) to +prevent cycles. + +Neither `Rc<T>` or `RcMut<T>` is ever `Owned` and `RcMut<T>` is never `Const`. If `T` is `Const`, a +cycle cannot be created with `Rc<T>` because there is no way to modify it after creation. */ @@ -30,16 +34,26 @@ pub struct Rc<T> { priv ptr: *mut RcBox<T>, } -pub impl<T: Owned> Rc<T> { - fn new(value: T) -> Rc<T> { - unsafe { - let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>; - assert!(!ptr::is_null(ptr)); - intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1}); - Rc{ptr: ptr} - } +priv impl<T> Rc<T> { + unsafe fn new(value: T) -> Rc<T> { + let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>; + assert!(!ptr::is_null(ptr)); + intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1}); + Rc{ptr: ptr} } +} + +// FIXME: #6516: should be a static method +pub fn rc_from_owned<T: Owned>(value: T) -> Rc<T> { + unsafe { Rc::new(value) } +} + +// FIXME: #6516: should be a static method +pub fn rc_from_const<T: Const>(value: T) -> Rc<T> { + unsafe { Rc::new(value) } +} +pub impl<T> Rc<T> { #[inline(always)] fn borrow<'r>(&'r self) -> &'r T { unsafe { cast::copy_lifetime(self, &(*self.ptr).value) } @@ -48,7 +62,7 @@ pub impl<T: Owned> Rc<T> { #[unsafe_destructor] #[cfg(not(stage0))] -impl<T: Owned> Drop for Rc<T> { +impl<T> Drop for Rc<T> { fn finalize(&self) { unsafe { (*self.ptr).count -= 1; @@ -62,7 +76,7 @@ impl<T: Owned> Drop for Rc<T> { #[unsafe_destructor] #[cfg(stage0)] -impl<T: Owned> Drop for Rc<T> { +impl<T> Drop for Rc<T> { fn finalize(&self) { unsafe { (*self.ptr).count -= 1; @@ -75,7 +89,7 @@ impl<T: Owned> Drop for Rc<T> { } -impl<T: Owned> Clone for Rc<T> { +impl<T> Clone for Rc<T> { /// Return a shallow copy of the reference counted pointer. #[inline] fn clone(&self) -> Rc<T> { @@ -86,11 +100,11 @@ impl<T: Owned> Clone for Rc<T> { } } -impl<T: Owned + DeepClone> DeepClone for Rc<T> { +impl<T: DeepClone> DeepClone for Rc<T> { /// Return a deep copy of the reference counted pointer. #[inline] fn deep_clone(&self) -> Rc<T> { - Rc::new(self.borrow().deep_clone()) + unsafe { Rc::new(self.borrow().deep_clone()) } } } @@ -101,7 +115,7 @@ mod test_rc { #[test] fn test_clone() { - let x = Rc::new(Cell(5)); + let x = rc_from_owned(Cell(5)); let y = x.clone(); do x.borrow().with_mut_ref |inner| { *inner = 20; @@ -111,7 +125,7 @@ mod test_rc { #[test] fn test_deep_clone() { - let x = Rc::new(Cell(5)); + let x = rc_from_owned(Cell(5)); let y = x.deep_clone(); do x.borrow().with_mut_ref |inner| { *inner = 20; @@ -121,13 +135,13 @@ mod test_rc { #[test] fn test_simple() { - let x = Rc::new(5); + let x = rc_from_const(5); assert_eq!(*x.borrow(), 5); } #[test] fn test_simple_clone() { - let x = Rc::new(5); + let x = rc_from_const(5); let y = x.clone(); assert_eq!(*x.borrow(), 5); assert_eq!(*y.borrow(), 5); @@ -135,7 +149,7 @@ mod test_rc { #[test] fn test_destructor() { - let x = Rc::new(~5); + let x = rc_from_owned(~5); assert_eq!(**x.borrow(), 5); } } @@ -167,16 +181,26 @@ pub struct RcMut<T> { priv ptr: *mut RcMutBox<T>, } -pub impl<T: Owned> RcMut<T> { - fn new(value: T) -> RcMut<T> { - unsafe { - let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>; - assert!(!ptr::is_null(ptr)); - intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing}); - RcMut{ptr: ptr} - } +priv impl<T> RcMut<T> { + unsafe fn new(value: T) -> RcMut<T> { + let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>; + assert!(!ptr::is_null(ptr)); + intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing}); + RcMut{ptr: ptr} } +} + +// FIXME: #6516: should be a static method +pub fn rc_mut_from_owned<T: Owned>(value: T) -> RcMut<T> { + unsafe { RcMut::new(value) } +} + +// FIXME: #6516: should be a static method +pub fn rc_mut_from_const<T: Const>(value: T) -> RcMut<T> { + unsafe { RcMut::new(value) } +} +pub impl<T> RcMut<T> { /// Fails if there is already a mutable borrow of the box #[inline] fn with_borrow<U>(&self, f: &fn(&T) -> U) -> U { @@ -205,7 +229,7 @@ pub impl<T: Owned> RcMut<T> { #[unsafe_destructor] #[cfg(not(stage0))] -impl<T: Owned> Drop for RcMut<T> { +impl<T> Drop for RcMut<T> { fn finalize(&self) { unsafe { (*self.ptr).count -= 1; @@ -219,7 +243,7 @@ impl<T: Owned> Drop for RcMut<T> { #[unsafe_destructor] #[cfg(stage0)] -impl<T: Owned> Drop for RcMut<T> { +impl<T> Drop for RcMut<T> { fn finalize(&self) { unsafe { (*self.ptr).count -= 1; @@ -231,7 +255,7 @@ impl<T: Owned> Drop for RcMut<T> { } } -impl<T: Owned> Clone for RcMut<T> { +impl<T> Clone for RcMut<T> { /// Return a shallow copy of the reference counted pointer. #[inline] fn clone(&self) -> RcMut<T> { @@ -242,13 +266,13 @@ impl<T: Owned> Clone for RcMut<T> { } } -impl<T: Owned + DeepClone> DeepClone for RcMut<T> { +impl<T: DeepClone> DeepClone for RcMut<T> { /// Return a deep copy of the reference counted pointer. #[inline] fn deep_clone(&self) -> RcMut<T> { do self.with_borrow |x| { // FIXME: #6497: should avoid freeze (slow) - RcMut::new(x.deep_clone()) + unsafe { RcMut::new(x.deep_clone()) } } } } @@ -259,7 +283,7 @@ mod test_rc_mut { #[test] fn test_clone() { - let x = RcMut::new(5); + let x = rc_mut_from_owned(5); let y = x.clone(); do x.with_mut_borrow |value| { *value = 20; @@ -271,7 +295,7 @@ mod test_rc_mut { #[test] fn test_deep_clone() { - let x = RcMut::new(5); + let x = rc_mut_from_const(5); let y = x.deep_clone(); do x.with_mut_borrow |value| { *value = 20; @@ -283,7 +307,7 @@ mod test_rc_mut { #[test] fn borrow_many() { - let x = RcMut::new(5); + let x = rc_mut_from_owned(5); let y = x.clone(); do x.with_borrow |a| { @@ -299,7 +323,7 @@ mod test_rc_mut { #[test] fn modify() { - let x = RcMut::new(5); + let x = rc_mut_from_const(5); let y = x.clone(); do y.with_mut_borrow |a| { @@ -314,14 +338,14 @@ mod test_rc_mut { #[test] fn release_immutable() { - let x = RcMut::new(5); + let x = rc_mut_from_owned(5); do x.with_borrow |_| {} do x.with_mut_borrow |_| {} } #[test] fn release_mutable() { - let x = RcMut::new(5); + let x = rc_mut_from_const(5); do x.with_mut_borrow |_| {} do x.with_borrow |_| {} } @@ -329,7 +353,7 @@ mod test_rc_mut { #[test] #[should_fail] fn frozen() { - let x = RcMut::new(5); + let x = rc_mut_from_owned(5); let y = x.clone(); do x.with_borrow |_| { @@ -341,7 +365,7 @@ mod test_rc_mut { #[test] #[should_fail] fn mutable_dupe() { - let x = RcMut::new(5); + let x = rc_mut_from_const(5); let y = x.clone(); do x.with_mut_borrow |_| { @@ -353,7 +377,7 @@ mod test_rc_mut { #[test] #[should_fail] fn mutable_freeze() { - let x = RcMut::new(5); + let x = rc_mut_from_owned(5); let y = x.clone(); do x.with_mut_borrow |_| { @@ -365,7 +389,7 @@ mod test_rc_mut { #[test] #[should_fail] fn restore_freeze() { - let x = RcMut::new(5); + let x = rc_mut_from_const(5); let y = x.clone(); do x.with_borrow |_| { |
