     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82

    use crate::alloc::Allocator;
    use core::iter::TrustedLen;
    use core::ptr::{self};
    use core::slice::{self};

    use super::{IntoIter, SetLenOnDrop, Vec};

    // Specialization trait used for Vec::extend
    pub(super) trait SpecExtend<T, I> {
        fn spec_extend(&mut self, iter: I);
    }

    impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
    where
        I: Iterator<Item = T>,
    {
        default fn spec_extend(&mut self, iter: I) {
            self.extend_desugared(iter)
        }
    }

    impl<T, I, A: Allocator> SpecExtend<T, I> for Vec<T, A>
    where
        I: TrustedLen<Item = T>,
    {
        default fn spec_extend(&mut self, iterator: I) {
            // This is the case for a TrustedLen iterator.
            let (low, high) = iterator.size_hint();
            if let Some(high_value) = high {
                debug_assert_eq!(
                    low,
                    high_value,
                    "TrustedLen iterator's size hint is not exact: {:?}",
                    (low, high)
                );
            }
            if let Some(additional) = high {
                self.reserve(additional);
                unsafe {
                    let mut ptr = self.as_mut_ptr().add(self.len());
                    let mut local_len = SetLenOnDrop::new(&mut self.len);
                    iterator.for_each(move |element| {
                        ptr::write(ptr, element);
                        ptr = ptr.offset(1);
                        // NB can't overflow since we would have had to alloc the address space
                        local_len.increment_len(1);
                    });
                }
            } else {
                self.extend_desugared(iterator)
            }
        }
    }

    impl<T, A: Allocator> SpecExtend<T, IntoIter<T>> for Vec<T, A> {
        fn spec_extend(&mut self, mut iterator: IntoIter<T>) {
            unsafe {
                self.append_elements(iterator.as_slice() as _);
            }
            iterator.ptr = iterator.end;
        }
    }

    impl<'a, T: 'a, I, A: Allocator + 'a> SpecExtend<&'a T, I> for Vec<T, A>
    where
        I: Iterator<Item = &'a T>,
        T: Clone,
    {
        default fn spec_extend(&mut self, iterator: I) {
            self.spec_extend(iterator.cloned())
        }
    }

    impl<'a, T: 'a, A: Allocator + 'a> SpecExtend<&'a T, slice::Iter<'a, T>> for Vec<T, A>
    where
        T: Copy,
    {
        fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) {
            let slice = iterator.as_slice();
            unsafe { self.append_elements(slice) };
        }
    }