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