1 | use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; |
2 | use core::num::NonZero; |
3 | use core::ops::Try; |
4 | use core::{fmt, mem, slice}; |
5 | |
6 | /// A mutable iterator over the elements of a `VecDeque`. |
7 | /// |
8 | /// This `struct` is created by the [`iter_mut`] method on [`super::VecDeque`]. See its |
9 | /// documentation for more. |
10 | /// |
11 | /// [`iter_mut`]: super::VecDeque::iter_mut |
12 | #[stable (feature = "rust1" , since = "1.0.0" )] |
13 | pub struct IterMut<'a, T: 'a> { |
14 | i1: slice::IterMut<'a, T>, |
15 | i2: slice::IterMut<'a, T>, |
16 | } |
17 | |
18 | impl<'a, T> IterMut<'a, T> { |
19 | pub(super) fn new(i1: slice::IterMut<'a, T>, i2: slice::IterMut<'a, T>) -> Self { |
20 | Self { i1, i2 } |
21 | } |
22 | } |
23 | |
24 | #[stable (feature = "collection_debug" , since = "1.17.0" )] |
25 | impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> { |
26 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
27 | f.debug_tuple(name:"IterMut" ).field(&self.i1.as_slice()).field(&self.i2.as_slice()).finish() |
28 | } |
29 | } |
30 | |
31 | #[stable (feature = "rust1" , since = "1.0.0" )] |
32 | impl<'a, T> Iterator for IterMut<'a, T> { |
33 | type Item = &'a mut T; |
34 | |
35 | #[inline ] |
36 | fn next(&mut self) -> Option<&'a mut T> { |
37 | match self.i1.next() { |
38 | Some(val) => Some(val), |
39 | None => { |
40 | // most of the time, the iterator will either always |
41 | // call next(), or always call next_back(). By swapping |
42 | // the iterators once the first one is empty, we ensure |
43 | // that the first branch is taken as often as possible, |
44 | // without sacrificing correctness, as i1 is empty anyways |
45 | mem::swap(&mut self.i1, &mut self.i2); |
46 | self.i1.next() |
47 | } |
48 | } |
49 | } |
50 | |
51 | fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
52 | match self.i1.advance_by(n) { |
53 | Ok(()) => return Ok(()), |
54 | Err(remaining) => { |
55 | mem::swap(&mut self.i1, &mut self.i2); |
56 | self.i1.advance_by(remaining.get()) |
57 | } |
58 | } |
59 | } |
60 | |
61 | #[inline ] |
62 | fn size_hint(&self) -> (usize, Option<usize>) { |
63 | let len = self.len(); |
64 | (len, Some(len)) |
65 | } |
66 | |
67 | fn fold<Acc, F>(self, accum: Acc, mut f: F) -> Acc |
68 | where |
69 | F: FnMut(Acc, Self::Item) -> Acc, |
70 | { |
71 | let accum = self.i1.fold(accum, &mut f); |
72 | self.i2.fold(accum, &mut f) |
73 | } |
74 | |
75 | fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R |
76 | where |
77 | F: FnMut(B, Self::Item) -> R, |
78 | R: Try<Output = B>, |
79 | { |
80 | let acc = self.i1.try_fold(init, &mut f)?; |
81 | self.i2.try_fold(acc, &mut f) |
82 | } |
83 | |
84 | #[inline ] |
85 | fn last(mut self) -> Option<&'a mut T> { |
86 | self.next_back() |
87 | } |
88 | |
89 | #[inline ] |
90 | unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { |
91 | // Safety: The TrustedRandomAccess contract requires that callers only pass an index |
92 | // that is in bounds. |
93 | unsafe { |
94 | let i1_len = self.i1.len(); |
95 | if idx < i1_len { |
96 | self.i1.__iterator_get_unchecked(idx) |
97 | } else { |
98 | self.i2.__iterator_get_unchecked(idx - i1_len) |
99 | } |
100 | } |
101 | } |
102 | } |
103 | |
104 | #[stable (feature = "rust1" , since = "1.0.0" )] |
105 | impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { |
106 | #[inline ] |
107 | fn next_back(&mut self) -> Option<&'a mut T> { |
108 | match self.i2.next_back() { |
109 | Some(val) => Some(val), |
110 | None => { |
111 | // most of the time, the iterator will either always |
112 | // call next(), or always call next_back(). By swapping |
113 | // the iterators once the first one is empty, we ensure |
114 | // that the first branch is taken as often as possible, |
115 | // without sacrificing correctness, as i2 is empty anyways |
116 | mem::swap(&mut self.i1, &mut self.i2); |
117 | self.i2.next_back() |
118 | } |
119 | } |
120 | } |
121 | |
122 | fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { |
123 | match self.i2.advance_back_by(n) { |
124 | Ok(()) => return Ok(()), |
125 | Err(remaining) => { |
126 | mem::swap(&mut self.i1, &mut self.i2); |
127 | self.i2.advance_back_by(remaining.get()) |
128 | } |
129 | } |
130 | } |
131 | |
132 | fn rfold<Acc, F>(self, accum: Acc, mut f: F) -> Acc |
133 | where |
134 | F: FnMut(Acc, Self::Item) -> Acc, |
135 | { |
136 | let accum = self.i2.rfold(accum, &mut f); |
137 | self.i1.rfold(accum, &mut f) |
138 | } |
139 | |
140 | fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R |
141 | where |
142 | F: FnMut(B, Self::Item) -> R, |
143 | R: Try<Output = B>, |
144 | { |
145 | let acc = self.i2.try_rfold(init, &mut f)?; |
146 | self.i1.try_rfold(acc, &mut f) |
147 | } |
148 | } |
149 | |
150 | #[stable (feature = "rust1" , since = "1.0.0" )] |
151 | impl<T> ExactSizeIterator for IterMut<'_, T> { |
152 | fn len(&self) -> usize { |
153 | self.i1.len() + self.i2.len() |
154 | } |
155 | |
156 | fn is_empty(&self) -> bool { |
157 | self.i1.is_empty() && self.i2.is_empty() |
158 | } |
159 | } |
160 | |
161 | #[stable (feature = "fused" , since = "1.26.0" )] |
162 | impl<T> FusedIterator for IterMut<'_, T> {} |
163 | |
164 | #[unstable (feature = "trusted_len" , issue = "37572" )] |
165 | unsafe impl<T> TrustedLen for IterMut<'_, T> {} |
166 | |
167 | #[doc (hidden)] |
168 | #[unstable (feature = "trusted_random_access" , issue = "none" )] |
169 | unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {} |
170 | |
171 | #[doc (hidden)] |
172 | #[unstable (feature = "trusted_random_access" , issue = "none" )] |
173 | unsafe impl<T> TrustedRandomAccessNoCoerce for IterMut<'_, T> { |
174 | const MAY_HAVE_SIDE_EFFECT: bool = false; |
175 | } |
176 | |