Skip to content

Commit 03ee3f5

Browse files
Ariel Ben-Yehudaarielb1
authored andcommitted
add an Ivar for write-only variables
1 parent 859d295 commit 03ee3f5

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

src/librustc_data_structures/ivar.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::fmt;
12+
use std::cell::Cell;
13+
14+
/// A write-once variable. When constructed, it is empty, and
15+
/// can only be set once.
16+
///
17+
/// Ivars ensure that data that can only be initialised once. A full
18+
/// implementation is used for concurrency and blocks on a read of an
19+
/// unfulfilled value. This implementation is more minimal and panics
20+
/// if you attempt to read the value before it has been set. It is also
21+
/// not `Sync`, but may be extended in the future to be usable as a true
22+
/// concurrency type.
23+
#[derive(PartialEq)]
24+
pub struct Ivar<T: Copy> {
25+
data: Cell<Option<T>>
26+
}
27+
28+
impl<T: Copy> Ivar<T> {
29+
pub fn new() -> Ivar<T> {
30+
Ivar {
31+
data: Cell::new(None)
32+
}
33+
}
34+
35+
pub fn get(&self) -> Option<T> {
36+
self.data.get()
37+
}
38+
39+
pub fn fulfill(&self, value: T) {
40+
assert!(self.data.get().is_none(),
41+
"Value already set!");
42+
self.data.set(Some(value));
43+
}
44+
45+
pub fn is_fulfilled(&self) -> bool {
46+
self.data.get().is_some()
47+
}
48+
49+
pub fn unwrap(&self) -> T {
50+
self.get().unwrap()
51+
}
52+
}
53+
54+
impl<T: Copy+fmt::Debug> fmt::Debug for Ivar<T> {
55+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56+
match self.get() {
57+
Some(val) => write!(f, "Ivar({:?})", val),
58+
None => f.write_str("Ivar(<unfulfilled>)")
59+
}
60+
}
61+
}
62+
63+
impl<T: Copy> Clone for Ivar<T> {
64+
fn clone(&self) -> Ivar<T> {
65+
match self.get() {
66+
Some(val) => Ivar { data: Cell::new(Some(val)) },
67+
None => Ivar::new()
68+
}
69+
}
70+
}

src/librustc_data_structures/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ extern crate serialize as rustc_serialize; // used by deriving
3636
pub mod snapshot_vec;
3737
pub mod graph;
3838
pub mod bitvec;
39+
pub mod ivar;
3940
pub mod unify;

0 commit comments

Comments
 (0)