@@ -196,20 +196,21 @@ use crate::vec::Vec;
196
196
///
197
197
/// let story = String::from("Once upon a time...");
198
198
///
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();
200
204
/// let len = story.len();
201
205
/// let capacity = story.capacity();
202
206
///
203
207
/// // story has nineteen bytes
204
208
/// assert_eq!(19, len);
205
209
///
206
- /// // Now that we have our parts, we throw the story away.
207
- /// mem::forget(story);
208
- ///
209
210
/// // We can re-build a String out of ptr, len, and capacity. This is all
210
211
/// // unsafe because we are responsible for making sure the components are
211
212
/// // 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) } ;
213
214
///
214
215
/// assert_eq!(String::from("Once upon a time..."), s);
215
216
/// ```
@@ -647,6 +648,37 @@ impl String {
647
648
decode_utf16 ( v. iter ( ) . cloned ( ) ) . map ( |r| r. unwrap_or ( REPLACEMENT_CHARACTER ) ) . collect ( )
648
649
}
649
650
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
+
650
682
/// Creates a new `String` from a length, capacity, and pointer.
651
683
///
652
684
/// # Safety
@@ -677,13 +709,16 @@ impl String {
677
709
///
678
710
/// unsafe {
679
711
/// 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();
681
718
/// let len = s.len();
682
719
/// let capacity = s.capacity();
683
720
///
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);
687
722
///
688
723
/// assert_eq!(String::from("hello"), s);
689
724
/// }
0 commit comments