Skip to content

Commit e7fbc1f

Browse files
committed
libstd: Implement the new Cell.
1 parent caf34b4 commit e7fbc1f

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

src/libstd/cell.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,71 @@ use prelude::*;
1414
use cast;
1515
use 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]
1984
pub 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

137226
impl<T: Clone> Clone for RefCell<T> {
@@ -202,6 +291,17 @@ impl<'b, T> RefMut<'b, T> {
202291
mod 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

Comments
 (0)