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
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        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
335        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    /// Creates a `Flatten` iterator from the default value of `I`.
345    ///
346    /// ```
347    /// # use core::slice;
348    /// # use std::iter::Flatten;
349    /// let iter: Flatten<slice::Iter<'_, [u8; 4]>> = Default::default();
350    /// assert_eq!(iter.count(), 0);
351    /// ```
352    fn default() -> Self {
353        Flatten::new(Default::default())
354    }
355}
356
357/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
358/// this type.
359#[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    /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
372    #[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    /// Folds the inner iterators into an accumulator by applying an operation.
383    ///
384    /// Folds over the inner iterators, not over their elements. Is used by the `fold`, `count`,
385    /// and `last` methods.
386    #[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    /// Folds over the inner iterators as long as the given function returns successfully,
412    /// always storing the most recent inner iterator in `self.frontiter`.
413    ///
414    /// Folds over the inner iterators, not over their elements. Is used by the `try_fold` and
415    /// `advance_by` methods.
416    #[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    /// Folds the inner iterators into an accumulator by applying an operation, starting form the
452    /// back.
453    ///
454    /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method.
455    #[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    /// Folds over the inner iterators in reverse order as long as the given function returns
481    /// successfully, always storing the most recent inner iterator in `self.backiter`.
482    ///
483    /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
484    /// `advance_back_by` methods.
485    #[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
516// See also the `OneShot` specialization below.
517impl<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
631// See also the `OneShot` specialization below.
632impl<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    // FIXME(#31844): convert to an associated const once specialization supports that
724    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/// Specialization trait for iterator types that never return more than one item.
768///
769/// Note that we still have to deal with the possibility that the iterator was
770/// already exhausted before it came into our control.
771#[rustc_specialization_trait]
772trait OneShot {}
773
774// These all have exactly one item, if not already consumed.
775impl<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
785// These are always empty, which is fine to optimize too.
786impl<T> OneShot for Empty<T> {}
787impl<T> OneShot for array::IntoIter<T, 0> {}
788
789// These adapters never increase the number of items.
790// (There are more possible, but for now this matches BoundedSize above.)
791impl<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
797// Blanket impls pass this property through as well
798// (but we can't do `Box<I>` unless we expose this trait to alloc)
799impl<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
840// Specialization: When the inner iterator `U` never returns more than one item, the `frontiter` and
841// `backiter` states are a waste, because they'll always have already consumed their item. So in
842// this impl, we completely ignore them and just focus on `self.iter`, and we only call the inner
843// `U::next()` one time.
844//
845// It's mostly fine if we accidentally mix this with the more generic impls, e.g. by forgetting to
846// specialize one of the methods. If the other impl did set the front or back, we wouldn't see it
847// here, but it would be empty anyway; and if the other impl looked for a front or back that we
848// didn't bother setting, it would just see `None` (or a previous empty) and move on.
849//
850// An exception to that is `advance_by(0)` and `advance_back_by(0)`, where the generic impls may set
851// `frontiter` or `backiter` without consuming the item, so we **must** override those.
852impl<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            // Just advance the outer iterator
901            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
916// Note: We don't actually care about `U: DoubleEndedIterator`, since forward and backward are the
917// same for a one-shot iterator, but we have to keep that to match the default specialization.
918impl<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            // Just advance the outer iterator
957            self.iter.advance_back_by(0)
958        }
959    }
960}