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")]
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        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
171        unsafe { SourceIter::as_inner(&mut self.inner.iter) }
172    }
173}
174
175/// An iterator that flattens one level of nesting in an iterator of things
176/// that can be turned into iterators.
177///
178/// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
179/// documentation for more.
180///
181/// [`flatten`]: Iterator::flatten()
182#[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        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
331        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    /// Creates a `Flatten` iterator from the default value of `I`.
341    ///
342    /// ```
343    /// # use core::slice;
344    /// # use std::iter::Flatten;
345    /// let iter: Flatten<slice::Iter<'_, [u8; 4]>> = Default::default();
346    /// assert_eq!(iter.count(), 0);
347    /// ```
348    fn default() -> Self {
349        Flatten::new(Default::default())
350    }
351}
352
353/// Real logic of both `Flatten` and `FlatMap` which simply delegate to
354/// this type.
355#[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    /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
369    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    /// Folds the inner iterators into an accumulator by applying an operation.
379    ///
380    /// Folds over the inner iterators, not over their elements. Is used by the `fold`, `count`,
381    /// and `last` methods.
382    #[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    /// Folds over the inner iterators as long as the given function returns successfully,
408    /// always storing the most recent inner iterator in `self.frontiter`.
409    ///
410    /// Folds over the inner iterators, not over their elements. Is used by the `try_fold` and
411    /// `advance_by` methods.
412    #[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    /// Folds the inner iterators into an accumulator by applying an operation, starting form the
448    /// back.
449    ///
450    /// Folds over the inner iterators, not over their elements. Is used by the `rfold` method.
451    #[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    /// Folds over the inner iterators in reverse order as long as the given function returns
477    /// successfully, always storing the most recent inner iterator in `self.backiter`.
478    ///
479    /// Folds over the inner iterators, not over their elements. Is used by the `try_rfold` and
480    /// `advance_back_by` methods.
481    #[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
512// See also the `OneShot` specialization below.
513impl<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
627// See also the `OneShot` specialization below.
628impl<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    // FIXME(#31844): convert to an associated const once specialization supports that
720    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/// Specialization trait for iterator types that never return more than one item.
764///
765/// Note that we still have to deal with the possibility that the iterator was
766/// already exhausted before it came into our control.
767#[rustc_specialization_trait]
768trait OneShot {}
769
770// These all have exactly one item, if not already consumed.
771impl<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
781// These are always empty, which is fine to optimize too.
782impl<T> OneShot for Empty<T> {}
783impl<T> OneShot for array::IntoIter<T, 0> {}
784
785// These adapters never increase the number of items.
786// (There are more possible, but for now this matches BoundedSize above.)
787impl<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
793// Blanket impls pass this property through as well
794// (but we can't do `Box<I>` unless we expose this trait to alloc)
795impl<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
836// Specialization: When the inner iterator `U` never returns more than one item, the `frontiter` and
837// `backiter` states are a waste, because they'll always have already consumed their item. So in
838// this impl, we completely ignore them and just focus on `self.iter`, and we only call the inner
839// `U::next()` one time.
840//
841// It's mostly fine if we accidentally mix this with the more generic impls, e.g. by forgetting to
842// specialize one of the methods. If the other impl did set the front or back, we wouldn't see it
843// here, but it would be empty anyway; and if the other impl looked for a front or back that we
844// didn't bother setting, it would just see `None` (or a previous empty) and move on.
845//
846// An exception to that is `advance_by(0)` and `advance_back_by(0)`, where the generic impls may set
847// `frontiter` or `backiter` without consuming the item, so we **must** override those.
848impl<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            // Just advance the outer iterator
897            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
912// Note: We don't actually care about `U: DoubleEndedIterator`, since forward and backward are the
913// same for a one-shot iterator, but we have to keep that to match the default specialization.
914impl<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            // Just advance the outer iterator
953            self.iter.advance_back_by(0)
954        }
955    }
956}