Ok(elem)
}
}
+
+ /// Consumes the `Arc`, returning the wrapped pointer.
+ ///
+ /// To avoid a memory leak the pointer must be converted back to an `Arc` using
+ /// [`Arc::from_raw`][from_raw].
+ ///
+ /// [from_raw]: struct.Arc.html#method.from_raw
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(rc_raw)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x = Arc::new(10);
+ /// let x_ptr = Arc::into_raw(x);
+ /// assert_eq!(unsafe { *x_ptr }, 10);
+ /// ```
+ #[unstable(feature = "rc_raw", issue = "37197")]
+ pub fn into_raw(this: Self) -> *mut T {
+ let ptr = unsafe { &mut (**this.ptr).data as *mut _ };
+ mem::forget(this);
+ ptr
+ }
+
+ /// Constructs an `Arc` from a raw pointer.
+ ///
+ /// The raw pointer must have been previously returned by a call to a
+ /// [`Arc::into_raw`][into_raw].
+ ///
+ /// This function is unsafe because improper use may lead to memory problems. For example, a
+ /// double-free may occur if the function is called twice on the same raw pointer.
+ ///
+ /// [into_raw]: struct.Arc.html#method.into_raw
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(rc_raw)]
+ ///
+ /// use std::sync::Arc;
+ ///
+ /// let x = Arc::new(10);
+ /// let x_ptr = Arc::into_raw(x);
+ ///
+ /// unsafe {
+ /// // Convert back to an `Arc` to prevent leak.
+ /// let x = Arc::from_raw(x_ptr);
+ /// assert_eq!(*x, 10);
+ ///
+ /// // Further calls to `Arc::from_raw(x_ptr)` would be memory unsafe.
+ /// }
+ ///
+ /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
+ /// ```
+ #[unstable(feature = "rc_raw", issue = "37197")]
+ pub unsafe fn from_raw(ptr: *mut T) -> Self {
+ // To find the corresponding pointer to the `ArcInner` we need to subtract the offset of the
+ // `data` field from the pointer.
+ Arc { ptr: Shared::new((ptr as *mut u8).offset(-offset_of!(ArcInner<T>, data)) as *mut _) }
+ }
}
impl<T: ?Sized> Arc<T> {
assert_eq!(Arc::try_unwrap(x), Ok(5));
}
+ #[test]
+ fn into_from_raw() {
+ let x = Arc::new(box "hello");
+ let y = x.clone();
+
+ let x_ptr = Arc::into_raw(x);
+ drop(y);
+ unsafe {
+ assert_eq!(**x_ptr, "hello");
+
+ let x = Arc::from_raw(x_ptr);
+ assert_eq!(**x, "hello");
+
+ assert_eq!(Arc::try_unwrap(x).map(|x| *x), Ok("hello"));
+ }
+ }
+
#[test]
fn test_cowarc_clone_make_mut() {
let mut cow0 = Arc::new(75);
#[macro_use]
extern crate std;
+// Module with internal macros used by other modules (needs to be included before other modules).
+#[macro_use]
+mod macros;
+
// Heaps provided for low-level allocation strategies
pub mod heap;
--- /dev/null
+// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Private macro to get the offset of a struct field in bytes from the address of the struct.
+macro_rules! offset_of {
+ ($container:path, $field:ident) => {{
+ // Make sure the field actually exists. This line ensures that a compile-time error is
+ // generated if $field is accessed through a Deref impl.
+ let $container { $field : _, .. };
+
+ // Create an (invalid) instance of the container and calculate the offset to its
+ // field. Using a null pointer might be UB if `&(*(0 as *const T)).field` is interpreted to
+ // be nullptr deref.
+ let invalid: $container = ::core::mem::uninitialized();
+ let offset = &invalid.$field as *const _ as usize - &invalid as *const _ as usize;
+
+ // Do not run destructors on the made up invalid instance.
+ ::core::mem::forget(invalid);
+ offset as isize
+ }};
+}
pub fn would_unwrap(this: &Self) -> bool {
Rc::strong_count(&this) == 1
}
+
+ /// Consumes the `Rc`, returning the wrapped pointer.
+ ///
+ /// To avoid a memory leak the pointer must be converted back to an `Rc` using
+ /// [`Rc::from_raw`][from_raw].
+ ///
+ /// [from_raw]: struct.Rc.html#method.from_raw
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(rc_raw)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let x = Rc::new(10);
+ /// let x_ptr = Rc::into_raw(x);
+ /// assert_eq!(unsafe { *x_ptr }, 10);
+ /// ```
+ #[unstable(feature = "rc_raw", issue = "37197")]
+ pub fn into_raw(this: Self) -> *mut T {
+ let ptr = unsafe { &mut (**this.ptr).value as *mut _ };
+ mem::forget(this);
+ ptr
+ }
+
+ /// Constructs an `Rc` from a raw pointer.
+ ///
+ /// The raw pointer must have been previously returned by a call to a
+ /// [`Rc::into_raw`][into_raw].
+ ///
+ /// This function is unsafe because improper use may lead to memory problems. For example, a
+ /// double-free may occur if the function is called twice on the same raw pointer.
+ ///
+ /// [into_raw]: struct.Rc.html#method.into_raw
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(rc_raw)]
+ ///
+ /// use std::rc::Rc;
+ ///
+ /// let x = Rc::new(10);
+ /// let x_ptr = Rc::into_raw(x);
+ ///
+ /// unsafe {
+ /// // Convert back to an `Rc` to prevent leak.
+ /// let x = Rc::from_raw(x_ptr);
+ /// assert_eq!(*x, 10);
+ ///
+ /// // Further calls to `Rc::from_raw(x_ptr)` would be memory unsafe.
+ /// }
+ ///
+ /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
+ /// ```
+ #[unstable(feature = "rc_raw", issue = "37197")]
+ pub unsafe fn from_raw(ptr: *mut T) -> Self {
+ // To find the corresponding pointer to the `RcBox` we need to subtract the offset of the
+ // `value` field from the pointer.
+ Rc { ptr: Shared::new((ptr as *mut u8).offset(-offset_of!(RcBox<T>, value)) as *mut _) }
+ }
}
impl<T: ?Sized> Rc<T> {
assert_eq!(Rc::try_unwrap(x), Ok(5));
}
+ #[test]
+ fn into_from_raw() {
+ let x = Rc::new(box "hello");
+ let y = x.clone();
+
+ let x_ptr = Rc::into_raw(x);
+ drop(y);
+ unsafe {
+ assert_eq!(**x_ptr, "hello");
+
+ let x = Rc::from_raw(x_ptr);
+ assert_eq!(**x, "hello");
+
+ assert_eq!(Rc::try_unwrap(x).map(|x| *x), Ok("hello"));
+ }
+ }
+
#[test]
fn get_mut() {
let mut x = Rc::new(3);