@@ -303,6 +303,12 @@ impl CString {
303303 & self . inner
304304 }
305305
306+ /// Converts this `CString` into a boxed `CStr`.
307+ #[ unstable( feature = "into_boxed_c_str" , issue = "0" ) ]
308+ pub fn into_boxed_c_str ( self ) -> Box < CStr > {
309+ unsafe { mem:: transmute ( self . into_inner ( ) ) }
310+ }
311+
306312 // Bypass "move out of struct which implements `Drop` trait" restriction.
307313 fn into_inner ( self ) -> Box < [ u8 ] > {
308314 unsafe {
@@ -380,6 +386,22 @@ impl Borrow<CStr> for CString {
380386 fn borrow ( & self ) -> & CStr { self }
381387}
382388
389+ #[ stable( feature = "box_from_c_str" , since = "1.17.0" ) ]
390+ impl < ' a > From < & ' a CStr > for Box < CStr > {
391+ fn from ( s : & ' a CStr ) -> Box < CStr > {
392+ let boxed: Box < [ u8 ] > = Box :: from ( s. to_bytes_with_nul ( ) ) ;
393+ unsafe { mem:: transmute ( boxed) }
394+ }
395+ }
396+
397+ #[ stable( feature = "default_box_extra" , since = "1.17.0" ) ]
398+ impl Default for Box < CStr > {
399+ fn default ( ) -> Box < CStr > {
400+ let boxed: Box < [ u8 ] > = Box :: from ( [ 0 ] ) ;
401+ unsafe { mem:: transmute ( boxed) }
402+ }
403+ }
404+
383405impl NulError {
384406 /// Returns the position of the nul byte in the slice that was provided to
385407 /// `CString::new`.
@@ -686,7 +708,7 @@ impl ToOwned for CStr {
686708 type Owned = CString ;
687709
688710 fn to_owned ( & self ) -> CString {
689- CString { inner : self . to_bytes_with_nul ( ) . to_vec ( ) . into_boxed_slice ( ) }
711+ CString { inner : self . to_bytes_with_nul ( ) . into ( ) }
690712 }
691713}
692714
@@ -847,4 +869,22 @@ mod tests {
847869 let cstr = CStr :: from_bytes_with_nul ( data) ;
848870 assert ! ( cstr. is_err( ) ) ;
849871 }
872+
873+ #[ test]
874+ fn into_boxed ( ) {
875+ let orig: & [ u8 ] = b"Hello, world!\0 " ;
876+ let cstr = CStr :: from_bytes_with_nul ( orig) . unwrap ( ) ;
877+ let cstring = cstr. to_owned ( ) ;
878+ let box1: Box < CStr > = Box :: from ( cstr) ;
879+ let box2 = cstring. into_boxed_c_str ( ) ;
880+ assert_eq ! ( cstr, & * box1) ;
881+ assert_eq ! ( box1, box2) ;
882+ assert_eq ! ( & * box2, cstr) ;
883+ }
884+
885+ #[ test]
886+ fn boxed_default ( ) {
887+ let boxed = <Box < CStr > >:: default ( ) ;
888+ assert_eq ! ( boxed. to_bytes_with_nul( ) , & [ 0 ] ) ;
889+ }
850890}
0 commit comments