(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(valueT) -> 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  }