cp_library_rs/utils/
index_isize.rs

1//! isizeによる巡回的な添字アクセス
2
3/// `isize`による巡回的な添字アクセス
4pub trait IndexIsize {
5    type T;
6    /// 添字 `idx` を `0` 以上 `array.len()` 未満の値に変換する
7    fn iidx(&self, idx: isize) -> usize;
8    /// `array[array.iidx(idx)]` への**不変**参照を取得する
9    fn iget(&self, idx: isize) -> &Self::T;
10    /// `array[array.iidx(idx)]` への**可変**参照を取得する
11    fn iget_mut(&mut self, idx: isize) -> &mut Self::T;
12}
13
14impl<T> IndexIsize for Vec<T> {
15    type T = T;
16    fn iidx(&self, idx: isize) -> usize {
17        idx.rem_euclid(self.len() as isize) as usize
18    }
19    fn iget(&self, idx: isize) -> &Self::T {
20        &self[self.iidx(idx)]
21    }
22    fn iget_mut(&mut self, idx: isize) -> &mut Self::T {
23        let idx = self.iidx(idx);
24        &mut self[idx]
25    }
26}
27
28impl<T> IndexIsize for [T] {
29    type T = T;
30    fn iidx(&self, idx: isize) -> usize {
31        idx.rem_euclid(self.len() as isize) as usize
32    }
33    fn iget(&self, idx: isize) -> &Self::T {
34        &self[self.iidx(idx)]
35    }
36    fn iget_mut(&mut self, idx: isize) -> &mut Self::T {
37        let idx = self.iidx(idx);
38        &mut self[idx]
39    }
40}
41
42impl<T, const N: usize> IndexIsize for [T; N] {
43    type T = T;
44    fn iidx(&self, idx: isize) -> usize {
45        idx.rem_euclid(N as isize) as usize
46    }
47    fn iget(&self, idx: isize) -> &Self::T {
48        &self[self.iidx(idx)]
49    }
50    fn iget_mut(&mut self, idx: isize) -> &mut Self::T {
51        let idx = self.iidx(idx);
52        &mut self[idx]
53    }
54}