generalize slice::fill specialization for byte-sized items

This should also improve cross-crate inlining since the method is generic
This commit is contained in:
The8472 2021-03-17 23:45:03 +01:00
parent 36f1f04f18
commit dd166da8f8

View File

@ -1,3 +1,4 @@
use crate::mem::{size_of, transmute_copy};
use crate::ptr::write_bytes;
pub(super) trait SpecFill<T> {
@ -17,42 +18,18 @@ impl<T: Clone> SpecFill<T> for [T] {
}
impl<T: Copy> SpecFill<T> for [T] {
default fn spec_fill(&mut self, value: T) {
fn spec_fill(&mut self, value: T) {
if size_of::<T>() == 1 {
// SAFETY: The size_of check above ensures that values are 1 byte wide, as required
// for the transmute and write_bytes
unsafe {
let value: u8 = transmute_copy(&value);
write_bytes(self.as_mut_ptr(), value, self.len());
}
} else {
for item in self.iter_mut() {
*item = value;
}
}
}
impl SpecFill<u8> for [u8] {
fn spec_fill(&mut self, value: u8) {
// SAFETY: this is slice of u8
unsafe {
let ptr = self.as_mut_ptr();
let len = self.len();
write_bytes(ptr, value, len);
}
}
}
impl SpecFill<i8> for [i8] {
fn spec_fill(&mut self, value: i8) {
// SAFETY: this is slice of i8
unsafe {
let ptr = self.as_mut_ptr();
let len = self.len();
write_bytes(ptr, value as u8, len);
}
}
}
impl SpecFill<bool> for [bool] {
fn spec_fill(&mut self, value: bool) {
// SAFETY: this is slice of bool
unsafe {
let ptr = self.as_mut_ptr();
let len = self.len();
write_bytes(ptr, value as u8, len);
}
}
}