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
This commit is contained in:
commit
a808ba374f
3 changed files with 89 additions and 14 deletions
|
|
@ -196,20 +196,21 @@ use crate::vec::Vec;
|
|||
///
|
||||
/// let story = String::from("Once upon a time...");
|
||||
///
|
||||
/// let ptr = story.as_ptr();
|
||||
// FIXME Update this when vec_into_raw_parts is stabilized
|
||||
/// // Prevent automatically dropping the String's data
|
||||
/// let mut story = mem::ManuallyDrop::new(story);
|
||||
///
|
||||
/// let ptr = story.as_mut_ptr();
|
||||
/// let len = story.len();
|
||||
/// let capacity = story.capacity();
|
||||
///
|
||||
/// // story has nineteen bytes
|
||||
/// assert_eq!(19, len);
|
||||
///
|
||||
/// // Now that we have our parts, we throw the story away.
|
||||
/// mem::forget(story);
|
||||
///
|
||||
/// // We can re-build a String out of ptr, len, and capacity. This is all
|
||||
/// // unsafe because we are responsible for making sure the components are
|
||||
/// // valid:
|
||||
/// let s = unsafe { String::from_raw_parts(ptr as *mut _, len, capacity) } ;
|
||||
/// let s = unsafe { String::from_raw_parts(ptr, len, capacity) } ;
|
||||
///
|
||||
/// assert_eq!(String::from("Once upon a time..."), s);
|
||||
/// ```
|
||||
|
|
@ -647,6 +648,37 @@ impl String {
|
|||
decode_utf16(v.iter().cloned()).map(|r| r.unwrap_or(REPLACEMENT_CHARACTER)).collect()
|
||||
}
|
||||
|
||||
/// Decomposes a `String` into its raw components.
|
||||
///
|
||||
/// Returns the raw pointer to the underlying data, the length of
|
||||
/// the string (in bytes), and the allocated capacity of the data
|
||||
/// (in bytes). 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 `String`. The only way to do
|
||||
/// this is to convert the raw pointer, length, and capacity back
|
||||
/// into a `String` 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 s = String::from("hello");
|
||||
///
|
||||
/// let (ptr, len, cap) = s.into_raw_parts();
|
||||
///
|
||||
/// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
|
||||
/// assert_eq!(rebuilt, "hello");
|
||||
/// ```
|
||||
#[unstable(feature = "vec_into_raw_parts", reason = "new API", issue = "65816")]
|
||||
pub fn into_raw_parts(self) -> (*mut u8, usize, usize) {
|
||||
self.vec.into_raw_parts()
|
||||
}
|
||||
|
||||
/// Creates a new `String` from a length, capacity, and pointer.
|
||||
///
|
||||
/// # Safety
|
||||
|
|
@ -677,13 +709,16 @@ impl String {
|
|||
///
|
||||
/// unsafe {
|
||||
/// let s = String::from("hello");
|
||||
/// let ptr = s.as_ptr();
|
||||
///
|
||||
// FIXME Update this when vec_into_raw_parts is stabilized
|
||||
/// // Prevent automatically dropping the String's data
|
||||
/// let mut s = mem::ManuallyDrop::new(s);
|
||||
///
|
||||
/// let ptr = s.as_mut_ptr();
|
||||
/// let len = s.len();
|
||||
/// let capacity = s.capacity();
|
||||
///
|
||||
/// mem::forget(s);
|
||||
///
|
||||
/// let s = String::from_raw_parts(ptr as *mut _, len, capacity);
|
||||
/// let s = String::from_raw_parts(ptr, len, capacity);
|
||||
///
|
||||
/// assert_eq!(String::from("hello"), s);
|
||||
/// }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -874,6 +874,7 @@ extern "rust-intrinsic" {
|
|||
/// // the original inner type (`&i32`) to the converted inner type
|
||||
/// // (`Option<&i32>`), so read the nomicon pages linked above.
|
||||
/// let v_from_raw = unsafe {
|
||||
// FIXME Update this when vec_into_raw_parts is stabilized
|
||||
/// // Ensure the original vector is not dropped.
|
||||
/// let mut v_clone = std::mem::ManuallyDrop::new(v_clone);
|
||||
/// Vec::from_raw_parts(v_clone.as_mut_ptr() as *mut Option<&i32>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue