diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-05-01 11:19:56 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-05-07 08:16:14 -0700 |
| commit | f62c121eb0de35ac03a7860e6039202f2522e527 (patch) | |
| tree | ceabe832921580a94cc4892ec5c134f05dbadc43 /src/libstd | |
| parent | d4b5d82a3356630ede4ce1b436cb59760be7b703 (diff) | |
| download | rust-f62c121eb0de35ac03a7860e6039202f2522e527.tar.gz rust-f62c121eb0de35ac03a7860e6039202f2522e527.zip | |
core: Inherit the cell module
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/cell.rs | 317 | ||||
| -rw-r--r-- | src/libstd/fmt/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 2 |
3 files changed, 3 insertions, 318 deletions
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs deleted file mode 100644 index 1e4faf1a899..00000000000 --- a/src/libstd/cell.rs +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright 2012-2013 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. - -//! Types dealing with dynamic mutability - -use clone::Clone; -use cmp::Eq; -use fmt; -use kinds::{marker, Copy}; -use ops::{Deref, DerefMut, Drop}; -use option::{None, Option, Some}; -use ty::Unsafe; - -/// A mutable memory location that admits only `Copy` data. -pub struct Cell<T> { - value: Unsafe<T>, - noshare: marker::NoShare, -} - -impl<T:Copy> Cell<T> { - /// Creates a new `Cell` containing the given value. - pub fn new(value: T) -> Cell<T> { - Cell { - value: Unsafe::new(value), - noshare: marker::NoShare, - } - } - - /// Returns a copy of the contained value. - #[inline] - pub fn get(&self) -> T { - unsafe{ *self.value.get() } - } - - /// Sets the contained value. - #[inline] - pub fn set(&self, value: T) { - unsafe { - *self.value.get() = value; - } - } -} - -impl<T:Copy> Clone for Cell<T> { - fn clone(&self) -> Cell<T> { - Cell::new(self.get()) - } -} - -impl<T:Eq + Copy> Eq for Cell<T> { - fn eq(&self, other: &Cell<T>) -> bool { - self.get() == other.get() - } -} - -impl<T: Copy + fmt::Show> fmt::Show for Cell<T> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f.buf, r"Cell \{ value: {} \}", self.get()) - } -} - -/// A mutable memory location with dynamically checked borrow rules -pub struct RefCell<T> { - value: Unsafe<T>, - borrow: Cell<BorrowFlag>, - nocopy: marker::NoCopy, - noshare: marker::NoShare, -} - -// Values [1, MAX-1] represent the number of `Ref` active -// (will not outgrow its range since `uint` is the size of the address space) -type BorrowFlag = uint; -static UNUSED: BorrowFlag = 0; -static WRITING: BorrowFlag = -1; - -impl<T> RefCell<T> { - /// Create a new `RefCell` containing `value` - pub fn new(value: T) -> RefCell<T> { - RefCell { - value: Unsafe::new(value), - borrow: Cell::new(UNUSED), - nocopy: marker::NoCopy, - noshare: marker::NoShare, - } - } - - /// Consumes the `RefCell`, returning the wrapped value. - pub fn unwrap(self) -> T { - debug_assert!(self.borrow.get() == UNUSED); - unsafe{self.value.unwrap()} - } - - /// Attempts to immutably borrow the wrapped value. - /// - /// The borrow lasts until the returned `Ref` exits scope. Multiple - /// immutable borrows can be taken out at the same time. - /// - /// Returns `None` if the value is currently mutably borrowed. - pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> { - match self.borrow.get() { - WRITING => None, - borrow => { - self.borrow.set(borrow + 1); - Some(Ref { parent: self }) - } - } - } - - /// Immutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `Ref` exits scope. Multiple - /// immutable borrows can be taken out at the same time. - /// - /// # Failure - /// - /// Fails if the value is currently mutably borrowed. - pub fn borrow<'a>(&'a self) -> Ref<'a, T> { - match self.try_borrow() { - Some(ptr) => ptr, - None => fail!("RefCell<T> already mutably borrowed") - } - } - - /// Mutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `RefMut` exits scope. The value - /// cannot be borrowed while this borrow is active. - /// - /// Returns `None` if the value is currently borrowed. - pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> { - match self.borrow.get() { - UNUSED => { - self.borrow.set(WRITING); - Some(RefMut { parent: self }) - }, - _ => None - } - } - - /// Mutably borrows the wrapped value. - /// - /// The borrow lasts until the returned `RefMut` exits scope. The value - /// cannot be borrowed while this borrow is active. - /// - /// # Failure - /// - /// Fails if the value is currently borrowed. - pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> { - match self.try_borrow_mut() { - Some(ptr) => ptr, - None => fail!("RefCell<T> already borrowed") - } - } -} - -impl<T: Clone> Clone for RefCell<T> { - fn clone(&self) -> RefCell<T> { - RefCell::new(self.borrow().clone()) - } -} - -impl<T: Eq> Eq for RefCell<T> { - fn eq(&self, other: &RefCell<T>) -> bool { - *self.borrow() == *other.borrow() - } -} - -/// Wraps a borrowed reference to a value in a `RefCell` box. -pub struct Ref<'b, T> { - parent: &'b RefCell<T> -} - -#[unsafe_destructor] -impl<'b, T> Drop for Ref<'b, T> { - fn drop(&mut self) { - let borrow = self.parent.borrow.get(); - debug_assert!(borrow != WRITING && borrow != UNUSED); - self.parent.borrow.set(borrow - 1); - } -} - -impl<'b, T> Deref<T> for Ref<'b, T> { - #[inline] - fn deref<'a>(&'a self) -> &'a T { - unsafe { &*self.parent.value.get() } - } -} - -/// Wraps a mutable borrowed reference to a value in a `RefCell` box. -pub struct RefMut<'b, T> { - parent: &'b RefCell<T> -} - -#[unsafe_destructor] -impl<'b, T> Drop for RefMut<'b, T> { - fn drop(&mut self) { - let borrow = self.parent.borrow.get(); - debug_assert!(borrow == WRITING); - self.parent.borrow.set(UNUSED); - } -} - -impl<'b, T> Deref<T> for RefMut<'b, T> { - #[inline] - fn deref<'a>(&'a self) -> &'a T { - unsafe { &*self.parent.value.get() } - } -} - -impl<'b, T> DerefMut<T> for RefMut<'b, T> { - #[inline] - fn deref_mut<'a>(&'a mut self) -> &'a mut T { - unsafe { &mut *self.parent.value.get() } - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn smoketest_cell() { - let x = Cell::new(10); - assert_eq!(x, Cell::new(10)); - assert_eq!(x.get(), 10); - x.set(20); - assert_eq!(x, Cell::new(20)); - assert_eq!(x.get(), 20); - - let y = Cell::new((30, 40)); - assert_eq!(y, Cell::new((30, 40))); - assert_eq!(y.get(), (30, 40)); - } - - #[test] - fn cell_has_sensible_show() { - use str::StrSlice; - - let x = Cell::new("foo bar"); - assert!(format!("{}", x).contains(x.get())); - - x.set("baz qux"); - assert!(format!("{}", x).contains(x.get())); - } - - #[test] - fn double_imm_borrow() { - let x = RefCell::new(0); - let _b1 = x.borrow(); - x.borrow(); - } - - #[test] - fn no_mut_then_imm_borrow() { - let x = RefCell::new(0); - let _b1 = x.borrow_mut(); - assert!(x.try_borrow().is_none()); - } - - #[test] - fn no_imm_then_borrow_mut() { - let x = RefCell::new(0); - let _b1 = x.borrow(); - assert!(x.try_borrow_mut().is_none()); - } - - #[test] - fn no_double_borrow_mut() { - let x = RefCell::new(0); - let _b1 = x.borrow_mut(); - assert!(x.try_borrow_mut().is_none()); - } - - #[test] - fn imm_release_borrow_mut() { - let x = RefCell::new(0); - { - let _b1 = x.borrow(); - } - x.borrow_mut(); - } - - #[test] - fn mut_release_borrow_mut() { - let x = RefCell::new(0); - { - let _b1 = x.borrow_mut(); - } - x.borrow(); - } - - #[test] - fn double_borrow_single_release_no_borrow_mut() { - let x = RefCell::new(0); - let _b1 = x.borrow(); - { - let _b2 = x.borrow(); - } - assert!(x.try_borrow_mut().is_none()); - } - - #[test] - #[should_fail] - fn discard_doesnt_unborrow() { - let x = RefCell::new(0); - let _b = x.borrow(); - let _ = _b; - let _b = x.borrow_mut(); - } -} diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 8cfc0ae54c3..74ab874d319 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -485,6 +485,7 @@ will look like `"\\{"`. use any; use cast; +use cell::Cell; use char::Char; use cmp; use container::Container; @@ -492,6 +493,7 @@ use io::MemWriter; use io; use iter; use iter::{Iterator, range}; +use kinds::Copy; use num::Signed; use option::{Option, Some, None}; use owned::Box; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 95d67eb77d1..4a555035a08 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -141,6 +141,7 @@ extern crate core; pub use core::any; pub use core::bool; pub use core::cast; +pub use core::cell; pub use core::char; pub use core::clone; pub use core::container; @@ -220,7 +221,6 @@ pub mod hash; /* Common data structures */ pub mod result; -pub mod cell; /* Tasks and communication */ |
