1use core::fmt;
2use core::fmt::Debug;
3use core::iter::FusedIterator;
4use core::ops::Range;
5use core::ptr;
6use core::slice;
7
8use crate::capacity::Index;
9
10use super::buffer::VecBuffer;
11use super::index_panic;
12
13pub struct Drain<'d, B: VecBuffer> {
15 pub(super) range: Range<usize>,
16 pub(super) remain: Range<usize>,
17 pub(super) tail_length: usize,
18 pub(super) buf: &'d mut B,
19}
20
21impl<'d, B: VecBuffer> Drain<'d, B> {
22 pub(super) fn new(buf: &'d mut B, range: Range<usize>) -> Self {
23 let len = buf.length().to_usize();
24 if range.end < range.start || range.end > len {
25 index_panic();
26 }
27 if len > 0 {
28 unsafe { buf.set_length(B::Index::from_usize(range.start)) };
30 }
31 let tail_length = len - range.end;
32 Self {
33 range: range.clone(),
34 remain: range,
35 tail_length,
36 buf,
37 }
38 }
39
40 pub fn as_slice(&self) -> &[B::Item] {
42 unsafe {
43 slice::from_raw_parts(
44 self.buf.data_ptr().add(self.remain.start),
45 self.remain.len(),
46 )
47 }
48 }
49
50 pub fn as_mut_slice(&mut self) -> &mut [B::Item] {
52 unsafe {
53 slice::from_raw_parts_mut(
54 self.buf.data_ptr_mut().add(self.remain.start),
55 self.remain.len(),
56 )
57 }
58 }
59
60 pub const fn is_empty(&self) -> bool {
62 self.len() == 0
63 }
64
65 pub const fn len(&self) -> usize {
67 self.remain.end - self.remain.start
68 }
69
70 pub(super) fn clear_remain(&mut self) {
71 let remain_len = self.len();
72 if remain_len > 0 {
73 unsafe {
74 ptr::drop_in_place(self.as_mut_slice().as_mut_ptr());
75 }
76 self.remain.start = self.remain.end;
77 }
78 }
79
80 pub fn keep_rest(mut self) {
82 let len = self.len();
83 let shift = self.remain.start - self.range.start;
84 if len > 0 && shift > 0 {
85 unsafe {
86 let head = self.buf.data_ptr_mut().add(self.range.start);
87 ptr::copy(head.add(shift), head, len);
88 }
89 }
90 self.range.start += len;
91 self.remain = Range {
92 start: self.range.start,
93 end: self.range.start,
94 };
95 }
96}
97
98impl<'d, B: VecBuffer> AsRef<[B::Item]> for Drain<'d, B> {
99 fn as_ref(&self) -> &[B::Item] {
100 self.as_slice()
101 }
102}
103
104impl<'d, B: VecBuffer> fmt::Debug for Drain<'d, B>
105where
106 B::Item: Debug,
107{
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 f.debug_tuple("Drain").field(&self.as_slice()).finish()
110 }
111}
112
113impl<'d, B: VecBuffer> Iterator for Drain<'d, B> {
114 type Item = B::Item;
115
116 fn next(&mut self) -> Option<Self::Item> {
117 let index = self.remain.start;
118 if index != self.remain.end {
119 self.remain.start = index + 1;
120 unsafe {
121 let read = self.buf.data_ptr().add(index);
122 Some(ptr::read(read))
123 }
124 } else {
125 None
126 }
127 }
128
129 #[inline]
130 fn count(self) -> usize
131 where
132 Self: Sized,
133 {
134 self.len()
135 }
136
137 #[inline]
138 fn size_hint(&self) -> (usize, Option<usize>) {
139 let len = self.len();
140 (len, Some(len))
141 }
142}
143
144impl<'d, B: VecBuffer> DoubleEndedIterator for Drain<'d, B> {
145 fn next_back(&mut self) -> Option<Self::Item> {
146 let mut index = self.remain.end;
147 if index != self.remain.start {
148 index -= 1;
149 self.remain.end = index;
150 unsafe {
151 let read = self.buf.data_ptr().add(index);
152 Some(ptr::read(read))
153 }
154 } else {
155 None
156 }
157 }
158}
159
160impl<'d, B: VecBuffer> ExactSizeIterator for Drain<'d, B> {}
161
162impl<'d, B: VecBuffer> FusedIterator for Drain<'d, B> {}
163
164impl<'d, B: VecBuffer> Drop for Drain<'d, B> {
165 fn drop(&mut self) {
166 self.clear_remain();
167 if self.tail_length > 0 {
168 unsafe {
169 let head = self.buf.data_ptr_mut().add(self.range.start);
170 ptr::copy(head.add(self.range.len()), head, self.tail_length);
171 }
172 }
173 let len = self.range.start + self.tail_length;
174 if len > 0 {
175 unsafe {
177 self.buf
178 .set_length(B::Index::from_usize(self.range.start + self.tail_length))
179 }
180 }
181 }
182}