| use super::*; | |
| use core::{ | |
| ops::{Bound, RangeBounds}, | |
| slice, | |
| }; | |
| /// Draining iterator for [`ArrayVec`] | |
| /// | |
| /// See [`ArrayVec::drain`](ArrayVec::drain) | |
| pub struct ArrayVecDrain<'a, T: 'a + Default> { | |
| iter: slice::IterMut<'a, T>, | |
| } | |
| impl<'a, T: 'a + Default> ArrayVecDrain<'a, T> { | |
| pub(crate) fn new<A, R>(arr: &'a mut ArrayVec<A>, range: R) -> Self | |
| where | |
| A: Array<Item = T>, | |
| R: RangeBounds<usize>, | |
| { | |
| let start = match range.start_bound() { | |
| Bound::Unbounded => 0, | |
| Bound::Included(&n) => n, | |
| Bound::Excluded(&n) => n.saturating_add(1), | |
| }; | |
| let end = match range.end_bound() { | |
| Bound::Unbounded => arr.len(), | |
| Bound::Included(&n) => n.saturating_add(1), | |
| Bound::Excluded(&n) => n, | |
| }; | |
| assert!( | |
| start <= end, | |
| "ArrayVec::drain> Illegal range, {} to {}", | |
| start, | |
| end | |
| ); | |
| assert!( | |
| end <= arr.len(), | |
| "ArrayVec::drain> Range ends at {}, but length is only {}", | |
| end, | |
| arr.len() | |
| ); | |
| let len = end - start; | |
| let to_rotate = &mut arr[start..]; | |
| to_rotate.rotate_left(len); | |
| let oldlen = arr.len(); | |
| let newlen = oldlen - len; | |
| arr.set_len(newlen); | |
| let slice = &mut arr.data.as_slice_mut()[newlen..oldlen]; | |
| let iter = slice.iter_mut(); | |
| Self { iter } | |
| } | |
| } | |
| impl<'a, T: 'a + Default> DoubleEndedIterator for ArrayVecDrain<'a, T> { | |
| fn next_back(&mut self) -> Option<Self::Item> { | |
| self.iter.next_back().map(take) | |
| } | |
| #[cfg(feature = "rustc_1_40")] | |
| fn nth_back(&mut self, n: usize) -> Option<Self::Item> { | |
| self.iter.nth_back(n).map(take) | |
| } | |
| } | |
| impl<'a, T: 'a + Default> Iterator for ArrayVecDrain<'a, T> { | |
| type Item = T; | |
| fn next(&mut self) -> Option<Self::Item> { | |
| self.iter.next().map(take) | |
| } | |
| fn size_hint(&self) -> (usize, Option<usize>) { | |
| self.iter.size_hint() | |
| } | |
| fn nth(&mut self, n: usize) -> Option<Self::Item> { | |
| self.iter.nth(n).map(take) | |
| } | |
| fn last(self) -> Option<Self::Item> { | |
| self.iter.last().map(take) | |
| } | |
| fn for_each<F>(self, f: F) | |
| where | |
| F: FnMut(Self::Item), | |
| { | |
| self.iter.map(take).for_each(f) | |
| } | |
| } | |
| impl<'a, T: 'a + Default> FusedIterator for ArrayVecDrain<'a, T> {} | |
| impl<'a, T: 'a + Default> ExactSizeIterator for ArrayVecDrain<'a, T> {} | |
| /* No need to impl Drop! */ |