Skip to main content

rapier2d/utils/
index_mut2.rs

1//! IndexMut2 trait for simultaneously indexing with two distinct indices.
2
3use std::ops::IndexMut;
4
5/// Methods for simultaneously indexing a container with two distinct indices.
6pub trait IndexMut2<I>: IndexMut<I> {
7    /// Gets mutable references to two distinct elements of the container.
8    ///
9    /// Panics if `i == j`.
10    fn index_mut2(&mut self, i: usize, j: usize) -> (&mut Self::Output, &mut Self::Output);
11
12    /// Gets a mutable reference to one element, and immutable reference to a second one.
13    ///
14    /// Panics if `i == j`.
15    #[inline]
16    fn index_mut_const(&mut self, i: usize, j: usize) -> (&mut Self::Output, &Self::Output) {
17        let (a, b) = self.index_mut2(i, j);
18        (a, &*b)
19    }
20}
21
22impl<T> IndexMut2<usize> for Vec<T> {
23    #[inline]
24    fn index_mut2(&mut self, i: usize, j: usize) -> (&mut T, &mut T) {
25        assert!(i != j, "Unable to index the same element twice.");
26        assert!(i < self.len() && j < self.len(), "Index out of bounds.");
27
28        unsafe {
29            let a = &mut *(self.get_unchecked_mut(i) as *mut _);
30            let b = &mut *(self.get_unchecked_mut(j) as *mut _);
31            (a, b)
32        }
33    }
34}
35
36impl<T> IndexMut2<usize> for [T] {
37    #[inline]
38    fn index_mut2(&mut self, i: usize, j: usize) -> (&mut T, &mut T) {
39        assert!(i != j, "Unable to index the same element twice.");
40        assert!(i < self.len() && j < self.len(), "Index out of bounds.");
41
42        unsafe {
43            let a = &mut *(self.get_unchecked_mut(i) as *mut _);
44            let b = &mut *(self.get_unchecked_mut(j) as *mut _);
45            (a, b)
46        }
47    }
48}