1
Fork 0

Add Box::into_unique

This commit is contained in:
Simon Sapin 2017-07-14 12:47:06 +02:00
parent 1ef24bb3e2
commit cbd2b6b484
5 changed files with 48 additions and 21 deletions

View file

@ -280,7 +280,7 @@ impl<T> Arc<T> {
weak: atomic::AtomicUsize::new(1), weak: atomic::AtomicUsize::new(1),
data: data, data: data,
}; };
Arc { ptr: unsafe { Shared::new_unchecked(Box::into_raw(x)) } } Arc { ptr: Shared::from(Box::into_unique(x)) }
} }
/// Returns the contained value, if the `Arc` has exactly one strong reference. /// Returns the contained value, if the `Arc` has exactly one strong reference.
@ -842,7 +842,7 @@ impl<T> Weak<T> {
pub fn new() -> Weak<T> { pub fn new() -> Weak<T> {
unsafe { unsafe {
Weak { Weak {
ptr: Shared::new_unchecked(Box::into_raw(box ArcInner { ptr: Shared::from(Box::into_unique(box ArcInner {
strong: atomic::AtomicUsize::new(0), strong: atomic::AtomicUsize::new(0),
weak: atomic::AtomicUsize::new(1), weak: atomic::AtomicUsize::new(1),
data: uninitialized(), data: uninitialized(),

View file

@ -297,6 +297,37 @@ impl<T: ?Sized> Box<T> {
pub fn into_raw(b: Box<T>) -> *mut T { pub fn into_raw(b: Box<T>) -> *mut T {
unsafe { mem::transmute(b) } unsafe { mem::transmute(b) }
} }
/// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`.
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the
/// caller should properly destroy `T` and release the memory. The
/// proper way to do so is to convert the raw pointer back into a
/// `Box` with the [`Box::from_raw`] function.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Box::into_unique(b)` instead of `b.into_unique()`. This
/// is so that there is no conflict with a method on the inner type.
///
/// [`Box::from_raw`]: struct.Box.html#method.from_raw
///
/// # Examples
///
/// ```
/// #![feature(unique)]
///
/// fn main() {
/// let x = Box::new(5);
/// let ptr = Box::into_unique(x);
/// }
/// ```
#[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
issue = "27730")]
#[inline]
pub fn into_unique(b: Box<T>) -> Unique<T> {
unsafe { mem::transmute(b) }
}
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]

View file

@ -140,9 +140,7 @@ struct BoxedNode<K, V> {
impl<K, V> BoxedNode<K, V> { impl<K, V> BoxedNode<K, V> {
fn from_leaf(node: Box<LeafNode<K, V>>) -> Self { fn from_leaf(node: Box<LeafNode<K, V>>) -> Self {
unsafe { BoxedNode { ptr: Box::into_unique(node) }
BoxedNode { ptr: Unique::new_unchecked(Box::into_raw(node)) }
}
} }
fn from_internal(node: Box<InternalNode<K, V>>) -> Self { fn from_internal(node: Box<InternalNode<K, V>>) -> Self {

View file

@ -157,7 +157,7 @@ impl<T> LinkedList<T> {
unsafe { unsafe {
node.next = self.head; node.next = self.head;
node.prev = None; node.prev = None;
let node = Some(Shared::new_unchecked(Box::into_raw(node))); let node = Some(Shared::from(Box::into_unique(node)));
match self.head { match self.head {
None => self.tail = node, None => self.tail = node,
@ -192,7 +192,7 @@ impl<T> LinkedList<T> {
unsafe { unsafe {
node.next = None; node.next = None;
node.prev = self.tail; node.prev = self.tail;
let node = Some(Shared::new_unchecked(Box::into_raw(node))); let node = Some(Shared::from(Box::into_unique(node)));
match self.tail { match self.tail {
None => self.head = node, None => self.head = node,
@ -921,7 +921,7 @@ impl<'a, T> IterMut<'a, T> {
Some(prev) => prev, Some(prev) => prev,
}; };
let node = Some(Shared::new_unchecked(Box::into_raw(box Node { let node = Some(Shared::from(Box::into_unique(box Node {
next: Some(head), next: Some(head),
prev: Some(prev), prev: Some(prev),
element: element, element: element,

View file

@ -303,18 +303,16 @@ impl<T> Rc<T> {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn new(value: T) -> Rc<T> { pub fn new(value: T) -> Rc<T> {
unsafe { Rc {
Rc { // there is an implicit weak pointer owned by all the strong
// there is an implicit weak pointer owned by all the strong // pointers, which ensures that the weak destructor never frees
// pointers, which ensures that the weak destructor never frees // the allocation while the strong destructor is running, even
// the allocation while the strong destructor is running, even // if the weak pointer is stored inside the strong one.
// if the weak pointer is stored inside the strong one. ptr: Shared::from(Box::into_unique(box RcBox {
ptr: Shared::new_unchecked(Box::into_raw(box RcBox { strong: Cell::new(1),
strong: Cell::new(1), weak: Cell::new(1),
weak: Cell::new(1), value: value,
value: value, })),
})),
}
} }
} }
@ -1016,7 +1014,7 @@ impl<T> Weak<T> {
pub fn new() -> Weak<T> { pub fn new() -> Weak<T> {
unsafe { unsafe {
Weak { Weak {
ptr: Shared::new_unchecked(Box::into_raw(box RcBox { ptr: Shared::from(Box::into_unique(box RcBox {
strong: Cell::new(0), strong: Cell::new(0),
weak: Cell::new(1), weak: Cell::new(1),
value: uninitialized(), value: uninitialized(),