Skip to content

Commit 267ef61

Browse files
committed
Add fill and copy_within methods for slices
The `fill` method is only support for `u8` slices because there is no intrinsic for volatile memset with a generic type `T`.
1 parent 9bc9f95 commit 267ef61

File tree

1 file changed

+53
-2
lines changed

1 file changed

+53
-2
lines changed

src/lib.rs

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010
#![no_std]
1111
#![cfg_attr(feature = "unstable", feature(core_intrinsics))]
1212
#![cfg_attr(feature = "unstable", feature(const_generics))]
13+
#![cfg_attr(feature = "unstable", feature(slice_check_range))]
1314
#![cfg_attr(feature = "unstable", allow(incomplete_features))]
1415
#![warn(missing_docs)]
1516

1617
use access::{ReadOnly, ReadWrite, Readable, Writable, WriteOnly};
17-
#[cfg(feature = "unstable")]
18-
use core::intrinsics;
1918
use core::{
2019
fmt,
2120
marker::PhantomData,
@@ -24,6 +23,11 @@ use core::{
2423
ptr,
2524
slice::SliceIndex,
2625
};
26+
#[cfg(feature = "unstable")]
27+
use core::{
28+
intrinsics,
29+
ops::{Range, RangeBounds},
30+
};
2731

2832
/// Allows creating read-only and write-only `Volatile` values.
2933
pub mod access;
@@ -576,6 +580,53 @@ where
576580
);
577581
}
578582
}
583+
584+
#[cfg(feature = "unstable")]
585+
pub fn copy_within(&mut self, src: impl RangeBounds<usize>, dest: usize)
586+
where
587+
T: Copy,
588+
R: DerefMut,
589+
{
590+
// implementation taken from https://github.com/rust-lang/rust/blob/683d1bcd405727fcc9209f64845bd3b9104878b8/library/core/src/slice/mod.rs#L2726-L2738
591+
let Range {
592+
start: src_start,
593+
end: src_end,
594+
} = self.reference.check_range(src);
595+
let count = src_end - src_start;
596+
assert!(
597+
dest <= self.reference.len() - count,
598+
"dest is out of bounds"
599+
);
600+
// SAFETY: the conditions for `volatile_copy_memory` have all been checked above,
601+
// as have those for `ptr::add`.
602+
unsafe {
603+
intrinsics::volatile_copy_memory(
604+
self.reference.as_mut_ptr().add(dest),
605+
self.reference.as_ptr().add(src_start),
606+
count,
607+
);
608+
}
609+
}
610+
}
611+
612+
/// Methods for volatile byte slices
613+
impl<R, A> Volatile<R, A>
614+
where
615+
R: Deref<Target = [u8]>,
616+
{
617+
#[cfg(feature = "unstable")]
618+
pub fn fill(&mut self, value: u8)
619+
where
620+
R: DerefMut,
621+
{
622+
unsafe {
623+
intrinsics::volatile_set_memory(
624+
self.reference.as_mut_ptr(),
625+
value,
626+
self.reference.len(),
627+
);
628+
}
629+
}
579630
}
580631

581632
/// Methods for converting arrays to slices

0 commit comments

Comments
 (0)