10
10
11
11
//! Types dealing with dynamic mutability
12
12
13
- use cast;
14
13
use clone:: Clone ;
15
14
use cmp:: Eq ;
16
15
use fmt;
@@ -70,7 +69,7 @@ impl<T: Copy + fmt::Show> fmt::Show for Cell<T> {
70
69
/// A mutable memory location with dynamically checked borrow rules
71
70
pub struct RefCell < T > {
72
71
value : Unsafe < T > ,
73
- borrow : BorrowFlag ,
72
+ borrow : Cell < BorrowFlag > ,
74
73
nocopy : marker:: NoCopy ,
75
74
noshare : marker:: NoShare ,
76
75
}
@@ -86,33 +85,29 @@ impl<T> RefCell<T> {
86
85
pub fn new ( value : T ) -> RefCell < T > {
87
86
RefCell {
88
87
value : Unsafe :: new ( value) ,
88
+ borrow : Cell :: new ( UNUSED ) ,
89
89
nocopy : marker:: NoCopy ,
90
90
noshare : marker:: NoShare ,
91
- borrow : UNUSED ,
92
91
}
93
92
}
94
93
95
94
/// Consumes the `RefCell`, returning the wrapped value.
96
95
pub fn unwrap ( self ) -> T {
97
- assert ! ( self . borrow == UNUSED ) ;
96
+ assert ! ( self . borrow. get ( ) == UNUSED ) ;
98
97
unsafe { self . value . unwrap ( ) }
99
98
}
100
99
101
- unsafe fn as_mut < ' a > ( & ' a self ) -> & ' a mut RefCell < T > {
102
- cast:: transmute_mut ( self )
103
- }
104
-
105
100
/// Attempts to immutably borrow the wrapped value.
106
101
///
107
102
/// The borrow lasts until the returned `Ref` exits scope. Multiple
108
103
/// immutable borrows can be taken out at the same time.
109
104
///
110
105
/// Returns `None` if the value is currently mutably borrowed.
111
106
pub fn try_borrow < ' a > ( & ' a self ) -> Option < Ref < ' a , T > > {
112
- match self . borrow {
107
+ match self . borrow . get ( ) {
113
108
WRITING => None ,
114
- _ => {
115
- unsafe { self . as_mut ( ) . borrow += 1 ; }
109
+ borrow => {
110
+ self . borrow . set ( borrow + 1 ) ;
116
111
Some ( Ref { parent : self } )
117
112
}
118
113
}
@@ -140,11 +135,10 @@ impl<T> RefCell<T> {
140
135
///
141
136
/// Returns `None` if the value is currently borrowed.
142
137
pub fn try_borrow_mut < ' a > ( & ' a self ) -> Option < RefMut < ' a , T > > {
143
- match self . borrow {
144
- UNUSED => unsafe {
145
- let mut_self = self . as_mut ( ) ;
146
- mut_self. borrow = WRITING ;
147
- Some ( RefMut { parent : mut_self } )
138
+ match self . borrow . get ( ) {
139
+ UNUSED => {
140
+ self . borrow . set ( WRITING ) ;
141
+ Some ( RefMut { parent : self } )
148
142
} ,
149
143
_ => None
150
144
}
@@ -186,8 +180,9 @@ pub struct Ref<'b, T> {
186
180
#[ unsafe_destructor]
187
181
impl < ' b , T > Drop for Ref < ' b , T > {
188
182
fn drop ( & mut self ) {
189
- assert ! ( self . parent. borrow != WRITING && self . parent. borrow != UNUSED ) ;
190
- unsafe { self . parent . as_mut ( ) . borrow -= 1 ; }
183
+ let borrow = self . parent . borrow . get ( ) ;
184
+ assert ! ( borrow != WRITING && borrow != UNUSED ) ;
185
+ self . parent . borrow . set ( borrow - 1 ) ;
191
186
}
192
187
}
193
188
@@ -200,14 +195,15 @@ impl<'b, T> Deref<T> for Ref<'b, T> {
200
195
201
196
/// Wraps a mutable borrowed reference to a value in a `RefCell` box.
202
197
pub struct RefMut < ' b , T > {
203
- parent : & ' b mut RefCell < T >
198
+ parent : & ' b RefCell < T >
204
199
}
205
200
206
201
#[ unsafe_destructor]
207
202
impl < ' b , T > Drop for RefMut < ' b , T > {
208
203
fn drop ( & mut self ) {
209
- assert ! ( self . parent. borrow == WRITING ) ;
210
- self . parent . borrow = UNUSED ;
204
+ let borrow = self . parent . borrow . get ( ) ;
205
+ assert ! ( borrow == WRITING ) ;
206
+ self . parent . borrow . set ( UNUSED ) ;
211
207
}
212
208
}
213
209
0 commit comments