Skip to main content

core/iter/adapters/
flatten.rs

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/// An iterator that maps each element to an iterator, and yields the elements
11/// of the produced iterators.
12///
13/// This `struct` is created by [`Iterator::flat_map`]. See its documentation
14/// for more.
15#[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        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
176        unsafe { SourceIter::as_inner(&mut self.inner.iter) }
177    }
178}
179
180/// An iterator that flattens one level of nesting in an iterator of things
181/// that can be turned into iterators.
182///
183/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
184/// documentation for more.
185///
186/// [`flatten`]: Iterator::flatten()
187#[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
193#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
194const impl<I: [const] Iterator<Item: IntoIterator>> Flatten<I> {
195    pub(in super::super) fn new(iter: I) -> Flatten<I> {
196        Flatten { inner: FlattenCompat::new(iter) }
197    }
198}
199
200#[stable(feature = "iterator_flatten", since = "1.29.0")]
201impl<I, U> fmt::Debug for Flatten<I>
202where
203    I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
204    U: fmt::Debug + Iterator,
205{
206    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207        f.debug_struct("Flatten").field("inner", &self.inner).finish()
208    }
209}
210
211#[stable(feature = "iterator_flatten", since = "1.29.0")]
212impl<I, U> Clone for Flatten<I>
213where
214    I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
215    U: Clone + Iterator,
216{
217    fn clone(&self) -> Self {
218        Flatten { inner: self.inner.clone() }
219    }
220}
221
222#[stable(feature = "iterator_flatten", since = "1.29.0")]
223impl<I, U> Iterator for Flatten<I>
224where
225    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
226    U: Iterator,
227{
228    type Item = U::Item;
229
230    #[inline]
231    fn next(&mut self) -> Option<U::Item> {
232        self.inner.next()
233    }
234
235    #[inline]
236    fn size_hint(&self) -> (usize, Option<usize>) {
237        self.inner.size_hint()
238    }
239
240    #[inline]
241    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
242    where
243        Self: Sized,
244        Fold: FnMut(Acc, Self::Item) -> R,
245        R: Try<Output = Acc>,
246    {
247        self.inner.try_fold(init, fold)
248    }
249
250    #[inline]
251    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
252    where
253        Fold: FnMut(Acc, Self::Item) -> Acc,
254    {
255        self.inner.fold(init, fold)
256    }
257
258    #[inline]
259    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
260        self.inner.advance_by(n)
261    }
262
263    #[inline]
264    fn count(self) -> usize {
265        self.inner.count()
266    }
267
268    #[inline]
269    fn last(self) -> Option<Self::Item> {
270        self.inner.last()
271    }
272}
273
274#[stable(feature = "iterator_flatten", since = "1.29.0")]
275impl<I, U> DoubleEndedIterator for Flatten<I>
276where
277    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
278    U: DoubleEndedIterator,
279{
280    #[inline]
281    fn next_back(&mut self) -> Option<U::Item> {
282        self.inner.next_back()
283    }
284
285    #[inline]
286    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
287    where
288        Self: Sized,
289        Fold: FnMut(Acc, Self::Item) -> R,
290        R: Try<Output = Acc>,
291    {
292        self.inner.try_rfold(init, fold)
293    }
294
295    #[inline]
296    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
297    where
298        Fold: FnMut(Acc, Self::Item) -> Acc,
299    {
300        self.inner.rfold(init, fold)
301    }
302
303    #[inline]
304    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
305        self.inner.advance_back_by(n)
306    }
307}
308
309#[stable(feature = "iterator_flatten", since = "1.29.0")]
310impl<I, U> FusedIterator for Flatten<I>
311where
312    I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
313    U: Iterator,
314{
315}
316
317#[unstable(feature = "trusted_len", issue = "37572")]
318unsafe impl<I> TrustedLen for Flatten<I>
319where
320    I: Iterator<Item: IntoIterator>,
321    FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>: TrustedLen,
322{
323}
324
325#[unstable(issue = "none", feature = "inplace_iteration")]
326unsafe impl<I> SourceIter for Flatten<I>
327where
328    I: SourceIter + TrustedFused + Iterator,
329    <I as Iterator>::Item: IntoIterator,
330{
331    type Source = I::Source;
332
333    #[inline]
334    unsafe fn as_inner(&mut self) -> &mut I::Source {
335        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
336        unsafe { SourceIter::as_inner(&mut self.inner.iter) }
337    }
338}
339
340#[stable(feature = "default_iters", since = "1.70.0")]
341impl<I> Default for Flatten<I>
342where
343    I: Default + Iterator<Item: IntoIterator>,
344{
345    /// Creates a `Flatten` iterator from the default value of `I`.
346    ///
347    /// ```
348    /// # use core::slice;
349    /// # use std::iter::Flatten;
350    /// let iter: Flatten<slice::Iter<'_, [u8; 4]>> = Default::default();
351    /// assert_eq!(iter.count(), 0);
352    /// ```
353    fn default() -> Self {
354        Flatten::new(Default::default())
355    }
356}
357
358/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
359/// this type.
360#[derive(Clone, Debug)]
361#[unstable(feature = "trusted_len", issue = "37572")]
362#[ferrocene::prevalidated]
363struct FlattenCompat<I, U> {
364    iter: Fuse<I>,
365    frontiter: Option<U>,
366    backiter: Option<U>,
367}
368
369#[rustc_const_unstable(feature = "const_iter", issue = "92476")]
370const impl<I, U> FlattenCompat<I, U>
371where
372    I: [const] Iterator,
373{
374    /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
375    #[ferrocene::prevalidated]
376    fn new(iter: I) -> FlattenCompat<I, U> {
377        FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
378    }
379}
380
381impl<I, U> FlattenCompat<I, U>
382where
383    I: Iterator<Item: IntoIterator<IntoIter = U>>,
384{
385    /// Folds the inner iterators into an accumulator by applying an operation.
386    ///
387    /// Folds over the inner iterators, not over their elements. Is used by the `fold`, `count`,
388    /// and `last` methods.
389    #[inline]
390    fn iter_fold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
391    where
392        Fold: FnMut(Acc, U) -> Acc,
393    {
394        #[inline]
395        fn flatten<T: IntoIterator, Acc>(
396            fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
397        ) -> impl FnMut(Acc, T) -> Acc + '_ {
398            move |acc, iter| fold(acc, iter.into_iter())
399        }
400
401        if let Some(iter) = self.frontiter {
402            acc = fold(acc, iter);
403        }
404
405        acc = self.iter.fold(acc, flatten(&mut fold));
406
407        if let Some(iter) = self.backiter {
408            acc = fold(acc, iter);
409        }
410
411        acc
412    }
413
414    /// Folds over the inner iterators as long as the given function returns successfully,
415    /// always storing the most recent inner iterator in `self.frontiter`.
416    ///
417    /// Folds over the inner iterators, not over their elements. Is used by the `try_fold` and
418    /// `advance_by` methods.
419    #[inline]
420    fn iter_try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
421    where
422        Fold: FnMut(Acc, &mut U) -> R,
423        R: Try<Output = Acc>,
424    {
425        #[inline]
426        fn flatten<'a, T: IntoIterator, Acc, R: Try<Output = Acc>>(
427            frontiter: &'a mut Option<T::IntoIter>,
428            fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
429        ) -> impl FnMut(Acc, T) -> R + 'a {
430            move |acc, iter| fold(acc, frontiter.insert(iter.into_iter()))
431        }
432
433        if let Some(iter) = &mut self.frontiter {
434            acc = fold(acc, iter)?;
435        }
436        self.frontiter = None;
437
438        acc = self.iter.try_fold(acc, flatten(&mut self.frontiter, &mut fold))?;
439        self.frontiter = None;
440
441        if let Some(iter) = &mut self.backiter {
442            acc = fold(acc, iter)?;
443        }
444        self.backiter = None;
445
446        try { acc }
447    }
448}
449
450impl<I, U> FlattenCompat<I, U>
451where
452    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U>>,
453{
454    /// Folds the inner iterators into an accumulator by applying an operation, starting form the
455    /// back.
456    ///
457    /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method.
458    #[inline]
459    fn iter_rfold<Acc, Fold>(self, mut acc: Acc, mut fold: Fold) -> Acc
460    where
461        Fold: FnMut(Acc, U) -> Acc,
462    {
463        #[inline]
464        fn flatten<T: IntoIterator, Acc>(
465            fold: &mut impl FnMut(Acc, T::IntoIter) -> Acc,
466        ) -> impl FnMut(Acc, T) -> Acc + '_ {
467            move |acc, iter| fold(acc, iter.into_iter())
468        }
469
470        if let Some(iter) = self.backiter {
471            acc = fold(acc, iter);
472        }
473
474        acc = self.iter.rfold(acc, flatten(&mut fold));
475
476        if let Some(iter) = self.frontiter {
477            acc = fold(acc, iter);
478        }
479
480        acc
481    }
482
483    /// Folds over the inner iterators in reverse order as long as the given function returns
484    /// successfully, always storing the most recent inner iterator in `self.backiter`.
485    ///
486    /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
487    /// `advance_back_by` methods.
488    #[inline]
489    fn iter_try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, mut fold: Fold) -> R
490    where
491        Fold: FnMut(Acc, &mut U) -> R,
492        R: Try<Output = Acc>,
493    {
494        #[inline]
495        fn flatten<'a, T: IntoIterator, Acc, R: Try>(
496            backiter: &'a mut Option<T::IntoIter>,
497            fold: &'a mut impl FnMut(Acc, &mut T::IntoIter) -> R,
498        ) -> impl FnMut(Acc, T) -> R + 'a {
499            move |acc, iter| fold(acc, backiter.insert(iter.into_iter()))
500        }
501
502        if let Some(iter) = &mut self.backiter {
503            acc = fold(acc, iter)?;
504        }
505        self.backiter = None;
506
507        acc = self.iter.try_rfold(acc, flatten(&mut self.backiter, &mut fold))?;
508        self.backiter = None;
509
510        if let Some(iter) = &mut self.frontiter {
511            acc = fold(acc, iter)?;
512        }
513        self.frontiter = None;
514
515        try { acc }
516    }
517}
518
519// See also the `OneShot` specialization below.
520impl<I, U> Iterator for FlattenCompat<I, U>
521where
522    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
523    U: Iterator,
524{
525    type Item = U::Item;
526
527    #[inline]
528    default fn next(&mut self) -> Option<U::Item> {
529        loop {
530            if let elt @ Some(_) = and_then_or_clear(&mut self.frontiter, Iterator::next) {
531                return elt;
532            }
533            match self.iter.next() {
534                None => return and_then_or_clear(&mut self.backiter, Iterator::next),
535                Some(inner) => self.frontiter = Some(inner.into_iter()),
536            }
537        }
538    }
539
540    #[inline]
541    default fn size_hint(&self) -> (usize, Option<usize>) {
542        let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
543        let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
544        let lo = flo.saturating_add(blo);
545
546        if let Some(fixed_size) = <<I as Iterator>::Item as ConstSizeIntoIterator>::size() {
547            let (lower, upper) = self.iter.size_hint();
548
549            let lower = lower.saturating_mul(fixed_size).saturating_add(lo);
550            let upper =
551                try { fhi?.checked_add(bhi?)?.checked_add(fixed_size.checked_mul(upper?)?)? };
552
553            return (lower, upper);
554        }
555
556        match (self.iter.size_hint(), fhi, bhi) {
557            ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
558            _ => (lo, None),
559        }
560    }
561
562    #[inline]
563    default fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
564    where
565        Self: Sized,
566        Fold: FnMut(Acc, Self::Item) -> R,
567        R: Try<Output = Acc>,
568    {
569        #[inline]
570        fn flatten<U: Iterator, Acc, R: Try<Output = Acc>>(
571            mut fold: impl FnMut(Acc, U::Item) -> R,
572        ) -> impl FnMut(Acc, &mut U) -> R {
573            move |acc, iter| iter.try_fold(acc, &mut fold)
574        }
575
576        self.iter_try_fold(init, flatten(fold))
577    }
578
579    #[inline]
580    default fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
581    where
582        Fold: FnMut(Acc, Self::Item) -> Acc,
583    {
584        #[inline]
585        fn flatten<U: Iterator, Acc>(
586            mut fold: impl FnMut(Acc, U::Item) -> Acc,
587        ) -> impl FnMut(Acc, U) -> Acc {
588            move |acc, iter| iter.fold(acc, &mut fold)
589        }
590
591        self.iter_fold(init, flatten(fold))
592    }
593
594    #[inline]
595    #[rustc_inherit_overflow_checks]
596    default fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
597        #[inline]
598        #[rustc_inherit_overflow_checks]
599        fn advance<U: Iterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
600            match iter.advance_by(n) {
601                Ok(()) => ControlFlow::Break(()),
602                Err(remaining) => ControlFlow::Continue(remaining.get()),
603            }
604        }
605
606        match self.iter_try_fold(n, advance) {
607            ControlFlow::Continue(remaining) => NonZero::new(remaining).map_or(Ok(()), Err),
608            _ => Ok(()),
609        }
610    }
611
612    #[inline]
613    default fn count(self) -> usize {
614        #[inline]
615        #[rustc_inherit_overflow_checks]
616        fn count<U: Iterator>(acc: usize, iter: U) -> usize {
617            acc + iter.count()
618        }
619
620        self.iter_fold(0, count)
621    }
622
623    #[inline]
624    default fn last(self) -> Option<Self::Item> {
625        #[inline]
626        fn last<U: Iterator>(last: Option<U::Item>, iter: U) -> Option<U::Item> {
627            iter.last().or(last)
628        }
629
630        self.iter_fold(None, last)
631    }
632}
633
634// See also the `OneShot` specialization below.
635impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
636where
637    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
638    U: DoubleEndedIterator,
639{
640    #[inline]
641    default fn next_back(&mut self) -> Option<U::Item> {
642        loop {
643            if let elt @ Some(_) = and_then_or_clear(&mut self.backiter, |b| b.next_back()) {
644                return elt;
645            }
646            match self.iter.next_back() {
647                None => return and_then_or_clear(&mut self.frontiter, |f| f.next_back()),
648                Some(inner) => self.backiter = Some(inner.into_iter()),
649            }
650        }
651    }
652
653    #[inline]
654    default fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
655    where
656        Self: Sized,
657        Fold: FnMut(Acc, Self::Item) -> R,
658        R: Try<Output = Acc>,
659    {
660        #[inline]
661        fn flatten<U: DoubleEndedIterator, Acc, R: Try<Output = Acc>>(
662            mut fold: impl FnMut(Acc, U::Item) -> R,
663        ) -> impl FnMut(Acc, &mut U) -> R {
664            move |acc, iter| iter.try_rfold(acc, &mut fold)
665        }
666
667        self.iter_try_rfold(init, flatten(fold))
668    }
669
670    #[inline]
671    default fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
672    where
673        Fold: FnMut(Acc, Self::Item) -> Acc,
674    {
675        #[inline]
676        fn flatten<U: DoubleEndedIterator, Acc>(
677            mut fold: impl FnMut(Acc, U::Item) -> Acc,
678        ) -> impl FnMut(Acc, U) -> Acc {
679            move |acc, iter| iter.rfold(acc, &mut fold)
680        }
681
682        self.iter_rfold(init, flatten(fold))
683    }
684
685    #[inline]
686    #[rustc_inherit_overflow_checks]
687    default fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
688        #[inline]
689        #[rustc_inherit_overflow_checks]
690        fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), usize> {
691            match iter.advance_back_by(n) {
692                Ok(()) => ControlFlow::Break(()),
693                Err(remaining) => ControlFlow::Continue(remaining.get()),
694            }
695        }
696
697        match self.iter_try_rfold(n, advance) {
698            ControlFlow::Continue(remaining) => NonZero::new(remaining).map_or(Ok(()), Err),
699            _ => Ok(()),
700        }
701    }
702}
703
704unsafe impl<const N: usize, I, T> TrustedLen
705    for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter>
706where
707    I: TrustedLen<Item = [T; N]>,
708{
709}
710
711unsafe impl<'a, const N: usize, I, T> TrustedLen
712    for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter>
713where
714    I: TrustedLen<Item = &'a [T; N]>,
715{
716}
717
718unsafe impl<'a, const N: usize, I, T> TrustedLen
719    for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter>
720where
721    I: TrustedLen<Item = &'a mut [T; N]>,
722{
723}
724
725trait ConstSizeIntoIterator: IntoIterator {
726    // FIXME(#31844): convert to an associated const once specialization supports that
727    fn size() -> Option<usize>;
728}
729
730impl<T> ConstSizeIntoIterator for T
731where
732    T: IntoIterator,
733{
734    #[inline]
735    default fn size() -> Option<usize> {
736        None
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 &[T; N] {
748    #[inline]
749    fn size() -> Option<usize> {
750        Some(N)
751    }
752}
753
754impl<T, const N: usize> ConstSizeIntoIterator for &mut [T; N] {
755    #[inline]
756    fn size() -> Option<usize> {
757        Some(N)
758    }
759}
760
761#[inline]
762fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
763    let x = f(opt.as_mut()?);
764    if x.is_none() {
765        *opt = None;
766    }
767    x
768}
769
770/// Specialization trait for iterator types that never return more than one item.
771///
772/// Note that we still have to deal with the possibility that the iterator was
773/// already exhausted before it came into our control.
774#[rustc_specialization_trait]
775trait OneShot {}
776
777// These all have exactly one item, if not already consumed.
778impl<T> OneShot for Once<T> {}
779impl<F> OneShot for OnceWith<F> {}
780impl<T> OneShot for array::IntoIter<T, 1> {}
781impl<T> OneShot for option::IntoIter<T> {}
782impl<T> OneShot for option::Iter<'_, T> {}
783impl<T> OneShot for option::IterMut<'_, T> {}
784impl<T> OneShot for result::IntoIter<T> {}
785impl<T> OneShot for result::Iter<'_, T> {}
786impl<T> OneShot for result::IterMut<'_, T> {}
787
788// These are always empty, which is fine to optimize too.
789impl<T> OneShot for Empty<T> {}
790impl<T> OneShot for array::IntoIter<T, 0> {}
791
792// These adapters never increase the number of items.
793// (There are more possible, but for now this matches BoundedSize above.)
794impl<I: OneShot> OneShot for Cloned<I> {}
795impl<I: OneShot> OneShot for Copied<I> {}
796impl<I: OneShot, P> OneShot for Filter<I, P> {}
797impl<I: OneShot, P> OneShot for FilterMap<I, P> {}
798impl<I: OneShot, F> OneShot for Map<I, F> {}
799
800// Blanket impls pass this property through as well
801// (but we can't do `Box<I>` unless we expose this trait to alloc)
802impl<I: OneShot> OneShot for &mut I {}
803
804#[inline]
805fn into_item<I>(inner: I) -> Option<I::Item>
806where
807    I: IntoIterator<IntoIter: OneShot>,
808{
809    inner.into_iter().next()
810}
811
812#[inline]
813fn flatten_one<I: IntoIterator<IntoIter: OneShot>, Acc>(
814    mut fold: impl FnMut(Acc, I::Item) -> Acc,
815) -> impl FnMut(Acc, I) -> Acc {
816    move |acc, inner| match inner.into_iter().next() {
817        Some(item) => fold(acc, item),
818        None => acc,
819    }
820}
821
822#[inline]
823fn try_flatten_one<I: IntoIterator<IntoIter: OneShot>, Acc, R: Try<Output = Acc>>(
824    mut fold: impl FnMut(Acc, I::Item) -> R,
825) -> impl FnMut(Acc, I) -> R {
826    move |acc, inner| match inner.into_iter().next() {
827        Some(item) => fold(acc, item),
828        None => try { acc },
829    }
830}
831
832#[inline]
833fn advance_by_one<I>(n: NonZero<usize>, inner: I) -> Option<NonZero<usize>>
834where
835    I: IntoIterator<IntoIter: OneShot>,
836{
837    match inner.into_iter().next() {
838        Some(_) => NonZero::new(n.get() - 1),
839        None => Some(n),
840    }
841}
842
843// Specialization: When the inner iterator `U` never returns more than one item, the `frontiter` and
844// `backiter` states are a waste, because they'll always have already consumed their item. So in
845// this impl, we completely ignore them and just focus on `self.iter`, and we only call the inner
846// `U::next()` one time.
847//
848// It's mostly fine if we accidentally mix this with the more generic impls, e.g. by forgetting to
849// specialize one of the methods. If the other impl did set the front or back, we wouldn't see it
850// here, but it would be empty anyway; and if the other impl looked for a front or back that we
851// didn't bother setting, it would just see `None` (or a previous empty) and move on.
852//
853// An exception to that is `advance_by(0)` and `advance_back_by(0)`, where the generic impls may set
854// `frontiter` or `backiter` without consuming the item, so we **must** override those.
855impl<I, U> Iterator for FlattenCompat<I, U>
856where
857    I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
858    U: Iterator + OneShot,
859{
860    #[inline]
861    fn next(&mut self) -> Option<U::Item> {
862        while let Some(inner) = self.iter.next() {
863            if let item @ Some(_) = inner.into_iter().next() {
864                return item;
865            }
866        }
867        None
868    }
869
870    #[inline]
871    fn size_hint(&self) -> (usize, Option<usize>) {
872        let (lower, upper) = self.iter.size_hint();
873        match <I::Item as ConstSizeIntoIterator>::size() {
874            Some(0) => (0, Some(0)),
875            Some(1) => (lower, upper),
876            _ => (0, upper),
877        }
878    }
879
880    #[inline]
881    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
882    where
883        Self: Sized,
884        Fold: FnMut(Acc, Self::Item) -> R,
885        R: Try<Output = Acc>,
886    {
887        self.iter.try_fold(init, try_flatten_one(fold))
888    }
889
890    #[inline]
891    fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
892    where
893        Fold: FnMut(Acc, Self::Item) -> Acc,
894    {
895        self.iter.fold(init, flatten_one(fold))
896    }
897
898    #[inline]
899    fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
900        if let Some(n) = NonZero::new(n) {
901            self.iter.try_fold(n, advance_by_one).map_or(Ok(()), Err)
902        } else {
903            // Just advance the outer iterator
904            self.iter.advance_by(0)
905        }
906    }
907
908    #[inline]
909    fn count(self) -> usize {
910        self.iter.filter_map(into_item).count()
911    }
912
913    #[inline]
914    fn last(self) -> Option<Self::Item> {
915        self.iter.filter_map(into_item).last()
916    }
917}
918
919// Note: We don't actually care about `U: DoubleEndedIterator`, since forward and backward are the
920// same for a one-shot iterator, but we have to keep that to match the default specialization.
921impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
922where
923    I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
924    U: DoubleEndedIterator + OneShot,
925{
926    #[inline]
927    fn next_back(&mut self) -> Option<U::Item> {
928        while let Some(inner) = self.iter.next_back() {
929            if let item @ Some(_) = inner.into_iter().next() {
930                return item;
931            }
932        }
933        None
934    }
935
936    #[inline]
937    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
938    where
939        Self: Sized,
940        Fold: FnMut(Acc, Self::Item) -> R,
941        R: Try<Output = Acc>,
942    {
943        self.iter.try_rfold(init, try_flatten_one(fold))
944    }
945
946    #[inline]
947    fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
948    where
949        Fold: FnMut(Acc, Self::Item) -> Acc,
950    {
951        self.iter.rfold(init, flatten_one(fold))
952    }
953
954    #[inline]
955    fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
956        if let Some(n) = NonZero::new(n) {
957            self.iter.try_rfold(n, advance_by_one).map_or(Ok(()), Err)
958        } else {
959            // Just advance the outer iterator
960            self.iter.advance_back_by(0)
961        }
962    }
963}