Rollup merge of #112263 - GrishaVar:remove-extend-element, r=scottmcm
Remove ExtendElement, ExtendWith, extend_with Related to #104624, broken up into two commits. The first removes wrapper trait ExtendWith and its only implementer struct ExtendElement. The second may have perf issues so may be reverted/removed if no alternate fix is found; it should be profiled. r? `@scottmcm`
This commit is contained in:
commit
200d03acad
@ -2355,7 +2355,7 @@ pub fn resize(&mut self, new_len: usize, value: T) {
|
||||
let len = self.len();
|
||||
|
||||
if new_len > len {
|
||||
self.extend_with(new_len - len, ExtendElement(value))
|
||||
self.extend_with(new_len - len, value)
|
||||
} else {
|
||||
self.truncate(new_len);
|
||||
}
|
||||
@ -2469,26 +2469,10 @@ pub fn into_flattened(self) -> Vec<T, A> {
|
||||
}
|
||||
}
|
||||
|
||||
// This code generalizes `extend_with_{element,default}`.
|
||||
trait ExtendWith<T> {
|
||||
fn next(&mut self) -> T;
|
||||
fn last(self) -> T;
|
||||
}
|
||||
|
||||
struct ExtendElement<T>(T);
|
||||
impl<T: Clone> ExtendWith<T> for ExtendElement<T> {
|
||||
fn next(&mut self) -> T {
|
||||
self.0.clone()
|
||||
}
|
||||
fn last(self) -> T {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> Vec<T, A> {
|
||||
impl<T: Clone, A: Allocator> Vec<T, A> {
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
/// Extend the vector by `n` values, using the given generator.
|
||||
fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
|
||||
/// Extend the vector by `n` clones of value.
|
||||
fn extend_with(&mut self, n: usize, value: T) {
|
||||
self.reserve(n);
|
||||
|
||||
unsafe {
|
||||
@ -2500,15 +2484,15 @@ fn extend_with<E: ExtendWith<T>>(&mut self, n: usize, mut value: E) {
|
||||
|
||||
// Write all elements except the last one
|
||||
for _ in 1..n {
|
||||
ptr::write(ptr, value.next());
|
||||
ptr::write(ptr, value.clone());
|
||||
ptr = ptr.add(1);
|
||||
// Increment the length in every step in case next() panics
|
||||
// Increment the length in every step in case clone() panics
|
||||
local_len.increment_len(1);
|
||||
}
|
||||
|
||||
if n > 0 {
|
||||
// We can write the last element directly without cloning needlessly
|
||||
ptr::write(ptr, value.last());
|
||||
ptr::write(ptr, value);
|
||||
local_len.increment_len(1);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::alloc::Allocator;
|
||||
use crate::raw_vec::RawVec;
|
||||
|
||||
use super::{ExtendElement, IsZero, Vec};
|
||||
use super::{IsZero, Vec};
|
||||
|
||||
// Specialization trait used for Vec::from_elem
|
||||
pub(super) trait SpecFromElem: Sized {
|
||||
@ -13,7 +13,7 @@ pub(super) trait SpecFromElem: Sized {
|
||||
impl<T: Clone> SpecFromElem for T {
|
||||
default fn from_elem<A: Allocator>(elem: Self, n: usize, alloc: A) -> Vec<Self, A> {
|
||||
let mut v = Vec::with_capacity_in(n, alloc);
|
||||
v.extend_with(n, ExtendElement(elem));
|
||||
v.extend_with(n, elem);
|
||||
v
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@ impl<T: Clone + IsZero> SpecFromElem for T {
|
||||
return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
|
||||
}
|
||||
let mut v = Vec::with_capacity_in(n, alloc);
|
||||
v.extend_with(n, ExtendElement(elem));
|
||||
v.extend_with(n, elem);
|
||||
v
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user