diff options
| author | Benoît du Garreau <bdgdlm@outlook.com> | 2021-08-10 11:45:52 +0200 |
|---|---|---|
| committer | Benoît du Garreau <bdgdlm@outlook.com> | 2021-08-10 11:53:40 +0200 |
| commit | 361398009be65f9aa6ae539c2ea37fbd943cc789 (patch) | |
| tree | dd3e48855a93123c2ada11bf265cd50974eb469e | |
| parent | ae90dcf0207c57c3034f00b07048d63f8b2363c8 (diff) | |
| download | rust-361398009be65f9aa6ae539c2ea37fbd943cc789.tar.gz rust-361398009be65f9aa6ae539c2ea37fbd943cc789.zip | |
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 | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e14ebd869a3..e5441f13870 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2378,6 +2378,32 @@ impl<T, A: Allocator> ops::DerefMut for Vec<T, A> { } } +trait SpecCloneFrom { + fn clone_from(this: &mut Self, other: &Self); +} + +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); + } +} + +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> { @@ -2398,16 +2424,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) } } |
