Skip to content

Commit dd166da

Browse files
committed
generalize slice::fill specialization for byte-sized items
This should also improve cross-crate inlining since the method is generic
1 parent 36f1f04 commit dd166da

File tree

1 file changed

+13
-36
lines changed

1 file changed

+13
-36
lines changed

library/core/src/slice/specialize.rs

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::mem::{size_of, transmute_copy};
12
use crate::ptr::write_bytes;
23

34
pub(super) trait SpecFill<T> {
@@ -17,42 +18,18 @@ impl<T: Clone> SpecFill<T> for [T] {
1718
}
1819

1920
impl<T: Copy> SpecFill<T> for [T] {
20-
default fn spec_fill(&mut self, value: T) {
21-
for item in self.iter_mut() {
22-
*item = value;
23-
}
24-
}
25-
}
26-
27-
impl SpecFill<u8> for [u8] {
28-
fn spec_fill(&mut self, value: u8) {
29-
// SAFETY: this is slice of u8
30-
unsafe {
31-
let ptr = self.as_mut_ptr();
32-
let len = self.len();
33-
write_bytes(ptr, value, len);
34-
}
35-
}
36-
}
37-
38-
impl SpecFill<i8> for [i8] {
39-
fn spec_fill(&mut self, value: i8) {
40-
// SAFETY: this is slice of i8
41-
unsafe {
42-
let ptr = self.as_mut_ptr();
43-
let len = self.len();
44-
write_bytes(ptr, value as u8, len);
45-
}
46-
}
47-
}
48-
49-
impl SpecFill<bool> for [bool] {
50-
fn spec_fill(&mut self, value: bool) {
51-
// SAFETY: this is slice of bool
52-
unsafe {
53-
let ptr = self.as_mut_ptr();
54-
let len = self.len();
55-
write_bytes(ptr, value as u8, len);
21+
fn spec_fill(&mut self, value: T) {
22+
if size_of::<T>() == 1 {
23+
// SAFETY: The size_of check above ensures that values are 1 byte wide, as required
24+
// for the transmute and write_bytes
25+
unsafe {
26+
let value: u8 = transmute_copy(&value);
27+
write_bytes(self.as_mut_ptr(), value, self.len());
28+
}
29+
} else {
30+
for item in self.iter_mut() {
31+
*item = value;
32+
}
5633
}
5734
}
5835
}

0 commit comments

Comments
 (0)