diff options
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/gc.rs | 99 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 1 |
2 files changed, 100 insertions, 0 deletions
diff --git a/src/libstd/gc.rs b/src/libstd/gc.rs new file mode 100644 index 00000000000..5e2ba808d31 --- /dev/null +++ b/src/libstd/gc.rs @@ -0,0 +1,99 @@ +// Copyright 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. + +/*! Task-local garbage-collected boxes + +The `Gc` type provides shared ownership of an immutable value. Destruction is not deterministic, and +will occur some time between every `Gc` handle being gone and the end of the task. The garbage +collector is task-local so `Gc<T>` is not sendable. + +*/ + +use kinds::Send; +use clone::{Clone, DeepClone}; + +/// Immutable garbage-collected pointer type +#[no_send] +#[deriving(Clone)] +pub struct Gc<T> { + priv ptr: @T +} + +impl<T: 'static> Gc<T> { + /// Construct a new garbage-collected box + #[inline] + pub fn new(value: T) -> Gc<T> { + Gc { ptr: @value } + } +} + +impl<T: 'static> Gc<T> { + /// Borrow the value contained in the garbage-collected box + #[inline] + pub fn borrow<'r>(&'r self) -> &'r T { + &*self.ptr + } +} + +/// The `Send` bound restricts this to acyclic graphs where it is well-defined. +/// +/// A `Freeze` bound would also work, but `Send` *or* `Freeze` cannot be expressed. +impl<T: DeepClone + Send + 'static> DeepClone for Gc<T> { + #[inline] + fn deep_clone(&self) -> Gc<T> { + Gc::new(self.borrow().deep_clone()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use cell::Cell; + + #[test] + fn test_clone() { + let x = Gc::new(Cell::new(5)); + let y = x.clone(); + do x.borrow().with_mut_ref |inner| { + *inner = 20; + } + assert_eq!(y.borrow().take(), 20); + } + + #[test] + fn test_deep_clone() { + let x = Gc::new(Cell::new(5)); + let y = x.deep_clone(); + do x.borrow().with_mut_ref |inner| { + *inner = 20; + } + assert_eq!(y.borrow().take(), 5); + } + + #[test] + fn test_simple() { + let x = Gc::new(5); + assert_eq!(*x.borrow(), 5); + } + + #[test] + fn test_simple_clone() { + let x = Gc::new(5); + let y = x.clone(); + assert_eq!(*x.borrow(), 5); + assert_eq!(*y.borrow(), 5); + } + + #[test] + fn test_destructor() { + let x = Gc::new(~5); + assert_eq!(**x.borrow(), 5); + } +} diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e0908dcb290..ffa91df4e8a 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -133,6 +133,7 @@ pub mod owned; pub mod managed; pub mod borrow; pub mod rc; +pub mod gc; /* Core language traits */ |
