rune_alloc/vec_deque/
drain.rs
1use core::fmt;
2use core::iter::FusedIterator;
3use core::marker::PhantomData;
4use core::mem;
5
6use crate::alloc::{Allocator, Global, SizedTypeProperties};
7use crate::ptr::{self, NonNull};
8
9use super::VecDeque;
10
11pub struct Drain<'a, T: 'a, A: Allocator = Global> {
18 deque: NonNull<VecDeque<T, A>>,
21 drain_len: usize,
23 idx: usize,
25 tail_len: usize,
27 remaining: usize,
28 _marker: PhantomData<&'a T>,
30}
31
32impl<'a, T, A: Allocator> Drain<'a, T, A> {
33 pub(super) unsafe fn new(
34 deque: &'a mut VecDeque<T, A>,
35 drain_start: usize,
36 drain_len: usize,
37 ) -> Self {
38 let orig_len = mem::replace(&mut deque.len, drain_start);
39 let tail_len = orig_len - drain_start - drain_len;
40 Drain {
41 deque: NonNull::from(deque),
42 drain_len,
43 idx: drain_start,
44 tail_len,
45 remaining: drain_len,
46 _marker: PhantomData,
47 }
48 }
49
50 unsafe fn as_slices(&self) -> (*mut [T], *mut [T]) {
53 unsafe {
54 let deque = self.deque.as_ref();
55
56 let logical_remaining_range = self.idx..self.idx + self.remaining;
58
59 let (a_range, b_range) =
65 deque.slice_ranges(logical_remaining_range.clone(), logical_remaining_range.end);
66 (deque.buffer_range(a_range), deque.buffer_range(b_range))
67 }
68 }
69}
70
71impl<T: fmt::Debug, A: Allocator> fmt::Debug for Drain<'_, T, A> {
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 f.debug_tuple("Drain")
74 .field(&self.drain_len)
75 .field(&self.idx)
76 .field(&self.tail_len)
77 .field(&self.remaining)
78 .finish()
79 }
80}
81
82unsafe impl<T: Sync, A: Allocator + Sync> Sync for Drain<'_, T, A> {}
83unsafe impl<T: Send, A: Allocator + Send> Send for Drain<'_, T, A> {}
84
85impl<T, A: Allocator> Drop for Drain<'_, T, A> {
86 fn drop(&mut self) {
87 struct DropGuard<'r, 'a, T, A: Allocator>(&'r mut Drain<'a, T, A>);
88
89 impl<T, A: Allocator> Drop for DropGuard<'_, '_, T, A> {
90 fn drop(&mut self) {
91 if self.0.remaining != 0 {
92 unsafe {
93 let (front, back) = self.0.as_slices();
95 ptr::drop_in_place(front);
96 ptr::drop_in_place(back);
97 }
98 }
99
100 let source_deque = unsafe { self.0.deque.as_mut() };
101
102 let drain_start = source_deque.len();
103 let drain_len = self.0.drain_len;
104 let drain_end = drain_start + drain_len;
105
106 let orig_len = self.0.tail_len + drain_end;
107
108 if T::IS_ZST {
109 source_deque.len = orig_len - drain_len;
111 return;
112 }
113
114 let head_len = drain_start;
115 let tail_len = self.0.tail_len;
116
117 match (head_len, tail_len) {
118 (0, 0) => {
119 source_deque.head = 0;
120 source_deque.len = 0;
121 }
122 (0, _) => {
123 source_deque.head = source_deque.to_physical_idx(drain_len);
124 source_deque.len = orig_len - drain_len;
125 }
126 (_, 0) => {
127 source_deque.len = orig_len - drain_len;
128 }
129 _ => unsafe {
130 if head_len <= tail_len {
131 source_deque.wrap_copy(
132 source_deque.head,
133 source_deque.to_physical_idx(drain_len),
134 head_len,
135 );
136 source_deque.head = source_deque.to_physical_idx(drain_len);
137 source_deque.len = orig_len - drain_len;
138 } else {
139 source_deque.wrap_copy(
140 source_deque.to_physical_idx(head_len + drain_len),
141 source_deque.to_physical_idx(head_len),
142 tail_len,
143 );
144 source_deque.len = orig_len - drain_len;
145 }
146 },
147 }
148 }
149 }
150
151 let guard = DropGuard(self);
152
153 if guard.0.remaining != 0 {
154 unsafe {
155 let (front, back) = guard.0.as_slices();
157 guard.0.idx += ptr::slice_len(front);
159 guard.0.remaining -= ptr::slice_len(front);
160 ptr::drop_in_place(front);
161 guard.0.remaining = 0;
162 ptr::drop_in_place(back);
163 }
164 }
165
166 }
168}
169
170impl<T, A: Allocator> Iterator for Drain<'_, T, A> {
171 type Item = T;
172
173 #[inline]
174 fn next(&mut self) -> Option<T> {
175 if self.remaining == 0 {
176 return None;
177 }
178 let wrapped_idx = unsafe { self.deque.as_ref().to_physical_idx(self.idx) };
179 self.idx += 1;
180 self.remaining -= 1;
181 Some(unsafe { self.deque.as_mut().buffer_read(wrapped_idx) })
182 }
183
184 #[inline]
185 fn size_hint(&self) -> (usize, Option<usize>) {
186 let len = self.remaining;
187 (len, Some(len))
188 }
189}
190
191impl<T, A: Allocator> DoubleEndedIterator for Drain<'_, T, A> {
192 #[inline]
193 fn next_back(&mut self) -> Option<T> {
194 if self.remaining == 0 {
195 return None;
196 }
197 self.remaining -= 1;
198 let wrapped_idx = unsafe {
199 self.deque
200 .as_ref()
201 .to_physical_idx(self.idx + self.remaining)
202 };
203 Some(unsafe { self.deque.as_mut().buffer_read(wrapped_idx) })
204 }
205}
206
207impl<T, A: Allocator> ExactSizeIterator for Drain<'_, T, A> {}
208
209impl<T, A: Allocator> FusedIterator for Drain<'_, T, A> {}