diff options
| author | Yuki Okushi <huyuumi.dev@gmail.com> | 2019-10-26 02:45:56 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-10-26 02:45:56 +0900 |
| commit | a808ba374f7fdf6fea3f0bde9ce09f98f0db7d2d (patch) | |
| tree | 53532045ef05b19d5dd34f08575ee645329ae6ab /src/liballoc/vec.rs | |
| parent | 23f890f10202a71168c6424da0cdf94135d3c40c (diff) | |
| parent | 6600cf604091a99bba990d41b93885b40c02a97d (diff) | |
| download | rust-a808ba374f7fdf6fea3f0bde9ce09f98f0db7d2d.tar.gz rust-a808ba374f7fdf6fea3f0bde9ce09f98f0db7d2d.zip | |
Rollup merge of #65705 - shepmaster:vec-into-raw, r=SimonSapin
Add {String,Vec}::into_raw_parts
Aspects to address:
- [x] Create a tracking issue
- #65816
Diffstat (limited to 'src/liballoc/vec.rs')
| -rw-r--r-- | src/liballoc/vec.rs | 49 |
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); |
