diff options
| author | bors <bors@rust-lang.org> | 2021-08-14 14:52:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-08-14 14:52:33 +0000 |
| commit | a59e8853148c6a26ed583cccd0f1c3fc50444c9c (patch) | |
| tree | 8645e66f2d42e1c40e76ffc0cbf033a8b289b699 | |
| parent | 136eaa1b25d13635b773a481ecab61a3162cb627 (diff) | |
| parent | 94d6b22fc36f50b021e47eae2a9437689ee83077 (diff) | |
| download | rust-a59e8853148c6a26ed583cccd0f1c3fc50444c9c.tar.gz rust-a59e8853148c6a26ed583cccd0f1c3fc50444c9c.zip | |
Auto merge of #87913 - a1phyr:vec_spec_clone_from, r=dtolnay
Specialize `Vec::clone_from` for `Copy` types This should improve performance and reduce code size. This also improves `clone_from` for `String`, `OsString` and `PathBuf`.
| -rw-r--r-- | library/alloc/src/vec/mod.rs | 40 |
1 files changed, 30 insertions, 10 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e14ebd869a3..933361d812c 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2379,6 +2379,35 @@ impl<T, A: Allocator> ops::DerefMut for Vec<T, A> { } #[cfg(not(no_global_oom_handling))] +trait SpecCloneFrom { + fn clone_from(this: &mut Self, other: &Self); +} + +#[cfg(not(no_global_oom_handling))] +impl<T: Clone, A: Allocator> SpecCloneFrom for Vec<T, A> { + default fn clone_from(this: &mut Self, other: &Self) { + // drop anything that will not be overwritten + this.truncate(other.len()); + + // self.len <= other.len due to the truncate above, so the + // slices here are always in-bounds. + let (init, tail) = other.split_at(this.len()); + + // reuse the contained values' allocations/resources. + this.clone_from_slice(init); + this.extend_from_slice(tail); + } +} + +#[cfg(not(no_global_oom_handling))] +impl<T: Copy, A: Allocator> SpecCloneFrom for Vec<T, A> { + fn clone_from(this: &mut Self, other: &Self) { + this.clear(); + this.extend_from_slice(other); + } +} + +#[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> { #[cfg(not(test))] @@ -2398,16 +2427,7 @@ impl<T: Clone, A: Allocator + Clone> Clone for Vec<T, A> { } fn clone_from(&mut self, other: &Self) { - // drop anything that will not be overwritten - self.truncate(other.len()); - - // self.len <= other.len due to the truncate above, so the - // slices here are always in-bounds. - let (init, tail) = other.split_at(self.len()); - - // reuse the contained values' allocations/resources. - self.clone_from_slice(init); - self.extend_from_slice(tail); + SpecCloneFrom::clone_from(self, other) } } |
