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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
pub mod data;
pub use data::*;
pub trait IterQuintMutTrait {
type Item;
fn iter_quint_mut(&mut self) -> IterQuintMut<'_, Self::Item>;
fn iter_quint_mut_range(&mut self, start: usize, end: usize) -> IterQuintMut<'_, Self::Item>;
}
pub struct IterQuintMut<'a, T> {
vec: &'a mut [T],
target: usize,
}
impl<'a, T> IterQuintMut<'a, T> {
pub fn new(vec: &'a mut [T]) -> Self {
Self { vec, target: 0 }
}
// This method cannot be converted into trait because of the mutable references
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<Quintuple<&mut T>> {
let next = Self::next_iter(self.target, self.vec);
self.target += 1;
next
}
// pub fn next_with_extra(
// &mut self,
// index: Option<usize>,
// ) -> (usize, Option<&mut T>, Option<Quintuple<&mut T>>) {
// if let Some(i) = index {
// if i + 1 >= self.target {
// panic!()
// }
// // self.target>=1 is guaranteed by previous `if`
// let (a, b) = self.vec.split_at_mut(self.target - 1);
// let next = Self::next_iter(1, b);
// let result = (self.target, a.get_mut(i), next);
// self.target += 1;
// result
// } else {
// (self.target, None, self.next())
// }
// }
fn next_iter(target: usize, vec: &mut [T]) -> Option<Quintuple<&mut T>> {
use Quintuple::*;
match (vec.len(), target) {
(0, _) => None,
(1, 0) => vec.first_mut().map(Single),
(1, _) => None,
(2, 0) => {
let [i0, i1] = &mut vec[0..2] else { unreachable!() };
Some(Double(i0, i1))
}
(3, 0) => {
let [i0, i1, i2] = &mut vec[0..3] else { unreachable!() };
Some(Triple(i0, i1, i2))
}
(_, 0) => {
let [i0, i1, i2,i3] = &mut vec[0..4] else { unreachable!() };
Some(First(i0, i1, i2, i3))
}
(_, t) => match &mut vec[t - 1..] {
[i0, i1, i2, i3, i4, ..] => Some(Full(i0, i1, i2, i3, i4)),
[i0, i1, i2, i3] => Some(ThreeLeft(i0, i1, i2, i3)),
[i0, i1, i2] => Some(TwoLeft(i0, i1, i2)),
[i0, i1] => Some(Last(i0, i1)),
[_] => None,
_ => unreachable!(),
},
}
}
}