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