specialize.rs - source
Description: Source of the Rust file `library/core/src/slice/specialize.rs`.

#
core/slice/
specialize.rs

    1use crate::clone::TrivialClone;
    2use crate::ptr;
    3
    4pub(super) trait SpecFill<T> {
    5    fn spec_fill(&mut self, value: T);
    6}
    7
    8impl<T: Clone> SpecFill<T> for [T] {
    9    default fn spec_fill(&mut self, value: T) {
    10        if let Some((last, elems)) = self.split_last_mut() {
    11            for el in elems {
    12                el.clone_from(&value);
    13            }
    14
    15            *last = value
    16        }
    17    }
    18}
    19
    20impl<T: TrivialClone> SpecFill<T> for [T] {
    21    default fn spec_fill(&mut self, value: T) {
    22        for item in self.iter_mut() {
    23            // SAFETY: `TrivialClone` indicates that this is equivalent to
    24            // calling `Clone::clone`
    25            *item = unsafe { ptr::read(&value) };
    26        }
    27    }
    28}
    29
    30impl SpecFill<u8> for [u8] {
    31    fn spec_fill(&mut self, value: u8) {
    32        // SAFETY: The pointer is derived from a reference, so it's writable.
    33        unsafe {
    34            crate::intrinsics::write_bytes(self.as_mut_ptr(), value, self.len());
    35        }
    36    }
    37}
    38
    39impl SpecFill<i8> for [i8] {
    40    fn spec_fill(&mut self, value: i8) {
    41        // SAFETY: The pointer is derived from a reference, so it's writable.
    42        unsafe {
    43            crate::intrinsics::write_bytes(self.as_mut_ptr(), value.cast_unsigned(), self.len());
    44        }
    45    }
    46}
    47
    48macro spec_fill_int {
    49    ($($type:ty)*) => {$(
    50        impl SpecFill<$type> for [$type] {
    51            #[inline]
    52            fn spec_fill(&mut self, value: $type) {
    53                // We always take this fastpath in Miri for long slices as the manual `for`
    54                // loop can be prohibitively slow.
    55                if (cfg!(miri) && self.len() > 32) || crate::intrinsics::is_val_statically_known(value) {
    56                    let bytes = value.to_ne_bytes();
    57                    if value == <$type>::from_ne_bytes([bytes[0]; size_of::<$type>()]) {
    58                        // SAFETY: The pointer is derived from a reference, so it's writable.
    59                        unsafe {
    60                            crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0], self.len());
    61                        }
    62                        return;
    63                    }
    64                }
    65                for item in self.iter_mut() {
    66                    *item = value;
    67                }
    68            }
    69        }
    70    )*}
    71}
    72
    73spec_fill_int! { u16 i16 u32 i32 u64 i64 u128 i128 usize isize }