diff options
| author | Matt Brubeck <mbrubeck@limpet.net> | 2017-03-09 17:53:01 -0800 |
|---|---|---|
| committer | Matt Brubeck <mbrubeck@limpet.net> | 2017-04-15 09:01:56 -0700 |
| commit | 675475c4d3e3b1ebff5b761570f4a3f9a0ca23df (patch) | |
| tree | 49cfa5b4d6edca5205909e9b0729e9744507940c /src/libcollections | |
| parent | 5637ed756632ded9e458b82a23cc1dddbb57c51f (diff) | |
| download | rust-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.rs | 35 |
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 + } + } } //////////////////////////////////////////////////////////////////////////////// |
