1 | use super::{Bucket, Entries, IndexSet, Slice}; |
2 | |
3 | use alloc::vec::{self, Vec}; |
4 | use core::fmt; |
5 | use core::hash::{BuildHasher, Hash}; |
6 | use core::iter::{Chain, FusedIterator}; |
7 | use core::ops::RangeBounds; |
8 | use core::slice::Iter as SliceIter; |
9 | |
10 | impl<'a, T, S> IntoIterator for &'a IndexSet<T, S> { |
11 | type Item = &'a T; |
12 | type IntoIter = Iter<'a, T>; |
13 | |
14 | fn into_iter(self) -> Self::IntoIter { |
15 | self.iter() |
16 | } |
17 | } |
18 | |
19 | impl<T, S> IntoIterator for IndexSet<T, S> { |
20 | type Item = T; |
21 | type IntoIter = IntoIter<T>; |
22 | |
23 | fn into_iter(self) -> Self::IntoIter { |
24 | IntoIter::new(self.into_entries()) |
25 | } |
26 | } |
27 | |
28 | /// An iterator over the items of an [`IndexSet`]. |
29 | /// |
30 | /// This `struct` is created by the [`IndexSet::iter`] method. |
31 | /// See its documentation for more. |
32 | pub struct Iter<'a, T> { |
33 | iter: SliceIter<'a, Bucket<T>>, |
34 | } |
35 | |
36 | impl<'a, T> Iter<'a, T> { |
37 | pub(super) fn new(entries: &'a [Bucket<T>]) -> Self { |
38 | Self { |
39 | iter: entries.iter(), |
40 | } |
41 | } |
42 | |
43 | /// Returns a slice of the remaining entries in the iterator. |
44 | pub fn as_slice(&self) -> &'a Slice<T> { |
45 | Slice::from_slice(self.iter.as_slice()) |
46 | } |
47 | } |
48 | |
49 | impl<'a, T> Iterator for Iter<'a, T> { |
50 | type Item = &'a T; |
51 | |
52 | iterator_methods!(Bucket::key_ref); |
53 | } |
54 | |
55 | impl<T> DoubleEndedIterator for Iter<'_, T> { |
56 | double_ended_iterator_methods!(Bucket::key_ref); |
57 | } |
58 | |
59 | impl<T> ExactSizeIterator for Iter<'_, T> { |
60 | fn len(&self) -> usize { |
61 | self.iter.len() |
62 | } |
63 | } |
64 | |
65 | impl<T> FusedIterator for Iter<'_, T> {} |
66 | |
67 | impl<T> Clone for Iter<'_, T> { |
68 | fn clone(&self) -> Self { |
69 | Iter { |
70 | iter: self.iter.clone(), |
71 | } |
72 | } |
73 | } |
74 | |
75 | impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> { |
76 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
77 | f.debug_list().entries(self.clone()).finish() |
78 | } |
79 | } |
80 | |
81 | impl<T> Default for Iter<'_, T> { |
82 | fn default() -> Self { |
83 | Self { iter: [].iter() } |
84 | } |
85 | } |
86 | |
87 | /// An owning iterator over the items of an [`IndexSet`]. |
88 | /// |
89 | /// This `struct` is created by the [`IndexSet::into_iter`] method |
90 | /// (provided by the [`IntoIterator`] trait). See its documentation for more. |
91 | #[derive (Clone)] |
92 | pub struct IntoIter<T> { |
93 | iter: vec::IntoIter<Bucket<T>>, |
94 | } |
95 | |
96 | impl<T> IntoIter<T> { |
97 | pub(super) fn new(entries: Vec<Bucket<T>>) -> Self { |
98 | Self { |
99 | iter: entries.into_iter(), |
100 | } |
101 | } |
102 | |
103 | /// Returns a slice of the remaining entries in the iterator. |
104 | pub fn as_slice(&self) -> &Slice<T> { |
105 | Slice::from_slice(self.iter.as_slice()) |
106 | } |
107 | } |
108 | |
109 | impl<T> Iterator for IntoIter<T> { |
110 | type Item = T; |
111 | |
112 | iterator_methods!(Bucket::key); |
113 | } |
114 | |
115 | impl<T> DoubleEndedIterator for IntoIter<T> { |
116 | double_ended_iterator_methods!(Bucket::key); |
117 | } |
118 | |
119 | impl<T> ExactSizeIterator for IntoIter<T> { |
120 | fn len(&self) -> usize { |
121 | self.iter.len() |
122 | } |
123 | } |
124 | |
125 | impl<T> FusedIterator for IntoIter<T> {} |
126 | |
127 | impl<T: fmt::Debug> fmt::Debug for IntoIter<T> { |
128 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
129 | let iter: impl Iterator = self.iter.as_slice().iter().map(Bucket::key_ref); |
130 | f.debug_list().entries(iter).finish() |
131 | } |
132 | } |
133 | |
134 | impl<T> Default for IntoIter<T> { |
135 | fn default() -> Self { |
136 | Self { |
137 | iter: Vec::new().into_iter(), |
138 | } |
139 | } |
140 | } |
141 | |
142 | /// A draining iterator over the items of an [`IndexSet`]. |
143 | /// |
144 | /// This `struct` is created by the [`IndexSet::drain`] method. |
145 | /// See its documentation for more. |
146 | pub struct Drain<'a, T> { |
147 | iter: vec::Drain<'a, Bucket<T>>, |
148 | } |
149 | |
150 | impl<'a, T> Drain<'a, T> { |
151 | pub(super) fn new(iter: vec::Drain<'a, Bucket<T>>) -> Self { |
152 | Self { iter } |
153 | } |
154 | |
155 | /// Returns a slice of the remaining entries in the iterator. |
156 | pub fn as_slice(&self) -> &Slice<T> { |
157 | Slice::from_slice(self.iter.as_slice()) |
158 | } |
159 | } |
160 | |
161 | impl<T> Iterator for Drain<'_, T> { |
162 | type Item = T; |
163 | |
164 | iterator_methods!(Bucket::key); |
165 | } |
166 | |
167 | impl<T> DoubleEndedIterator for Drain<'_, T> { |
168 | double_ended_iterator_methods!(Bucket::key); |
169 | } |
170 | |
171 | impl<T> ExactSizeIterator for Drain<'_, T> { |
172 | fn len(&self) -> usize { |
173 | self.iter.len() |
174 | } |
175 | } |
176 | |
177 | impl<T> FusedIterator for Drain<'_, T> {} |
178 | |
179 | impl<T: fmt::Debug> fmt::Debug for Drain<'_, T> { |
180 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
181 | let iter: impl Iterator = self.iter.as_slice().iter().map(Bucket::key_ref); |
182 | f.debug_list().entries(iter).finish() |
183 | } |
184 | } |
185 | |
186 | /// A lazy iterator producing elements in the difference of [`IndexSet`]s. |
187 | /// |
188 | /// This `struct` is created by the [`IndexSet::difference`] method. |
189 | /// See its documentation for more. |
190 | pub struct Difference<'a, T, S> { |
191 | iter: Iter<'a, T>, |
192 | other: &'a IndexSet<T, S>, |
193 | } |
194 | |
195 | impl<'a, T, S> Difference<'a, T, S> { |
196 | pub(super) fn new<S1>(set: &'a IndexSet<T, S1>, other: &'a IndexSet<T, S>) -> Self { |
197 | Self { |
198 | iter: set.iter(), |
199 | other, |
200 | } |
201 | } |
202 | } |
203 | |
204 | impl<'a, T, S> Iterator for Difference<'a, T, S> |
205 | where |
206 | T: Eq + Hash, |
207 | S: BuildHasher, |
208 | { |
209 | type Item = &'a T; |
210 | |
211 | fn next(&mut self) -> Option<Self::Item> { |
212 | while let Some(item: &'a T) = self.iter.next() { |
213 | if !self.other.contains(item) { |
214 | return Some(item); |
215 | } |
216 | } |
217 | None |
218 | } |
219 | |
220 | fn size_hint(&self) -> (usize, Option<usize>) { |
221 | (0, self.iter.size_hint().1) |
222 | } |
223 | } |
224 | |
225 | impl<T, S> DoubleEndedIterator for Difference<'_, T, S> |
226 | where |
227 | T: Eq + Hash, |
228 | S: BuildHasher, |
229 | { |
230 | fn next_back(&mut self) -> Option<Self::Item> { |
231 | while let Some(item: &T) = self.iter.next_back() { |
232 | if !self.other.contains(item) { |
233 | return Some(item); |
234 | } |
235 | } |
236 | None |
237 | } |
238 | } |
239 | |
240 | impl<T, S> FusedIterator for Difference<'_, T, S> |
241 | where |
242 | T: Eq + Hash, |
243 | S: BuildHasher, |
244 | { |
245 | } |
246 | |
247 | impl<T, S> Clone for Difference<'_, T, S> { |
248 | fn clone(&self) -> Self { |
249 | Difference { |
250 | iter: self.iter.clone(), |
251 | ..*self |
252 | } |
253 | } |
254 | } |
255 | |
256 | impl<T, S> fmt::Debug for Difference<'_, T, S> |
257 | where |
258 | T: fmt::Debug + Eq + Hash, |
259 | S: BuildHasher, |
260 | { |
261 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
262 | f.debug_list().entries(self.clone()).finish() |
263 | } |
264 | } |
265 | |
266 | /// A lazy iterator producing elements in the intersection of [`IndexSet`]s. |
267 | /// |
268 | /// This `struct` is created by the [`IndexSet::intersection`] method. |
269 | /// See its documentation for more. |
270 | pub struct Intersection<'a, T, S> { |
271 | iter: Iter<'a, T>, |
272 | other: &'a IndexSet<T, S>, |
273 | } |
274 | |
275 | impl<'a, T, S> Intersection<'a, T, S> { |
276 | pub(super) fn new<S1>(set: &'a IndexSet<T, S1>, other: &'a IndexSet<T, S>) -> Self { |
277 | Self { |
278 | iter: set.iter(), |
279 | other, |
280 | } |
281 | } |
282 | } |
283 | |
284 | impl<'a, T, S> Iterator for Intersection<'a, T, S> |
285 | where |
286 | T: Eq + Hash, |
287 | S: BuildHasher, |
288 | { |
289 | type Item = &'a T; |
290 | |
291 | fn next(&mut self) -> Option<Self::Item> { |
292 | while let Some(item: &'a T) = self.iter.next() { |
293 | if self.other.contains(item) { |
294 | return Some(item); |
295 | } |
296 | } |
297 | None |
298 | } |
299 | |
300 | fn size_hint(&self) -> (usize, Option<usize>) { |
301 | (0, self.iter.size_hint().1) |
302 | } |
303 | } |
304 | |
305 | impl<T, S> DoubleEndedIterator for Intersection<'_, T, S> |
306 | where |
307 | T: Eq + Hash, |
308 | S: BuildHasher, |
309 | { |
310 | fn next_back(&mut self) -> Option<Self::Item> { |
311 | while let Some(item: &T) = self.iter.next_back() { |
312 | if self.other.contains(item) { |
313 | return Some(item); |
314 | } |
315 | } |
316 | None |
317 | } |
318 | } |
319 | |
320 | impl<T, S> FusedIterator for Intersection<'_, T, S> |
321 | where |
322 | T: Eq + Hash, |
323 | S: BuildHasher, |
324 | { |
325 | } |
326 | |
327 | impl<T, S> Clone for Intersection<'_, T, S> { |
328 | fn clone(&self) -> Self { |
329 | Intersection { |
330 | iter: self.iter.clone(), |
331 | ..*self |
332 | } |
333 | } |
334 | } |
335 | |
336 | impl<T, S> fmt::Debug for Intersection<'_, T, S> |
337 | where |
338 | T: fmt::Debug + Eq + Hash, |
339 | S: BuildHasher, |
340 | { |
341 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
342 | f.debug_list().entries(self.clone()).finish() |
343 | } |
344 | } |
345 | |
346 | /// A lazy iterator producing elements in the symmetric difference of [`IndexSet`]s. |
347 | /// |
348 | /// This `struct` is created by the [`IndexSet::symmetric_difference`] method. |
349 | /// See its documentation for more. |
350 | pub struct SymmetricDifference<'a, T, S1, S2> { |
351 | iter: Chain<Difference<'a, T, S2>, Difference<'a, T, S1>>, |
352 | } |
353 | |
354 | impl<'a, T, S1, S2> SymmetricDifference<'a, T, S1, S2> |
355 | where |
356 | T: Eq + Hash, |
357 | S1: BuildHasher, |
358 | S2: BuildHasher, |
359 | { |
360 | pub(super) fn new(set1: &'a IndexSet<T, S1>, set2: &'a IndexSet<T, S2>) -> Self { |
361 | let diff1: Difference<'_, T, S2> = set1.difference(set2); |
362 | let diff2: Difference<'_, T, S1> = set2.difference(set1); |
363 | Self { |
364 | iter: diff1.chain(diff2), |
365 | } |
366 | } |
367 | } |
368 | |
369 | impl<'a, T, S1, S2> Iterator for SymmetricDifference<'a, T, S1, S2> |
370 | where |
371 | T: Eq + Hash, |
372 | S1: BuildHasher, |
373 | S2: BuildHasher, |
374 | { |
375 | type Item = &'a T; |
376 | |
377 | fn next(&mut self) -> Option<Self::Item> { |
378 | self.iter.next() |
379 | } |
380 | |
381 | fn size_hint(&self) -> (usize, Option<usize>) { |
382 | self.iter.size_hint() |
383 | } |
384 | |
385 | fn fold<B, F>(self, init: B, f: F) -> B |
386 | where |
387 | F: FnMut(B, Self::Item) -> B, |
388 | { |
389 | self.iter.fold(init, f) |
390 | } |
391 | } |
392 | |
393 | impl<T, S1, S2> DoubleEndedIterator for SymmetricDifference<'_, T, S1, S2> |
394 | where |
395 | T: Eq + Hash, |
396 | S1: BuildHasher, |
397 | S2: BuildHasher, |
398 | { |
399 | fn next_back(&mut self) -> Option<Self::Item> { |
400 | self.iter.next_back() |
401 | } |
402 | |
403 | fn rfold<B, F>(self, init: B, f: F) -> B |
404 | where |
405 | F: FnMut(B, Self::Item) -> B, |
406 | { |
407 | self.iter.rfold(init, f) |
408 | } |
409 | } |
410 | |
411 | impl<T, S1, S2> FusedIterator for SymmetricDifference<'_, T, S1, S2> |
412 | where |
413 | T: Eq + Hash, |
414 | S1: BuildHasher, |
415 | S2: BuildHasher, |
416 | { |
417 | } |
418 | |
419 | impl<T, S1, S2> Clone for SymmetricDifference<'_, T, S1, S2> { |
420 | fn clone(&self) -> Self { |
421 | SymmetricDifference { |
422 | iter: self.iter.clone(), |
423 | } |
424 | } |
425 | } |
426 | |
427 | impl<T, S1, S2> fmt::Debug for SymmetricDifference<'_, T, S1, S2> |
428 | where |
429 | T: fmt::Debug + Eq + Hash, |
430 | S1: BuildHasher, |
431 | S2: BuildHasher, |
432 | { |
433 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
434 | f.debug_list().entries(self.clone()).finish() |
435 | } |
436 | } |
437 | |
438 | /// A lazy iterator producing elements in the union of [`IndexSet`]s. |
439 | /// |
440 | /// This `struct` is created by the [`IndexSet::union`] method. |
441 | /// See its documentation for more. |
442 | pub struct Union<'a, T, S> { |
443 | iter: Chain<Iter<'a, T>, Difference<'a, T, S>>, |
444 | } |
445 | |
446 | impl<'a, T, S> Union<'a, T, S> |
447 | where |
448 | T: Eq + Hash, |
449 | S: BuildHasher, |
450 | { |
451 | pub(super) fn new<S2>(set1: &'a IndexSet<T, S>, set2: &'a IndexSet<T, S2>) -> Self |
452 | where |
453 | S2: BuildHasher, |
454 | { |
455 | Self { |
456 | iter: set1.iter().chain(set2.difference(set1)), |
457 | } |
458 | } |
459 | } |
460 | |
461 | impl<'a, T, S> Iterator for Union<'a, T, S> |
462 | where |
463 | T: Eq + Hash, |
464 | S: BuildHasher, |
465 | { |
466 | type Item = &'a T; |
467 | |
468 | fn next(&mut self) -> Option<Self::Item> { |
469 | self.iter.next() |
470 | } |
471 | |
472 | fn size_hint(&self) -> (usize, Option<usize>) { |
473 | self.iter.size_hint() |
474 | } |
475 | |
476 | fn fold<B, F>(self, init: B, f: F) -> B |
477 | where |
478 | F: FnMut(B, Self::Item) -> B, |
479 | { |
480 | self.iter.fold(init, f) |
481 | } |
482 | } |
483 | |
484 | impl<T, S> DoubleEndedIterator for Union<'_, T, S> |
485 | where |
486 | T: Eq + Hash, |
487 | S: BuildHasher, |
488 | { |
489 | fn next_back(&mut self) -> Option<Self::Item> { |
490 | self.iter.next_back() |
491 | } |
492 | |
493 | fn rfold<B, F>(self, init: B, f: F) -> B |
494 | where |
495 | F: FnMut(B, Self::Item) -> B, |
496 | { |
497 | self.iter.rfold(init, f) |
498 | } |
499 | } |
500 | |
501 | impl<T, S> FusedIterator for Union<'_, T, S> |
502 | where |
503 | T: Eq + Hash, |
504 | S: BuildHasher, |
505 | { |
506 | } |
507 | |
508 | impl<T, S> Clone for Union<'_, T, S> { |
509 | fn clone(&self) -> Self { |
510 | Union { |
511 | iter: self.iter.clone(), |
512 | } |
513 | } |
514 | } |
515 | |
516 | impl<T, S> fmt::Debug for Union<'_, T, S> |
517 | where |
518 | T: fmt::Debug + Eq + Hash, |
519 | S: BuildHasher, |
520 | { |
521 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
522 | f.debug_list().entries(self.clone()).finish() |
523 | } |
524 | } |
525 | |
526 | /// A splicing iterator for `IndexSet`. |
527 | /// |
528 | /// This `struct` is created by [`IndexSet::splice()`]. |
529 | /// See its documentation for more. |
530 | pub struct Splice<'a, I, T, S> |
531 | where |
532 | I: Iterator<Item = T>, |
533 | T: Hash + Eq, |
534 | S: BuildHasher, |
535 | { |
536 | iter: crate::map::Splice<'a, UnitValue<I>, T, (), S>, |
537 | } |
538 | |
539 | impl<'a, I, T, S> Splice<'a, I, T, S> |
540 | where |
541 | I: Iterator<Item = T>, |
542 | T: Hash + Eq, |
543 | S: BuildHasher, |
544 | { |
545 | #[track_caller ] |
546 | pub(super) fn new<R>(set: &'a mut IndexSet<T, S>, range: R, replace_with: I) -> Self |
547 | where |
548 | R: RangeBounds<usize>, |
549 | { |
550 | Self { |
551 | iter: set.map.splice(range, replace_with:UnitValue(replace_with)), |
552 | } |
553 | } |
554 | } |
555 | |
556 | impl<I, T, S> Iterator for Splice<'_, I, T, S> |
557 | where |
558 | I: Iterator<Item = T>, |
559 | T: Hash + Eq, |
560 | S: BuildHasher, |
561 | { |
562 | type Item = T; |
563 | |
564 | fn next(&mut self) -> Option<Self::Item> { |
565 | Some(self.iter.next()?.0) |
566 | } |
567 | |
568 | fn size_hint(&self) -> (usize, Option<usize>) { |
569 | self.iter.size_hint() |
570 | } |
571 | } |
572 | |
573 | impl<I, T, S> DoubleEndedIterator for Splice<'_, I, T, S> |
574 | where |
575 | I: Iterator<Item = T>, |
576 | T: Hash + Eq, |
577 | S: BuildHasher, |
578 | { |
579 | fn next_back(&mut self) -> Option<Self::Item> { |
580 | Some(self.iter.next_back()?.0) |
581 | } |
582 | } |
583 | |
584 | impl<I, T, S> ExactSizeIterator for Splice<'_, I, T, S> |
585 | where |
586 | I: Iterator<Item = T>, |
587 | T: Hash + Eq, |
588 | S: BuildHasher, |
589 | { |
590 | fn len(&self) -> usize { |
591 | self.iter.len() |
592 | } |
593 | } |
594 | |
595 | impl<I, T, S> FusedIterator for Splice<'_, I, T, S> |
596 | where |
597 | I: Iterator<Item = T>, |
598 | T: Hash + Eq, |
599 | S: BuildHasher, |
600 | { |
601 | } |
602 | |
603 | struct UnitValue<I>(I); |
604 | |
605 | impl<I: Iterator> Iterator for UnitValue<I> { |
606 | type Item = (I::Item, ()); |
607 | |
608 | fn next(&mut self) -> Option<Self::Item> { |
609 | self.0.next().map(|x: ::Item| (x, ())) |
610 | } |
611 | } |
612 | |
613 | impl<I, T, S> fmt::Debug for Splice<'_, I, T, S> |
614 | where |
615 | I: fmt::Debug + Iterator<Item = T>, |
616 | T: fmt::Debug + Hash + Eq, |
617 | S: BuildHasher, |
618 | { |
619 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
620 | fmt::Debug::fmt(&self.iter, f) |
621 | } |
622 | } |
623 | |
624 | impl<I: fmt::Debug> fmt::Debug for UnitValue<I> { |
625 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
626 | fmt::Debug::fmt(&self.0, f) |
627 | } |
628 | } |
629 | |