@@ -24,20 +24,18 @@ pointers, and then storing the parent pointers as `Weak` pointers.
24
24
*/
25
25
26
26
use cast:: transmute;
27
- use cell:: Cell ;
28
27
use clone:: Clone ;
29
28
use cmp:: { Eq , Ord } ;
30
29
use kinds:: marker;
31
30
use ops:: { Deref , Drop } ;
32
31
use option:: { Option , Some , None } ;
33
32
use ptr;
34
- use ptr:: RawPtr ;
35
33
use rt:: global_heap:: exchange_free;
36
34
37
35
struct RcBox < T > {
38
36
value : T ,
39
- strong : Cell < uint > ,
40
- weak : Cell < uint >
37
+ strong : uint ,
38
+ weak : uint
41
39
}
42
40
43
41
/// Immutable reference counted pointer type
@@ -58,11 +56,7 @@ impl<T> Rc<T> {
58
56
// destructor never frees the allocation while the
59
57
// strong destructor is running, even if the weak
60
58
// pointer is stored inside the strong one.
61
- ptr : transmute ( ~RcBox {
62
- value : value,
63
- strong : Cell :: new ( 1 ) ,
64
- weak : Cell :: new ( 1 )
65
- } ) ,
59
+ ptr : transmute ( ~RcBox { value : value, strong : 1 , weak : 1 } ) ,
66
60
nosend : marker:: NoSend ,
67
61
noshare : marker:: NoShare
68
62
}
@@ -73,11 +67,13 @@ impl<T> Rc<T> {
73
67
impl < T > Rc < T > {
74
68
/// Downgrade the reference-counted pointer to a weak reference
75
69
pub fn downgrade ( & self ) -> Weak < T > {
76
- self . inc_weak ( ) ;
77
- Weak {
78
- ptr : self . ptr ,
79
- nosend : marker:: NoSend ,
80
- noshare : marker:: NoShare
70
+ unsafe {
71
+ ( * self . ptr ) . weak += 1 ;
72
+ Weak {
73
+ ptr : self . ptr ,
74
+ nosend : marker:: NoSend ,
75
+ noshare : marker:: NoShare
76
+ }
81
77
}
82
78
}
83
79
}
@@ -86,24 +82,24 @@ impl<T> Deref<T> for Rc<T> {
86
82
/// Borrow the value contained in the reference-counted box
87
83
#[ inline( always) ]
88
84
fn deref < ' a > ( & ' a self ) -> & ' a T {
89
- & self . inner ( ) . value
85
+ unsafe { & ( * self . ptr ) . value }
90
86
}
91
87
}
92
88
93
89
#[ unsafe_destructor]
94
90
impl < T > Drop for Rc < T > {
95
91
fn drop ( & mut self ) {
96
92
unsafe {
97
- if ! self . ptr . is_null ( ) {
98
- self . dec_strong ( ) ;
99
- if self . strong ( ) == 0 {
93
+ if self . ptr != 0 as * mut RcBox < T > {
94
+ ( * self . ptr ) . strong -= 1 ;
95
+ if ( * self . ptr ) . strong == 0 {
100
96
ptr:: read ( self . deref ( ) ) ; // destroy the contained object
101
97
102
98
// remove the implicit "strong weak" pointer now
103
99
// that we've destroyed the contents.
104
- self . dec_weak ( ) ;
100
+ ( * self . ptr ) . weak -= 1 ;
105
101
106
- if self . weak ( ) == 0 {
102
+ if ( * self . ptr ) . weak == 0 {
107
103
exchange_free ( self . ptr as * u8 )
108
104
}
109
105
}
@@ -115,8 +111,10 @@ impl<T> Drop for Rc<T> {
115
111
impl < T > Clone for Rc < T > {
116
112
#[ inline]
117
113
fn clone ( & self ) -> Rc < T > {
118
- self . inc_strong ( ) ;
119
- Rc { ptr : self . ptr , nosend : marker:: NoSend , noshare : marker:: NoShare }
114
+ unsafe {
115
+ ( * self . ptr ) . strong += 1 ;
116
+ Rc { ptr : self . ptr , nosend : marker:: NoSend , noshare : marker:: NoShare }
117
+ }
120
118
}
121
119
}
122
120
@@ -153,11 +151,13 @@ pub struct Weak<T> {
153
151
impl < T > Weak < T > {
154
152
/// Upgrade a weak reference to a strong reference
155
153
pub fn upgrade ( & self ) -> Option < Rc < T > > {
156
- if self . strong ( ) == 0 {
157
- None
158
- } else {
159
- self . inc_strong ( ) ;
160
- Some ( Rc { ptr : self . ptr , nosend : marker:: NoSend , noshare : marker:: NoShare } )
154
+ unsafe {
155
+ if ( * self . ptr ) . strong == 0 {
156
+ None
157
+ } else {
158
+ ( * self . ptr ) . strong += 1 ;
159
+ Some ( Rc { ptr : self . ptr , nosend : marker:: NoSend , noshare : marker:: NoShare } )
160
+ }
161
161
}
162
162
}
163
163
}
@@ -166,11 +166,11 @@ impl<T> Weak<T> {
166
166
impl < T > Drop for Weak < T > {
167
167
fn drop ( & mut self ) {
168
168
unsafe {
169
- if ! self . ptr . is_null ( ) {
170
- self . dec_weak ( ) ;
169
+ if self . ptr != 0 as * mut RcBox < T > {
170
+ ( * self . ptr ) . weak -= 1 ;
171
171
// the weak count starts at 1, and will only go to
172
172
// zero if all the strong pointers have disappeared.
173
- if self . weak ( ) == 0 {
173
+ if ( * self . ptr ) . weak == 0 {
174
174
exchange_free ( self . ptr as * u8 )
175
175
}
176
176
}
@@ -181,44 +181,13 @@ impl<T> Drop for Weak<T> {
181
181
impl < T > Clone for Weak < T > {
182
182
#[ inline]
183
183
fn clone ( & self ) -> Weak < T > {
184
- self . inc_weak ( ) ;
185
- Weak { ptr : self . ptr , nosend : marker:: NoSend , noshare : marker:: NoShare }
184
+ unsafe {
185
+ ( * self . ptr ) . weak += 1 ;
186
+ Weak { ptr : self . ptr , nosend : marker:: NoSend , noshare : marker:: NoShare }
187
+ }
186
188
}
187
189
}
188
190
189
- #[ allow( missing_doc) ]
190
- trait RcBoxPtr < T > {
191
- fn inner < ' a > ( & ' a self ) -> & ' a RcBox < T > ;
192
-
193
- #[ inline]
194
- fn strong ( & self ) -> uint { self . inner ( ) . strong . get ( ) }
195
-
196
- #[ inline]
197
- fn inc_strong ( & self ) { self . inner ( ) . strong . set ( self . strong ( ) + 1 ) ; }
198
-
199
- #[ inline]
200
- fn dec_strong ( & self ) { self . inner ( ) . strong . set ( self . strong ( ) - 1 ) ; }
201
-
202
- #[ inline]
203
- fn weak ( & self ) -> uint { self . inner ( ) . weak . get ( ) }
204
-
205
- #[ inline]
206
- fn inc_weak ( & self ) { self . inner ( ) . weak . set ( self . weak ( ) + 1 ) ; }
207
-
208
- #[ inline]
209
- fn dec_weak ( & self ) { self . inner ( ) . weak . set ( self . weak ( ) - 1 ) ; }
210
- }
211
-
212
- impl < T > RcBoxPtr < T > for Rc < T > {
213
- #[ inline( always) ]
214
- fn inner < ' a > ( & ' a self ) -> & ' a RcBox < T > { unsafe { & ( * self . ptr ) } }
215
- }
216
-
217
- impl < T > RcBoxPtr < T > for Weak < T > {
218
- #[ inline( always) ]
219
- fn inner < ' a > ( & ' a self ) -> & ' a RcBox < T > { unsafe { & ( * self . ptr ) } }
220
- }
221
-
222
191
#[ cfg( test) ]
223
192
mod tests {
224
193
use prelude:: * ;
0 commit comments