Remove RcMut
Rc<Mut<T>> should be used instead
This commit is contained in:
237
src/libstd/rc.rs
237
src/libstd/rc.rs
@@ -14,10 +14,6 @@ The `Rc` type provides shared ownership of an immutable value. Destruction is de
|
||||
will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
|
||||
overhead of atomic reference counting.
|
||||
|
||||
The `RcMut` type provides shared ownership of a mutable value. Since multiple owners prevent
|
||||
inherited mutability, a dynamic freezing check is used to maintain the invariant that an `&mut`
|
||||
reference is a unique handle and the type is marked as non-`Freeze`.
|
||||
|
||||
*/
|
||||
|
||||
use ptr::RawPtr;
|
||||
@@ -151,236 +147,3 @@ mod test_rc {
|
||||
assert_eq!(**x.borrow(), 5);
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
enum Borrow {
|
||||
Mutable,
|
||||
Immutable,
|
||||
Nothing
|
||||
}
|
||||
|
||||
struct RcMutBox<T> {
|
||||
value: T,
|
||||
count: uint,
|
||||
borrow: Borrow
|
||||
}
|
||||
|
||||
/// Mutable reference counted pointer type
|
||||
#[no_send]
|
||||
#[no_freeze]
|
||||
#[unsafe_no_drop_flag]
|
||||
pub struct RcMut<T> {
|
||||
priv ptr: *mut RcMutBox<T>,
|
||||
}
|
||||
|
||||
impl<T: Freeze> RcMut<T> {
|
||||
/// Construct a new mutable reference-counted box from a `Freeze` value
|
||||
#[inline]
|
||||
pub fn new(value: T) -> RcMut<T> {
|
||||
unsafe { RcMut::new_unchecked(value) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Send> RcMut<T> {
|
||||
/// Construct a new mutable reference-counted box from a `Send` value
|
||||
#[inline]
|
||||
pub fn from_send(value: T) -> RcMut<T> {
|
||||
unsafe { RcMut::new_unchecked(value) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RcMut<T> {
|
||||
/// Unsafety construct a new mutable reference-counted box from any value.
|
||||
///
|
||||
/// It is possible to create cycles, which will leak, and may interact
|
||||
/// poorly with managed pointers.
|
||||
#[inline]
|
||||
pub unsafe fn new_unchecked(value: T) -> RcMut<T> {
|
||||
RcMut{ptr: transmute(~RcMutBox{value: value, count: 1, borrow: Nothing})}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> RcMut<T> {
|
||||
/// Fails if there is already a mutable borrow of the box
|
||||
#[inline]
|
||||
pub fn with_borrow<U>(&self, f: |&T| -> U) -> U {
|
||||
unsafe {
|
||||
assert!((*self.ptr).borrow != Mutable);
|
||||
let previous = (*self.ptr).borrow;
|
||||
(*self.ptr).borrow = Immutable;
|
||||
let res = f(&(*self.ptr).value);
|
||||
(*self.ptr).borrow = previous;
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
/// Fails if there is already a mutable or immutable borrow of the box
|
||||
#[inline]
|
||||
pub fn with_mut_borrow<U>(&self, f: |&mut T| -> U) -> U {
|
||||
unsafe {
|
||||
assert_eq!((*self.ptr).borrow, Nothing);
|
||||
(*self.ptr).borrow = Mutable;
|
||||
let res = f(&mut (*self.ptr).value);
|
||||
(*self.ptr).borrow = Nothing;
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
impl<T> Drop for RcMut<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if self.ptr.is_not_null() {
|
||||
(*self.ptr).count -= 1;
|
||||
if (*self.ptr).count == 0 {
|
||||
let _: ~RcMutBox<T> = transmute(self.ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Clone for RcMut<T> {
|
||||
/// Return a shallow copy of the reference counted pointer.
|
||||
#[inline]
|
||||
fn clone(&self) -> RcMut<T> {
|
||||
unsafe {
|
||||
(*self.ptr).count += 1;
|
||||
RcMut{ptr: self.ptr}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
unsafe { RcMut::new_unchecked(x.deep_clone()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_rc_mut {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_clone() {
|
||||
let x = RcMut::from_send(5);
|
||||
let y = x.clone();
|
||||
do x.with_mut_borrow |value| {
|
||||
*value = 20;
|
||||
}
|
||||
do y.with_borrow |value| {
|
||||
assert_eq!(*value, 20);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_deep_clone() {
|
||||
let x = RcMut::new(5);
|
||||
let y = x.deep_clone();
|
||||
do x.with_mut_borrow |value| {
|
||||
*value = 20;
|
||||
}
|
||||
do y.with_borrow |value| {
|
||||
assert_eq!(*value, 5);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn borrow_many() {
|
||||
let x = RcMut::from_send(5);
|
||||
let y = x.clone();
|
||||
|
||||
do x.with_borrow |a| {
|
||||
assert_eq!(*a, 5);
|
||||
do y.with_borrow |b| {
|
||||
assert_eq!(*b, 5);
|
||||
do x.with_borrow |c| {
|
||||
assert_eq!(*c, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modify() {
|
||||
let x = RcMut::new(5);
|
||||
let y = x.clone();
|
||||
|
||||
do y.with_mut_borrow |a| {
|
||||
assert_eq!(*a, 5);
|
||||
*a = 6;
|
||||
}
|
||||
|
||||
do x.with_borrow |a| {
|
||||
assert_eq!(*a, 6);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_immutable() {
|
||||
let x = RcMut::from_send(5);
|
||||
do x.with_borrow |_| {}
|
||||
do x.with_mut_borrow |_| {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn release_mutable() {
|
||||
let x = RcMut::new(5);
|
||||
do x.with_mut_borrow |_| {}
|
||||
do x.with_borrow |_| {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn frozen() {
|
||||
let x = RcMut::from_send(5);
|
||||
let y = x.clone();
|
||||
|
||||
do x.with_borrow |_| {
|
||||
do y.with_mut_borrow |_| {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn mutable_dupe() {
|
||||
let x = RcMut::new(5);
|
||||
let y = x.clone();
|
||||
|
||||
do x.with_mut_borrow |_| {
|
||||
do y.with_mut_borrow |_| {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn mutable_freeze() {
|
||||
let x = RcMut::from_send(5);
|
||||
let y = x.clone();
|
||||
|
||||
do x.with_mut_borrow |_| {
|
||||
do y.with_borrow |_| {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn restore_freeze() {
|
||||
let x = RcMut::new(5);
|
||||
let y = x.clone();
|
||||
|
||||
do x.with_borrow |_| {
|
||||
do x.with_borrow |_| {}
|
||||
do y.with_mut_borrow |_| {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user