about summary refs log tree commit diff
path: root/src/libcollections
diff options
context:
space:
mode:
authorMatt Brubeck <mbrubeck@limpet.net>2017-03-09 17:53:01 -0800
committerMatt Brubeck <mbrubeck@limpet.net>2017-04-15 09:01:56 -0700
commit675475c4d3e3b1ebff5b761570f4a3f9a0ca23df (patch)
tree49cfa5b4d6edca5205909e9b0729e9744507940c /src/libcollections
parent5637ed756632ded9e458b82a23cc1dddbb57c51f (diff)
downloadrust-675475c4d3e3b1ebff5b761570f4a3f9a0ca23df.tar.gz
rust-675475c4d3e3b1ebff5b761570f4a3f9a0ca23df.zip
Specialize Vec::from_elem<u8> to use calloc or memset
Fixes #38723.
Diffstat (limited to 'src/libcollections')
-rw-r--r--src/libcollections/vec.rs35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 8824185d280..f488e36c077 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -1370,9 +1370,38 @@ impl<T: PartialEq> Vec<T> {
 #[doc(hidden)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
-    let mut v = Vec::with_capacity(n);
-    v.extend_with_element(n, elem);
-    v
+    <T as SpecFromElem>::from_elem(elem, n)
+}
+
+// Specialization trait used for Vec::from_elem
+trait SpecFromElem: Sized {
+    fn from_elem(elem: Self, n: usize) -> Vec<Self>;
+}
+
+impl<T: Clone> SpecFromElem for T {
+    default fn from_elem(elem: Self, n: usize) -> Vec<Self> {
+        let mut v = Vec::with_capacity(n);
+        v.extend_with_element(n, elem);
+        v
+    }
+}
+
+impl SpecFromElem for u8 {
+    #[inline]
+    fn from_elem(elem: u8, n: usize) -> Vec<u8> {
+        if elem == 0 {
+            return Vec {
+                buf: RawVec::with_capacity_zeroed(n),
+                len: n,
+            }
+        }
+        unsafe {
+            let mut v = Vec::with_capacity(n);
+            ptr::write_bytes(v.as_mut_ptr(), elem, n);
+            v.set_len(n);
+            v
+        }
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////