streaming_iterator/
slice.rs1use crate::{
2 DoubleEndedStreamingIterator, DoubleEndedStreamingIteratorMut, StreamingIterator,
3 StreamingIteratorMut,
4};
5
6use core::mem;
7use core::num::NonZeroUsize;
8
9pub fn windows_mut<T>(slice: &mut [T], size: usize) -> WindowsMut<'_, T> {
18 WindowsMut {
19 slice,
20 size: NonZeroUsize::new(size).expect("size is zero"),
21 position: Position::Init,
22 }
23}
24
25pub struct WindowsMut<'a, T> {
29 slice: &'a mut [T],
30 size: NonZeroUsize,
31 position: Position,
32}
33
34enum Position {
35 Init,
36 Front,
37 Back,
38}
39
40impl<T> WindowsMut<'_, T> {
41 fn consume(&mut self) {
42 match self.position {
43 Position::Init => {}
44 Position::Front => {
45 let slice = mem::take(&mut self.slice);
46 if let Some((_, tail)) = slice.split_first_mut() {
47 self.slice = tail;
48 }
49 }
50 Position::Back => {
51 let slice = mem::take(&mut self.slice);
52 if let Some((_, head)) = slice.split_last_mut() {
53 self.slice = head;
54 }
55 }
56 }
57 }
58
59 fn get_front(&self) -> Option<&[T]> {
60 self.slice.get(..self.size.get())
61 }
62
63 fn get_front_mut(&mut self) -> Option<&mut [T]> {
64 self.slice.get_mut(..self.size.get())
65 }
66
67 fn get_back(&self) -> Option<&[T]> {
68 let start = self.slice.len().checked_sub(self.size.get())?;
69 self.slice.get(start..)
70 }
71
72 fn get_back_mut(&mut self) -> Option<&mut [T]> {
73 let start = self.slice.len().checked_sub(self.size.get())?;
74 self.slice.get_mut(start..)
75 }
76
77 fn len(&self) -> usize {
78 let len = match self.position {
79 Position::Init => self.slice.len(),
80 _ => self.slice.len().saturating_sub(1),
81 };
82 len.saturating_sub(self.size.get() - 1)
83 }
84}
85
86impl<T> StreamingIterator for WindowsMut<'_, T> {
87 type Item = [T];
88
89 fn advance(&mut self) {
90 self.consume();
91 self.position = Position::Front;
92 }
93
94 fn get(&self) -> Option<&Self::Item> {
95 match self.position {
96 Position::Init => None,
97 Position::Front => self.get_front(),
98 Position::Back => self.get_back(),
99 }
100 }
101
102 fn next(&mut self) -> Option<&Self::Item> {
103 self.advance();
104 self.get_front()
105 }
106
107 fn size_hint(&self) -> (usize, Option<usize>) {
108 let len = self.len();
109 (len, Some(len))
110 }
111
112 fn is_done(&self) -> bool {
113 self.slice.len() < self.size.get()
114 }
115
116 fn count(self) -> usize {
117 self.len()
118 }
119}
120
121impl<T> StreamingIteratorMut for WindowsMut<'_, T> {
122 fn get_mut(&mut self) -> Option<&mut Self::Item> {
123 match self.position {
124 Position::Init => None,
125 Position::Front => self.get_front_mut(),
126 Position::Back => self.get_back_mut(),
127 }
128 }
129
130 fn next_mut(&mut self) -> Option<&mut Self::Item> {
131 self.advance();
132 self.get_front_mut()
133 }
134}
135
136impl<T> DoubleEndedStreamingIterator for WindowsMut<'_, T> {
137 fn advance_back(&mut self) {
138 self.consume();
139 self.position = Position::Back;
140 }
141
142 fn next_back(&mut self) -> Option<&Self::Item> {
143 self.advance_back();
144 self.get_back()
145 }
146}
147
148impl<T> DoubleEndedStreamingIteratorMut for WindowsMut<'_, T> {
149 fn next_back_mut(&mut self) -> Option<&mut Self::Item> {
150 self.advance_back();
151 self.get_back_mut()
152 }
153}
154
155#[test]
156fn test_windows_mut() {
157 let slice: &mut [_] = &mut [0; 6];
158
159 windows_mut(slice, 3).fold_mut(0, |i, win| {
160 win.copy_from_slice(&[i; 3]);
161 i + 1
162 });
163 assert_eq!(slice, &[0, 1, 2, 3, 3, 3]);
164
165 windows_mut(slice, 2).rfold_mut(0, |i, win| {
166 win.copy_from_slice(&[i; 2]);
167 i + 1
168 });
169 assert_eq!(slice, &[4, 4, 3, 2, 1, 0]);
170
171 let mut i = 0;
172 let mut iter = windows_mut(slice, 1);
173 while let Some(win) = iter.next_mut() {
174 win.copy_from_slice(&[i]);
175 i += 1;
176
177 if let Some(win) = iter.next_back_mut() {
178 win.copy_from_slice(&[i]);
179 i += 1;
180 }
181 }
182 assert_eq!(slice, &[0, 2, 4, 5, 3, 1]);
183}
184
185#[test]
186fn test_windows_mut_count() {
187 let slice: &mut [_] = &mut [0; 6];
188
189 assert_eq!(windows_mut(slice, 3).count(), 4);
190 assert_eq!(windows_mut(slice, 6).count(), 1);
191 assert_eq!(windows_mut(slice, 9).count(), 0);
192
193 let mut iter = windows_mut(slice, 3);
194 assert_eq!(iter.size_hint(), (4, Some(4)));
195 iter.advance();
196 assert_eq!(iter.count(), 3);
197}
198
199#[test]
200#[should_panic]
201fn test_windows_mut_0() {
202 let _: WindowsMut<'_, i32> = windows_mut(&mut [], 0);
203}