Skip to content

Commit 727ae37

Browse files
committed
---
yaml --- r: 90493 b: refs/heads/master c: e7fbc1f h: refs/heads/master i: 90491: 742b34b v: v3
1 parent a606316 commit 727ae37

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: caf34b41c3b81d946410e16c20f05a8183b1d0ed
2+
refs/heads/master: e7fbc1f553062f59b127d8c48345da72918accb4
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
55
refs/heads/try: b160761e35efcd1207112b3b782c06633cf441a8

trunk/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)