]> git.proxmox.com Git - rustc.git/blob - library/alloc/src/collections/vec_deque/pair_slices.rs
New upstream version 1.50.0+dfsg1
[rustc.git] / library / alloc / src / collections / vec_deque / pair_slices.rs
1 use core::array;
2 use core::cmp::{self};
3 use core::mem::replace;
4
5 use super::VecDeque;
6
7 /// PairSlices pairs up equal length slice parts of two deques
8 ///
9 /// For example, given deques "A" and "B" with the following division into slices:
10 ///
11 /// A: [0 1 2] [3 4 5]
12 /// B: [a b] [c d e]
13 ///
14 /// It produces the following sequence of matching slices:
15 ///
16 /// ([0 1], [a b])
17 /// (\[2\], \[c\])
18 /// ([3 4], [d e])
19 ///
20 /// and the uneven remainder of either A or B is skipped.
21 pub struct PairSlices<'a, 'b, T> {
22 pub(crate) a0: &'a mut [T],
23 pub(crate) a1: &'a mut [T],
24 pub(crate) b0: &'b [T],
25 pub(crate) b1: &'b [T],
26 }
27
28 impl<'a, 'b, T> PairSlices<'a, 'b, T> {
29 pub fn from(to: &'a mut VecDeque<T>, from: &'b VecDeque<T>) -> Self {
30 let (a0, a1) = to.as_mut_slices();
31 let (b0, b1) = from.as_slices();
32 PairSlices { a0, a1, b0, b1 }
33 }
34
35 pub fn has_remainder(&self) -> bool {
36 !self.b0.is_empty()
37 }
38
39 pub fn remainder(self) -> impl Iterator<Item = &'b [T]> {
40 array::IntoIter::new([self.b0, self.b1])
41 }
42 }
43
44 impl<'a, 'b, T> Iterator for PairSlices<'a, 'b, T> {
45 type Item = (&'a mut [T], &'b [T]);
46 fn next(&mut self) -> Option<Self::Item> {
47 // Get next part length
48 let part = cmp::min(self.a0.len(), self.b0.len());
49 if part == 0 {
50 return None;
51 }
52 let (p0, p1) = replace(&mut self.a0, &mut []).split_at_mut(part);
53 let (q0, q1) = self.b0.split_at(part);
54
55 // Move a1 into a0, if it's empty (and b1, b0 the same way).
56 self.a0 = p1;
57 self.b0 = q1;
58 if self.a0.is_empty() {
59 self.a0 = replace(&mut self.a1, &mut []);
60 }
61 if self.b0.is_empty() {
62 self.b0 = replace(&mut self.b1, &[]);
63 }
64 Some((p0, q0))
65 }
66 }