core/slice/
specialize.rs

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