Auto merge of #81874 - tesuji:spec_slice_fill, r=matthewjasper

Specialize slice::fill with Copy type and u8/i8/bool

I don't expect rustperf could measure any perf improvements with this changes
since `slice::fill` is newly added.

Godbolt link for this change: <https://rust.godbolt.org/z/r3fzee>.

r? `@matthewjasper` since this patch added new specialization.
This commit is contained in:
bors 2021-02-27 14:54:31 +00:00
commit ec7f8d94df
2 changed files with 60 additions and 7 deletions

View File

@ -35,6 +35,7 @@ mod iter;
mod raw;
mod rotate;
mod sort;
mod specialize;
#[stable(feature = "rust1", since = "1.0.0")]
pub use iter::{Chunks, ChunksMut, Windows};
@ -2866,13 +2867,7 @@ impl<T> [T] {
where
T: Clone,
{
if let Some((last, elems)) = self.split_last_mut() {
for el in elems {
el.clone_from(&value);
}
*last = value
}
specialize::SpecFill::spec_fill(self, value);
}
/// Fills `self` with elements returned by calling a closure repeatedly.

View File

@ -0,0 +1,58 @@
use crate::ptr::write_bytes;
pub(super) trait SpecFill<T> {
fn spec_fill(&mut self, value: T);
}
impl<T: Clone> SpecFill<T> for [T] {
default fn spec_fill(&mut self, value: T) {
if let Some((last, elems)) = self.split_last_mut() {
for el in elems {
el.clone_from(&value);
}
*last = value
}
}
}
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);
}
}
}