auto merge of #19112 : steveklabnik/rust/doc_rc, r=Gankro
This commit is contained in:
commit
4eb72d268f
1 changed files with 296 additions and 57 deletions
|
@ -8,27 +8,25 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
//! Task-local reference-counted boxes (the `Rc` type).
|
//! Task-local reference-counted boxes (the `Rc<T>` type).
|
||||||
//!
|
//!
|
||||||
//! The `Rc` type provides shared ownership of an immutable value. Destruction is
|
//! The `Rc<T>` type provides shared ownership of an immutable value. Destruction is deterministic,
|
||||||
//! deterministic, and will occur as soon as the last owner is gone. It is marked
|
//! and will occur as soon as the last owner is gone. It is marked as non-sendable because it
|
||||||
//! as non-sendable because it avoids the overhead of atomic reference counting.
|
//! avoids the overhead of atomic reference counting.
|
||||||
//!
|
//!
|
||||||
//! The `downgrade` method can be used to create a non-owning `Weak` pointer to the
|
//! The `downgrade` method can be used to create a non-owning `Weak<T>` pointer to the box. A
|
||||||
//! box. A `Weak` pointer can be upgraded to an `Rc` pointer, but will return
|
//! `Weak<T>` pointer can be upgraded to an `Rc<T>` pointer, but will return `None` if the value
|
||||||
//! `None` if the value has already been freed.
|
//! has already been dropped.
|
||||||
//!
|
//!
|
||||||
//! For example, a tree with parent pointers can be represented by putting the
|
//! For example, a tree with parent pointers can be represented by putting the nodes behind strong
|
||||||
//! nodes behind strong `Rc` pointers, and then storing the parent pointers as
|
//! `Rc<T>` pointers, and then storing the parent pointers as `Weak<T>` pointers.
|
||||||
//! `Weak` pointers.
|
|
||||||
//!
|
//!
|
||||||
//! # Examples
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
//! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`.
|
//! Consider a scenario where a set of `Gadget`s are owned by a given `Owner`. We want to have our
|
||||||
//! We want to have our `Gadget`s point to their `Owner`. We can't do this with
|
//! `Gadget`s point to their `Owner`. We can't do this with unique ownership, because more than one
|
||||||
//! unique ownership, because more than one gadget may belong to the same
|
//! gadget may belong to the same `Owner`. `Rc<T>` allows us to share an `Owner` between multiple
|
||||||
//! `Owner`. `Rc` allows us to share an `Owner` between multiple `Gadget`s, and
|
//! `Gadget`s, and have the `Owner` remain allocated as long as any `Gadget` points at it.
|
||||||
//! have the `Owner` kept alive as long as any `Gadget` points at it.
|
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! use std::rc::Rc;
|
//! use std::rc::Rc;
|
||||||
|
@ -51,7 +49,7 @@
|
||||||
//! );
|
//! );
|
||||||
//!
|
//!
|
||||||
//! // Create Gadgets belonging to gadget_owner. To increment the reference
|
//! // Create Gadgets belonging to gadget_owner. To increment the reference
|
||||||
//! // count we clone the Rc object.
|
//! // count we clone the `Rc<T>` object.
|
||||||
//! let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() };
|
//! let gadget1 = Gadget { id: 1, owner: gadget_owner.clone() };
|
||||||
//! let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() };
|
//! let gadget2 = Gadget { id: 2, owner: gadget_owner.clone() };
|
||||||
//!
|
//!
|
||||||
|
@ -60,8 +58,8 @@
|
||||||
//! // Despite dropping gadget_owner, we're still able to print out the name of
|
//! // Despite dropping gadget_owner, we're still able to print out the name of
|
||||||
//! // the Owner of the Gadgets. This is because we've only dropped the
|
//! // the Owner of the Gadgets. This is because we've only dropped the
|
||||||
//! // reference count object, not the Owner it wraps. As long as there are
|
//! // reference count object, not the Owner it wraps. As long as there are
|
||||||
//! // other Rc objects pointing at the same Owner, it will stay alive. Notice
|
//! // other `Rc<T>` objects pointing at the same Owner, it will remain allocated. Notice
|
||||||
//! // that the Rc wrapper around Gadget.owner gets automatically dereferenced
|
//! // that the `Rc<T>` wrapper around Gadget.owner gets automatically dereferenced
|
||||||
//! // for us.
|
//! // for us.
|
||||||
//! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
|
//! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
|
||||||
//! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
|
//! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
|
||||||
|
@ -72,23 +70,19 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! If our requirements change, and we also need to be able to traverse from
|
//! If our requirements change, and we also need to be able to traverse from Owner → Gadget, we
|
||||||
//! Owner → Gadget, we will run into problems: an `Rc` pointer from Owner → Gadget
|
//! will run into problems: an `Rc<T>` pointer from Owner → Gadget introduces a cycle between the
|
||||||
//! introduces a cycle between the objects. This means that their reference counts
|
//! objects. This means that their reference counts can never reach 0, and the objects will remain
|
||||||
//! can never reach 0, and the objects will stay alive: a memory leak. In order to
|
//! allocated: a memory leak. In order to get around this, we can use `Weak<T>` pointers. These
|
||||||
//! get around this, we can use `Weak` pointers. These are reference counted
|
//! pointers don't contribute to the total count.
|
||||||
//! pointers that don't keep an object alive if there are no normal `Rc` (or
|
|
||||||
//! *strong*) pointers left.
|
|
||||||
//!
|
//!
|
||||||
//! Rust actually makes it somewhat difficult to produce this loop in the first
|
//! Rust actually makes it somewhat difficult to produce this loop in the first place: in order to
|
||||||
//! place: in order to end up with two objects that point at each other, one of
|
//! end up with two objects that point at each other, one of them needs to be mutable. This is
|
||||||
//! them needs to be mutable. This is problematic because `Rc` enforces memory
|
//! problematic because `Rc<T>` enforces memory safety by only giving out shared references to the
|
||||||
//! safety by only giving out shared references to the object it wraps, and these
|
//! object it wraps, and these don't allow direct mutation. We need to wrap the part of the object
|
||||||
//! don't allow direct mutation. We need to wrap the part of the object we wish to
|
//! we wish to mutate in a `RefCell`, which provides *interior mutability*: a method to achieve
|
||||||
//! mutate in a `RefCell`, which provides *interior mutability*: a method to
|
//! mutability through a shared reference. `RefCell` enforces Rust's borrowing rules at runtime.
|
||||||
//! achieve mutability through a shared reference. `RefCell` enforces Rust's
|
//! Read the `Cell` documentation for more details on interior mutability.
|
||||||
//! borrowing rules at runtime. Read the `Cell` documentation for more details on
|
|
||||||
//! interior mutability.
|
|
||||||
//!
|
//!
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! use std::rc::Rc;
|
//! use std::rc::Rc;
|
||||||
|
@ -131,7 +125,7 @@
|
||||||
//! for gadget_opt in gadget_owner.gadgets.borrow().iter() {
|
//! for gadget_opt in gadget_owner.gadgets.borrow().iter() {
|
||||||
//!
|
//!
|
||||||
//! // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee
|
//! // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee
|
||||||
//! // that their object is still alive, we need to call upgrade() on them
|
//! // that their object is still allocated, we need to call upgrade() on them
|
||||||
//! // to turn them into a strong reference. This returns an Option, which
|
//! // to turn them into a strong reference. This returns an Option, which
|
||||||
//! // contains a reference to our object if it still exists.
|
//! // contains a reference to our object if it still exists.
|
||||||
//! let gadget = gadget_opt.upgrade().unwrap();
|
//! let gadget = gadget_opt.upgrade().unwrap();
|
||||||
|
@ -139,7 +133,7 @@
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! // At the end of the method, gadget_owner, gadget1 and gadget2 get
|
//! // At the end of the method, gadget_owner, gadget1 and gadget2 get
|
||||||
//! // destroyed. There are now no strong (Rc) references to the gadgets.
|
//! // destroyed. There are now no strong (`Rc<T>`) references to the gadgets.
|
||||||
//! // Once they get destroyed, the Gadgets get destroyed. This zeroes the
|
//! // Once they get destroyed, the Gadgets get destroyed. This zeroes the
|
||||||
//! // reference count on Gadget Man, so he gets destroyed as well.
|
//! // reference count on Gadget Man, so he gets destroyed as well.
|
||||||
//! }
|
//! }
|
||||||
|
@ -169,6 +163,8 @@ struct RcBox<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An immutable reference-counted pointer type.
|
/// An immutable reference-counted pointer type.
|
||||||
|
///
|
||||||
|
/// See the [module level documentation](../index.html) for more.
|
||||||
#[unsafe_no_drop_flag]
|
#[unsafe_no_drop_flag]
|
||||||
#[stable]
|
#[stable]
|
||||||
pub struct Rc<T> {
|
pub struct Rc<T> {
|
||||||
|
@ -180,7 +176,15 @@ pub struct Rc<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Rc<T> {
|
impl<T> Rc<T> {
|
||||||
/// Constructs a new reference-counted pointer.
|
/// Constructs a new `Rc<T>`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[stable]
|
#[stable]
|
||||||
pub fn new(value: T) -> Rc<T> {
|
pub fn new(value: T) -> Rc<T> {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -201,7 +205,17 @@ impl<T> Rc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Downgrades the reference-counted pointer to a weak reference.
|
/// Downgrades the `Rc<T>` to a `Weak<T>` reference.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// let weak_five = five.downgrade();
|
||||||
|
/// ```
|
||||||
#[experimental = "Weak pointers may not belong in this module"]
|
#[experimental = "Weak pointers may not belong in this module"]
|
||||||
pub fn downgrade(&self) -> Weak<T> {
|
pub fn downgrade(&self) -> Weak<T> {
|
||||||
self.inc_weak();
|
self.inc_weak();
|
||||||
|
@ -223,27 +237,36 @@ pub fn weak_count<T>(this: &Rc<T>) -> uint { this.weak() - 1 }
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn strong_count<T>(this: &Rc<T>) -> uint { this.strong() }
|
pub fn strong_count<T>(this: &Rc<T>) -> uint { this.strong() }
|
||||||
|
|
||||||
/// Returns true if the `Rc` currently has unique ownership.
|
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the same inner value.
|
||||||
///
|
///
|
||||||
/// Unique ownership means that there are no other `Rc` or `Weak` values
|
/// # Examples
|
||||||
/// that share the same contents.
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc;
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// rc::is_unique(&five);
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn is_unique<T>(rc: &Rc<T>) -> bool {
|
pub fn is_unique<T>(rc: &Rc<T>) -> bool {
|
||||||
weak_count(rc) == 0 && strong_count(rc) == 1
|
weak_count(rc) == 0 && strong_count(rc) == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwraps the contained value if the `Rc` has unique ownership.
|
/// Unwraps the contained value if the `Rc<T>` is unique.
|
||||||
///
|
///
|
||||||
/// If the `Rc` does not have unique ownership, `Err` is returned with the
|
/// If the `Rc<T>` is not unique, an `Err` is returned with the same `Rc<T>`.
|
||||||
/// same `Rc`.
|
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::rc::{mod, Rc};
|
/// use std::rc::{mod, Rc};
|
||||||
|
///
|
||||||
/// let x = Rc::new(3u);
|
/// let x = Rc::new(3u);
|
||||||
/// assert_eq!(rc::try_unwrap(x), Ok(3u));
|
/// assert_eq!(rc::try_unwrap(x), Ok(3u));
|
||||||
|
///
|
||||||
/// let x = Rc::new(4u);
|
/// let x = Rc::new(4u);
|
||||||
/// let _y = x.clone();
|
/// let _y = x.clone();
|
||||||
/// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4u)));
|
/// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4u)));
|
||||||
|
@ -266,18 +289,19 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable reference to the contained value if the `Rc` has
|
/// Returns a mutable reference to the contained value if the `Rc<T>` is unique.
|
||||||
/// unique ownership.
|
|
||||||
///
|
///
|
||||||
/// Returns `None` if the `Rc` does not have unique ownership.
|
/// Returns `None` if the `Rc<T>` is not unique.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::rc::{mod, Rc};
|
/// use std::rc::{mod, Rc};
|
||||||
|
///
|
||||||
/// let mut x = Rc::new(3u);
|
/// let mut x = Rc::new(3u);
|
||||||
/// *rc::get_mut(&mut x).unwrap() = 4u;
|
/// *rc::get_mut(&mut x).unwrap() = 4u;
|
||||||
/// assert_eq!(*x, 4u);
|
/// assert_eq!(*x, 4u);
|
||||||
|
///
|
||||||
/// let _y = x.clone();
|
/// let _y = x.clone();
|
||||||
/// assert!(rc::get_mut(&mut x).is_none());
|
/// assert!(rc::get_mut(&mut x).is_none());
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -293,11 +317,20 @@ pub fn get_mut<'a, T>(rc: &'a mut Rc<T>) -> Option<&'a mut T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Rc<T> {
|
impl<T: Clone> Rc<T> {
|
||||||
/// Acquires a mutable pointer to the inner contents by guaranteeing that
|
/// Make a mutable reference from the given `Rc<T>`.
|
||||||
/// the reference count is one (no sharing is possible).
|
|
||||||
///
|
///
|
||||||
/// This is also referred to as a copy-on-write operation because the inner
|
/// This is also referred to as a copy-on-write operation because the inner data is cloned if
|
||||||
/// data is cloned if the reference count is greater than one.
|
/// the reference count is greater than one.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let mut five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// let mut_five = five.make_unique();
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[experimental]
|
#[experimental]
|
||||||
pub fn make_unique(&mut self) -> &mut T {
|
pub fn make_unique(&mut self) -> &mut T {
|
||||||
|
@ -307,8 +340,8 @@ impl<T: Clone> Rc<T> {
|
||||||
// This unsafety is ok because we're guaranteed that the pointer
|
// This unsafety is ok because we're guaranteed that the pointer
|
||||||
// returned is the *only* pointer that will ever be returned to T. Our
|
// returned is the *only* pointer that will ever be returned to T. Our
|
||||||
// reference count is guaranteed to be 1 at this point, and we required
|
// reference count is guaranteed to be 1 at this point, and we required
|
||||||
// the Rc itself to be `mut`, so we're returning the only possible
|
// the `Rc<T>` itself to be `mut`, so we're returning the only possible
|
||||||
// reference to the inner data.
|
// reference to the inner value.
|
||||||
let inner = unsafe { &mut *self._ptr };
|
let inner = unsafe { &mut *self._ptr };
|
||||||
&mut inner.value
|
&mut inner.value
|
||||||
}
|
}
|
||||||
|
@ -316,7 +349,6 @@ impl<T: Clone> Rc<T> {
|
||||||
|
|
||||||
#[experimental = "Deref is experimental."]
|
#[experimental = "Deref is experimental."]
|
||||||
impl<T> Deref<T> for Rc<T> {
|
impl<T> Deref<T> for Rc<T> {
|
||||||
/// Borrows the value contained in the reference-counted pointer.
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
&self.inner().value
|
&self.inner().value
|
||||||
|
@ -326,6 +358,30 @@ impl<T> Deref<T> for Rc<T> {
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
#[experimental = "Drop is experimental."]
|
#[experimental = "Drop is experimental."]
|
||||||
impl<T> Drop for Rc<T> {
|
impl<T> Drop for Rc<T> {
|
||||||
|
/// Drops the `Rc<T>`.
|
||||||
|
///
|
||||||
|
/// This will decrement the strong reference count. If the strong reference count becomes zero
|
||||||
|
/// and the only other references are `Weak<T>` ones, `drop`s the inner value.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// // stuff
|
||||||
|
///
|
||||||
|
/// drop(five); // explict drop
|
||||||
|
/// }
|
||||||
|
/// {
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// // stuff
|
||||||
|
///
|
||||||
|
/// } // implicit drop
|
||||||
|
/// ```
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !self._ptr.is_null() {
|
if !self._ptr.is_null() {
|
||||||
|
@ -349,6 +405,19 @@ impl<T> Drop for Rc<T> {
|
||||||
|
|
||||||
#[unstable = "Clone is unstable."]
|
#[unstable = "Clone is unstable."]
|
||||||
impl<T> Clone for Rc<T> {
|
impl<T> Clone for Rc<T> {
|
||||||
|
/// Makes a clone of the `Rc<T>`.
|
||||||
|
///
|
||||||
|
/// This increases the strong reference count.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five.clone();
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Rc<T> {
|
fn clone(&self) -> Rc<T> {
|
||||||
self.inc_strong();
|
self.inc_strong();
|
||||||
|
@ -358,6 +427,16 @@ impl<T> Clone for Rc<T> {
|
||||||
|
|
||||||
#[stable]
|
#[stable]
|
||||||
impl<T: Default> Default for Rc<T> {
|
impl<T: Default> Default for Rc<T> {
|
||||||
|
/// Creates a new `Rc<T>`, with the `Default` value for `T`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
/// use std::default::Default;
|
||||||
|
///
|
||||||
|
/// let x: Rc<int> = Default::default();
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Rc<T> {
|
fn default() -> Rc<T> {
|
||||||
Rc::new(Default::default())
|
Rc::new(Default::default())
|
||||||
|
@ -366,8 +445,35 @@ impl<T: Default> Default for Rc<T> {
|
||||||
|
|
||||||
#[unstable = "PartialEq is unstable."]
|
#[unstable = "PartialEq is unstable."]
|
||||||
impl<T: PartialEq> PartialEq for Rc<T> {
|
impl<T: PartialEq> PartialEq for Rc<T> {
|
||||||
|
/// Equality for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// Two `Rc<T>`s are equal if their inner value are equal.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five == Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
|
fn eq(&self, other: &Rc<T>) -> bool { **self == **other }
|
||||||
|
|
||||||
|
/// Inequality for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// Two `Rc<T>`s are unequal if their inner value are unequal.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five != Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
|
fn ne(&self, other: &Rc<T>) -> bool { **self != **other }
|
||||||
}
|
}
|
||||||
|
@ -377,26 +483,104 @@ impl<T: Eq> Eq for Rc<T> {}
|
||||||
|
|
||||||
#[unstable = "PartialOrd is unstable."]
|
#[unstable = "PartialOrd is unstable."]
|
||||||
impl<T: PartialOrd> PartialOrd for Rc<T> {
|
impl<T: PartialOrd> PartialOrd for Rc<T> {
|
||||||
|
/// Partial comparison for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// The two are compared by calling `partial_cmp()` on their inner values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five.partial_cmp(&Rc::new(5i));
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Rc<T>) -> Option<Ordering> {
|
||||||
(**self).partial_cmp(&**other)
|
(**self).partial_cmp(&**other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Less-than comparison for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// The two are compared by calling `<` on their inner values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five < Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
|
fn lt(&self, other: &Rc<T>) -> bool { **self < **other }
|
||||||
|
|
||||||
|
/// 'Less-than or equal to' comparison for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// The two are compared by calling `<=` on their inner values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five <= Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn le(&self, other: &Rc<T>) -> bool { **self <= **other }
|
fn le(&self, other: &Rc<T>) -> bool { **self <= **other }
|
||||||
|
|
||||||
|
/// Greater-than comparison for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// The two are compared by calling `>` on their inner values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five > Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
|
fn gt(&self, other: &Rc<T>) -> bool { **self > **other }
|
||||||
|
|
||||||
|
/// 'Greater-than or equal to' comparison for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// The two are compared by calling `>=` on their inner values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five >= Rc::new(5i);
|
||||||
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
|
fn ge(&self, other: &Rc<T>) -> bool { **self >= **other }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable = "Ord is unstable."]
|
#[unstable = "Ord is unstable."]
|
||||||
impl<T: Ord> Ord for Rc<T> {
|
impl<T: Ord> Ord for Rc<T> {
|
||||||
|
/// Comparison for two `Rc<T>`s.
|
||||||
|
///
|
||||||
|
/// The two are compared by calling `cmp()` on their inner values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// five.partial_cmp(&Rc::new(5i));
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
|
fn cmp(&self, other: &Rc<T>) -> Ordering { (**self).cmp(&**other) }
|
||||||
}
|
}
|
||||||
|
@ -408,7 +592,11 @@ impl<T: fmt::Show> fmt::Show for Rc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A weak reference to a reference-counted pointer.
|
/// A weak version of `Rc<T>`.
|
||||||
|
///
|
||||||
|
/// Weak references do not count when determining if the inner value should be dropped.
|
||||||
|
///
|
||||||
|
/// See the [module level documentation](../index.html) for more.
|
||||||
#[unsafe_no_drop_flag]
|
#[unsafe_no_drop_flag]
|
||||||
#[experimental = "Weak pointers may not belong in this module."]
|
#[experimental = "Weak pointers may not belong in this module."]
|
||||||
pub struct Weak<T> {
|
pub struct Weak<T> {
|
||||||
|
@ -423,8 +611,21 @@ pub struct Weak<T> {
|
||||||
impl<T> Weak<T> {
|
impl<T> Weak<T> {
|
||||||
/// Upgrades a weak reference to a strong reference.
|
/// Upgrades a weak reference to a strong reference.
|
||||||
///
|
///
|
||||||
/// Returns `None` if there were no strong references and the data was
|
/// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
|
||||||
/// destroyed.
|
///
|
||||||
|
/// Returns `None` if there were no strong references and the data was destroyed.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
///
|
||||||
|
/// let weak_five = five.downgrade();
|
||||||
|
///
|
||||||
|
/// let strong_five: Option<Rc<_>> = weak_five.upgrade();
|
||||||
|
/// ```
|
||||||
pub fn upgrade(&self) -> Option<Rc<T>> {
|
pub fn upgrade(&self) -> Option<Rc<T>> {
|
||||||
if self.strong() == 0 {
|
if self.strong() == 0 {
|
||||||
None
|
None
|
||||||
|
@ -438,6 +639,31 @@ impl<T> Weak<T> {
|
||||||
#[unsafe_destructor]
|
#[unsafe_destructor]
|
||||||
#[experimental = "Weak pointers may not belong in this module."]
|
#[experimental = "Weak pointers may not belong in this module."]
|
||||||
impl<T> Drop for Weak<T> {
|
impl<T> Drop for Weak<T> {
|
||||||
|
/// Drops the `Weak<T>`.
|
||||||
|
///
|
||||||
|
/// This will decrement the weak reference count.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// {
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
/// let weak_five = five.downgrade();
|
||||||
|
///
|
||||||
|
/// // stuff
|
||||||
|
///
|
||||||
|
/// drop(weak_five); // explict drop
|
||||||
|
/// }
|
||||||
|
/// {
|
||||||
|
/// let five = Rc::new(5i);
|
||||||
|
/// let weak_five = five.downgrade();
|
||||||
|
///
|
||||||
|
/// // stuff
|
||||||
|
///
|
||||||
|
/// } // implicit drop
|
||||||
|
/// ```
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if !self._ptr.is_null() {
|
if !self._ptr.is_null() {
|
||||||
|
@ -455,6 +681,19 @@ impl<T> Drop for Weak<T> {
|
||||||
|
|
||||||
#[experimental = "Weak pointers may not belong in this module."]
|
#[experimental = "Weak pointers may not belong in this module."]
|
||||||
impl<T> Clone for Weak<T> {
|
impl<T> Clone for Weak<T> {
|
||||||
|
/// Makes a clone of the `Weak<T>`.
|
||||||
|
///
|
||||||
|
/// This increases the weak reference count.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::rc::Rc;
|
||||||
|
///
|
||||||
|
/// let weak_five = Rc::new(5i).downgrade();
|
||||||
|
///
|
||||||
|
/// weak_five.clone();
|
||||||
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
fn clone(&self) -> Weak<T> {
|
fn clone(&self) -> Weak<T> {
|
||||||
self.inc_weak();
|
self.inc_weak();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue