Skip to content

Commit 56d82b3

Browse files
committed
refactor: moved SpecFromIterNested to spec_from_iter_nested.rs
1 parent 9e08ce7 commit 56d82b3

File tree

2 files changed

+60
-52
lines changed

2 files changed

+60
-52
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ use self::in_place_drop::InPlaceDrop;
117117

118118
mod in_place_drop;
119119

120+
use self::spec_from_iter_nested::SpecFromIterNested;
121+
122+
mod spec_from_iter_nested;
123+
120124
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
121125
///
122126
/// # Examples
@@ -2176,58 +2180,6 @@ trait SpecFromIter<T, I> {
21762180
fn from_iter(iter: I) -> Self;
21772181
}
21782182

2179-
/// Another specialization trait for Vec::from_iter
2180-
/// necessary to manually prioritize overlapping specializations
2181-
/// see [`SpecFromIter`] for details.
2182-
trait SpecFromIterNested<T, I> {
2183-
fn from_iter(iter: I) -> Self;
2184-
}
2185-
2186-
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
2187-
where
2188-
I: Iterator<Item = T>,
2189-
{
2190-
default fn from_iter(mut iterator: I) -> Self {
2191-
// Unroll the first iteration, as the vector is going to be
2192-
// expanded on this iteration in every case when the iterable is not
2193-
// empty, but the loop in extend_desugared() is not going to see the
2194-
// vector being full in the few subsequent loop iterations.
2195-
// So we get better branch prediction.
2196-
let mut vector = match iterator.next() {
2197-
None => return Vec::new(),
2198-
Some(element) => {
2199-
let (lower, _) = iterator.size_hint();
2200-
let mut vector = Vec::with_capacity(lower.saturating_add(1));
2201-
unsafe {
2202-
ptr::write(vector.as_mut_ptr(), element);
2203-
vector.set_len(1);
2204-
}
2205-
vector
2206-
}
2207-
};
2208-
// must delegate to spec_extend() since extend() itself delegates
2209-
// to spec_from for empty Vecs
2210-
<Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
2211-
vector
2212-
}
2213-
}
2214-
2215-
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
2216-
where
2217-
I: TrustedLen<Item = T>,
2218-
{
2219-
fn from_iter(iterator: I) -> Self {
2220-
let mut vector = match iterator.size_hint() {
2221-
(_, Some(upper)) => Vec::with_capacity(upper),
2222-
_ => Vec::new(),
2223-
};
2224-
// must delegate to spec_extend() since extend() itself delegates
2225-
// to spec_from for empty Vecs
2226-
vector.spec_extend(iterator);
2227-
vector
2228-
}
2229-
}
2230-
22312183
impl<T, I> SpecFromIter<T, I> for Vec<T>
22322184
where
22332185
I: Iterator<Item = T>,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use core::ptr::{self};
2+
use core::iter::{TrustedLen};
3+
4+
use super::{Vec, SpecExtend};
5+
6+
/// Another specialization trait for Vec::from_iter
7+
/// necessary to manually prioritize overlapping specializations
8+
/// see [`SpecFromIter`] for details.
9+
pub(super) trait SpecFromIterNested<T, I> {
10+
fn from_iter(iter: I) -> Self;
11+
}
12+
13+
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
14+
where
15+
I: Iterator<Item = T>,
16+
{
17+
default fn from_iter(mut iterator: I) -> Self {
18+
// Unroll the first iteration, as the vector is going to be
19+
// expanded on this iteration in every case when the iterable is not
20+
// empty, but the loop in extend_desugared() is not going to see the
21+
// vector being full in the few subsequent loop iterations.
22+
// So we get better branch prediction.
23+
let mut vector = match iterator.next() {
24+
None => return Vec::new(),
25+
Some(element) => {
26+
let (lower, _) = iterator.size_hint();
27+
let mut vector = Vec::with_capacity(lower.saturating_add(1));
28+
unsafe {
29+
ptr::write(vector.as_mut_ptr(), element);
30+
vector.set_len(1);
31+
}
32+
vector
33+
}
34+
};
35+
// must delegate to spec_extend() since extend() itself delegates
36+
// to spec_from for empty Vecs
37+
<Vec<T> as SpecExtend<T, I>>::spec_extend(&mut vector, iterator);
38+
vector
39+
}
40+
}
41+
42+
impl<T, I> SpecFromIterNested<T, I> for Vec<T>
43+
where
44+
I: TrustedLen<Item = T>,
45+
{
46+
fn from_iter(iterator: I) -> Self {
47+
let mut vector = match iterator.size_hint() {
48+
(_, Some(upper)) => Vec::with_capacity(upper),
49+
_ => Vec::new(),
50+
};
51+
// must delegate to spec_extend() since extend() itself delegates
52+
// to spec_from for empty Vecs
53+
vector.spec_extend(iterator);
54+
vector
55+
}
56+
}

0 commit comments

Comments
 (0)