diff options
| author | Neil Roberts <bpeeluk@yahoo.co.uk> | 2023-01-28 14:19:01 +0100 |
|---|---|---|
| committer | Neil Roberts <bpeeluk@yahoo.co.uk> | 2023-01-28 20:37:01 +0100 |
| commit | ba80c662f448c69cbd184d18630b8824f0169b2e (patch) | |
| tree | 9204e8b8b73c81e9b386b1a5b4f16144ba1b0a66 | |
| parent | d6f0642827e21a088b0130c84857d84f5433301d (diff) | |
| download | rust-ba80c662f448c69cbd184d18630b8824f0169b2e.tar.gz rust-ba80c662f448c69cbd184d18630b8824f0169b2e.zip | |
slice: Add a specialization for clone_into when T is Copy
The implementation for the ToOwned::clone_into method on [T] is a copy of the code for vec::clone_from. In 361398009be6 the code for vec::clone_from gained a specialization for when T is Copy. This commit copies that specialization over to the clone_into implementation.
| -rw-r--r-- | library/alloc/src/slice.rs | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index fecacc2bb63..093dcbbe8bf 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -782,6 +782,38 @@ impl<T, A: Allocator> BorrowMut<[T]> for Vec<T, A> { } } +// Specializable trait for implementing ToOwned::clone_into. This is +// public in the crate and has the Allocator parameter so that +// vec::clone_from use it too. +#[cfg(not(no_global_oom_handling))] +pub(crate) trait SpecCloneIntoVec<T, A: Allocator> { + fn clone_into(&self, target: &mut Vec<T, A>); +} + +#[cfg(not(no_global_oom_handling))] +impl<T: Clone, A: Allocator> SpecCloneIntoVec<T, A> for [T] { + default fn clone_into(&self, target: &mut Vec<T, A>) { + // drop anything in target that will not be overwritten + target.truncate(self.len()); + + // target.len <= self.len due to the truncate above, so the + // slices here are always in-bounds. + let (init, tail) = self.split_at(target.len()); + + // reuse the contained values' allocations/resources. + target.clone_from_slice(init); + target.extend_from_slice(tail); + } +} + +#[cfg(not(no_global_oom_handling))] +impl<T: Copy, A: Allocator> SpecCloneIntoVec<T, A> for [T] { + fn clone_into(&self, target: &mut Vec<T, A>) { + target.clear(); + target.extend_from_slice(self); + } +} + #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] impl<T: Clone> ToOwned for [T] { @@ -797,16 +829,7 @@ impl<T: Clone> ToOwned for [T] { } fn clone_into(&self, target: &mut Vec<T>) { - // drop anything in target that will not be overwritten - target.truncate(self.len()); - - // target.len <= self.len due to the truncate above, so the - // slices here are always in-bounds. - let (init, tail) = self.split_at(target.len()); - - // reuse the contained values' allocations/resources. - target.clone_from_slice(init); - target.extend_from_slice(tail); + SpecCloneIntoVec::clone_into(self, target); } } |
