Auto merge of #83245 - the8472:generalize-slice-fill, r=m-ou-se
Generalize and inline slice::fill specializations This makes the memset specialization applicable to more types. And since the code now lives in a generic method it is also eligible for cross-crate inlining which should fix #83235
This commit is contained in:
commit
1010038814
@ -114,3 +114,16 @@ rotate!(rotate_16_usize_4, 16, |i| [i; 4]);
|
||||
rotate!(rotate_16_usize_5, 16, |i| [i; 5]);
|
||||
rotate!(rotate_64_usize_4, 64, |i| [i; 4]);
|
||||
rotate!(rotate_64_usize_5, 64, |i| [i; 5]);
|
||||
|
||||
#[bench]
|
||||
fn fill_byte_sized(b: &mut Bencher) {
|
||||
#[derive(Copy, Clone)]
|
||||
struct NewType(u8);
|
||||
|
||||
let mut ary = [NewType(0); 1024];
|
||||
|
||||
b.iter(|| {
|
||||
let slice = &mut ary[..];
|
||||
black_box(slice.fill(black_box(NewType(42))));
|
||||
});
|
||||
}
|
||||
|
@ -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) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user