use core::ptr::{self, PtrExt};
use core::result::Result;
use core::result::Result::{Ok, Err};
+use core::intrinsics::assume;
use heap::deallocate;
/// See the [module level documentation](../index.html) for more details.
#[unsafe_no_drop_flag]
#[stable]
-#[cfg(stage0)] // NOTE remove impl after next snapshot
pub struct Rc<T> {
// FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
// type via Deref
_ptr: NonZero<*mut RcBox<T>>,
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
}
-/// An immutable reference-counted pointer type.
-///
-/// See the [module level documentation](../index.html) for more details.
-#[unsafe_no_drop_flag]
-#[stable]
-#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
-pub struct Rc<T> {
- // FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
- // type via Deref
- _ptr: NonZero<*mut RcBox<T>>,
-}
-
-#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
impl<T> !marker::Send for Rc<T> {}
-#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
impl<T> !marker::Sync for Rc<T> {}
impl<T> Rc<T> {
- /// Constructs a new `Rc<T>`.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::rc::Rc;
- ///
- /// let five = Rc::new(5i);
- /// ```
- #[stable]
- #[cfg(stage0)] // NOTE remove after next snapshot
- pub fn new(value: T) -> Rc<T> {
- unsafe {
- Rc {
- // there is an implicit weak pointer owned by all the strong pointers, which
- // ensures that the weak destructor never frees the allocation while the strong
- // destructor is running, even if the weak pointer is stored inside the strong one.
- _ptr: NonZero::new(transmute(box RcBox {
- value: value,
- strong: Cell::new(1),
- weak: Cell::new(1)
- })),
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
- }
- }
- }
/// Constructs a new `Rc<T>`.
///
/// let five = Rc::new(5i);
/// ```
#[stable]
- #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
pub fn new(value: T) -> Rc<T> {
unsafe {
Rc {
///
/// let weak_five = five.downgrade();
/// ```
- #[cfg(stage0)] // NOTE remove after next snapshot
- #[unstable = "Weak pointers may not belong in this module"]
- pub fn downgrade(&self) -> Weak<T> {
- self.inc_weak();
- Weak {
- _ptr: self._ptr,
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
- }
- }
-
- /// Downgrades the `Rc<T>` to a `Weak<T>` reference.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::rc::Rc;
- ///
- /// let five = Rc::new(5i);
- ///
- /// let weak_five = five.downgrade();
- /// ```
- #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
#[unstable = "Weak pointers may not belong in this module"]
pub fn downgrade(&self) -> Weak<T> {
self.inc_weak();
#[stable]
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]
- #[cfg(stage0)] // NOTE remove after next snapshot
- fn clone(&self) -> Rc<T> {
- self.inc_strong();
- Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
- }
/// Makes a clone of the `Rc<T>`.
///
/// five.clone();
/// ```
#[inline]
- #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
fn clone(&self) -> Rc<T> {
self.inc_strong();
Rc { _ptr: self._ptr }
/// See the [module level documentation](../index.html) for more.
#[unsafe_no_drop_flag]
#[unstable = "Weak pointers may not belong in this module."]
-#[cfg(stage0)] // NOTE remove impl after next snapshot
pub struct Weak<T> {
// FIXME #12808: strange names to try to avoid interfering with
// field accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
- _nosend: marker::NoSend,
- _noshare: marker::NoSync
}
-/// 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]
-#[unstable = "Weak pointers may not belong in this module."]
-#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
-pub struct Weak<T> {
- // FIXME #12808: strange names to try to avoid interfering with
- // field accesses of the contained type via Deref
- _ptr: NonZero<*mut RcBox<T>>,
-}
-
-#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
#[allow(unstable)]
impl<T> !marker::Send for Weak<T> {}
-#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
#[allow(unstable)]
impl<T> !marker::Sync for Weak<T> {}
#[unstable = "Weak pointers may not belong in this module."]
impl<T> Weak<T> {
- /// Upgrades a weak reference to a strong reference.
- ///
- /// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
- ///
- /// 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();
- /// ```
- #[cfg(stage0)] // NOTE remove after next snapshot
- pub fn upgrade(&self) -> Option<Rc<T>> {
- if self.strong() == 0 {
- None
- } else {
- self.inc_strong();
- Some(Rc { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync })
- }
- }
/// Upgrades a weak reference to a strong reference.
///
///
/// let strong_five: Option<Rc<_>> = weak_five.upgrade();
/// ```
- #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
pub fn upgrade(&self) -> Option<Rc<T>> {
if self.strong() == 0 {
None
#[unstable = "Weak pointers may not belong in this module."]
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]
- #[cfg(stage0)] // NOTE remove after next snapshot
- fn clone(&self) -> Weak<T> {
- self.inc_weak();
- Weak { _ptr: self._ptr, _nosend: marker::NoSend, _noshare: marker::NoSync }
- }
/// Makes a clone of the `Weak<T>`.
///
/// weak_five.clone();
/// ```
#[inline]
- #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
fn clone(&self) -> Weak<T> {
self.inc_weak();
Weak { _ptr: self._ptr }
fn strong(&self) -> uint { self.inner().strong.get() }
#[inline]
- fn inc_strong(&self) { self.inner().strong.set(self.strong() + 1); }
+ fn inc_strong(&self) {
+ let strong = self.strong();
+ // The reference count is always at least one unless we're about to drop the type
+ // This allows the bulk of the destructor to be omitted in cases where we know that
+ // the reference count must be > 0.
+ unsafe { assume(strong > 0); }
+ self.inner().strong.set(strong + 1);
+ }
#[inline]
- fn dec_strong(&self) { self.inner().strong.set(self.strong() - 1); }
+ fn dec_strong(&self) {
+ let strong = self.strong();
+ // The reference count is always at least one unless we're about to drop the type
+ // This allows the bulk of the destructor to be omitted in cases where we know that
+ // the reference count must be > 0
+ unsafe { assume(strong > 0); }
+ self.inner().strong.set(strong - 1);
+ }
#[inline]
fn weak(&self) -> uint { self.inner().weak.get() }
impl<T> RcBoxPtr<T> for Rc<T> {
#[inline(always)]
- fn inner(&self) -> &RcBox<T> { unsafe { &(**self._ptr) } }
+ fn inner(&self) -> &RcBox<T> {
+ unsafe {
+ // Safe to assume this here, as if it weren't true, we'd be breaking
+ // the contract anyway.
+ // This allows the null check to be elided in the destructor if we
+ // manipulated the reference count in the same function.
+ assume(!self._ptr.is_null());
+ &(**self._ptr)
+ }
+ }
}
impl<T> RcBoxPtr<T> for Weak<T> {
#[inline(always)]
- fn inner(&self) -> &RcBox<T> { unsafe { &(**self._ptr) } }
+ fn inner(&self) -> &RcBox<T> {
+ unsafe {
+ // Safe to assume this here, as if it weren't true, we'd be breaking
+ // the contract anyway
+ // This allows the null check to be elided in the destructor if we
+ // manipulated the reference count in the same function.
+ assume(!self._ptr.is_null());
+ &(**self._ptr)
+ }
+ }
}
#[cfg(test)]