diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2015-07-20 15:48:24 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <ariel.byd@gmail.com> | 2015-08-06 14:16:52 +0300 |
| commit | 03ee3f5c204cb9b20c58a5cd2d61dc792727dad7 (patch) | |
| tree | 35456b07c4c96009ea260208613d8df70eb15a9f | |
| parent | 859d2954ed974e4d81ea4c20140f6f15f4c6077e (diff) | |
| download | rust-03ee3f5c204cb9b20c58a5cd2d61dc792727dad7.tar.gz rust-03ee3f5c204cb9b20c58a5cd2d61dc792727dad7.zip | |
add an Ivar for write-only variables
| -rw-r--r-- | src/librustc_data_structures/ivar.rs | 70 | ||||
| -rw-r--r-- | src/librustc_data_structures/lib.rs | 1 |
2 files changed, 71 insertions, 0 deletions
diff --git a/src/librustc_data_structures/ivar.rs b/src/librustc_data_structures/ivar.rs new file mode 100644 index 00000000000..c16a2ea077c --- /dev/null +++ b/src/librustc_data_structures/ivar.rs @@ -0,0 +1,70 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::fmt; +use std::cell::Cell; + +/// A write-once variable. When constructed, it is empty, and +/// can only be set once. +/// +/// Ivars ensure that data that can only be initialised once. A full +/// implementation is used for concurrency and blocks on a read of an +/// unfulfilled value. This implementation is more minimal and panics +/// if you attempt to read the value before it has been set. It is also +/// not `Sync`, but may be extended in the future to be usable as a true +/// concurrency type. +#[derive(PartialEq)] +pub struct Ivar<T: Copy> { + data: Cell<Option<T>> +} + +impl<T: Copy> Ivar<T> { + pub fn new() -> Ivar<T> { + Ivar { + data: Cell::new(None) + } + } + + pub fn get(&self) -> Option<T> { + self.data.get() + } + + pub fn fulfill(&self, value: T) { + assert!(self.data.get().is_none(), + "Value already set!"); + self.data.set(Some(value)); + } + + pub fn is_fulfilled(&self) -> bool { + self.data.get().is_some() + } + + pub fn unwrap(&self) -> T { + self.get().unwrap() + } +} + +impl<T: Copy+fmt::Debug> fmt::Debug for Ivar<T> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { + Some(val) => write!(f, "Ivar({:?})", val), + None => f.write_str("Ivar(<unfulfilled>)") + } + } +} + +impl<T: Copy> Clone for Ivar<T> { + fn clone(&self) -> Ivar<T> { + match self.get() { + Some(val) => Ivar { data: Cell::new(Some(val)) }, + None => Ivar::new() + } + } +} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 1f8f7694ff9..558d15610df 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -36,4 +36,5 @@ extern crate serialize as rustc_serialize; // used by deriving pub mod snapshot_vec; pub mod graph; pub mod bitvec; +pub mod ivar; pub mod unify; |
