     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93

    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! */