Skip to content

Commit b705008

Browse files
committed
---
yaml --- r: 123870 b: refs/heads/snap-stage3 c: f1ea540 h: refs/heads/master v: v3
1 parent 2341fca commit b705008

File tree

2 files changed

+45
-32
lines changed

2 files changed

+45
-32
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 4e2da7cb79143b0e7206a684629ed942599ec8e9
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 065b98d5774954a42733bcc3de382029dcdcf0cf
4+
refs/heads/snap-stage3: f1ea540e9024db9b5d2e6a6e92431875feb345b3
55
refs/heads/try: 296eb104620b346d88bc4a2c2ab7693e6d3db019
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libcollections/vec.rs

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,9 @@ impl<T: Clone> Vec<T> {
197197
/// ```
198198
#[inline]
199199
pub fn from_slice(values: &[T]) -> Vec<T> {
200-
values.iter().map(|x| x.clone()).collect()
200+
let mut vector = Vec::with_capacity(values.len());
201+
vector.push_all(values);
202+
vector
201203
}
202204

203205
/// Constructs a `Vec` with copies of a value.
@@ -238,7 +240,10 @@ impl<T: Clone> Vec<T> {
238240
/// ```
239241
#[inline]
240242
pub fn push_all(&mut self, other: &[T]) {
241-
self.extend(other.iter().map(|e| e.clone()));
243+
unsafe {
244+
self.reserve_additional(other.len());
245+
unsafe_push_all_clone(self, other)
246+
}
242247
}
243248

244249
/// Grows the `Vec` in-place.
@@ -318,41 +323,31 @@ impl<T: Clone> Vec<T> {
318323
#[unstable]
319324
impl<T:Clone> Clone for Vec<T> {
320325
fn clone(&self) -> Vec<T> {
321-
let len = self.len;
322-
let mut vector = Vec::with_capacity(len);
323-
// Unsafe code so this can be optimised to a memcpy (or something
324-
// similarly fast) when T is Copy. LLVM is easily confused, so any
325-
// extra operations during the loop can prevent this optimisation
326-
{
327-
let this_slice = self.as_slice();
328-
while vector.len < len {
329-
unsafe {
330-
let len = vector.len;
331-
ptr::write(
332-
vector.as_mut_slice().unsafe_mut_ref(len),
333-
this_slice.unsafe_ref(len).clone());
334-
}
335-
vector.len += 1;
336-
}
326+
unsafe {
327+
let mut vector = Vec::with_capacity(self.len);
328+
unsafe_push_all_clone(&mut vector, self.as_slice());
329+
vector
337330
}
338-
vector
339331
}
340332

341333
fn clone_from(&mut self, other: &Vec<T>) {
342-
// drop anything in self that will not be overwritten
343-
if self.len() > other.len() {
344-
self.truncate(other.len())
345-
}
334+
unsafe {
335+
// drop anything in self that will not be overwritten
336+
if self.len() > other.len() {
337+
self.truncate(other.len())
338+
}
346339

347-
// reuse the contained values' allocations/resources.
348-
for (place, thing) in self.mut_iter().zip(other.iter()) {
349-
place.clone_from(thing)
350-
}
340+
// reuse the contained values' allocations/resources.
341+
for (place, thing) in self.mut_iter().zip(other.iter()) {
342+
place.clone_from(thing)
343+
}
351344

352-
// self.len <= other.len due to the truncate above, so the
353-
// slice here is always in-bounds.
354-
let len = self.len();
355-
self.extend(other.slice_from(len).iter().map(|x| x.clone()));
345+
// self.len <= other.len due to the truncate above, so the
346+
// slice here is always in-bounds.
347+
let slice = other.slice_from(self.len());
348+
self.reserve_additional(slice.len());
349+
unsafe_push_all_clone(self, slice)
350+
}
356351
}
357352
}
358353

@@ -1555,6 +1550,24 @@ pub mod raw {
15551550
}
15561551
}
15571552

1553+
// Unsafe code so this can be optimised to a memcpy (or something similarly
1554+
// fast) when T is Copy. LLVM is easily confused, so any extra operations
1555+
// during the loop can prevent this optimisation.
1556+
//
1557+
// WARNING: You must preallocate space on the vector before you call this
1558+
// method.
1559+
#[inline(always)]
1560+
unsafe fn unsafe_push_all_clone<T: Clone>(dst: &mut Vec<T>, src: &[T]) {
1561+
let mut dst_len = dst.len();
1562+
1563+
for i in range(0, src.len()) {
1564+
ptr::write(
1565+
dst.as_mut_slice().unsafe_mut_ref(dst_len),
1566+
src.unsafe_ref(i).clone());
1567+
dst_len += 1;
1568+
dst.set_len(dst_len);
1569+
}
1570+
}
15581571

15591572
#[cfg(test)]
15601573
mod tests {

0 commit comments

Comments
 (0)