diff options
| author | bors <bors@rust-lang.org> | 2014-04-03 17:17:02 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-04-03 17:17:02 -0700 |
| commit | e7fe20722904cd2829a65f845ee7a1718cdf7292 (patch) | |
| tree | de906a26828f4a01fcdec0112047d16250d5c991 /src/libstd | |
| parent | bb31cb8d2e4e415cbb71d368918d72902e655e01 (diff) | |
| parent | 487fa9568b69753fecb74a8460109239f4bf3631 (diff) | |
| download | rust-e7fe20722904cd2829a65f845ee7a1718cdf7292.tar.gz rust-e7fe20722904cd2829a65f845ee7a1718cdf7292.zip | |
auto merge of #13290 : alexcrichton/rust/rollup, r=alexcrichton
Closes #13285 (rustc: Stop using LLVMGetSectionName) Closes #13280 (std: override clone_from for Vec.) Closes #13277 (serialize: add a few missing pubs to base64) Closes #13275 (Add and remove some ignore-win32 flags) Closes #13273 (Removed managed boxes from libarena.) Closes #13270 (Minor copy-editing for the tutorial) Closes #13267 (fix Option<~ZeroSizeType>) Closes #13265 (Update emacs mode to support new `#![inner(attribute)]` syntax.) Closes #13263 (syntax: Remove AbiSet, use one Abi)
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/lib.rs | 1 | ||||
| -rw-r--r-- | src/libstd/rt/global_heap.rs | 13 | ||||
| -rw-r--r-- | src/libstd/vec.rs | 56 |
3 files changed, 64 insertions, 6 deletions
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 75d6b83803f..b6e3e56835f 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/rt/global_heap.rs b/src/libstd/rt/global_heap.rs index 23b23cf8af0..5c1b6cd4791 100644 --- a/src/libstd/rt/global_heap.rs +++ b/src/libstd/rt/global_heap.rs @@ -68,8 +68,17 @@ pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 { #[cfg(not(test))] #[lang="exchange_malloc"] #[inline] -pub unsafe fn exchange_malloc(size: uint) -> *u8 { - malloc_raw(size) as *u8 +pub unsafe fn exchange_malloc(size: uint) -> *mut u8 { + // The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size + // allocations can point to this `static`. It would be incorrect to use a null + // pointer, due to enums assuming types like unique pointers are never null. + static EMPTY: () = (); + + if size == 0 { + &EMPTY as *() as *mut u8 + } else { + malloc_raw(size) + } } // FIXME: #7496 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) + } } |
