Skip to content

Commit

Permalink
Rollup merge of #112263 - GrishaVar:remove-extend-element, r=scottmcm
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
GuillaumeGomez authored Jun 5, 2023
2 parents aabffef + dd2bd03 commit 200d03a
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 26 deletions.
30 changes: 7 additions & 23 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2355,7 +2355,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
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);
}
Expand Down Expand Up @@ -2469,26 +2469,10 @@ impl<T, A: Allocator, const N: usize> Vec<[T; N], 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 {
Expand All @@ -2500,15 +2484,15 @@ impl<T, A: Allocator> Vec<T, A> {

// 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);
}

Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/vec/spec_from_elem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::ptr;
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 {
Expand All @@ -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
}
}
Expand All @@ -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
}
}
Expand Down

0 comments on commit 200d03a

Please sign in to comment.