Remove RcMut

Rc<Mut<T>> should be used instead
This commit is contained in:
Steven Fackler
2013-11-14 19:57:11 -08:00
parent 0fade3a714
commit 7c9daa8ff7
3 changed files with 14 additions and 247 deletions

View File

@@ -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 |_| {}
}
}
}