Rollup merge of #138372 - Eclips4:issue-138196, r=scottmcm

Refactor `pick2_mut` & `pick3_mut` to use `get_disjoint_mut`

Closes #138196
This commit is contained in:
Matthias Krüger 2025-03-12 08:06:50 +01:00 committed by GitHub
commit 2bdb10f164
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,6 +1,7 @@
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::{Index, IndexMut}; use std::ops::{Index, IndexMut};
use std::slice::GetDisjointMutError::*;
use std::slice::{self, SliceIndex}; use std::slice::{self, SliceIndex};
use crate::{Idx, IndexVec, IntoSliceIdx}; use crate::{Idx, IndexVec, IntoSliceIdx};
@ -121,32 +122,36 @@ impl<I: Idx, T> IndexSlice<I, T> {
/// Returns mutable references to two distinct elements, `a` and `b`. /// Returns mutable references to two distinct elements, `a` and `b`.
/// ///
/// Panics if `a == b`. /// Panics if `a == b` or if some of them are out of bounds.
#[inline] #[inline]
pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) {
let (ai, bi) = (a.index(), b.index()); let (ai, bi) = (a.index(), b.index());
assert!(ai != bi);
if ai < bi { match self.raw.get_disjoint_mut([ai, bi]) {
let (c1, c2) = self.raw.split_at_mut(bi); Ok([a, b]) => (a, b),
(&mut c1[ai], &mut c2[0]) Err(OverlappingIndices) => panic!("Indices {ai:?} and {bi:?} are not disjoint!"),
} else { Err(IndexOutOfBounds) => {
let (c2, c1) = self.pick2_mut(b, a); panic!("Some indices among ({ai:?}, {bi:?}) are out of bounds")
(c1, c2) }
} }
} }
/// Returns mutable references to three distinct elements. /// Returns mutable references to three distinct elements.
/// ///
/// Panics if the elements are not distinct. /// Panics if the elements are not distinct or if some of them are out of bounds.
#[inline] #[inline]
pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) { pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) {
let (ai, bi, ci) = (a.index(), b.index(), c.index()); let (ai, bi, ci) = (a.index(), b.index(), c.index());
assert!(ai != bi && bi != ci && ci != ai);
let len = self.raw.len(); match self.raw.get_disjoint_mut([ai, bi, ci]) {
assert!(ai < len && bi < len && ci < len); Ok([a, b, c]) => (a, b, c),
let ptr = self.raw.as_mut_ptr(); Err(OverlappingIndices) => {
unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) } panic!("Indices {ai:?}, {bi:?} and {ci:?} are not disjoint!")
}
Err(IndexOutOfBounds) => {
panic!("Some indices among ({ai:?}, {bi:?}, {ci:?}) are out of bounds")
}
}
} }
#[inline] #[inline]