Skip to content

Commit 760942d

Browse files
committed
auto merge of #10576 : thestinger/rust/gc, r=pcwalton
This isn't very useful yet, but it does replace most functionality of `@T`. The `Mut<T>` type will make it unnecessary to have a `GcMut<T>` so I haven't included one. Obviously it doesn't work for trait objects but that needs to be figured out for `Rc<T>` too.
2 parents e12bc23 + 543cae9 commit 760942d

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

src/libstd/gc.rs

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/*! Task-local garbage-collected boxes
12+
13+
The `Gc` type provides shared ownership of an immutable value. Destruction is not deterministic, and
14+
will occur some time between every `Gc` handle being gone and the end of the task. The garbage
15+
collector is task-local so `Gc<T>` is not sendable.
16+
17+
*/
18+
19+
use kinds::Send;
20+
use clone::{Clone, DeepClone};
21+
22+
/// Immutable garbage-collected pointer type
23+
#[no_send]
24+
#[deriving(Clone)]
25+
pub struct Gc<T> {
26+
priv ptr: @T
27+
}
28+
29+
impl<T: 'static> Gc<T> {
30+
/// Construct a new garbage-collected box
31+
#[inline]
32+
pub fn new(value: T) -> Gc<T> {
33+
Gc { ptr: @value }
34+
}
35+
}
36+
37+
impl<T: 'static> Gc<T> {
38+
/// Borrow the value contained in the garbage-collected box
39+
#[inline]
40+
pub fn borrow<'r>(&'r self) -> &'r T {
41+
&*self.ptr
42+
}
43+
}
44+
45+
/// The `Send` bound restricts this to acyclic graphs where it is well-defined.
46+
///
47+
/// A `Freeze` bound would also work, but `Send` *or* `Freeze` cannot be expressed.
48+
impl<T: DeepClone + Send + 'static> DeepClone for Gc<T> {
49+
#[inline]
50+
fn deep_clone(&self) -> Gc<T> {
51+
Gc::new(self.borrow().deep_clone())
52+
}
53+
}
54+
55+
#[cfg(test)]
56+
mod tests {
57+
use super::*;
58+
use cell::Cell;
59+
60+
#[test]
61+
fn test_clone() {
62+
let x = Gc::new(Cell::new(5));
63+
let y = x.clone();
64+
do x.borrow().with_mut_ref |inner| {
65+
*inner = 20;
66+
}
67+
assert_eq!(y.borrow().take(), 20);
68+
}
69+
70+
#[test]
71+
fn test_deep_clone() {
72+
let x = Gc::new(Cell::new(5));
73+
let y = x.deep_clone();
74+
do x.borrow().with_mut_ref |inner| {
75+
*inner = 20;
76+
}
77+
assert_eq!(y.borrow().take(), 5);
78+
}
79+
80+
#[test]
81+
fn test_simple() {
82+
let x = Gc::new(5);
83+
assert_eq!(*x.borrow(), 5);
84+
}
85+
86+
#[test]
87+
fn test_simple_clone() {
88+
let x = Gc::new(5);
89+
let y = x.clone();
90+
assert_eq!(*x.borrow(), 5);
91+
assert_eq!(*y.borrow(), 5);
92+
}
93+
94+
#[test]
95+
fn test_destructor() {
96+
let x = Gc::new(~5);
97+
assert_eq!(**x.borrow(), 5);
98+
}
99+
}

src/libstd/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub mod owned;
133133
pub mod managed;
134134
pub mod borrow;
135135
pub mod rc;
136+
pub mod gc;
136137

137138

138139
/* Core language traits */

0 commit comments

Comments
 (0)