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
=> return self.backiter
.as_mut()?
.next(),
269 Some(inner
) => self.frontiter
= Some(inner
.into_iter()),
275 fn size_hint(&self) -> (usize, Option
<usize>) {
276 let (flo
, fhi
) = self.frontiter
.as_ref().map_or((0, Some(0)), U
::size_hint
);
277 let (blo
, bhi
) = self.backiter
.as_ref().map_or((0, Some(0)), U
::size_hint
);
278 let lo
= flo
.saturating_add(blo
);
279 match (self.iter
.size_hint(), fhi
, bhi
) {
280 ((0, Some(0)), Some(a
), Some(b
)) => (lo
, a
.checked_add(b
)),
286 fn try_fold
<Acc
, Fold
, R
>(&mut self, mut init
: Acc
, mut fold
: Fold
) -> R
289 Fold
: FnMut(Acc
, Self::Item
) -> R
,
293 fn flatten
<'a
, T
: IntoIterator
, Acc
, R
: Try
<Ok
= Acc
>>(
294 frontiter
: &'a
mut Option
<T
::IntoIter
>,
295 fold
: &'a
mut impl FnMut(Acc
, T
::Item
) -> R
,
296 ) -> impl FnMut(Acc
, T
) -> R
+ 'a
{
298 let mut mid
= x
.into_iter();
299 let r
= mid
.try_fold(acc
, &mut *fold
);
300 *frontiter
= Some(mid
);
305 if let Some(ref mut front
) = self.frontiter
{
306 init
= front
.try_fold(init
, &mut fold
)?
;
308 self.frontiter
= None
;
310 init
= self.iter
.try_fold(init
, flatten(&mut self.frontiter
, &mut fold
))?
;
311 self.frontiter
= None
;
313 if let Some(ref mut back
) = self.backiter
{
314 init
= back
.try_fold(init
, &mut fold
)?
;
316 self.backiter
= None
;
322 fn fold
<Acc
, Fold
>(self, init
: Acc
, ref mut fold
: Fold
) -> Acc
324 Fold
: FnMut(Acc
, Self::Item
) -> Acc
,
327 fn flatten
<U
: Iterator
, Acc
>(
328 fold
: &mut impl FnMut(Acc
, U
::Item
) -> Acc
,
329 ) -> impl FnMut(Acc
, U
) -> Acc
+ '_
{
330 move |acc
, iter
| iter
.fold(acc
, &mut *fold
)
335 .chain(self.iter
.map(IntoIterator
::into_iter
))
336 .chain(self.backiter
)
337 .fold(init
, flatten(fold
))
341 impl<I
, U
> DoubleEndedIterator
for FlattenCompat
<I
, U
>
343 I
: DoubleEndedIterator
<Item
: IntoIterator
<IntoIter
= U
, Item
= U
::Item
>>,
344 U
: DoubleEndedIterator
,
347 fn next_back(&mut self) -> Option
<U
::Item
> {
349 if let Some(ref mut inner
) = self.backiter
{
350 match inner
.next_back() {
351 None
=> self.backiter
= None
,
352 elt @
Some(_
) => return elt
,
355 match self.iter
.next_back() {
356 None
=> return self.frontiter
.as_mut()?
.next_back(),
357 next
=> self.backiter
= next
.map(IntoIterator
::into_iter
),
363 fn try_rfold
<Acc
, Fold
, R
>(&mut self, mut init
: Acc
, mut fold
: Fold
) -> R
366 Fold
: FnMut(Acc
, Self::Item
) -> R
,
370 fn flatten
<'a
, T
: IntoIterator
, Acc
, R
: Try
<Ok
= Acc
>>(
371 backiter
: &'a
mut Option
<T
::IntoIter
>,
372 fold
: &'a
mut impl FnMut(Acc
, T
::Item
) -> R
,
373 ) -> impl FnMut(Acc
, T
) -> R
+ 'a
375 T
::IntoIter
: DoubleEndedIterator
,
378 let mut mid
= x
.into_iter();
379 let r
= mid
.try_rfold(acc
, &mut *fold
);
380 *backiter
= Some(mid
);
385 if let Some(ref mut back
) = self.backiter
{
386 init
= back
.try_rfold(init
, &mut fold
)?
;
388 self.backiter
= None
;
390 init
= self.iter
.try_rfold(init
, flatten(&mut self.backiter
, &mut fold
))?
;
391 self.backiter
= None
;
393 if let Some(ref mut front
) = self.frontiter
{
394 init
= front
.try_rfold(init
, &mut fold
)?
;
396 self.frontiter
= None
;
402 fn rfold
<Acc
, Fold
>(self, init
: Acc
, ref mut fold
: Fold
) -> Acc
404 Fold
: FnMut(Acc
, Self::Item
) -> Acc
,
407 fn flatten
<U
: DoubleEndedIterator
, Acc
>(
408 fold
: &mut impl FnMut(Acc
, U
::Item
) -> Acc
,
409 ) -> impl FnMut(Acc
, U
) -> Acc
+ '_
{
410 move |acc
, iter
| iter
.rfold(acc
, &mut *fold
)
415 .chain(self.iter
.map(IntoIterator
::into_iter
))
416 .chain(self.backiter
)
417 .rfold(init
, flatten(fold
))