1use crate::iter::adapters::SourceIter;
2use crate::iter::{
3 Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, Map, Once, OnceWith,
4 TrustedFused, TrustedLen,
5};
6use crate::num::NonZero;
7use crate::ops::{ControlFlow, Try};
8use crate::{array, fmt, option, result};
9
10#[must_use = "iterators are lazy and do nothing unless consumed"]
16#[stable(feature = "rust1", since = "1.0.0")]
17#[ferrocene::prevalidated]
18pub struct FlatMap<I, U: IntoIterator, F> {
19 inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
20}
21
22impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
23 #[ferrocene::prevalidated]
24 pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
25 FlatMap { inner: FlattenCompat::new(iter.map(f)) }
26 }
27
28 #[ferrocene::prevalidated]
29 pub(crate) fn into_parts(self) -> (Option<U::IntoIter>, Option<I>, Option<U::IntoIter>) {
30 (
31 self.inner.frontiter,
32 self.inner.iter.into_inner().map(Map::into_inner),
33 self.inner.backiter,
34 )
35 }
36}
37
38#[stable(feature = "rust1", since = "1.0.0")]
39impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
40where
41 U: Clone + IntoIterator<IntoIter: Clone>,
42{
43 #[ferrocene::prevalidated]
44 fn clone(&self) -> Self {
45 FlatMap { inner: self.inner.clone() }
46 }
47}
48
49#[stable(feature = "core_impl_debug", since = "1.9.0")]
50impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
51where
52 U: IntoIterator<IntoIter: fmt::Debug>,
53{
54 #[ferrocene::prevalidated]
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 f.debug_struct("FlatMap").field("inner", &self.inner).finish()
57 }
58}
59
60#[stable(feature = "rust1", since = "1.0.0")]
61impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
62where
63 F: FnMut(I::Item) -> U,
64{
65 type Item = U::Item;
66
67 #[inline]
68 fn next(&mut self) -> Option<U::Item> {
69 self.inner.next()
70 }
71
72 #[inline]
73 fn size_hint(&self) -> (usize, Option<usize>) {
74 self.inner.size_hint()
75 }
76
77 #[inline]
78 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
79 where
80 Self: Sized,
81 Fold: FnMut(Acc, Self::Item) -> R,
82 R: Try<Output = Acc>,
83 {
84 self.inner.try_fold(init, fold)
85 }
86
87 #[inline]
88 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
89 where
90 Fold: FnMut(Acc, Self::Item) -> Acc,
91 {
92 self.inner.fold(init, fold)
93 }
94
95 #[inline]
96 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
97 self.inner.advance_by(n)
98 }
99
100 #[inline]
101 fn count(self) -> usize {
102 self.inner.count()
103 }
104
105 #[inline]
106 fn last(self) -> Option<Self::Item> {
107 self.inner.last()
108 }
109}
110
111#[stable(feature = "rust1", since = "1.0.0")]
112impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
113where
114 F: FnMut(I::Item) -> U,
115 U: IntoIterator<IntoIter: DoubleEndedIterator>,
116{
117 #[inline]
118 fn next_back(&mut self) -> Option<U::Item> {
119 self.inner.next_back()
120 }
121
122 #[inline]
123 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
124 where
125 Self: Sized,
126 Fold: FnMut(Acc, Self::Item) -> R,
127 R: Try<Output = Acc>,
128 {
129 self.inner.try_rfold(init, fold)
130 }
131
132 #[inline]
133 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
134 where
135 Fold: FnMut(Acc, Self::Item) -> Acc,
136 {
137 self.inner.rfold(init, fold)
138 }
139
140 #[inline]
141 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
142 self.inner.advance_back_by(n)
143 }
144}
145
146#[stable(feature = "fused", since = "1.26.0")]
147impl<I, U, F> FusedIterator for FlatMap<I, U, F>
148where
149 I: FusedIterator,
150 U: IntoIterator,
151 F: FnMut(I::Item) -> U,
152{
153}
154
155#[unstable(feature = "trusted_len", issue = "37572")]
156unsafe impl<I, U, F> TrustedLen for FlatMap<I, U, F>
157where
158 I: Iterator,
159 U: IntoIterator,
160 F: FnMut(I::Item) -> U,
161 FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>: TrustedLen,
162{
163}
164
165#[unstable(issue = "none", feature = "inplace_iteration")]
166unsafe impl<I, U, F> SourceIter for FlatMap<I, U, F>
167where
168 I: SourceIter + TrustedFused,
169 U: IntoIterator,
170{
171 type Source = I::Source;
172
173 #[inline]
174 unsafe fn as_inner(&mut self) -> &mut I::Source {
175 unsafe { SourceIter::as_inner(&mut self.inner.iter) }
177 }
178}
179
180#[must_use = "iterators are lazy and do nothing unless consumed"]
188#[stable(feature = "iterator_flatten", since = "1.29.0")]
189pub struct Flatten<I: Iterator<Item: IntoIterator>> {
190 inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
191}
192
193impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
194 pub(in super::super) fn new(iter: I) -> Flatten<I> {
195 Flatten { inner: FlattenCompat::new(iter) }
196 }
197}
198
199#[stable(feature = "iterator_flatten", since = "1.29.0")]
200impl<I, U> fmt::Debug for Flatten<I>
201where
202 I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
203 U: fmt::Debug + Iterator,
204{
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 f.debug_struct("Flatten").field("inner", &self.inner).finish()
207 }
208}
209
210#[stable(feature = "iterator_flatten", since = "1.29.0")]
211impl<I, U> Clone for Flatten<I>
212where
213 I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
214 U: Clone + Iterator,
215{
216 fn clone(&self) -> Self {
217 Flatten { inner: self.inner.clone() }
218 }
219}
220
221#[stable(feature = "iterator_flatten", since = "1.29.0")]
222impl<I, U> Iterator for Flatten<I>
223where
224 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
225 U: Iterator,
226{
227 type Item = U::Item;
228
229 #[inline]
230 fn next(&mut self) -> Option<U::Item> {
231 self.inner.next()
232 }
233
234 #[inline]
235 fn size_hint(&self) -> (usize, Option<usize>) {
236 self.inner.size_hint()
237 }
238
239 #[inline]
240 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
241 where
242 Self: Sized,
243 Fold: FnMut(Acc, Self::Item) -> R,
244 R: Try<Output = Acc>,
245 {
246 self.inner.try_fold(init, fold)
247 }
248
249 #[inline]
250 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
251 where
252 Fold: FnMut(Acc, Self::Item) -> Acc,
253 {
254 self.inner.fold(init, fold)
255 }
256
257 #[inline]
258 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
259 self.inner.advance_by(n)
260 }
261
262 #[inline]
263 fn count(self) -> usize {
264 self.inner.count()
265 }
266
267 #[inline]
268 fn last(self) -> Option<Self::Item> {
269 self.inner.last()
270 }
271}
272
273#[stable(feature = "iterator_flatten", since = "1.29.0")]
274impl<I, U> DoubleEndedIterator for Flatten<I>
275where
276 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
277 U: DoubleEndedIterator,
278{
279 #[inline]
280 fn next_back(&mut self) -> Option<U::Item> {
281 self.inner.next_back()
282 }
283
284 #[inline]
285 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
286 where
287 Self: Sized,
288 Fold: FnMut(Acc, Self::Item) -> R,
289 R: Try<Output = Acc>,
290 {
291 self.inner.try_rfold(init, fold)
292 }
293
294 #[inline]
295 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
296 where
297 Fold: FnMut(Acc, Self::Item) -> Acc,
298 {
299 self.inner.rfold(init, fold)
300 }
301
302 #[inline]
303 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
304 self.inner.advance_back_by(n)
305 }
306}
307
308#[stable(feature = "iterator_flatten", since = "1.29.0")]
309impl<I, U> FusedIterator for Flatten<I>
310where
311 I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
312 U: Iterator,
313{
314}
315
316#[unstable(feature = "trusted_len", issue = "37572")]
317unsafe impl<I> TrustedLen for Flatten<I>
318where
319 I: Iterator<Item: IntoIterator>,
320 FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>: TrustedLen,
321{
322}
323
324#[unstable(issue = "none", feature = "inplace_iteration")]
325unsafe impl<I> SourceIter for Flatten<I>
326where
327 I: SourceIter + TrustedFused + Iterator,
328 <I as Iterator>::Item: IntoIterator,
329{
330 type Source = I::Source;
331
332 #[inline]
333 unsafe fn as_inner(&mut self) -> &mut I::Source {
334 unsafe { SourceIter::as_inner(&mut self.inner.iter) }
336 }
337}
338
339#[stable(feature = "default_iters", since = "1.70.0")]
340impl<I> Default for Flatten<I>
341where
342 I: Default + Iterator<Item: IntoIterator>,
343{
344 fn default() -> Self {
353 Flatten::new(Default::default())
354 }
355}
356
357#[derive(Clone, Debug)]
360#[unstable(feature = "trusted_len", issue = "37572")]
361#[ferrocene::prevalidated]
362struct FlattenCompat<I, U> {
363 iter: Fuse<I>,
364 frontiter: Option<U>,
365 backiter: Option<U>,
366}
367impl<I, U> FlattenCompat<I, U>
368where
369 I: Iterator,
370{
371 #[ferrocene::prevalidated]
373 fn new(iter: I) -> FlattenCompat<I, U> {
374 FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
375 }
376}
377
378impl<I, U> FlattenCompat<I, U>
379where
380 I: Iterator<Item: IntoIterator<IntoIter = U>>,
381{
382 #[inline]
387 fn iter_fold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
388 where
389 Fold: FnMut(Acc, U) -> Acc,
390 {
391 #[inline]
392 fn flatten<T: IntoIterator, Acc>(
393 fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
394 ) -> impl FnMut(Acc, T) -> Acc + '_ {
395 move |acc, iter| fold(acc, iter.into_iter())
396 }
397
398 if let Some(iter) = self.frontiter {
399 acc = fold(acc, iter);
400 }
401
402 acc = self.iter.fold(acc, flatten(&mut fold));
403
404 if let Some(iter) = self.backiter {
405 acc = fold(acc, iter);
406 }
407
408 acc
409 }
410
411 #[inline]
417 fn iter_try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
418 where
419 Fold: FnMut(Acc, &mut U) -> R,
420 R: Try<Output = Acc>,
421 {
422 #[inline]
423 fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
424 frontiter: &'a mut Option<T::IntoIter>,
425 fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
426 ) -> impl FnMut(Acc, T) -> R + 'a {
427 move |acc, iter| fold(acc, frontiter.insert(iter.into_iter()))
428 }
429
430 if let Some(iter) = &mut self.frontiter {
431 acc = fold(acc, iter)?;
432 }
433 self.frontiter = None;
434
435 acc = self.iter.try_fold(acc, flatten(&mut self.frontiter, &mut fold))?;
436 self.frontiter = None;
437
438 if let Some(iter) = &mut self.backiter {
439 acc = fold(acc, iter)?;
440 }
441 self.backiter = None;
442
443 try { acc }
444 }
445}
446
447impl<I, U> FlattenCompat<I, U>
448where
449 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U>>,
450{
451 #[inline]
456 fn iter_rfold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
457 where
458 Fold: FnMut(Acc, U) -> Acc,
459 {
460 #[inline]
461 fn flatten<T: IntoIterator, Acc>(
462 fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
463 ) -> impl FnMut(Acc, T) -> Acc + '_ {
464 move |acc, iter| fold(acc, iter.into_iter())
465 }
466
467 if let Some(iter) = self.backiter {
468 acc = fold(acc, iter);
469 }
470
471 acc = self.iter.rfold(acc, flatten(&mut fold));
472
473 if let Some(iter) = self.frontiter {
474 acc = fold(acc, iter);
475 }
476
477 acc
478 }
479
480 #[inline]
486 fn iter_try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
487 where
488 Fold: FnMut(Acc, &mut U) -> R,
489 R: Try<Output = Acc>,
490 {
491 #[inline]
492 fn flatten<'a, T: IntoIterator, Acc, R: Try>(
493 backiter: &'a mut Option<T::IntoIter>,
494 fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
495 ) -> impl FnMut(Acc, T) -> R + 'a {
496 move |acc, iter| fold(acc, backiter.insert(iter.into_iter()))
497 }
498
499 if let Some(iter) = &mut self.backiter {
500 acc = fold(acc, iter)?;
501 }
502 self.backiter = None;
503
504 acc = self.iter.try_rfold(acc, flatten(&mut self.backiter, &mut fold))?;
505 self.backiter = None;
506
507 if let Some(iter) = &mut self.frontiter {
508 acc = fold(acc, iter)?;
509 }
510 self.frontiter = None;
511
512 try { acc }
513 }
514}
515
516impl<I, U> Iterator for FlattenCompat<I, U>
518where
519 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
520 U: Iterator,
521{
522 type Item = U::Item;
523
524 #[inline]
525 default fn next(&mut self) -> Option<U::Item> {
526 loop {
527 if let elt @ Some(_) = and_then_or_clear(&mut self.frontiter, Iterator::next) {
528 return elt;
529 }
530 match self.iter.next() {
531 None => return and_then_or_clear(&mut self.backiter, Iterator::next),
532 Some(inner) => self.frontiter = Some(inner.into_iter()),
533 }
534 }
535 }
536
537 #[inline]
538 default fn size_hint(&self) -> (usize, Option<usize>) {
539 let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
540 let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
541 let lo = flo.saturating_add(blo);
542
543 if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIntoIterator>::size() {
544 let (lower, upper) = self.iter.size_hint();
545
546 let lower = lower.saturating_mul(fixed_size).saturating_add(lo);
547 let upper =
548 try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };
549
550 return (lower, upper);
551 }
552
553 match (self.iter.size_hint(), fhi, bhi) {
554 ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
555 _ => (lo, None),
556 }
557 }
558
559 #[inline]
560 default fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
561 where
562 Self: Sized,
563 Fold: FnMut(Acc, Self::Item) -> R,
564 R: Try<Output = Acc>,
565 {
566 #[inline]
567 fn flatten<U: Iterator, Acc, R: Try<Output = Acc>>(
568 mut fold: impl FnMut(Acc, U::Item) -> R,
569 ) -> impl FnMut(Acc, &mut U) -> R {
570 move |acc, iter| iter.try_fold(acc, &mut fold)
571 }
572
573 self.iter_try_fold(init, flatten(fold))
574 }
575
576 #[inline]
577 default fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
578 where
579 Fold: FnMut(Acc, Self::Item) -> Acc,
580 {
581 #[inline]
582 fn flatten<U: Iterator, Acc>(
583 mut fold: impl FnMut(Acc, U::Item) -> Acc,
584 ) -> impl FnMut(Acc, U) -> Acc {
585 move |acc, iter| iter.fold(acc, &mut fold)
586 }
587
588 self.iter_fold(init, flatten(fold))
589 }
590
591 #[inline]
592 #[rustc_inherit_overflow_checks]
593 default fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
594 #[inline]
595 #[rustc_inherit_overflow_checks]
596 fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
597 match iter.advance_by(n) {
598 Ok(()) => ControlFlow::Break(()),
599 Err(remaining) => ControlFlow::Continue(remaining.get()),
600 }
601 }
602
603 match self.iter_try_fold(n, advance) {
604 ControlFlow::Continue(remaining) => NonZero::new(remaining).map_or(Ok(()), Err),
605 _ => Ok(()),
606 }
607 }
608
609 #[inline]
610 default fn count(self) -> usize {
611 #[inline]
612 #[rustc_inherit_overflow_checks]
613 fn count<U: Iterator>(acc: usize, iter: U) -> usize {
614 acc + iter.count()
615 }
616
617 self.iter_fold(0, count)
618 }
619
620 #[inline]
621 default fn last(self) -> Option<Self::Item> {
622 #[inline]
623 fn last<U: Iterator>(last: Option<U::Item>, iter: U) -> Option<U::Item> {
624 iter.last().or(last)
625 }
626
627 self.iter_fold(None, last)
628 }
629}
630
631impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
633where
634 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
635 U: DoubleEndedIterator,
636{
637 #[inline]
638 default fn next_back(&mut self) -> Option<U::Item> {
639 loop {
640 if let elt @ Some(_) = and_then_or_clear(&mut self.backiter, |b| b.next_back()) {
641 return elt;
642 }
643 match self.iter.next_back() {
644 None => return and_then_or_clear(&mut self.frontiter, |f| f.next_back()),
645 Some(inner) => self.backiter = Some(inner.into_iter()),
646 }
647 }
648 }
649
650 #[inline]
651 default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
652 where
653 Self: Sized,
654 Fold: FnMut(Acc, Self::Item) -> R,
655 R: Try<Output = Acc>,
656 {
657 #[inline]
658 fn flatten<U: DoubleEndedIterator, Acc, R: Try<Output = Acc>>(
659 mut fold: impl FnMut(Acc, U::Item) -> R,
660 ) -> impl FnMut(Acc, &mut U) -> R {
661 move |acc, iter| iter.try_rfold(acc, &mut fold)
662 }
663
664 self.iter_try_rfold(init, flatten(fold))
665 }
666
667 #[inline]
668 default fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
669 where
670 Fold: FnMut(Acc, Self::Item) -> Acc,
671 {
672 #[inline]
673 fn flatten<U: DoubleEndedIterator, Acc>(
674 mut fold: impl FnMut(Acc, U::Item) -> Acc,
675 ) -> impl FnMut(Acc, U) -> Acc {
676 move |acc, iter| iter.rfold(acc, &mut fold)
677 }
678
679 self.iter_rfold(init, flatten(fold))
680 }
681
682 #[inline]
683 #[rustc_inherit_overflow_checks]
684 default fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
685 #[inline]
686 #[rustc_inherit_overflow_checks]
687 fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
688 match iter.advance_back_by(n) {
689 Ok(()) => ControlFlow::Break(()),
690 Err(remaining) => ControlFlow::Continue(remaining.get()),
691 }
692 }
693
694 match self.iter_try_rfold(n, advance) {
695 ControlFlow::Continue(remaining) => NonZero::new(remaining).map_or(Ok(()), Err),
696 _ => Ok(()),
697 }
698 }
699}
700
701unsafe impl<const N: usize, I, T> TrustedLen
702 for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter>
703where
704 I: TrustedLen<Item = [T; N]>,
705{
706}
707
708unsafe impl<'a, const N: usize, I, T> TrustedLen
709 for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter>
710where
711 I: TrustedLen<Item = &'a [T; N]>,
712{
713}
714
715unsafe impl<'a, const N: usize, I, T> TrustedLen
716 for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter>
717where
718 I: TrustedLen<Item = &'a mut [T; N]>,
719{
720}
721
722trait ConstSizeIntoIterator: IntoIterator {
723 fn size() -> Option<usize>;
725}
726
727impl<T> ConstSizeIntoIterator for T
728where
729 T: IntoIterator,
730{
731 #[inline]
732 default fn size() -> Option<usize> {
733 None
734 }
735}
736
737impl<T, const N: usize> ConstSizeIntoIterator for [T; N] {
738 #[inline]
739 fn size() -> Option<usize> {
740 Some(N)
741 }
742}
743
744impl<T, const N: usize> ConstSizeIntoIterator for &[T; N] {
745 #[inline]
746 fn size() -> Option<usize> {
747 Some(N)
748 }
749}
750
751impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
752 #[inline]
753 fn size() -> Option<usize> {
754 Some(N)
755 }
756}
757
758#[inline]
759fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
760 let x = f(opt.as_mut()?);
761 if x.is_none() {
762 *opt = None;
763 }
764 x
765}
766
767#[rustc_specialization_trait]
772trait OneShot {}
773
774impl<T> OneShot for Once<T> {}
776impl<F> OneShot for OnceWith<F> {}
777impl<T> OneShot for array::IntoIter<T, 1> {}
778impl<T> OneShot for option::IntoIter<T> {}
779impl<T> OneShot for option::Iter<'_, T> {}
780impl<T> OneShot for option::IterMut<'_, T> {}
781impl<T> OneShot for result::IntoIter<T> {}
782impl<T> OneShot for result::Iter<'_, T> {}
783impl<T> OneShot for result::IterMut<'_, T> {}
784
785impl<T> OneShot for Empty<T> {}
787impl<T> OneShot for array::IntoIter<T, 0> {}
788
789impl<I: OneShot> OneShot for Cloned<I> {}
792impl<I: OneShot> OneShot for Copied<I> {}
793impl<I: OneShot, P> OneShot for Filter<I, P> {}
794impl<I: OneShot, P> OneShot for FilterMap<I, P> {}
795impl<I: OneShot, F> OneShot for Map<I, F> {}
796
797impl<I: OneShot> OneShot for &mut I {}
800
801#[inline]
802fn into_item<I>(inner: I) -> Option<I::Item>
803where
804 I: IntoIterator<IntoIter: OneShot>,
805{
806 inner.into_iter().next()
807}
808
809#[inline]
810fn flatten_one<I: IntoIterator<IntoIter: OneShot>, Acc>(
811 mut fold: impl FnMut(Acc, I::Item) -> Acc,
812) -> impl FnMut(Acc, I) -> Acc {
813 move |acc, inner| match inner.into_iter().next() {
814 Some(item) => fold(acc, item),
815 None => acc,
816 }
817}
818
819#[inline]
820fn try_flatten_one<I: IntoIterator<IntoIter: OneShot>, Acc, R: Try<Output = Acc>>(
821 mut fold: impl FnMut(Acc, I::Item) -> R,
822) -> impl FnMut(Acc, I) -> R {
823 move |acc, inner| match inner.into_iter().next() {
824 Some(item) => fold(acc, item),
825 None => try { acc },
826 }
827}
828
829#[inline]
830fn advance_by_one<I>(n: NonZero<usize>, inner: I) -> Option<NonZero<usize>>
831where
832 I: IntoIterator<IntoIter: OneShot>,
833{
834 match inner.into_iter().next() {
835 Some(_) => NonZero::new(n.get() - 1),
836 None => Some(n),
837 }
838}
839
840impl<I, U> Iterator for FlattenCompat<I, U>
853where
854 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
855 U: Iterator + OneShot,
856{
857 #[inline]
858 fn next(&mut self) -> Option<U::Item> {
859 while let Some(inner) = self.iter.next() {
860 if let item @ Some(_) = inner.into_iter().next() {
861 return item;
862 }
863 }
864 None
865 }
866
867 #[inline]
868 fn size_hint(&self) -> (usize, Option<usize>) {
869 let (lower, upper) = self.iter.size_hint();
870 match <I::Item as ConstSizeIntoIterator>::size() {
871 Some(0) => (0, Some(0)),
872 Some(1) => (lower, upper),
873 _ => (0, upper),
874 }
875 }
876
877 #[inline]
878 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
879 where
880 Self: Sized,
881 Fold: FnMut(Acc, Self::Item) -> R,
882 R: Try<Output = Acc>,
883 {
884 self.iter.try_fold(init, try_flatten_one(fold))
885 }
886
887 #[inline]
888 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
889 where
890 Fold: FnMut(Acc, Self::Item) -> Acc,
891 {
892 self.iter.fold(init, flatten_one(fold))
893 }
894
895 #[inline]
896 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
897 if let Some(n) = NonZero::new(n) {
898 self.iter.try_fold(n, advance_by_one).map_or(Ok(()), Err)
899 } else {
900 self.iter.advance_by(0)
902 }
903 }
904
905 #[inline]
906 fn count(self) -> usize {
907 self.iter.filter_map(into_item).count()
908 }
909
910 #[inline]
911 fn last(self) -> Option<Self::Item> {
912 self.iter.filter_map(into_item).last()
913 }
914}
915
916impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
919where
920 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
921 U: DoubleEndedIterator + OneShot,
922{
923 #[inline]
924 fn next_back(&mut self) -> Option<U::Item> {
925 while let Some(inner) = self.iter.next_back() {
926 if let item @ Some(_) = inner.into_iter().next() {
927 return item;
928 }
929 }
930 None
931 }
932
933 #[inline]
934 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
935 where
936 Self: Sized,
937 Fold: FnMut(Acc, Self::Item) -> R,
938 R: Try<Output = Acc>,
939 {
940 self.iter.try_rfold(init, try_flatten_one(fold))
941 }
942
943 #[inline]
944 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
945 where
946 Fold: FnMut(Acc, Self::Item) -> Acc,
947 {
948 self.iter.rfold(init, flatten_one(fold))
949 }
950
951 #[inline]
952 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
953 if let Some(n) = NonZero::new(n) {
954 self.iter.try_rfold(n, advance_by_one).map_or(Ok(()), Err)
955 } else {
956 self.iter.advance_back_by(0)
958 }
959 }
960}