1use crate::iter::adapters::SourceIter;
2use crate::iter::{
3 Cloned, Copied, Empty, Filter, FilterMap, Fuse, FusedIterator, Map, Once, OnceWith,
4 TrustedFused, TrustedLen,
5};
6use crate::num::NonZero;
7use crate::ops::{ControlFlow, Try};
8use crate::{array, fmt, option, result};
9
10#[must_use = "iterators are lazy and do nothing unless consumed"]
16#[stable(feature = "rust1", since = "1.0.0")]
17#[ferrocene::prevalidated]
18pub struct FlatMap<I, U: IntoIterator, F> {
19 inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
20}
21
22impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
23 #[ferrocene::prevalidated]
24 pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
25 FlatMap { inner: FlattenCompat::new(iter.map(f)) }
26 }
27
28 #[ferrocene::prevalidated]
29 pub(crate) fn into_parts(self) -> (Option<U::IntoIter>, Option<I>, Option<U::IntoIter>) {
30 (
31 self.inner.frontiter,
32 self.inner.iter.into_inner().map(Map::into_inner),
33 self.inner.backiter,
34 )
35 }
36}
37
38#[stable(feature = "rust1", since = "1.0.0")]
39impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
40where
41 U: Clone + IntoIterator<IntoIter: Clone>,
42{
43 #[ferrocene::prevalidated]
44 fn clone(&self) -> Self {
45 FlatMap { inner: self.inner.clone() }
46 }
47}
48
49#[stable(feature = "core_impl_debug", since = "1.9.0")]
50impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
51where
52 U: IntoIterator<IntoIter: fmt::Debug>,
53{
54 #[ferrocene::prevalidated]
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 f.debug_struct("FlatMap").field("inner", &self.inner).finish()
57 }
58}
59
60#[stable(feature = "rust1", since = "1.0.0")]
61impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
62where
63 F: FnMut(I::Item) -> U,
64{
65 type Item = U::Item;
66
67 #[inline]
68 fn next(&mut self) -> Option<U::Item> {
69 self.inner.next()
70 }
71
72 #[inline]
73 fn size_hint(&self) -> (usize, Option<usize>) {
74 self.inner.size_hint()
75 }
76
77 #[inline]
78 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
79 where
80 Self: Sized,
81 Fold: FnMut(Acc, Self::Item) -> R,
82 R: Try<Output = Acc>,
83 {
84 self.inner.try_fold(init, fold)
85 }
86
87 #[inline]
88 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
89 where
90 Fold: FnMut(Acc, Self::Item) -> Acc,
91 {
92 self.inner.fold(init, fold)
93 }
94
95 #[inline]
96 fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
97 self.inner.advance_by(n)
98 }
99
100 #[inline]
101 fn count(self) -> usize {
102 self.inner.count()
103 }
104
105 #[inline]
106 fn last(self) -> Option<Self::Item> {
107 self.inner.last()
108 }
109}
110
111#[stable(feature = "rust1", since = "1.0.0")]
112impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
113where
114 F: FnMut(I::Item) -> U,
115 U: IntoIterator<IntoIter: DoubleEndedIterator>,
116{
117 #[inline]
118 fn next_back(&mut self) -> Option<U::Item> {
119 self.inner.next_back()
120 }
121
122 #[inline]
123 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
124 where
125 Self: Sized,
126 Fold: FnMut(Acc, Self::Item) -> R,
127 R: Try<Output = Acc>,
128 {
129 self.inner.try_rfold(init, fold)
130 }
131
132 #[inline]
133 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
134 where
135 Fold: FnMut(Acc, Self::Item) -> Acc,
136 {
137 self.inner.rfold(init, fold)
138 }
139
140 #[inline]
141 fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>> {
142 self.inner.advance_back_by(n)
143 }
144}
145
146#[stable(feature = "fused", since = "1.26.0")]
147impl<I, U, F> FusedIterator for FlatMap<I, U, F>
148where
149 I: FusedIterator,
150 U: IntoIterator,
151 F: FnMut(I::Item) -> U,
152{
153}
154
155#[unstable(feature = "trusted_len", issue = "37572")]
156unsafe impl<I, U, F> TrustedLen for FlatMap<I, U, F>
157where
158 I: Iterator,
159 U: IntoIterator,
160 F: FnMut(I::Item) -> U,
161 FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>: TrustedLen,
162{
163}
164
165#[unstable(issue = "none", feature = "inplace_iteration")]
166unsafe impl<I, U, F> SourceIter for FlatMap<I, U, F>
167where
168 I: SourceIter + TrustedFused,
169 U: IntoIterator,
170{
171 type Source = I::Source;
172
173 #[inline]
174 unsafe fn as_inner(&mut self) -> &mut I::Source {
175 unsafe { SourceIter::as_inner(&mut self.inner.iter) }
177 }
178}
179
180#[must_use = "iterators are lazy and do nothing unless consumed"]
188#[stable(feature = "iterator_flatten", since = "1.29.0")]
189pub struct Flatten<I: Iterator<Item: IntoIterator>> {
190 inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
191}
192
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 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 fn default() -> Self {
354 Flatten::new(Default::default())
355 }
356}
357
358#[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 #[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 #[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 #[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 #[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 #[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
519impl<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
634impl<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 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#[rustc_specialization_trait]
775trait OneShot {}
776
777impl<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
788impl<T> OneShot for Empty<T> {}
790impl<T> OneShot for array::IntoIter<T, 0> {}
791
792impl<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
800impl<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
843impl<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 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
919impl<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 self.iter.advance_back_by(0)
961 }
962 }
963}