| use core::cmp; |
| use core::iter::TrustedLen; |
| use core::ptr; |
| |
| use crate::raw_vec::RawVec; |
| |
| use super::{SpecExtend, Vec}; |
| |
| /// 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 |
| } |
| } |