about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/gc.rs99
-rw-r--r--src/libstd/lib.rs1
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 */