Skip to content

Commit f5a4837

Browse files
huonwalexcrichton
authored andcommitted
std: override clone_from for Vec.
A vector can reuse its allocation (and the allocations/resources of any contained values) when cloning into an already-instantiated vector, so we might as well do so.
1 parent 0bd6f2c commit f5a4837

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

src/libstd/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,5 @@ mod std {
232232
pub use to_str;
233233
pub use ty;
234234
pub use unstable;
235+
pub use vec;
235236
}

src/libstd/vec.rs

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,24 @@ impl<T: Clone> Vec<T> {
310310

311311
impl<T:Clone> Clone for Vec<T> {
312312
fn clone(&self) -> Vec<T> {
313-
let mut vector = Vec::with_capacity(self.len());
314-
for element in self.iter() {
315-
vector.push((*element).clone())
313+
self.iter().map(|x| x.clone()).collect()
314+
}
315+
316+
fn clone_from(&mut self, other: &Vec<T>) {
317+
// drop anything in self that will not be overwritten
318+
if self.len() > other.len() {
319+
self.truncate(other.len())
316320
}
317-
vector
321+
322+
// reuse the contained values' allocations/resources.
323+
for (place, thing) in self.mut_iter().zip(other.iter()) {
324+
place.clone_from(thing)
325+
}
326+
327+
// self.len <= other.len due to the truncate above, so the
328+
// slice here is always in-bounds.
329+
let len = self.len();
330+
self.extend(other.slice_from(len).iter().map(|x| x.clone()));
318331
}
319332
}
320333

@@ -1475,4 +1488,39 @@ mod tests {
14751488

14761489
assert!(values == Vec::from_slice([2u8, 3, 5, 6, 7]));
14771490
}
1491+
1492+
#[test]
1493+
fn test_clone() {
1494+
let v: Vec<int> = vec!();
1495+
let w = vec!(1, 2, 3);
1496+
1497+
assert_eq!(v, v.clone());
1498+
1499+
let z = w.clone();
1500+
assert_eq!(w, z);
1501+
// they should be disjoint in memory.
1502+
assert!(w.as_ptr() != z.as_ptr())
1503+
}
1504+
1505+
#[test]
1506+
fn test_clone_from() {
1507+
let mut v = vec!();
1508+
let three = vec!(~1, ~2, ~3);
1509+
let two = vec!(~4, ~5);
1510+
// zero, long
1511+
v.clone_from(&three);
1512+
assert_eq!(v, three);
1513+
1514+
// equal
1515+
v.clone_from(&three);
1516+
assert_eq!(v, three);
1517+
1518+
// long, short
1519+
v.clone_from(&two);
1520+
assert_eq!(v, two);
1521+
1522+
// short, long
1523+
v.clone_from(&three);
1524+
assert_eq!(v, three)
1525+
}
14781526
}

0 commit comments

Comments
 (0)