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;
|
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'.
|
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
|
@ -2176,58 +2180,6 @@ trait SpecFromIter<T, I> {
|
||||||
fn from_iter(iter: I) -> Self;
|
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>
|
impl<T, I> SpecFromIter<T, I> for Vec<T>
|
||||||
where
|
where
|
||||||
I: Iterator<Item = T>,
|
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