about summary refs log tree commit diff
path: root/src/liballoc/vec.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-10-25 20:41:28 +0000
committerbors <bors@rust-lang.org>2019-10-25 20:41:28 +0000
commit246be7e1a557b8ac8287c6842379a0db67770be6 (patch)
tree6359f78c7c2bbf20c7e999fa95ddab93ba1a0ea7 /src/liballoc/vec.rs
parent23f890f10202a71168c6424da0cdf94135d3c40c (diff)
parentd40c6afba04c906907cb57157c0aec7e12519c94 (diff)
downloadrust-246be7e1a557b8ac8287c6842379a0db67770be6.tar.gz
rust-246be7e1a557b8ac8287c6842379a0db67770be6.zip
Auto merge of #65826 - JohnTitor:rollup-mr6crka, r=JohnTitor
Rollup of 6 pull requests

Successful merges:

 - #65705 (Add {String,Vec}::into_raw_parts)
 - #65749 (Insurance policy in case `iter.size_hint()` lies.)
 - #65799 (Fill tracking issue number for `array_value_iter`)
 - #65800 (self-profiling: Update measureme to 0.4.0 and remove non-RAII methods from profiler.)
 - #65806 (Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().)
 - #65810 (SGX: Clear additional flag on enclave entry)

Failed merges:

r? @ghost
Diffstat (limited to 'src/liballoc/vec.rs')
-rw-r--r--src/liballoc/vec.rs49
1 files changed, 44 insertions, 5 deletions
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 6350b189c5f..641f9eafa8d 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -358,6 +358,44 @@ impl<T> Vec<T> {
         }
     }
 
+    /// Decomposes a `Vec<T>` into its raw components.
+    ///
+    /// Returns the raw pointer to the underlying data, the length of
+    /// the vector (in elements), and the allocated capacity of the
+    /// data (in elements). These are the same arguments in the same
+    /// order as the arguments to [`from_raw_parts`].
+    ///
+    /// After calling this function, the caller is responsible for the
+    /// memory previously managed by the `Vec`. The only way to do
+    /// this is to convert the raw pointer, length, and capacity back
+    /// into a `Vec` with the [`from_raw_parts`] function, allowing
+    /// the destructor to perform the cleanup.
+    ///
+    /// [`from_raw_parts`]: #method.from_raw_parts
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(vec_into_raw_parts)]
+    /// let v: Vec<i32> = vec![-1, 0, 1];
+    ///
+    /// let (ptr, len, cap) = v.into_raw_parts();
+    ///
+    /// let rebuilt = unsafe {
+    ///     // We can now make changes to the components, such as
+    ///     // transmuting the raw pointer to a compatible type.
+    ///     let ptr = ptr as *mut u32;
+    ///
+    ///     Vec::from_raw_parts(ptr, len, cap)
+    /// };
+    /// assert_eq!(rebuilt, [4294967295, 0, 1]);
+    /// ```
+    #[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
+    pub fn into_raw_parts(self) -> (*mut T, usize, usize) {
+        let mut me = mem::ManuallyDrop::new(self);
+        (me.as_mut_ptr(), me.len(), me.capacity())
+    }
+
     /// Creates a `Vec<T>` directly from the raw components of another vector.
     ///
     /// # Safety
@@ -389,7 +427,12 @@ impl<T> Vec<T> {
     /// use std::ptr;
     /// use std::mem;
     ///
-    /// let mut v = vec![1, 2, 3];
+    /// let v = vec![1, 2, 3];
+    ///
+    // FIXME Update this when vec_into_raw_parts is stabilized
+    /// // Prevent running `v`'s destructor so we are in complete control
+    /// // of the allocation.
+    /// let mut v = mem::ManuallyDrop::new(v);
     ///
     /// // Pull out the various important pieces of information about `v`
     /// let p = v.as_mut_ptr();
@@ -397,10 +440,6 @@ impl<T> Vec<T> {
     /// let cap = v.capacity();
     ///
     /// unsafe {
-    ///     // Cast `v` into the void: no destructor run, so we are in
-    ///     // complete control of the allocation to which `p` points.
-    ///     mem::forget(v);
-    ///
     ///     // Overwrite memory with 4, 5, 6
     ///     for i in 0..len as isize {
     ///         ptr::write(p.offset(i), 4 + i);