Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: moved SpecFromIterNested to spec_from_iter_nested.rs
- Loading branch information
1 parent
9e08ce7
commit 56d82b3
Showing
2 changed files
with
60 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} | ||
} |