@@ -196,20 +196,21 @@ use crate::vec::Vec;
196196///
197197/// let story = String::from("Once upon a time...");
198198///
199- /// let ptr = story.as_ptr();
199+ // FIXME Update this when vec_into_raw_parts is stabilized
200+ /// // Prevent automatically dropping the String's data
201+ /// let mut story = mem::ManuallyDrop::new(story);
202+ ///
203+ /// let ptr = story.as_mut_ptr();
200204/// let len = story.len();
201205/// let capacity = story.capacity();
202206///
203207/// // story has nineteen bytes
204208/// assert_eq!(19, len);
205209///
206- /// // Now that we have our parts, we throw the story away.
207- /// mem::forget(story);
208- ///
209210/// // We can re-build a String out of ptr, len, and capacity. This is all
210211/// // unsafe because we are responsible for making sure the components are
211212/// // valid:
212- /// let s = unsafe { String::from_raw_parts(ptr as *mut _ , len, capacity) } ;
213+ /// let s = unsafe { String::from_raw_parts(ptr, len, capacity) } ;
213214///
214215/// assert_eq!(String::from("Once upon a time..."), s);
215216/// ```
@@ -647,6 +648,37 @@ impl String {
647648 decode_utf16 ( v. iter ( ) . cloned ( ) ) . map ( |r| r. unwrap_or ( REPLACEMENT_CHARACTER ) ) . collect ( )
648649 }
649650
651+ /// Decomposes a `String` into its raw components.
652+ ///
653+ /// Returns the raw pointer to the underlying data, the length of
654+ /// the string (in bytes), and the allocated capacity of the data
655+ /// (in bytes). These are the same arguments in the same order as
656+ /// the arguments to [`from_raw_parts`].
657+ ///
658+ /// After calling this function, the caller is responsible for the
659+ /// memory previously managed by the `String`. The only way to do
660+ /// this is to convert the raw pointer, length, and capacity back
661+ /// into a `String` with the [`from_raw_parts`] function, allowing
662+ /// the destructor to perform the cleanup.
663+ ///
664+ /// [`from_raw_parts`]: #method.from_raw_parts
665+ ///
666+ /// # Examples
667+ ///
668+ /// ```
669+ /// #![feature(vec_into_raw_parts)]
670+ /// let s = String::from("hello");
671+ ///
672+ /// let (ptr, len, cap) = s.into_raw_parts();
673+ ///
674+ /// let rebuilt = unsafe { String::from_raw_parts(ptr, len, cap) };
675+ /// assert_eq!(rebuilt, "hello");
676+ /// ```
677+ #[ unstable( feature = "vec_into_raw_parts" , reason = "new API" , issue = "65816" ) ]
678+ pub fn into_raw_parts ( self ) -> ( * mut u8 , usize , usize ) {
679+ self . vec . into_raw_parts ( )
680+ }
681+
650682 /// Creates a new `String` from a length, capacity, and pointer.
651683 ///
652684 /// # Safety
@@ -677,13 +709,16 @@ impl String {
677709 ///
678710 /// unsafe {
679711 /// let s = String::from("hello");
680- /// let ptr = s.as_ptr();
712+ ///
713+ // FIXME Update this when vec_into_raw_parts is stabilized
714+ /// // Prevent automatically dropping the String's data
715+ /// let mut s = mem::ManuallyDrop::new(s);
716+ ///
717+ /// let ptr = s.as_mut_ptr();
681718 /// let len = s.len();
682719 /// let capacity = s.capacity();
683720 ///
684- /// mem::forget(s);
685- ///
686- /// let s = String::from_raw_parts(ptr as *mut _, len, capacity);
721+ /// let s = String::from_raw_parts(ptr, len, capacity);
687722 ///
688723 /// assert_eq!(String::from("hello"), s);
689724 /// }
0 commit comments