std: Move free-functions to associated functions

This commit moves the free functions in the `rc`, `arc`, and `boxed` modules to
associated functions on their respective types, following the recent trend
towards this pattern. The previous free functions are all left in-place with
`#[deprecated]` pointers towards the new locations.

This commit also deprecates `arc::get_mut` and `Arc::make_unique` with no
replacement as they are racy in the face of weak pointers.
This commit is contained in:
Alex Crichton 2015-06-10 19:14:35 -07:00
parent 3346fb0442
commit aa931e9c6f
3 changed files with 153 additions and 35 deletions

View file

@ -205,9 +205,21 @@ impl<T: ?Sized> Arc<T> {
self.inner().weak.fetch_add(1, Relaxed);
Weak { _ptr: self._ptr }
}
}
impl<T: ?Sized> Arc<T> {
/// Get the number of weak references to this value.
#[inline]
#[unstable(feature = "arc_counts")]
pub fn weak_count(this: &Arc<T>) -> usize {
this.inner().weak.load(SeqCst) - 1
}
/// Get the number of strong references to this value.
#[inline]
#[unstable(feature = "arc_counts")]
pub fn strong_count(this: &Arc<T>) -> usize {
this.inner().strong.load(SeqCst)
}
#[inline]
fn inner(&self) -> &ArcInner<T> {
// This unsafety is ok because while this arc is alive we're guaranteed
@ -237,12 +249,14 @@ impl<T: ?Sized> Arc<T> {
/// Get the number of weak references to this value.
#[inline]
#[unstable(feature = "arc_counts")]
pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().weak.load(SeqCst) - 1 }
#[deprecated(since = "1.2.0", reason = "renamed to Arc::weak_count")]
pub fn weak_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::weak_count(this) }
/// Get the number of strong references to this value.
#[inline]
#[unstable(feature = "arc_counts")]
pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.load(SeqCst) }
#[deprecated(since = "1.2.0", reason = "renamed to Arc::strong_count")]
pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { Arc::strong_count(this) }
/// Returns a mutable reference to the contained value if the `Arc<T>` is unique.
@ -272,6 +286,8 @@ pub fn strong_count<T: ?Sized>(this: &Arc<T>) -> usize { this.inner().strong.loa
/// ```
#[inline]
#[unstable(feature = "arc_unique")]
#[deprecated(since = "1.2.0",
reason = "this function is unsafe with weak pointers")]
pub unsafe fn get_mut<T: ?Sized>(this: &mut Arc<T>) -> Option<&mut T> {
// FIXME(#24880) potential race with upgraded weak pointers here
if strong_count(this) == 1 && weak_count(this) == 0 {
@ -353,6 +369,8 @@ impl<T: Clone> Arc<T> {
/// ```
#[inline]
#[unstable(feature = "arc_unique")]
#[deprecated(since = "1.2.0",
reason = "this function is unsafe with weak pointers")]
pub unsafe fn make_unique(&mut self) -> &mut T {
// FIXME(#24880) potential race with upgraded weak pointers here
//

View file

@ -127,6 +127,29 @@ impl<T : ?Sized> Box<T> {
pub unsafe fn from_raw(raw: *mut T) -> Self {
mem::transmute(raw)
}
/// Consumes the `Box`, returning the wrapped raw pointer.
///
/// After call to this function, caller is responsible for the memory
/// previously managed by `Box`, in particular caller should properly
/// destroy `T` and release memory. The proper way to do it is to
/// convert pointer back to `Box` with `Box::from_raw` function, because
/// `Box` does not specify, how memory is allocated.
///
/// # Examples
/// ```
/// # #![feature(box_raw)]
/// use std::boxed;
///
/// let seventeen = Box::new(17u32);
/// let raw = boxed::into_raw(seventeen);
/// let boxed_again = unsafe { Box::from_raw(raw) };
/// ```
#[unstable(feature = "box_raw", reason = "may be renamed")]
#[inline]
pub fn into_raw(b: Box<T>) -> *mut T {
unsafe { mem::transmute(b) }
}
}
/// Consumes the `Box`, returning the wrapped raw pointer.
@ -146,11 +169,11 @@ impl<T : ?Sized> Box<T> {
/// let raw = boxed::into_raw(seventeen);
/// let boxed_again = unsafe { Box::from_raw(raw) };
/// ```
#[unstable(feature = "box_raw",
reason = "may be renamed")]
#[unstable(feature = "box_raw", reason = "may be renamed")]
#[deprecated(since = "1.2.0", reason = "renamed to Box::into_raw")]
#[inline]
pub fn into_raw<T : ?Sized>(b: Box<T>) -> *mut T {
unsafe { mem::transmute(b) }
Box::into_raw(b)
}
#[stable(feature = "rust1", since = "1.0.0")]

View file

@ -220,6 +220,42 @@ impl<T> Rc<T> {
}
}
}
/// Unwraps the contained value if the `Rc<T>` is unique.
///
/// If the `Rc<T>` is not unique, an `Err` is returned with the same
/// `Rc<T>`.
///
/// # Examples
///
/// ```
/// # #![feature(rc_unique)]
/// use std::rc::{self, Rc};
///
/// let x = Rc::new(3);
/// assert_eq!(rc::try_unwrap(x), Ok(3));
///
/// let x = Rc::new(4);
/// let _y = x.clone();
/// assert_eq!(rc::try_unwrap(x), Err(Rc::new(4)));
/// ```
#[inline]
#[unstable(feature = "rc_unique")]
pub fn try_unwrap(rc: Rc<T>) -> Result<T, Rc<T>> {
if Rc::is_unique(&rc) {
unsafe {
let val = ptr::read(&*rc); // copy the contained object
// destruct the box and skip our Drop
// we can ignore the refcounts because we know we're unique
deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(),
min_align_of::<RcBox<T>>());
forget(rc);
Ok(val)
}
} else {
Err(rc)
}
}
}
impl<T: ?Sized> Rc<T> {
@ -241,17 +277,78 @@ impl<T: ?Sized> Rc<T> {
self.inc_weak();
Weak { _ptr: self._ptr }
}
/// Get the number of weak references to this value.
#[inline]
#[unstable(feature = "rc_counts")]
pub fn weak_count(this: &Rc<T>) -> usize { this.weak() - 1 }
/// Get the number of strong references to this value.
#[inline]
#[unstable(feature = "rc_counts")]
pub fn strong_count(this: &Rc<T>) -> usize { this.strong() }
/// Returns true if there are no other `Rc` or `Weak<T>` values that share
/// the same inner value.
///
/// # Examples
///
/// ```
/// # #![feature(rc_unique)]
/// use std::rc;
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
///
/// rc::is_unique(&five);
/// ```
#[inline]
#[unstable(feature = "rc_unique")]
pub fn is_unique(rc: &Rc<T>) -> bool {
weak_count(rc) == 0 && strong_count(rc) == 1
}
/// Returns a mutable reference to the contained value if the `Rc<T>` is
/// unique.
///
/// Returns `None` if the `Rc<T>` is not unique.
///
/// # Examples
///
/// ```
/// # #![feature(rc_unique)]
/// use std::rc::{self, Rc};
///
/// let mut x = Rc::new(3);
/// *rc::get_mut(&mut x).unwrap() = 4;
/// assert_eq!(*x, 4);
///
/// let _y = x.clone();
/// assert!(rc::get_mut(&mut x).is_none());
/// ```
#[inline]
#[unstable(feature = "rc_unique")]
pub fn get_mut(rc: &mut Rc<T>) -> Option<&mut T> {
if Rc::is_unique(rc) {
let inner = unsafe { &mut **rc._ptr };
Some(&mut inner.value)
} else {
None
}
}
}
/// Get the number of weak references to this value.
#[inline]
#[unstable(feature = "rc_counts")]
pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { this.weak() - 1 }
#[deprecated(since = "1.2.0", reason = "renamed to Rc::weak_count")]
pub fn weak_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::weak_count(this) }
/// Get the number of strong references to this value.
#[inline]
#[unstable(feature = "rc_counts")]
pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() }
#[deprecated(since = "1.2.0", reason = "renamed to Rc::strong_count")]
pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { Rc::strong_count(this) }
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the
/// same inner value.
@ -269,9 +366,8 @@ pub fn strong_count<T: ?Sized>(this: &Rc<T>) -> usize { this.strong() }
/// ```
#[inline]
#[unstable(feature = "rc_unique")]
pub fn is_unique<T>(rc: &Rc<T>) -> bool {
weak_count(rc) == 0 && strong_count(rc) == 1
}
#[deprecated(since = "1.2.0", reason = "renamed to Rc::is_unique")]
pub fn is_unique<T>(rc: &Rc<T>) -> bool { Rc::is_unique(rc) }
/// Unwraps the contained value if the `Rc<T>` is unique.
///
@ -292,21 +388,8 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool {
/// ```
#[inline]
#[unstable(feature = "rc_unique")]
pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
if is_unique(&rc) {
unsafe {
let val = ptr::read(&*rc); // copy the contained object
// destruct the box and skip our Drop
// we can ignore the refcounts because we know we're unique
deallocate(*rc._ptr as *mut u8, size_of::<RcBox<T>>(),
min_align_of::<RcBox<T>>());
forget(rc);
Ok(val)
}
} else {
Err(rc)
}
}
#[deprecated(since = "1.2.0", reason = "renamed to Rc::try_unwrap")]
pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> { Rc::try_unwrap(rc) }
/// Returns a mutable reference to the contained value if the `Rc<T>` is unique.
///
@ -327,14 +410,8 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
/// ```
#[inline]
#[unstable(feature = "rc_unique")]
pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> {
if is_unique(rc) {
let inner = unsafe { &mut **rc._ptr };
Some(&mut inner.value)
} else {
None
}
}
#[deprecated(since = "1.2.0", reason = "renamed to Rc::get_mut")]
pub fn get_mut<T>(rc: &mut Rc<T>) -> Option<&mut T> { Rc::get_mut(rc) }
impl<T: Clone> Rc<T> {
/// Make a mutable reference from the given `Rc<T>`.