From 03ee3f5c204cb9b20c58a5cd2d61dc792727dad7 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Mon, 20 Jul 2015 15:48:24 +0300 Subject: add an Ivar for write-only variables --- src/librustc_data_structures/ivar.rs | 70 ++++++++++++++++++++++++++++++++++++ src/librustc_data_structures/lib.rs | 1 + 2 files changed, 71 insertions(+) create mode 100644 src/librustc_data_structures/ivar.rs 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 or the MIT license +// , 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 { + data: Cell> +} + +impl Ivar { + pub fn new() -> Ivar { + Ivar { + data: Cell::new(None) + } + } + + pub fn get(&self) -> Option { + 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 fmt::Debug for Ivar { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self.get() { + Some(val) => write!(f, "Ivar({:?})", val), + None => f.write_str("Ivar()") + } + } +} + +impl Clone for Ivar { + fn clone(&self) -> Ivar { + 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; -- cgit 1.4.1-3-g733a5