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 #[must_use = "iterators are lazy and do nothing unless consumed"]
125 #[stable(feature = "iterator_flatten", since = "1.29.0")]
126 pub struct Flatten<I: Iterator<Item: IntoIterator>> {
127 inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
130 impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
131 pub(in super::super) fn new(iter: I) -> Flatten<I> {
132 Flatten { inner: FlattenCompat::new(iter) }
136 #[stable(feature = "iterator_flatten", since = "1.29.0")]
137 impl<I, U> fmt::Debug for Flatten<I>
139 I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
140 U: fmt::Debug + Iterator,
142 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143 f.debug_struct("Flatten").field("inner", &self.inner).finish()
147 #[stable(feature = "iterator_flatten", since = "1.29.0")]
148 impl<I, U> Clone for Flatten<I>
150 I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
153 fn clone(&self) -> Self {
154 Flatten { inner: self.inner.clone() }
158 #[stable(feature = "iterator_flatten", since = "1.29.0")]
159 impl<I, U> Iterator for Flatten<I>
161 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
167 fn next(&mut self) -> Option<U::Item> {
172 fn size_hint(&self) -> (usize, Option<usize>) {
173 self.inner.size_hint()
177 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
180 Fold: FnMut(Acc, Self::Item) -> R,
183 self.inner.try_fold(init, fold)
187 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
189 Fold: FnMut(Acc, Self::Item) -> Acc,
191 self.inner.fold(init, fold)
195 #[stable(feature = "iterator_flatten", since = "1.29.0")]
196 impl<I, U> DoubleEndedIterator for Flatten<I>
198 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
199 U: DoubleEndedIterator,
202 fn next_back(&mut self) -> Option<U::Item> {
203 self.inner.next_back()
207 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
210 Fold: FnMut(Acc, Self::Item) -> R,
213 self.inner.try_rfold(init, fold)
217 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
219 Fold: FnMut(Acc, Self::Item) -> Acc,
221 self.inner.rfold(init, fold)
225 #[stable(feature = "iterator_flatten", since = "1.29.0")]
226 impl<I, U> FusedIterator for Flatten<I>
228 I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
233 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
235 #[derive(Clone, Debug)]
236 struct FlattenCompat<I, U> {
238 frontiter: Option<U>,
241 impl<I, U> FlattenCompat<I, U>
245 /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
246 fn new(iter: I) -> FlattenCompat<I, U> {
247 FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
251 impl<I, U> Iterator for FlattenCompat<I, U>
253 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
259 fn next(&mut self) -> Option<U::Item> {
261 if let Some(ref mut inner) = self.frontiter {
263 None => self.frontiter = None,
264 elt @ Some(_) => return elt,
267 match self.iter.next() {
268 None => match self.backiter.as_mut()?.next() {
270 self.backiter = None;
273 elt @ Some(_) => return elt,
275 Some(inner) => self.frontiter = Some(inner.into_iter()),
281 fn size_hint(&self) -> (usize, Option<usize>) {
282 let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
283 let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
284 let lo = flo.saturating_add(blo);
285 match (self.iter.size_hint(), fhi, bhi) {
286 ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
292 fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
295 Fold: FnMut(Acc, Self::Item) -> R,
299 fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
300 frontiter: &'a mut Option<T::IntoIter>,
301 fold: &'a mut impl FnMut(Acc, T::Item) -> R,
302 ) -> impl FnMut(Acc, T) -> R + 'a {
304 let mut mid = x.into_iter();
305 let r = mid.try_fold(acc, &mut *fold);
306 *frontiter = Some(mid);
311 if let Some(ref mut front) = self.frontiter {
312 init = front.try_fold(init, &mut fold)?;
314 self.frontiter = None;
316 init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
317 self.frontiter = None;
319 if let Some(ref mut back) = self.backiter {
320 init = back.try_fold(init, &mut fold)?;
322 self.backiter = None;
328 fn fold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
330 Fold: FnMut(Acc, Self::Item) -> Acc,
333 fn flatten<T: IntoIterator, Acc>(
334 fold: &mut impl FnMut(Acc, T::Item) -> Acc,
335 ) -> impl FnMut(Acc, T) -> Acc + '_ {
336 move |acc, x| x.into_iter().fold(acc, &mut *fold)
339 if let Some(front) = self.frontiter {
340 init = front.fold(init, &mut fold);
343 init = self.iter.fold(init, flatten(&mut fold));
345 if let Some(back) = self.backiter {
346 init = back.fold(init, &mut fold);
353 impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
355 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
356 U: DoubleEndedIterator,
359 fn next_back(&mut self) -> Option<U::Item> {
361 if let Some(ref mut inner) = self.backiter {
362 match inner.next_back() {
363 None => self.backiter = None,
364 elt @ Some(_) => return elt,
367 match self.iter.next_back() {
368 None => match self.frontiter.as_mut()?.next_back() {
370 self.frontiter = None;
373 elt @ Some(_) => return elt,
375 next => self.backiter = next.map(IntoIterator::into_iter),
381 fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
384 Fold: FnMut(Acc, Self::Item) -> R,
388 fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
389 backiter: &'a mut Option<T::IntoIter>,
390 fold: &'a mut impl FnMut(Acc, T::Item) -> R,
391 ) -> impl FnMut(Acc, T) -> R + 'a
393 T::IntoIter: DoubleEndedIterator,
396 let mut mid = x.into_iter();
397 let r = mid.try_rfold(acc, &mut *fold);
398 *backiter = Some(mid);
403 if let Some(ref mut back) = self.backiter {
404 init = back.try_rfold(init, &mut fold)?;
406 self.backiter = None;
408 init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
409 self.backiter = None;
411 if let Some(ref mut front) = self.frontiter {
412 init = front.try_rfold(init, &mut fold)?;
414 self.frontiter = None;
420 fn rfold<Acc, Fold>(self, mut init: Acc, mut fold: Fold) -> Acc
422 Fold: FnMut(Acc, Self::Item) -> Acc,
425 fn flatten<T: IntoIterator, Acc>(
426 fold: &mut impl FnMut(Acc, T::Item) -> Acc,
427 ) -> impl FnMut(Acc, T) -> Acc + '_
429 T::IntoIter: DoubleEndedIterator,
431 move |acc, x| x.into_iter().rfold(acc, &mut *fold)
434 if let Some(back) = self.backiter {
435 init = back.rfold(init, &mut fold);
438 init = self.iter.rfold(init, flatten(&mut fold));
440 if let Some(front) = self.frontiter {
441 init = front.rfold(init, &mut fold);