1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::ptr;
macro_rules! idx_check (
($slice:expr, $idx:expr) => {
assert!($idx < $slice.len(),
concat!("`", stringify!($idx), "` ({}) out of bounds. Length: {}"),
$idx, $slice.len());
}
);
macro_rules! len_check (
($slice:expr, $start:ident, $len:ident) => {
assert!(
$start.checked_add($len)
.expect(concat!("Overflow evaluating ", stringify!($start + $len)))
<= $slice.len(),
"Length {} starting at {} is out of bounds (slice len {}).", $len, $start, $slice.len()
)
}
);
pub fn copy<T: Copy>(slice: &mut [T], src_idx: usize, dest_idx: usize, len: usize) {
idx_check!(slice, src_idx);
idx_check!(slice, dest_idx);
len_check!(slice, src_idx, len);
len_check!(slice, dest_idx, len);
let src_ptr: *const T = &slice[src_idx];
let dest_ptr: *mut T = &mut slice[dest_idx];
unsafe {
ptr::copy(src_ptr, dest_ptr, len);
}
}
pub fn write_bytes(slice: &mut [u8], byte: u8) {
unsafe {
ptr::write_bytes(slice.as_mut_ptr(), byte, slice.len());
}
}
#[test]
#[should_panic]
fn test_bounds_check() {
let mut arr = [0i32, 1, 2, 3, 4, 5];
copy(&mut arr, 2, 1, 7);
}