1#![allow(unsafe_code)]
2
3use crate::GetDisjointMutError;
4
5pub(super) fn get_disjoint_mut<T, const N: usize>(
8 entries: &mut [T],
9 indices: [usize; N],
10) -> Result<[&mut T; N], GetDisjointMutError> {
11 let len = entries.len();
13 for i in 0..N {
14 let idx = indices[i];
15 if idx >= len {
16 return Err(GetDisjointMutError::IndexOutOfBounds);
17 } else if indices[..i].contains(&idx) {
18 return Err(GetDisjointMutError::OverlappingIndices);
19 }
20 }
21
22 let entries_ptr = entries.as_mut_ptr();
23 Ok(indices.map(move |idx| {
24 unsafe { &mut *(entries_ptr.add(idx)) }
27 }))
28}
29
30#[track_caller]
33pub(super) fn get_disjoint_opt_mut<T, const N: usize>(
34 entries: &mut [T],
35 indices: [Option<usize>; N],
36) -> [Option<&mut T>; N] {
37 let len = entries.len();
39 for i in 0..N {
40 if let Some(idx) = indices[i] {
41 if idx >= len {
42 unreachable!("`get_index_of` returned an out-of-bounds index");
43 } else if indices[..i].contains(&Some(idx)) {
44 panic!("duplicate keys found");
45 }
46 }
47 }
48
49 let entries_ptr = entries.as_mut_ptr();
50 indices.map(move |idx_opt| {
51 match idx_opt {
52 Some(idx) => {
53 Some(unsafe { &mut *entries_ptr.add(idx) })
56 }
57 None => None,
58 }
59 })
60}