1use crate::clone::TrivialClone;
2use crate::ptr;
3
4pub(super) trait SpecFill<T> {
5 fn spec_fill(&mut self, value: T);
6}
7
8impl<T: Clone> SpecFill<T> for [T] {
9 default fn spec_fill(&mut self, value: T) {
10 if let Some((last, elems)) = self.split_last_mut() {
11 for el in elems {
12 el.clone_from(&value);
13 }
14
15 *last = value
16 }
17 }
18}
19
20impl<T: TrivialClone> SpecFill<T> for [T] {
21 default fn spec_fill(&mut self, value: T) {
22 for item in self.iter_mut() {
23 *item = unsafe { ptr::read(&value) };
26 }
27 }
28}
29
30impl SpecFill<u8> for [u8] {
31 fn spec_fill(&mut self, value: u8) {
32 unsafe {
34 crate::intrinsics::write_bytes(self.as_mut_ptr(), value, self.len());
35 }
36 }
37}
38
39impl SpecFill<i8> for [i8] {
40 fn spec_fill(&mut self, value: i8) {
41 unsafe {
43 crate::intrinsics::write_bytes(self.as_mut_ptr(), value.cast_unsigned(), self.len());
44 }
45 }
46}
47
48macro spec_fill_int {
49 ($($type:ty)*) => {$(
50 impl SpecFill<$type> for [$type] {
51 #[inline]
52 fn spec_fill(&mut self, value: $type) {
53 if (cfg!(miri) && self.len() > 32) || crate::intrinsics::is_val_statically_known(value) {
56 let bytes = value.to_ne_bytes();
57 if value == <$type>::from_ne_bytes([bytes[0]; size_of::<$type>()]) {
58 unsafe {
60 crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0], self.len());
61 }
62 return;
63 }
64 }
65 for item in self.iter_mut() {
66 *item = value;
67 }
68 }
69 }
70 )*}
71}
72
73impl SpecFill<u16> for [u16] {
#[inline]
fn spec_fill(&mut self, value: u16) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <u16>::from_ne_bytes([bytes[0]; size_of::<u16>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<i16> for [i16] {
#[inline]
fn spec_fill(&mut self, value: i16) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <i16>::from_ne_bytes([bytes[0]; size_of::<i16>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<u32> for [u32] {
#[inline]
fn spec_fill(&mut self, value: u32) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <u32>::from_ne_bytes([bytes[0]; size_of::<u32>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<i32> for [i32] {
#[inline]
fn spec_fill(&mut self, value: i32) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <i32>::from_ne_bytes([bytes[0]; size_of::<i32>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<u64> for [u64] {
#[inline]
fn spec_fill(&mut self, value: u64) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <u64>::from_ne_bytes([bytes[0]; size_of::<u64>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<i64> for [i64] {
#[inline]
fn spec_fill(&mut self, value: i64) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <i64>::from_ne_bytes([bytes[0]; size_of::<i64>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<u128> for [u128] {
#[inline]
fn spec_fill(&mut self, value: u128) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <u128>::from_ne_bytes([bytes[0]; size_of::<u128>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<i128> for [i128] {
#[inline]
fn spec_fill(&mut self, value: i128) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <i128>::from_ne_bytes([bytes[0]; size_of::<i128>()]) {
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<usize> for [usize] {
#[inline]
fn spec_fill(&mut self, value: usize) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <usize>::from_ne_bytes([bytes[0]; size_of::<usize>()])
{
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}
impl SpecFill<isize> for [isize] {
#[inline]
fn spec_fill(&mut self, value: isize) {
if (false && self.len() > 32) ||
crate::intrinsics::is_val_statically_known(value) {
let bytes = value.to_ne_bytes();
if value == <isize>::from_ne_bytes([bytes[0]; size_of::<isize>()])
{
unsafe {
crate::intrinsics::write_bytes(self.as_mut_ptr(), bytes[0],
self.len());
}
return;
}
}
for item in self.iter_mut() { *item = value; }
}
}spec_fill_int! { u16 i16 u32 i32 u64 i64 u128 i128 usize isize }