about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-04-07 14:46:53 +0200
committerGitHub <noreply@github.com>2020-04-07 14:46:53 +0200
commit795bc2ccff5672389c1e9d2481f25bdcdfee299b (patch)
tree102f79b2bf4261484fb3354568a648c92c2fc2ae /src/libstd
parent39b62533c7f9d0581a6ea9b9fc2cc51f21c3b5b0 (diff)
parentf854070bb820501d88d1b029660bfde663595530 (diff)
downloadrust-795bc2ccff5672389c1e9d2481f25bdcdfee299b.tar.gz
rust-795bc2ccff5672389c1e9d2481f25bdcdfee299b.zip
Rollup merge of #70201 - cuviper:clone_into, r=dtolnay
Small tweaks in ToOwned::clone_into

- `<[T]>::clone_into` is slightly more optimized.
- `CStr::clone_into` is new, letting it reuse its allocation.
- `OsStr::clone_into` now forwards to the underlying slice/`Vec`.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/ffi/c_str.rs17
-rw-r--r--src/libstd/ffi/os_str.rs3
-rw-r--r--src/libstd/sys/windows/os_str.rs4
-rw-r--r--src/libstd/sys_common/os_str_bytes.rs4
-rw-r--r--src/libstd/sys_common/wtf8.rs4
5 files changed, 30 insertions, 2 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 04eaba515ff..0a4802fb2c8 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -1329,6 +1329,12 @@ impl ToOwned for CStr {
     fn to_owned(&self) -> CString {
         CString { inner: self.to_bytes_with_nul().into() }
     }
+
+    fn clone_into(&self, target: &mut CString) {
+        let mut b = Vec::from(mem::take(&mut target.inner));
+        self.to_bytes_with_nul().clone_into(&mut b);
+        target.inner = b.into_boxed_slice();
+    }
 }
 
 #[stable(feature = "cstring_asref", since = "1.7.0")]
@@ -1511,6 +1517,17 @@ mod tests {
     }
 
     #[test]
+    fn test_c_str_clone_into() {
+        let mut c_string = CString::new("lorem").unwrap();
+        let c_ptr = c_string.as_ptr();
+        let c_str = CStr::from_bytes_with_nul(b"ipsum\0").unwrap();
+        c_str.clone_into(&mut c_string);
+        assert_eq!(c_str, c_string.as_c_str());
+        // The exact same size shouldn't have needed to move its allocation
+        assert_eq!(c_ptr, c_string.as_ptr());
+    }
+
+    #[test]
     fn into_rc() {
         let orig: &[u8] = b"Hello, world!\0";
         let cstr = CStr::from_bytes_with_nul(orig).unwrap();
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 5e686946f8e..4fde3316973 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -1120,8 +1120,7 @@ impl ToOwned for OsStr {
         self.to_os_string()
     }
     fn clone_into(&self, target: &mut OsString) {
-        target.clear();
-        target.push(self);
+        self.inner.clone_into(&mut target.inner)
     }
 }
 
diff --git a/src/libstd/sys/windows/os_str.rs b/src/libstd/sys/windows/os_str.rs
index 6aab028873e..2f5fc72ab44 100644
--- a/src/libstd/sys/windows/os_str.rs
+++ b/src/libstd/sys/windows/os_str.rs
@@ -159,6 +159,10 @@ impl Slice {
         Buf { inner: buf }
     }
 
+    pub fn clone_into(&self, buf: &mut Buf) {
+        self.inner.clone_into(&mut buf.inner)
+    }
+
     #[inline]
     pub fn into_box(&self) -> Box<Slice> {
         unsafe { mem::transmute(self.inner.into_box()) }
diff --git a/src/libstd/sys_common/os_str_bytes.rs b/src/libstd/sys_common/os_str_bytes.rs
index aa6cc33d831..984c032e2a3 100644
--- a/src/libstd/sys_common/os_str_bytes.rs
+++ b/src/libstd/sys_common/os_str_bytes.rs
@@ -173,6 +173,10 @@ impl Slice {
         Buf { inner: self.inner.to_vec() }
     }
 
+    pub fn clone_into(&self, buf: &mut Buf) {
+        self.inner.clone_into(&mut buf.inner)
+    }
+
     #[inline]
     pub fn into_box(&self) -> Box<Slice> {
         let boxed: Box<[u8]> = self.inner.into();
diff --git a/src/libstd/sys_common/wtf8.rs b/src/libstd/sys_common/wtf8.rs
index fc6614552a9..a98407da448 100644
--- a/src/libstd/sys_common/wtf8.rs
+++ b/src/libstd/sys_common/wtf8.rs
@@ -613,6 +613,10 @@ impl Wtf8 {
         }
     }
 
+    pub fn clone_into(&self, buf: &mut Wtf8Buf) {
+        self.bytes.clone_into(&mut buf.bytes)
+    }
+
     /// Boxes this `Wtf8`.
     #[inline]
     pub fn into_box(&self) -> Box<Wtf8> {