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 { fn from_iter(iter: I) -> Self; } impl SpecFromIterNested for Vec where I: Iterator, { 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::::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 as SpecExtend>::spec_extend(&mut vector, iterator); vector } } impl SpecFromIterNested for Vec where I: TrustedLen, { 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 } }