1use crate::CircularBuffer;
5use core::fmt;
6use core::iter::FusedIterator;
7use core::ops::Bound;
8use core::ops::RangeBounds;
9
10#[derive(Clone)]
17pub struct IntoIter<const N: usize, T> {
18 inner: CircularBuffer<N, T>,
19}
20
21impl<const N: usize, T> IntoIter<N, T> {
22 pub(crate) const fn new(inner: CircularBuffer<N, T>) -> Self {
23 Self { inner }
24 }
25}
26
27impl<const N: usize, T> Iterator for IntoIter<N, T> {
28 type Item = T;
29
30 fn next(&mut self) -> Option<Self::Item> {
31 self.inner.pop_front()
32 }
33
34 #[inline]
35 fn size_hint(&self) -> (usize, Option<usize>) {
36 let len = self.inner.len();
37 (len, Some(len))
38 }
39}
40
41impl<const N: usize, T> ExactSizeIterator for IntoIter<N, T> {
42 #[inline]
43 fn len(&self) -> usize {
44 self.inner.len()
45 }
46}
47
48impl<const N: usize, T> FusedIterator for IntoIter<N, T> {}
49
50impl<const N: usize, T> DoubleEndedIterator for IntoIter<N, T> {
51 fn next_back(&mut self) -> Option<Self::Item> {
52 self.inner.pop_back()
53 }
54}
55
56impl<const N: usize, T> fmt::Debug for IntoIter<N, T>
57where
58 T: fmt::Debug,
59{
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 self.inner.fmt(f)
62 }
63}
64
65pub(crate) fn translate_range_bounds<const N: usize, T, R>(
66 buf: &CircularBuffer<N, T>,
67 range: R,
68) -> (usize, usize)
69where
70 R: RangeBounds<usize>,
71{
72 let start = match range.start_bound() {
73 Bound::Included(x) => *x,
74 Bound::Excluded(x) => x
75 .checked_add(1)
76 .expect("range start index exceeds maximum usize"),
77 Bound::Unbounded => 0,
78 };
79
80 let end = match range.end_bound() {
81 Bound::Included(x) => x
82 .checked_add(1)
83 .expect("range end index exceeds maximum usize"),
84 Bound::Excluded(x) => *x,
85 Bound::Unbounded => buf.len(),
86 };
87
88 assert!(
89 end <= buf.len(),
90 "range end index {} out of range for buffer of length {}",
91 end,
92 buf.len()
93 );
94 assert!(
95 start <= end,
96 "range starts at index {start} but ends at index {end}"
97 );
98
99 (start, end)
100}
101
102pub struct Iter<'a, T> {
107 pub(crate) right: &'a [T],
108 pub(crate) left: &'a [T],
109}
110
111impl<'a, T> Iter<'a, T> {
112 pub(crate) const fn empty() -> Self {
113 Self {
114 right: &[],
115 left: &[],
116 }
117 }
118
119 pub(crate) fn new<const N: usize>(buf: &'a CircularBuffer<N, T>) -> Self {
120 let (right, left) = buf.as_slices();
121 Self { right, left }
122 }
123
124 pub(crate) fn over_range<const N: usize, R>(buf: &'a CircularBuffer<N, T>, range: R) -> Self
125 where
126 R: RangeBounds<usize>,
127 {
128 let (start, end) = translate_range_bounds(buf, range);
129 if start >= end {
130 Self::empty()
131 } else {
132 let len = buf.len();
133 let mut it = Self::new(buf);
134 it.advance_front_by(start);
135 it.advance_back_by(len - end);
136 it
137 }
138 }
139
140 fn advance_front_by(&mut self, count: usize) {
141 if self.right.len() > count {
142 let _ = self.right.split_off(..count);
143 } else {
144 let take_left = count - self.right.len();
145 debug_assert!(
146 take_left <= self.left.len(),
147 "attempted to advance past the back of the buffer"
148 );
149 let _ = self.left.split_off(..take_left);
150 self.right = &[];
151 }
152 }
153
154 fn advance_back_by(&mut self, count: usize) {
155 if self.left.len() > count {
156 let take_left = self.left.len() - count;
157 let _ = self.left.split_off(take_left..);
158 } else {
159 let take_right = self.right.len() - (count - self.left.len());
160 debug_assert!(
161 take_right <= self.right.len(),
162 "attempted to advance past the front of the buffer"
163 );
164 let _ = self.right.split_off(take_right..);
165 self.left = &[];
166 }
167 }
168}
169
170impl<T> Default for Iter<'_, T> {
171 #[inline]
172 fn default() -> Self {
173 Self::empty()
174 }
175}
176
177impl<'a, T> Iterator for Iter<'a, T> {
178 type Item = &'a T;
179
180 fn next(&mut self) -> Option<Self::Item> {
181 if let Some(item) = self.right.split_off_first() {
182 Some(item)
183 } else if let Some(item) = self.left.split_off_first() {
184 Some(item)
185 } else {
186 None
187 }
188 }
189
190 #[inline]
191 fn size_hint(&self) -> (usize, Option<usize>) {
192 let len = self.len();
193 (len, Some(len))
194 }
195}
196
197impl<T> ExactSizeIterator for Iter<'_, T> {
198 #[inline]
199 fn len(&self) -> usize {
200 self.right.len() + self.left.len()
201 }
202}
203
204impl<T> FusedIterator for Iter<'_, T> {}
205
206impl<T> DoubleEndedIterator for Iter<'_, T> {
207 fn next_back(&mut self) -> Option<Self::Item> {
208 if let Some(item) = self.left.split_off_last() {
209 Some(item)
210 } else if let Some(item) = self.right.split_off_last() {
211 Some(item)
212 } else {
213 None
214 }
215 }
216}
217
218impl<T> Clone for Iter<'_, T> {
219 fn clone(&self) -> Self {
220 Self {
221 right: self.right,
222 left: self.left,
223 }
224 }
225}
226
227impl<T> fmt::Debug for Iter<'_, T>
228where
229 T: fmt::Debug,
230{
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 f.debug_list().entries(self.clone()).finish()
233 }
234}
235
236pub struct IterMut<'a, T> {
241 right: &'a mut [T],
242 left: &'a mut [T],
243}
244
245impl<'a, T> IterMut<'a, T> {
246 pub(crate) fn empty() -> Self {
247 Self {
248 right: &mut [],
249 left: &mut [],
250 }
251 }
252
253 pub(crate) fn new<const N: usize>(buf: &'a mut CircularBuffer<N, T>) -> Self {
254 let (right, left) = buf.as_mut_slices();
255 Self { right, left }
256 }
257
258 pub(crate) fn over_range<const N: usize, R>(buf: &'a mut CircularBuffer<N, T>, range: R) -> Self
259 where
260 R: RangeBounds<usize>,
261 {
262 let (start, end) = translate_range_bounds(buf, range);
263 if start >= end {
264 Self::empty()
265 } else {
266 let len = buf.len();
267 let mut it = Self::new(buf);
268 it.advance_front_by(start);
269 it.advance_back_by(len - end);
270 it
271 }
272 }
273
274 fn advance_front_by(&mut self, count: usize) {
275 if self.right.len() > count {
276 let _ = self.right.split_off_mut(..count);
277 } else {
278 let take_left = count - self.right.len();
279 debug_assert!(
280 take_left <= self.left.len(),
281 "attempted to advance past the back of the buffer"
282 );
283 let _ = self.left.split_off_mut(..take_left);
284 self.right = &mut [];
285 }
286 }
287
288 fn advance_back_by(&mut self, count: usize) {
289 if self.left.len() > count {
290 let take_left = self.left.len() - count;
291 let _ = self.left.split_off_mut(take_left..);
292 } else {
293 let take_right = self.right.len() - (count - self.left.len());
294 debug_assert!(
295 take_right <= self.right.len(),
296 "attempted to advance past the front of the buffer"
297 );
298 let _ = self.right.split_off_mut(take_right..);
299 self.left = &mut [];
300 }
301 }
302}
303
304impl<T> Default for IterMut<'_, T> {
305 #[inline]
306 fn default() -> Self {
307 Self::empty()
308 }
309}
310
311impl<'a, T> Iterator for IterMut<'a, T> {
312 type Item = &'a mut T;
313
314 fn next(&mut self) -> Option<Self::Item> {
315 if let Some(item) = self.right.split_off_first_mut() {
316 Some(item)
317 } else if let Some(item) = self.left.split_off_first_mut() {
318 Some(item)
319 } else {
320 None
321 }
322 }
323
324 #[inline]
325 fn size_hint(&self) -> (usize, Option<usize>) {
326 let len = self.len();
327 (len, Some(len))
328 }
329}
330
331impl<T> ExactSizeIterator for IterMut<'_, T> {
332 #[inline]
333 fn len(&self) -> usize {
334 self.right.len() + self.left.len()
335 }
336}
337
338impl<T> FusedIterator for IterMut<'_, T> {}
339
340impl<T> DoubleEndedIterator for IterMut<'_, T> {
341 fn next_back(&mut self) -> Option<Self::Item> {
342 if let Some(item) = self.left.split_off_last_mut() {
343 Some(item)
344 } else if let Some(item) = self.right.split_off_last_mut() {
345 Some(item)
346 } else {
347 None
348 }
349 }
350}
351
352impl<T> fmt::Debug for IterMut<'_, T>
353where
354 T: fmt::Debug,
355{
356 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357 let it = Iter {
358 right: self.right,
359 left: self.left,
360 };
361 it.fmt(f)
362 }
363}