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.
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.
11 /*! Task-local reference-counted boxes (`Rc` type)
13 The `Rc` type provides shared ownership of an immutable value. Destruction is deterministic, and
14 will occur as soon as the last owner is gone. It is marked as non-sendable because it avoids the
15 overhead of atomic reference counting.
17 The `downgrade` method can be used to create a non-owning `Weak` pointer to the box. A `Weak`
18 pointer can be upgraded to an `Rc` pointer, but will return `None` if the value has already been
21 For example, a tree with parent pointers can be represented by putting the nodes behind `Strong`
22 pointers, and then storing the parent pointers as `Weak` pointers.
29 use clone::{Clone, DeepClone};
30 use rt::global_heap::exchange_free;
32 use option::{Option, Some, None};
40 /// Immutable reference counted pointer type
41 #[unsafe_no_drop_flag]
44 priv ptr: *mut RcBox<T>
48 /// Construct a new reference-counted box
49 pub fn new(value: T) -> Rc<T> {
51 Rc { ptr: transmute(~RcBox { value: value, strong: 1, weak: 0 }) }
57 /// Borrow the value contained in the reference-counted box
59 pub fn borrow<'a>(&'a self) -> &'a T {
60 unsafe { &(*self.ptr).value }
63 /// Downgrade the reference-counted pointer to a weak reference
64 pub fn downgrade(&self) -> Weak<T> {
66 (*self.ptr).weak += 1;
67 Weak { ptr: self.ptr }
73 impl<T> Drop for Rc<T> {
76 if self.ptr != 0 as *mut RcBox<T> {
77 (*self.ptr).strong -= 1;
78 if (*self.ptr).strong == 0 {
79 read_ptr(self.borrow()); // destroy the contained object
80 if (*self.ptr).weak == 0 {
81 exchange_free(self.ptr as *mut u8 as *i8)
89 impl<T> Clone for Rc<T> {
91 fn clone(&self) -> Rc<T> {
93 (*self.ptr).strong += 1;
99 impl<T: DeepClone> DeepClone for Rc<T> {
101 fn deep_clone(&self) -> Rc<T> {
102 Rc::new(self.borrow().deep_clone())
106 impl<T: Eq> Eq for Rc<T> {
108 fn eq(&self, other: &Rc<T>) -> bool { *self.borrow() == *other.borrow() }
111 fn ne(&self, other: &Rc<T>) -> bool { *self.borrow() != *other.borrow() }
114 impl<T: Ord> Ord for Rc<T> {
116 fn lt(&self, other: &Rc<T>) -> bool { *self.borrow() < *other.borrow() }
119 fn le(&self, other: &Rc<T>) -> bool { *self.borrow() <= *other.borrow() }
122 fn gt(&self, other: &Rc<T>) -> bool { *self.borrow() > *other.borrow() }
125 fn ge(&self, other: &Rc<T>) -> bool { *self.borrow() >= *other.borrow() }
128 /// Weak reference to a reference-counted box
129 #[unsafe_no_drop_flag]
132 priv ptr: *mut RcBox<T>
136 /// Upgrade a weak reference to a strong reference
137 pub fn upgrade(&self) -> Option<Rc<T>> {
139 if (*self.ptr).strong == 0 {
142 (*self.ptr).strong += 1;
143 Some(Rc { ptr: self.ptr })
150 impl<T> Drop for Weak<T> {
153 if self.ptr != 0 as *mut RcBox<T> {
154 (*self.ptr).weak -= 1;
155 if (*self.ptr).weak == 0 && (*self.ptr).strong == 0 {
156 exchange_free(self.ptr as *mut u8 as *i8)
163 impl<T> Clone for Weak<T> {
165 fn clone(&self) -> Weak<T> {
167 (*self.ptr).weak += 1;
168 Weak { ptr: self.ptr }
181 let y = x.downgrade();
182 assert!(y.upgrade().is_some());
188 let y = x.downgrade();
190 assert!(y.upgrade().is_none());