1use crate::TinyVec;
4use core::iter::FusedIterator;
5use core::marker::PhantomData;
6use core::mem::{self, ManuallyDrop};
7use core::ptr::{self, NonNull};
8use core::slice;
9
10pub struct Drain<'a, T: 'a, const N: usize> {
14 pub (super) remaining_start: usize,
15 pub (super) remaining_len: usize,
16 pub (super) tail_start: usize,
17 pub (super) tail_len: usize,
18 pub (super) vec: NonNull<TinyVec<T, N>>,
19 pub (super) _marker: PhantomData<&'a mut TinyVec<T, N>>,
20}
21
22impl<'a, T: 'a, const N: usize> Drain<'a, T, N> {
23
24 #[inline]
26 pub fn as_slice(&self) -> &[T] {
27 unsafe {
28 let ptr = self.vec.as_ref().as_ptr().add(self.remaining_start);
29 slice::from_raw_parts(ptr, self.remaining_len)
30 }
31 }
32
33 pub fn keep_rest(self) {
51 let mut slf = ManuallyDrop::new(self);
52
53 unsafe {
55 let vec = slf.vec.as_mut();
56 let start = vec.len();
57
58 if mem::size_of::<T>() != 0 {
59 let buf = vec.as_mut_ptr();
60
61 let start_ptr = buf.add(start);
62 let remaining_ptr = buf.add(slf.remaining_start);
63
64 if remaining_ptr != start_ptr {
65 ptr::copy(remaining_ptr, start_ptr, slf.remaining_len);
67 }
68
69 if slf.tail_start != (start + slf.remaining_len) {
70 let src = buf.add(slf.tail_start);
71 let dst = start_ptr.add(slf.remaining_len);
72 ptr::copy(src, dst, slf.tail_len);
74 }
75 }
76 vec.set_len(start + slf.remaining_len + slf.tail_len);
77 }
78 }
79}
80
81impl<'a, T: 'a, const N: usize> Iterator for Drain<'a, T, N> {
82 type Item = T;
83
84 fn next(&mut self) -> Option<Self::Item> {
85 if self.remaining_len == 0 {
86 None
87 } else {
88 unsafe {
89 let e = self.vec.as_ref().as_ptr().add(self.remaining_start).read();
90 self.remaining_start += 1;
91 self.remaining_len -= 1;
92 Some(e)
93 }
94 }
95 }
96
97 fn size_hint(&self) -> (usize, Option<usize>) {
98 (self.remaining_len, Some(self.remaining_len))
99 }
100}
101
102impl<'a, T: 'a, const N: usize> DoubleEndedIterator for Drain<'a, T, N> {
103 fn next_back(&mut self) -> Option<Self::Item> {
104 if self.remaining_len == 0 {
105 None
106 } else {
107 unsafe {
108 let e = self.vec.as_ref()
109 .as_ptr()
110 .add(self.remaining_start + self.remaining_len - 1)
111 .read();
112 self.remaining_len -= 1;
113 Some(e)
114 }
115 }
116 }
117}
118
119impl<'a, T: 'a, const N: usize> ExactSizeIterator for Drain<'a, T, N> { }
120
121impl<'a, T: 'a, const N: usize> FusedIterator for Drain<'a, T, N> { }
122
123impl<'a, T: 'a, const N: usize> Drop for Drain<'a, T, N> {
124 fn drop(&mut self) {
125 for e in &mut *self { drop(e) }
128 unsafe {
129 let vec = self.vec.as_mut();
130
131 let len = vec.len();
132 let ptr = vec.as_mut_ptr();
133
134 let src = ptr.add(self.tail_start);
135 let dst = ptr.add(len);
136
137 ptr::copy(src, dst, self.tail_len);
138
139 vec.set_len(len + self.tail_len);
140 }
141 }
142}