1 use core::iter::FusedIterator;
2 use core::ptr::{self, NonNull};
5 use super::{count, Iter, VecDeque};
7 /// A draining iterator over the elements of a `VecDeque`.
9 /// This `struct` is created by the [`drain`] method on [`VecDeque`]. See its
10 /// documentation for more.
12 /// [`drain`]: VecDeque::drain
13 #[stable(feature = "drain", since = "1.6.0")]
14 pub struct Drain<'a, T: 'a> {
15 pub(crate) after_tail: usize,
16 pub(crate) after_head: usize,
17 pub(crate) iter: Iter<'a, T>,
18 pub(crate) deque: NonNull<VecDeque<T>>,
21 #[stable(feature = "collection_debug", since = "1.17.0")]
22 impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 f.debug_tuple("Drain")
25 .field(&self.after_tail)
26 .field(&self.after_head)
32 #[stable(feature = "drain", since = "1.6.0")]
33 unsafe impl<T: Sync> Sync for Drain<'_, T> {}
34 #[stable(feature = "drain", since = "1.6.0")]
35 unsafe impl<T: Send> Send for Drain<'_, T> {}
37 #[stable(feature = "drain", since = "1.6.0")]
38 impl<T> Drop for Drain<'_, T> {
40 struct DropGuard<'r, 'a, T>(&'r mut Drain<'a, T>);
42 impl<'r, 'a, T> Drop for DropGuard<'r, 'a, T> {
44 self.0.for_each(drop);
46 let source_deque = unsafe { self.0.deque.as_mut() };
48 // T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head
51 // [. . . o o x x o o . . .]
53 let orig_tail = source_deque.tail;
54 let drain_tail = source_deque.head;
55 let drain_head = self.0.after_tail;
56 let orig_head = self.0.after_head;
58 let tail_len = count(orig_tail, drain_tail, source_deque.cap());
59 let head_len = count(drain_head, orig_head, source_deque.cap());
61 // Restore the original head value
62 source_deque.head = orig_head;
64 match (tail_len, head_len) {
66 source_deque.head = 0;
67 source_deque.tail = 0;
70 source_deque.tail = drain_head;
73 source_deque.head = drain_tail;
76 if tail_len <= head_len {
77 source_deque.tail = source_deque.wrap_sub(drain_head, tail_len);
78 source_deque.wrap_copy(source_deque.tail, orig_tail, tail_len);
80 source_deque.head = source_deque.wrap_add(drain_tail, head_len);
81 source_deque.wrap_copy(drain_tail, drain_head, head_len);
88 while let Some(item) = self.next() {
89 let guard = DropGuard(self);
98 #[stable(feature = "drain", since = "1.6.0")]
99 impl<T> Iterator for Drain<'_, T> {
103 fn next(&mut self) -> Option<T> {
104 self.iter.next().map(|elt| unsafe { ptr::read(elt) })
108 fn size_hint(&self) -> (usize, Option<usize>) {
109 self.iter.size_hint()
113 #[stable(feature = "drain", since = "1.6.0")]
114 impl<T> DoubleEndedIterator for Drain<'_, T> {
116 fn next_back(&mut self) -> Option<T> {
117 self.iter.next_back().map(|elt| unsafe { ptr::read(elt) })
121 #[stable(feature = "drain", since = "1.6.0")]
122 impl<T> ExactSizeIterator for Drain<'_, T> {}
124 #[stable(feature = "fused", since = "1.26.0")]
125 impl<T> FusedIterator for Drain<'_, T> {}