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