]> git.lizzy.rs Git - rust.git/blob - src/libstd/gc.rs
libstd: Add `Fn`/`FnMut`/`FnOnce` to the prelude.
[rust.git] / src / libstd / gc.rs
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 #![experimental]
20 #![allow(experimental)]
21
22 use clone::Clone;
23 use cmp::{Ord, PartialOrd, Ordering, Eq, PartialEq};
24 use default::Default;
25 use fmt;
26 use hash;
27 use kinds::marker;
28 use option::Option;
29 use ops::Deref;
30 use raw;
31
32 /// Immutable garbage-collected pointer type
33 #[lang="gc"]
34 #[experimental = "Gc is currently based on reference-counting and will not collect cycles until \
35                   task annihilation. For now, cycles need to be broken manually by using `Rc<T>` \
36                   with a non-owning `Weak<T>` pointer. A tracing garbage collector is planned."]
37 pub struct Gc<T> {
38     _ptr: *mut T,
39     marker: marker::NoSend,
40 }
41
42 #[unstable]
43 impl<T> Clone for Gc<T> {
44     /// Clone the pointer only
45     #[inline]
46     fn clone(&self) -> Gc<T> { *self }
47 }
48
49 /// An value that represents the task-local managed heap.
50 ///
51 /// Use this like `let foo = box(GC) Bar::new(...);`
52 #[lang="managed_heap"]
53 #[cfg(not(test))]
54 pub static GC: () = ();
55
56 impl<T: PartialEq + 'static> PartialEq for Gc<T> {
57     #[inline]
58     fn eq(&self, other: &Gc<T>) -> bool { *(*self) == *(*other) }
59     #[inline]
60     fn ne(&self, other: &Gc<T>) -> bool { *(*self) != *(*other) }
61 }
62 impl<T: PartialOrd + 'static> PartialOrd for Gc<T> {
63     #[inline]
64     fn partial_cmp(&self, other: &Gc<T>) -> Option<Ordering> {
65         (**self).partial_cmp(&**other)
66     }
67     #[inline]
68     fn lt(&self, other: &Gc<T>) -> bool { *(*self) < *(*other) }
69     #[inline]
70     fn le(&self, other: &Gc<T>) -> bool { *(*self) <= *(*other) }
71     #[inline]
72     fn ge(&self, other: &Gc<T>) -> bool { *(*self) >= *(*other) }
73     #[inline]
74     fn gt(&self, other: &Gc<T>) -> bool { *(*self) > *(*other) }
75 }
76 impl<T: Ord + 'static> Ord for Gc<T> {
77     #[inline]
78     fn cmp(&self, other: &Gc<T>) -> Ordering { (**self).cmp(&**other) }
79 }
80 impl<T: Eq + 'static> Eq for Gc<T> {}
81
82 impl<T: 'static> Deref<T> for Gc<T> {
83     fn deref<'a>(&'a self) -> &'a T { &**self }
84 }
85
86 impl<T: Default + 'static> Default for Gc<T> {
87     fn default() -> Gc<T> {
88         box(GC) Default::default()
89     }
90 }
91
92 impl<T: 'static> raw::Repr<*const raw::Box<T>> for Gc<T> {}
93
94 impl<S: hash::Writer, T: hash::Hash<S> + 'static> hash::Hash<S> for Gc<T> {
95     fn hash(&self, s: &mut S) {
96         (**self).hash(s)
97     }
98 }
99
100 impl<T: 'static + fmt::Show> fmt::Show for Gc<T> {
101     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
102         (**self).fmt(f)
103     }
104 }
105
106 #[cfg(test)]
107 mod tests {
108     use prelude::*;
109     use super::*;
110     use cell::RefCell;
111
112     #[test]
113     fn test_managed_clone() {
114         let a = box(GC) 5i;
115         let b: Gc<int> = a.clone();
116         assert!(a == b);
117     }
118
119     #[test]
120     fn test_clone() {
121         let x = Gc::new(RefCell::new(5));
122         let y = x.clone();
123         *x.borrow().borrow_mut() = 20;
124         assert_eq!(*y.borrow().borrow(), 20);
125     }
126
127     #[test]
128     fn test_simple() {
129         let x = Gc::new(5);
130         assert_eq!(*x.borrow(), 5);
131     }
132
133     #[test]
134     fn test_simple_clone() {
135         let x = Gc::new(5);
136         let y = x.clone();
137         assert_eq!(*x.borrow(), 5);
138         assert_eq!(*y.borrow(), 5);
139     }
140
141     #[test]
142     fn test_ptr_eq() {
143         let x = Gc::new(5);
144         let y = x.clone();
145         let z = Gc::new(7);
146         assert!(x.ptr_eq(&x));
147         assert!(x.ptr_eq(&y));
148         assert!(!x.ptr_eq(&z));
149     }
150
151     #[test]
152     fn test_destructor() {
153         let x = Gc::new(box 5);
154         assert_eq!(**x.borrow(), 5);
155     }
156 }