They cause significant binary size overhead while contributing little value. Also removes them from the wrapping String methods that do not panic.
63 lines
2.3 KiB
Rust
63 lines
2.3 KiB
Rust
use core::iter::TrustedLen;
|
|
use core::{cmp, ptr};
|
|
|
|
use super::{SpecExtend, Vec};
|
|
use crate::raw_vec::RawVec;
|
|
|
|
/// Another specialization trait for Vec::from_iter
|
|
/// necessary to manually prioritize overlapping specializations
|
|
/// see [`SpecFromIter`](super::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 initial_capacity =
|
|
cmp::max(RawVec::<T>::MIN_NON_ZERO_CAP, lower.saturating_add(1));
|
|
let mut vector = Vec::with_capacity(initial_capacity);
|
|
unsafe {
|
|
// SAFETY: We requested capacity at least 1
|
|
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),
|
|
// TrustedLen contract guarantees that `size_hint() == (_, None)` means that there
|
|
// are more than `usize::MAX` elements.
|
|
// Since the previous branch would eagerly panic if the capacity is too large
|
|
// (via `with_capacity`) we do the same here.
|
|
_ => panic!("capacity overflow"),
|
|
};
|
|
// reuse extend specialization for TrustedLen
|
|
vector.spec_extend(iterator);
|
|
vector
|
|
}
|
|
}
|