(index<- ) ./libstd/gc.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
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 #![allow(experimental)]
20
21 use kinds::marker;
22 use clone::Clone;
23
24 /// Immutable garbage-collected pointer type
25 #[lang="gc"]
26 #[cfg(not(test))]
27 #[experimental = "Gc is currently based on reference-counting and will not collect cycles until \
28 task annihilation. For now, cycles need to be broken manually by using `Rc<T>` \
29 with a non-owning `Weak<T>` pointer. A tracing garbage collector is planned."]
30 pub struct Gc<T> {
31 ptr: @T,
32 marker: marker::NoSend,
33 }
34
35 #[cfg(test)]
36 pub struct Gc<T> {
37 ptr: @T,
38 marker: marker::NoSend,
39 }
40
41 impl<T: 'static> Gc<T> {
42 /// Construct a new garbage-collected box
43 #[inline]
44 pub fn new(value: T) -> Gc<T> {
45 Gc { ptr: @value, marker: marker::NoSend }
46 }
47
48 /// Borrow the value contained in the garbage-collected box
49 #[inline]
50 pub fn borrow<'r>(&'r self) -> &'r T {
51 &*self.ptr
52 }
53
54 /// Determine if two garbage-collected boxes point to the same object
55 #[inline]
56 pub fn ptr_eq(&self, other: &Gc<T>) -> bool {
57 self.borrow() as *T == other.borrow() as *T
58 }
59 }
60
61 impl<T> Clone for Gc<T> {
62 /// Clone the pointer only
63 #[inline]
64 fn clone(&self) -> Gc<T> {
65 Gc{ ptr: self.ptr, marker: marker::NoSend }
66 }
67 }
68
69 /// An value that represents the task-local managed heap.
70 ///
71 /// Use this like `let foo = box(GC) Bar::new(...);`
72 #[lang="managed_heap"]
73 #[cfg(not(test))]
74 pub static GC: () = ();
75
76 #[cfg(test)]
77 pub static GC: () = ();
78
79 #[cfg(test)]
80 mod tests {
81 use prelude::*;
82 use super::*;
83 use cell::RefCell;
84
85 #[test]
86 fn test_clone() {
87 let x = Gc::new(RefCell::new(5));
88 let y = x.clone();
89 *x.borrow().borrow_mut() = 20;
90 assert_eq!(*y.borrow().borrow(), 20);
91 }
92
93 #[test]
94 fn test_simple() {
95 let x = Gc::new(5);
96 assert_eq!(*x.borrow(), 5);
97 }
98
99 #[test]
100 fn test_simple_clone() {
101 let x = Gc::new(5);
102 let y = x.clone();
103 assert_eq!(*x.borrow(), 5);
104 assert_eq!(*y.borrow(), 5);
105 }
106
107 #[test]
108 fn test_ptr_eq() {
109 let x = Gc::new(5);
110 let y = x.clone();
111 let z = Gc::new(7);
112 assert!(x.ptr_eq(&x));
113 assert!(x.ptr_eq(&y));
114 assert!(!x.ptr_eq(&z));
115 }
116
117 #[test]
118 fn test_destructor() {
119 let x = Gc::new(box 5);
120 assert_eq!(**x.borrow(), 5);
121 }
122 }