diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2014-04-03 22:28:45 +1100 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-04-03 13:42:32 -0700 |
| commit | f5a4837df0885368352d118e1e71f4853bf55bf8 (patch) | |
| tree | 782fff3828b54a74c2ec885379414b350e951c8b /src/libstd | |
| parent | 0bd6f2ce0b650ebcb1d2b05dc501a9ed4907b6d2 (diff) | |
| download | rust-f5a4837df0885368352d118e1e71f4853bf55bf8.tar.gz rust-f5a4837df0885368352d118e1e71f4853bf55bf8.zip | |
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.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/lib.rs | 1 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 56 |
2 files changed, 53 insertions, 4 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index fb6c1b4c8a3..7971c332b27 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -232,4 +232,5 @@ mod std { pub use to_str; pub use ty; pub use unstable; + pub use vec; } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 69c3a85b2f1..e414ff25d43 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -310,11 +310,24 @@ impl<T: Clone> Vec<T> { impl<T:Clone> Clone for Vec<T> { fn clone(&self) -> Vec<T> { - let mut vector = Vec::with_capacity(self.len()); - for element in self.iter() { - vector.push((*element).clone()) + self.iter().map(|x| x.clone()).collect() + } + + fn clone_from(&mut self, other: &Vec<T>) { + // drop anything in self that will not be overwritten + if self.len() > other.len() { + self.truncate(other.len()) } - vector + + // reuse the contained values' allocations/resources. + for (place, thing) in self.mut_iter().zip(other.iter()) { + place.clone_from(thing) + } + + // self.len <= other.len due to the truncate above, so the + // slice here is always in-bounds. + let len = self.len(); + self.extend(other.slice_from(len).iter().map(|x| x.clone())); } } @@ -1475,4 +1488,39 @@ mod tests { assert!(values == Vec::from_slice([2u8, 3, 5, 6, 7])); } + + #[test] + fn test_clone() { + let v: Vec<int> = vec!(); + let w = vec!(1, 2, 3); + + assert_eq!(v, v.clone()); + + let z = w.clone(); + assert_eq!(w, z); + // they should be disjoint in memory. + assert!(w.as_ptr() != z.as_ptr()) + } + + #[test] + fn test_clone_from() { + let mut v = vec!(); + let three = vec!(~1, ~2, ~3); + let two = vec!(~4, ~5); + // zero, long + v.clone_from(&three); + assert_eq!(v, three); + + // equal + v.clone_from(&three); + assert_eq!(v, three); + + // long, short + v.clone_from(&two); + assert_eq!(v, two); + + // short, long + v.clone_from(&three); + assert_eq!(v, three) + } } |
