@@ -14,6 +14,71 @@ use prelude::*;
1414use cast;
1515use util:: NonCopyable ;
1616
17+ #[ cfg( stage0) ]
18+ use unstable:: intrinsics;
19+
20+ /// A mutable memory location that admits only `Pod` data.
21+ #[ no_freeze]
22+ #[ deriving( Clone ) ]
23+ pub struct Cell < T > {
24+ priv value : T ,
25+ }
26+
27+ // NB: For `stage0`, we omit the `Pod` bound. This is unsound but will help
28+ // us get started on removing `@mut` from `rustc`.
29+
30+ #[ cfg( stage0) ]
31+ impl < T > Cell < T > {
32+ /// Creates a new `Cell` containing the given value.
33+ pub fn new ( value : T ) -> Cell < T > {
34+ Cell {
35+ value : value,
36+ }
37+ }
38+
39+ /// Returns a copy of the contained value.
40+ #[ inline]
41+ pub fn get ( & self ) -> T {
42+ unsafe {
43+ let mut result = intrinsics:: uninit ( ) ;
44+ intrinsics:: copy_nonoverlapping_memory ( & mut result, & self . value , 1 ) ;
45+ result
46+ }
47+ }
48+
49+ /// Sets the contained value.
50+ #[ inline]
51+ pub fn set ( & self , value : T ) {
52+ unsafe {
53+ intrinsics:: copy_nonoverlapping_memory ( cast:: transmute_mut ( & self . value ) , & value, 1 )
54+ }
55+ }
56+ }
57+
58+ #[ cfg( not( stage0) ) ]
59+ impl < T : :: kinds:: Pod > Cell < T > {
60+ /// Creates a new `Cell` containing the given value.
61+ pub fn new ( value : T ) -> Cell < T > {
62+ Cell {
63+ value : value,
64+ }
65+ }
66+
67+ /// Returns a copy of the contained value.
68+ #[ inline]
69+ pub fn get ( & self ) -> T {
70+ self . value
71+ }
72+
73+ /// Sets the contained value.
74+ #[ inline]
75+ pub fn set ( & self , value : T ) {
76+ unsafe {
77+ * cast:: transmute_mut ( & self . value ) = value
78+ }
79+ }
80+ }
81+
1782/// A mutable memory location with dynamically checked borrow rules
1883#[ no_freeze]
1984pub struct RefCell < T > {
@@ -132,6 +197,30 @@ impl<T> RefCell<T> {
132197 let mut ptr = self . borrow_mut ( ) ;
133198 blk ( ptr. get ( ) )
134199 }
200+
201+ /// Sets the value, replacing what was there.
202+ ///
203+ /// # Failure
204+ ///
205+ /// Fails if the value is currently borrowed.
206+ #[ inline]
207+ pub fn set ( & self , value : T ) {
208+ let mut reference = self . borrow_mut ( ) ;
209+ * reference. get ( ) = value
210+ }
211+ }
212+
213+ impl < T : Clone > RefCell < T > {
214+ /// Returns a copy of the contained value.
215+ ///
216+ /// # Failure
217+ ///
218+ /// Fails if the value is currently mutably borrowed.
219+ #[ inline]
220+ pub fn get ( & self ) -> T {
221+ let reference = self . borrow ( ) ;
222+ ( * reference. get ( ) ) . clone ( )
223+ }
135224}
136225
137226impl < T : Clone > Clone for RefCell < T > {
@@ -202,6 +291,17 @@ impl<'b, T> RefMut<'b, T> {
202291mod test {
203292 use super :: * ;
204293
294+ #[ test]
295+ fn smoketest_cell ( ) {
296+ let x = Cell :: new ( 10 ) ;
297+ assert_eq ! ( x. get( ) , 10 ) ;
298+ x. set ( 20 ) ;
299+ assert_eq ! ( x. get( ) , 20 ) ;
300+
301+ let y = Cell :: new ( ( 30 , 40 ) ) ;
302+ assert_eq ! ( y. get( ) , ( 30 , 40 ) ) ;
303+ }
304+
205305 #[ test]
206306 fn double_imm_borrow ( ) {
207307 let x = RefCell :: new ( 0 ) ;
0 commit comments