refactor: moved SpecFromIterNested to spec_from_iter_nested.rs
This commit is contained in:
parent
9e08ce7190
commit
56d82b3dcc
2 changed files with 60 additions and 52 deletions
|
@ -117,6 +117,10 @@ use self::in_place_drop::InPlaceDrop;
|
|||
|
||||
mod in_place_drop;
|
||||
|
||||
use self::spec_from_iter_nested::SpecFromIterNested;
|
||||
|
||||
mod spec_from_iter_nested;
|
||||
|
||||
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -2176,58 +2180,6 @@ trait SpecFromIter<T, I> {
|
|||
fn from_iter(iter: I) -> Self;
|
||||
}
|
||||
|
||||
/// Another specialization trait for Vec::from_iter
|
||||
/// necessary to manually prioritize overlapping specializations
|
||||
/// see [`SpecFromIter`] for details.
|
||||
trait SpecFromIterNested<T, I> {
|
||||
fn from_iter(iter: I) -> Self;
|
||||
}
|
||||
|
||||
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
{
|
||||
default fn from_iter(mut iterator: I) -> Self {
|
||||
// Unroll the first iteration, as the vector is going to be
|
||||
// expanded on this iteration in every case when the iterable is not
|
||||
// empty, but the loop in extend_desugared() is not going to see the
|
||||
// vector being full in the few subsequent loop iterations.
|
||||
// So we get better branch prediction.
|
||||
let mut vector = match iterator.next() {
|
||||
None => return Vec::new(),
|
||||
Some(element) => {
|
||||
let (lower, _) = iterator.size_hint();
|
||||
let mut vector = Vec::with_capacity(lower.saturating_add(1));
|
||||
unsafe {
|
||||
ptr::write(vector.as_mut_ptr(), element);
|
||||
vector.set_len(1);
|
||||
}
|
||||
vector
|
||||
}
|
||||
};
|
||||
// must delegate to spec_extend() since extend() itself delegates
|
||||
// to spec_from for empty Vecs
|
||||
<Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
|
||||
vector
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
|
||||
where
|
||||
I: TrustedLen<Item = T>,
|
||||
{
|
||||
fn from_iter(iterator: I) -> Self {
|
||||
let mut vector = match iterator.size_hint() {
|
||||
(_, Some(upper)) => Vec::with_capacity(upper),
|
||||
_ => Vec::new(),
|
||||
};
|
||||
// must delegate to spec_extend() since extend() itself delegates
|
||||
// to spec_from for empty Vecs
|
||||
vector.spec_extend(iterator);
|
||||
vector
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I> SpecFromIter<T, I> for Vec<T>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
|
|
56
library/alloc/src/vec/spec_from_iter_nested.rs
Normal file
56
library/alloc/src/vec/spec_from_iter_nested.rs
Normal file
|
@ -0,0 +1,56 @@
|
|||
use core::ptr::{self};
|
||||
use core::iter::{TrustedLen};
|
||||
|
||||
use super::{Vec, SpecExtend};
|
||||
|
||||
/// Another specialization trait for Vec::from_iter
|
||||
/// necessary to manually prioritize overlapping specializations
|
||||
/// see [`SpecFromIter`] for details.
|
||||
pub(super) trait SpecFromIterNested<T, I> {
|
||||
fn from_iter(iter: I) -> Self;
|
||||
}
|
||||
|
||||
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
{
|
||||
default fn from_iter(mut iterator: I) -> Self {
|
||||
// Unroll the first iteration, as the vector is going to be
|
||||
// expanded on this iteration in every case when the iterable is not
|
||||
// empty, but the loop in extend_desugared() is not going to see the
|
||||
// vector being full in the few subsequent loop iterations.
|
||||
// So we get better branch prediction.
|
||||
let mut vector = match iterator.next() {
|
||||
None => return Vec::new(),
|
||||
Some(element) => {
|
||||
let (lower, _) = iterator.size_hint();
|
||||
let mut vector = Vec::with_capacity(lower.saturating_add(1));
|
||||
unsafe {
|
||||
ptr::write(vector.as_mut_ptr(), element);
|
||||
vector.set_len(1);
|
||||
}
|
||||
vector
|
||||
}
|
||||
};
|
||||
// must delegate to spec_extend() since extend() itself delegates
|
||||
// to spec_from for empty Vecs
|
||||
<Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
|
||||
vector
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
|
||||
where
|
||||
I: TrustedLen<Item = T>,
|
||||
{
|
||||
fn from_iter(iterator: I) -> Self {
|
||||
let mut vector = match iterator.size_hint() {
|
||||
(_, Some(upper)) => Vec::with_capacity(upper),
|
||||
_ => Vec::new(),
|
||||
};
|
||||
// must delegate to spec_extend() since extend() itself delegates
|
||||
// to spec_from for empty Vecs
|
||||
vector.spec_extend(iterator);
|
||||
vector
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue