1use core::{
2 iter::FusedIterator,
3 mem::transmute,
4 ptr::{metadata, DynMetadata, Pointee},
5};
6
7use crate::DynSliceMut;
8
9pub struct IterMut<'a, Dyn: ?Sized + Pointee<Metadata = DynMetadata<Dyn>>> {
11 pub(crate) slice: DynSliceMut<'a, Dyn>,
12}
13
14impl<'a, Dyn: ?Sized + Pointee<Metadata = DynMetadata<Dyn>> + 'a> Iterator for IterMut<'a, Dyn> {
15 type Item = &'a mut Dyn;
16
17 fn next(&mut self) -> Option<Self::Item> {
18 if self.slice.is_empty() {
19 None
20 } else {
21 let element: &'a mut Dyn = unsafe { transmute(self.slice.first_unchecked_mut()) };
27
28 self.slice.0.data = unsafe { self.slice.data.byte_add(metadata(element).size_of()) };
33 self.slice.0.len -= 1;
34
35 Some(element)
36 }
37 }
38
39 #[inline]
40 fn size_hint(&self) -> (usize, Option<usize>) {
41 let remaining = self.slice.len();
42 (remaining, Some(remaining))
43 }
44
45 #[inline]
46 fn count(self) -> usize {
47 self.slice.len()
48 }
49
50 fn nth(&mut self, n: usize) -> Option<Self::Item> {
51 if n >= self.slice.len() {
52 self.slice.0.len = 0;
53 return None;
54 }
55
56 let metadata: DynMetadata<Dyn> = unsafe { transmute(self.slice.vtable_ptr) };
60
61 self.slice.0.data = unsafe { self.slice.data.byte_add(metadata.size_of() * n) };
65 self.slice.0.len -= n;
66
67 self.next()
68 }
69
70 fn last(mut self) -> Option<Self::Item> {
71 unsafe { transmute(self.slice.last_mut()) }
75 }
76}
77
78impl<'a, Dyn: ?Sized + Pointee<Metadata = DynMetadata<Dyn>> + 'a> DoubleEndedIterator
79 for IterMut<'a, Dyn>
80{
81 fn next_back(&mut self) -> Option<Self::Item> {
82 if self.slice.is_empty() {
83 None
84 } else {
85 let element: &'a mut Dyn =
86 unsafe { transmute(self.slice.get_unchecked_mut(self.slice.len - 1)) };
92
93 self.slice.0.len -= 1;
94
95 Some(element)
96 }
97 }
98
99 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
100 if n >= self.slice.len() {
101 self.slice.0.len = 0;
102 return None;
103 }
104
105 self.slice.0.len -= n;
106
107 self.next_back()
108 }
109}
110
111impl<'a, Dyn: ?Sized + Pointee<Metadata = DynMetadata<Dyn>> + 'a> ExactSizeIterator
112 for IterMut<'a, Dyn>
113{
114 #[inline]
115 fn len(&self) -> usize {
116 self.slice.len()
117 }
118}
119
120impl<'a, Dyn: ?Sized + Pointee<Metadata = DynMetadata<Dyn>> + 'a> FusedIterator
121 for IterMut<'a, Dyn>
122{
123}
124
125#[cfg(test)]
126mod test {
127 use crate::standard::partial_eq;
128
129 #[test]
130 fn test_next() {
131 let array = [2, 3, 5, 7, 11];
132 let mut array2 = array;
133 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
134
135 let mut iter = slice.iter_mut();
136 for &expected in &array {
137 let actual = iter.next().expect("expected an element");
138 assert!(actual == &expected, "expected {expected}");
139 }
140 }
141
142 #[test]
143 fn test_size_hint() {
144 let array = [2, 3, 5, 7, 11];
145 let mut array2 = array;
146 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
147
148 let mut iter = slice.iter_mut();
149 for expected in (1..=array.len()).rev() {
150 let (lower, Some(upper)) = iter.size_hint() else {
151 panic!("expected an upper bound");
152 };
153
154 assert_eq!(lower, upper, "expected lower and upper bounds to be equal");
155 assert_eq!(
156 lower, expected,
157 "expected size hint to be {expected}, got {lower}"
158 );
159
160 let _ = iter.next().expect("expected an element");
161 }
162
163 let (lower, Some(upper)) = iter.size_hint() else {
164 panic!("expected an upper bound");
165 };
166
167 assert_eq!(lower, upper, "expected lower and upper bounds to be equal");
168 assert_eq!(lower, 0, "expected size hint to be 0, got {lower}");
169 }
170
171 #[test]
172 fn test_count() {
173 let array = [2, 3, 5, 7, 11];
174
175 for i in 0..=array.len() {
176 let mut array2 = array;
177 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
178
179 let iter = slice.iter_mut();
180 let actual = iter.skip(i).count();
181
182 let expected = array.len() - i;
183
184 assert_eq!(
185 actual, expected,
186 "expected count to be {expected}, got {actual}"
187 );
188 }
189 }
190
191 #[test]
192 fn test_nth() {
193 let array = [2, 3, 5, 7, 11];
194 let mut array2 = array;
195 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
196
197 let mut iter = slice.iter_mut();
198
199 #[allow(clippy::iter_nth_zero)]
200 let actual = iter.nth(0).expect("expected an element");
201 assert!(actual == &2, "expected 2");
202
203 assert!(
204 iter.nth(1).expect("expected an element") == &5,
205 "expected 5"
206 );
207 assert_eq!(iter.size_hint().0, 2, "expected 2 elements left");
208
209 assert!(iter.nth(2).is_none(), "expected none");
210 assert_eq!(iter.size_hint().0, 0, "expected 0 elements left");
211 }
212
213 #[test]
214 fn test_last() {
215 let array = [2, 3, 5, 7, 11];
216 let mut array2 = array;
217 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
218
219 assert!(
220 slice.iter_mut().last().expect("expected an element") == &11,
221 "expected 11"
222 );
223 }
224
225 #[test]
226 fn test_next_back() {
227 let array = [2, 3, 5, 7, 11];
228 let mut array2 = array;
229 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
230
231 let mut iter = slice.iter_mut();
232 for &expected in array.iter().rev() {
233 let actual = iter.next_back().expect("expected an element");
234 assert!(actual == &expected, "expected {expected}");
235 }
236 }
237
238 #[test]
239 fn test_nth_back() {
240 let array = [2, 3, 5, 7, 11];
241 let mut array2 = array;
242 let mut slice = partial_eq::new_mut::<u8, _>(&mut array2);
243
244 let mut iter = slice.iter_mut();
245
246 #[allow(clippy::iter_nth_zero)]
247 let actual = iter.nth_back(0).expect("expected an element");
248 assert!(actual == &11, "expected 11");
249
250 assert!(
251 iter.nth_back(1).expect("expected an element") == &5,
252 "expected 5"
253 );
254 assert_eq!(iter.size_hint().0, 2, "expected 2 elements left");
255
256 assert!(iter.nth_back(2).is_none(), "expected none");
257 assert_eq!(iter.size_hint().0, 0, "expected 0 elements left");
258 }
259
260 #[test]
261 fn test_bidirectional() {
262 let mut array = [2, 3, 5, 7, 11];
263 let mut slice = partial_eq::new_mut::<u8, _>(&mut array);
264
265 let mut iter = slice.iter_mut();
266
267 assert!(
268 iter.next().expect("expected an element") == &2,
269 "expected 2"
270 );
271 assert_eq!(iter.size_hint().0, 4, "expected 4 elements left");
272
273 assert!(
274 iter.next_back().expect("expected an element") == &11,
275 "expected 11"
276 );
277 assert_eq!(iter.size_hint().0, 3, "expected 3 elements left");
278
279 assert!(
280 iter.nth(1).expect("expected an element") == &5,
281 "expected 5"
282 );
283 assert_eq!(iter.size_hint().0, 1, "expected 1 element left");
284
285 assert!(
286 iter.nth_back(0).expect("expected an element") == &7,
287 "expected 7"
288 );
289 assert_eq!(iter.size_hint().0, 0, "expected 0 elements left");
290 }
291}