     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

    use crate::alloc::Allocator;
    use crate::raw_vec::RawVec;
    use core::ptr::{self};

    use super::{ExtendElement, IsZero, Vec};

    // Specialization trait used for Vec::from_elem
    pub(super) trait SpecFromElem: Sized {
        fn from_elem<A: Allocator>(elem: Self, n: usize, alloc: A) -> Vec<Self, A>;
    }

    impl<T: Clone> SpecFromElem for T {
        default fn from_elem<A: Allocator>(elem: Self, n: usize, alloc: A) -> Vec<Self, A> {
            let mut v = Vec::with_capacity_in(n, alloc);
            v.extend_with(n, ExtendElement(elem));
            v
        }
    }

    impl SpecFromElem for i8 {
        #[inline]
        fn from_elem<A: Allocator>(elem: i8, n: usize, alloc: A) -> Vec<i8, A> {
            if elem == 0 {
                return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
            }
            unsafe {
                let mut v = Vec::with_capacity_in(n, alloc);
                ptr::write_bytes(v.as_mut_ptr(), elem as u8, n);
                v.set_len(n);
                v
            }
        }
    }

    impl SpecFromElem for u8 {
        #[inline]
        fn from_elem<A: Allocator>(elem: u8, n: usize, alloc: A) -> Vec<u8, A> {
            if elem == 0 {
                return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
            }
            unsafe {
                let mut v = Vec::with_capacity_in(n, alloc);
                ptr::write_bytes(v.as_mut_ptr(), elem, n);
                v.set_len(n);
                v
            }
        }
    }

    impl<T: Clone + IsZero> SpecFromElem for T {
        #[inline]
        fn from_elem<A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<T, A> {
            if elem.is_zero() {
                return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n };
            }
            let mut v = Vec::with_capacity_in(n, alloc);
            v.extend_with(n, ExtendElement(elem));
            v
        }
    }