copy_stack_vec/vec/array/
drain.rs1use crate::{iter::IntoIter, vec::CopyStackVec};
6
7use core::{
9 iter::FusedIterator,
10 ops::{Bound, RangeBounds},
11};
12
13pub struct Drain<'a, T: Copy, const N: usize> {
19 pub(crate) _parent: &'a mut CopyStackVec<T, N>,
20 pub(crate) iter: IntoIter<T, N>,
21}
22
23impl<'a, T: Copy, const N: usize> Iterator for Drain<'a, T, N> {
24 type Item = T;
25
26 fn next(&mut self) -> Option<T> {
27 self.iter.next()
28 }
29
30 fn size_hint(&self) -> (usize, Option<usize>) {
31 self.iter.size_hint()
32 }
33
34 fn nth(&mut self, n: usize) -> Option<T> {
35 self.iter.nth(n)
36 }
37}
38
39impl<'a, T: Copy, const N: usize> DoubleEndedIterator for Drain<'a, T, N> {
40 fn next_back(&mut self) -> Option<T> {
41 self.iter.next_back()
42 }
43
44 fn nth_back(&mut self, n: usize) -> Option<T> {
45 self.iter.nth_back(n)
46 }
47}
48
49impl<'a, T: Copy, const N: usize> ExactSizeIterator for Drain<'a, T, N> {}
50impl<'a, T: Copy, const N: usize> FusedIterator for Drain<'a, T, N> {}
51
52impl<T: Copy + Default, const N: usize> CopyStackVec<T, N> {
53 pub fn drain<R>(
77 &mut self,
78 range: R,
79 ) -> impl DoubleEndedIterator<Item = T> + ExactSizeIterator + FusedIterator + '_
80 where
81 R: RangeBounds<usize>,
82 {
83 let len = self.len();
84
85 let start = match range.start_bound() {
86 Bound::Included(&i) => i,
87 Bound::Excluded(&i) => i + 1,
88 Bound::Unbounded => 0,
89 };
90 let end = match range.end_bound() {
91 Bound::Included(&i) => i + 1,
92 Bound::Excluded(&i) => i,
93 Bound::Unbounded => len,
94 };
95
96 if start > end {
97 panic!("drain range start > end: {} > {}", start, end);
98 }
99 if end > len {
100 panic!("drain range end {} exceeds length {}", end, len);
101 }
102
103 if start == end {
104 let tmp: CopyStackVec<T, N> = CopyStackVec::default();
106 return Drain {
107 _parent: self,
108 iter: tmp.into_iter(),
109 };
110 }
111
112 let slice = &self.as_slice()[start..end];
114 let mut tmp: CopyStackVec<T, N> = CopyStackVec::default();
115 tmp.extend_from_slice(slice).unwrap();
116
117 let range_len = end - start;
119 let tail_len = len - end;
120 if tail_len > 0 {
121 self.as_mut_slice().copy_within(end..len, start);
122 }
123 self.len = len - range_len;
124
125 Drain {
126 _parent: self,
127 iter: tmp.into_iter(),
128 }
129 }
130}