2 use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map};
5 /// An iterator that maps each element to an iterator, and yields the elements
6 /// of the produced iterators.
8 /// This `struct` is created by [`Iterator::flat_map`]. See its documentation
10 #[must_use = "iterators are lazy and do nothing unless consumed"]
11 #[stable(feature = "rust1", since = "1.0.0")]
12 pub struct FlatMap<I, U: IntoIterator, F> {
13 inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
16 impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
17 pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
18 FlatMap { inner: FlattenCompat::new(iter.map(f)) }
22 #[stable(feature = "rust1", since = "1.0.0")]
23 impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
25 U: Clone + IntoIterator<IntoIter: Clone>,
27 fn clone(&self) -> Self {
28 FlatMap { inner: self.inner.clone() }
32 #[stable(feature = "core_impl_debug", since = "1.9.0")]
33 impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
35 U: IntoIterator<IntoIter: fmt::Debug>,
37 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38 f.debug_struct("FlatMap").field("inner", &self.inner).finish()
42 #[stable(feature = "rust1", since = "1.0.0")]
43 impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
45 F: FnMut(I::Item) -> U,
50 fn next(&mut self) -> Option<U::Item> {
55 fn size_hint(&self) -> (usize, Option<usize>) {
56 self.inner.size_hint()
60 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
63 Fold: FnMut(Acc, Self::Item) -> R,
66 self.inner.try_fold(init, fold)
70 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
72 Fold: FnMut(Acc, Self::Item) -> Acc,
74 self.inner.fold(init, fold)
78 #[stable(feature = "rust1", since = "1.0.0")]
79 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
81 F: FnMut(I::Item) -> U,
82 U: IntoIterator<IntoIter: DoubleEndedIterator>,
85 fn next_back(&mut self) -> Option<U::Item> {
86 self.inner.next_back()
90 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
93 Fold: FnMut(Acc, Self::Item) -> R,
96 self.inner.try_rfold(init, fold)
100 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
102 Fold: FnMut(Acc, Self::Item) -> Acc,
104 self.inner.rfold(init, fold)
108 #[stable(feature = "fused", since = "1.26.0")]
109 impl<I, U, F> FusedIterator for FlatMap<I, U, F>
113 F: FnMut(I::Item) -> U,
117 /// An iterator that flattens one level of nesting in an iterator of things
118 /// that can be turned into iterators.
120 /// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
121 /// documentation for more.
123 /// [`flatten`]: Iterator::flatten
124 /// [`Iterator`]: trait.Iterator.html
125 #[must_use = "iterators are lazy and do nothing unless consumed"]
126 #[stable(feature = "iterator_flatten", since = "1.29.0")]
127 pub struct Flatten<I: Iterator<Item: IntoIterator>> {
128 inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
131 impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
132 pub(in super::super) fn new(iter: I) -> Flatten<I> {
133 Flatten { inner: FlattenCompat::new(iter) }
137 #[stable(feature = "iterator_flatten", since = "1.29.0")]
138 impl<I, U> fmt::Debug for Flatten<I>
140 I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
141 U: fmt::Debug + Iterator,
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 f.debug_struct("Flatten").field("inner", &self.inner).finish()
148 #[stable(feature = "iterator_flatten", since = "1.29.0")]
149 impl<I, U> Clone for Flatten<I>
151 I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
154 fn clone(&self) -> Self {
155 Flatten { inner: self.inner.clone() }
159 #[stable(feature = "iterator_flatten", since = "1.29.0")]
160 impl<I, U> Iterator for Flatten<I>
162 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
168 fn next(&mut self) -> Option<U::Item> {
173 fn size_hint(&self) -> (usize, Option<usize>) {
174 self.inner.size_hint()
178 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
181 Fold: FnMut(Acc, Self::Item) -> R,
184 self.inner.try_fold(init, fold)
188 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
190 Fold: FnMut(Acc, Self::Item) -> Acc,
192 self.inner.fold(init, fold)
196 #[stable(feature = "iterator_flatten", since = "1.29.0")]
197 impl<I, U> DoubleEndedIterator for Flatten<I>
199 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
200 U: DoubleEndedIterator,
203 fn next_back(&mut self) -> Option<U::Item> {
204 self.inner.next_back()
208 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
211 Fold: FnMut(Acc, Self::Item) -> R,
214 self.inner.try_rfold(init, fold)
218 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
220 Fold: FnMut(Acc, Self::Item) -> Acc,
222 self.inner.rfold(init, fold)
226 #[stable(feature = "iterator_flatten", since = "1.29.0")]
227 impl<I, U> FusedIterator for Flatten<I>
229 I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
234 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
236 #[derive(Clone, Debug)]
237 struct FlattenCompat<I, U> {
239 frontiter: Option<U>,
242 impl<I, U> FlattenCompat<I, U>
246 /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
247 fn new(iter: I) -> FlattenCompat<I, U> {
248 FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
252 impl<I, U> Iterator for FlattenCompat<I, U>
254 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
260 fn next(&mut self) -> Option<U::Item> {
262 if let Some(ref mut inner) = self.frontiter {
264 None => self.frontiter = None,
265 elt @ Some(_) => return elt,
268 match self.iter.next() {
269 None => return self.backiter.as_mut()?.next(),
270 Some(inner) => self.frontiter = Some(inner.into_iter()),
276 fn size_hint(&self) -> (usize, Option<usize>) {
277 let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
278 let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
279 let lo = flo.saturating_add(blo);
280 match (self.iter.size_hint(), fhi, bhi) {
281 ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
287 fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
290 Fold: FnMut(Acc, Self::Item) -> R,
294 fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
295 frontiter: &'a mut Option<T::IntoIter>,
296 fold: &'a mut impl FnMut(Acc, T::Item) -> R,
297 ) -> impl FnMut(Acc, T) -> R + 'a {
299 let mut mid = x.into_iter();
300 let r = mid.try_fold(acc, &mut *fold);
301 *frontiter = Some(mid);
306 if let Some(ref mut front) = self.frontiter {
307 init = front.try_fold(init, &mut fold)?;
309 self.frontiter = None;
311 init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
312 self.frontiter = None;
314 if let Some(ref mut back) = self.backiter {
315 init = back.try_fold(init, &mut fold)?;
317 self.backiter = None;
323 fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
325 Fold: FnMut(Acc, Self::Item) -> Acc,
328 fn flatten<U: Iterator, Acc>(
329 fold: &mut impl FnMut(Acc, U::Item) -> Acc,
330 ) -> impl FnMut(Acc, U) -> Acc + '_ {
331 move |acc, iter| iter.fold(acc, &mut *fold)
336 .chain(self.iter.map(IntoIterator::into_iter))
337 .chain(self.backiter)
338 .fold(init, flatten(fold))
342 impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
344 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
345 U: DoubleEndedIterator,
348 fn next_back(&mut self) -> Option<U::Item> {
350 if let Some(ref mut inner) = self.backiter {
351 match inner.next_back() {
352 None => self.backiter = None,
353 elt @ Some(_) => return elt,
356 match self.iter.next_back() {
357 None => return self.frontiter.as_mut()?.next_back(),
358 next => self.backiter = next.map(IntoIterator::into_iter),
364 fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
367 Fold: FnMut(Acc, Self::Item) -> R,
371 fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
372 backiter: &'a mut Option<T::IntoIter>,
373 fold: &'a mut impl FnMut(Acc, T::Item) -> R,
374 ) -> impl FnMut(Acc, T) -> R + 'a
376 T::IntoIter: DoubleEndedIterator,
379 let mut mid = x.into_iter();
380 let r = mid.try_rfold(acc, &mut *fold);
381 *backiter = Some(mid);
386 if let Some(ref mut back) = self.backiter {
387 init = back.try_rfold(init, &mut fold)?;
389 self.backiter = None;
391 init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
392 self.backiter = None;
394 if let Some(ref mut front) = self.frontiter {
395 init = front.try_rfold(init, &mut fold)?;
397 self.frontiter = None;
403 fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
405 Fold: FnMut(Acc, Self::Item) -> Acc,
408 fn flatten<U: DoubleEndedIterator, Acc>(
409 fold: &mut impl FnMut(Acc, U::Item) -> Acc,
410 ) -> impl FnMut(Acc, U) -> Acc + '_ {
411 move |acc, iter| iter.rfold(acc, &mut *fold)
416 .chain(self.iter.map(IntoIterator::into_iter))
417 .chain(self.backiter)
418 .rfold(init, flatten(fold))