1use super::*;
2
3use core::{
4 ops::{Bound, RangeBounds},
5 slice,
6};
7
8/// Draining iterator for [`ArrayVec`]
9///
10/// See [`ArrayVec::drain`](ArrayVec::drain)
11pub struct ArrayVecDrain<'a, T: 'a + Default> {
12 iter: slice::IterMut<'a, T>,
13}
14
15impl<'a, T: 'a + Default> ArrayVecDrain<'a, T> {
16 pub(crate) fn new<A, R>(arr: &'a mut ArrayVec<A>, range: R) -> Self
17 where
18 A: Array<Item = T>,
19 R: RangeBounds<usize>,
20 {
21 let start = match range.start_bound() {
22 Bound::Unbounded => 0,
23 Bound::Included(&n) => n,
24 Bound::Excluded(&n) => n.saturating_add(1),
25 };
26 let end = match range.end_bound() {
27 Bound::Unbounded => arr.len(),
28 Bound::Included(&n) => n.saturating_add(1),
29 Bound::Excluded(&n) => n,
30 };
31
32 assert!(
33 start <= end,
34 "ArrayVec::drain> Illegal range, {} to {}",
35 start,
36 end
37 );
38 assert!(
39 end <= arr.len(),
40 "ArrayVec::drain> Range ends at {}, but length is only {}",
41 end,
42 arr.len()
43 );
44
45 let len = end - start;
46 let to_rotate = &mut arr[start..];
47 to_rotate.rotate_left(len);
48
49 let oldlen = arr.len();
50 let newlen = oldlen - len;
51 arr.set_len(newlen);
52 let slice = &mut arr.data.as_slice_mut()[newlen..oldlen];
53 let iter = slice.iter_mut();
54 Self { iter }
55 }
56}
57
58impl<'a, T: 'a + Default> DoubleEndedIterator for ArrayVecDrain<'a, T> {
59 fn next_back(&mut self) -> Option<Self::Item> {
60 self.iter.next_back().map(take)
61 }
62
63 #[cfg(feature = "rustc_1_40")]
64 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
65 self.iter.nth_back(n).map(take)
66 }
67}
68
69impl<'a, T: 'a + Default> Iterator for ArrayVecDrain<'a, T> {
70 type Item = T;
71 fn next(&mut self) -> Option<Self::Item> {
72 self.iter.next().map(take)
73 }
74 fn size_hint(&self) -> (usize, Option<usize>) {
75 self.iter.size_hint()
76 }
77 fn nth(&mut self, n: usize) -> Option<Self::Item> {
78 self.iter.nth(n).map(take)
79 }
80 fn last(self) -> Option<Self::Item> {
81 self.iter.last().map(take)
82 }
83 fn for_each<F>(self, f: F)
84 where
85 F: FnMut(Self::Item),
86 {
87 self.iter.map(take).for_each(f)
88 }
89}
90
91impl<'a, T: 'a + Default> FusedIterator for ArrayVecDrain<'a, T> {}
92impl<'a, T: 'a + Default> ExactSizeIterator for ArrayVecDrain<'a, T> {}
93/* No need to impl Drop! */
94