4 use super::super::{DoubleEndedIterator, Fuse, FusedIterator, Iterator};
7 /// An iterator that maps each element to an iterator, and yields the elements
8 /// of the produced iterators.
10 /// This `struct` is created by [`Iterator::flat_map`]. See its documentation
12 #[must_use = "iterators are lazy and do nothing unless consumed"]
13 #[stable(feature = "rust1", since = "1.0.0")]
14 pub struct FlatMap<I, U: IntoIterator, F> {
15 inner: FlattenCompat<Map<I, F>, <U as IntoIterator>::IntoIter>,
18 impl<I: Iterator, U: IntoIterator, F: FnMut(I::Item) -> U> FlatMap<I, U, F> {
19 pub(in crate::iter) fn new(iter: I, f: F) -> FlatMap<I, U, F> {
20 FlatMap { inner: FlattenCompat::new(iter.map(f)) }
24 #[stable(feature = "rust1", since = "1.0.0")]
25 impl<I: Clone, U, F: Clone> Clone for FlatMap<I, U, F>
27 U: Clone + IntoIterator<IntoIter: Clone>,
29 fn clone(&self) -> Self {
30 FlatMap { inner: self.inner.clone() }
34 #[stable(feature = "core_impl_debug", since = "1.9.0")]
35 impl<I: fmt::Debug, U, F> fmt::Debug for FlatMap<I, U, F>
37 U: IntoIterator<IntoIter: fmt::Debug>,
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 f.debug_struct("FlatMap").field("inner", &self.inner).finish()
44 #[stable(feature = "rust1", since = "1.0.0")]
45 impl<I: Iterator, U: IntoIterator, F> Iterator for FlatMap<I, U, F>
47 F: FnMut(I::Item) -> U,
52 fn next(&mut self) -> Option<U::Item> {
57 fn size_hint(&self) -> (usize, Option<usize>) {
58 self.inner.size_hint()
62 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
65 Fold: FnMut(Acc, Self::Item) -> R,
68 self.inner.try_fold(init, fold)
72 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
74 Fold: FnMut(Acc, Self::Item) -> Acc,
76 self.inner.fold(init, fold)
80 #[stable(feature = "rust1", since = "1.0.0")]
81 impl<I: DoubleEndedIterator, U, F> DoubleEndedIterator for FlatMap<I, U, F>
83 F: FnMut(I::Item) -> U,
84 U: IntoIterator<IntoIter: DoubleEndedIterator>,
87 fn next_back(&mut self) -> Option<U::Item> {
88 self.inner.next_back()
92 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
95 Fold: FnMut(Acc, Self::Item) -> R,
98 self.inner.try_rfold(init, fold)
102 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
104 Fold: FnMut(Acc, Self::Item) -> Acc,
106 self.inner.rfold(init, fold)
110 #[stable(feature = "fused", since = "1.26.0")]
111 impl<I, U, F> FusedIterator for FlatMap<I, U, F>
115 F: FnMut(I::Item) -> U,
119 /// An iterator that flattens one level of nesting in an iterator of things
120 /// that can be turned into iterators.
122 /// This `struct` is created by the [`flatten`] method on [`Iterator`]. See its
123 /// documentation for more.
125 /// [`flatten`]: Iterator::flatten
126 /// [`Iterator`]: trait.Iterator.html
127 #[must_use = "iterators are lazy and do nothing unless consumed"]
128 #[stable(feature = "iterator_flatten", since = "1.29.0")]
129 pub struct Flatten<I: Iterator<Item: IntoIterator>> {
130 inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
133 impl<I: Iterator<Item: IntoIterator>> Flatten<I> {
134 pub(in super::super) fn new(iter: I) -> Flatten<I> {
135 Flatten { inner: FlattenCompat::new(iter) }
139 #[stable(feature = "iterator_flatten", since = "1.29.0")]
140 impl<I, U> fmt::Debug for Flatten<I>
142 I: fmt::Debug + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
143 U: fmt::Debug + Iterator,
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 f.debug_struct("Flatten").field("inner", &self.inner).finish()
150 #[stable(feature = "iterator_flatten", since = "1.29.0")]
151 impl<I, U> Clone for Flatten<I>
153 I: Clone + Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
156 fn clone(&self) -> Self {
157 Flatten { inner: self.inner.clone() }
161 #[stable(feature = "iterator_flatten", since = "1.29.0")]
162 impl<I, U> Iterator for Flatten<I>
164 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
170 fn next(&mut self) -> Option<U::Item> {
175 fn size_hint(&self) -> (usize, Option<usize>) {
176 self.inner.size_hint()
180 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
183 Fold: FnMut(Acc, Self::Item) -> R,
186 self.inner.try_fold(init, fold)
190 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
192 Fold: FnMut(Acc, Self::Item) -> Acc,
194 self.inner.fold(init, fold)
198 #[stable(feature = "iterator_flatten", since = "1.29.0")]
199 impl<I, U> DoubleEndedIterator for Flatten<I>
201 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
202 U: DoubleEndedIterator,
205 fn next_back(&mut self) -> Option<U::Item> {
206 self.inner.next_back()
210 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
213 Fold: FnMut(Acc, Self::Item) -> R,
216 self.inner.try_rfold(init, fold)
220 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
222 Fold: FnMut(Acc, Self::Item) -> Acc,
224 self.inner.rfold(init, fold)
228 #[stable(feature = "iterator_flatten", since = "1.29.0")]
229 impl<I, U> FusedIterator for Flatten<I>
231 I: FusedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
236 /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
238 #[derive(Clone, Debug)]
239 struct FlattenCompat<I, U> {
241 frontiter: Option<U>,
244 impl<I, U> FlattenCompat<I, U>
248 /// Adapts an iterator by flattening it, for use in `flatten()` and `flat_map()`.
249 fn new(iter: I) -> FlattenCompat<I, U> {
250 FlattenCompat { iter: iter.fuse(), frontiter: None, backiter: None }
254 impl<I, U> Iterator for FlattenCompat<I, U>
256 I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
262 fn next(&mut self) -> Option<U::Item> {
264 if let Some(ref mut inner) = self.frontiter {
266 None => self.frontiter = None,
267 elt @ Some(_) => return elt,
270 match self.iter.next() {
271 None => return self.backiter.as_mut()?.next(),
272 Some(inner) => self.frontiter = Some(inner.into_iter()),
278 fn size_hint(&self) -> (usize, Option<usize>) {
279 let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), U::size_hint);
280 let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), U::size_hint);
281 let lo = flo.saturating_add(blo);
282 match (self.iter.size_hint(), fhi, bhi) {
283 ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
289 fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
292 Fold: FnMut(Acc, Self::Item) -> R,
296 fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
297 frontiter: &'a mut Option<T::IntoIter>,
298 fold: &'a mut impl FnMut(Acc, T::Item) -> R,
299 ) -> impl FnMut(Acc, T) -> R + 'a {
301 let mut mid = x.into_iter();
302 let r = mid.try_fold(acc, &mut *fold);
303 *frontiter = Some(mid);
308 if let Some(ref mut front) = self.frontiter {
309 init = front.try_fold(init, &mut fold)?;
311 self.frontiter = None;
313 init = self.iter.try_fold(init, flatten(&mut self.frontiter, &mut fold))?;
314 self.frontiter = None;
316 if let Some(ref mut back) = self.backiter {
317 init = back.try_fold(init, &mut fold)?;
319 self.backiter = None;
325 fn fold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
327 Fold: FnMut(Acc, Self::Item) -> Acc,
330 fn flatten<U: Iterator, Acc>(
331 fold: &mut impl FnMut(Acc, U::Item) -> Acc,
332 ) -> impl FnMut(Acc, U) -> Acc + '_ {
333 move |acc, iter| iter.fold(acc, &mut *fold)
338 .chain(self.iter.map(IntoIterator::into_iter))
339 .chain(self.backiter)
340 .fold(init, flatten(fold))
344 impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
346 I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
347 U: DoubleEndedIterator,
350 fn next_back(&mut self) -> Option<U::Item> {
352 if let Some(ref mut inner) = self.backiter {
353 match inner.next_back() {
354 None => self.backiter = None,
355 elt @ Some(_) => return elt,
358 match self.iter.next_back() {
359 None => return self.frontiter.as_mut()?.next_back(),
360 next => self.backiter = next.map(IntoIterator::into_iter),
366 fn try_rfold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
369 Fold: FnMut(Acc, Self::Item) -> R,
373 fn flatten<'a, T: IntoIterator, Acc, R: Try<Ok = Acc>>(
374 backiter: &'a mut Option<T::IntoIter>,
375 fold: &'a mut impl FnMut(Acc, T::Item) -> R,
376 ) -> impl FnMut(Acc, T) -> R + 'a
378 T::IntoIter: DoubleEndedIterator,
381 let mut mid = x.into_iter();
382 let r = mid.try_rfold(acc, &mut *fold);
383 *backiter = Some(mid);
388 if let Some(ref mut back) = self.backiter {
389 init = back.try_rfold(init, &mut fold)?;
391 self.backiter = None;
393 init = self.iter.try_rfold(init, flatten(&mut self.backiter, &mut fold))?;
394 self.backiter = None;
396 if let Some(ref mut front) = self.frontiter {
397 init = front.try_rfold(init, &mut fold)?;
399 self.frontiter = None;
405 fn rfold<Acc, Fold>(self, init: Acc, ref mut fold: Fold) -> Acc
407 Fold: FnMut(Acc, Self::Item) -> Acc,
410 fn flatten<U: DoubleEndedIterator, Acc>(
411 fold: &mut impl FnMut(Acc, U::Item) -> Acc,
412 ) -> impl FnMut(Acc, U) -> Acc + '_ {
413 move |acc, iter| iter.rfold(acc, &mut *fold)
418 .chain(self.iter.map(IntoIterator::into_iter))
419 .chain(self.backiter)
420 .rfold(init, flatten(fold))