core/iter/adapters/
map_while.rs

1use crate::fmt;
2use crate::iter::InPlaceIterable;
3use crate::iter::adapters::SourceIter;
4use crate::num::NonZero;
5use crate::ops::{ControlFlow, Try};
6
7/// An iterator that only accepts elements while `predicate` returns `Some(_)`.
8///
9/// This `struct` is created by the [`map_while`] method on [`Iterator`]. See its
10/// documentation for more.
11///
12/// [`map_while`]: Iterator::map_while
13/// [`Iterator`]: trait.Iterator.html
14#[must_use = "iterators are lazy and do nothing unless consumed"]
15#[stable(feature = "iter_map_while", since = "1.57.0")]
16#[derive(Clone)]
17pub struct MapWhile<I, P> {
18    iter: I,
19    predicate: P,
20}
21
22impl<I, P> MapWhile<I, P> {
23    pub(in crate::iter) fn new(iter: I, predicate: P) -> MapWhile<I, P> {
24        MapWhile { iter, predicate }
25    }
26}
27
28#[stable(feature = "iter_map_while", since = "1.57.0")]
29impl<I: fmt::Debug, P> fmt::Debug for MapWhile<I, P> {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        f.debug_struct("MapWhile").field("iter", &self.iter).finish()
32    }
33}
34
35#[stable(feature = "iter_map_while", since = "1.57.0")]
36impl<B, I: Iterator, P> Iterator for MapWhile<I, P>
37where
38    P: FnMut(I::Item) -> Option<B>,
39{
40    type Item = B;
41
42    #[inline]
43    fn next(&mut self) -> Option<B> {
44        let x = self.iter.next()?;
45        (self.predicate)(x)
46    }
47
48    #[inline]
49    fn size_hint(&self) -> (usize, Option<usize>) {
50        let (_, upper) = self.iter.size_hint();
51        (0, upper) // can't know a lower bound, due to the predicate
52    }
53
54    #[inline]
55    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, mut fold: Fold) -> R
56    where
57        Self: Sized,
58        Fold: FnMut(Acc, Self::Item) -> R,
59        R: Try<Output = Acc>,
60    {
61        let Self { iter, predicate } = self;
62        iter.try_fold(init, |acc, x| match predicate(x) {
63            Some(item) => ControlFlow::from_try(fold(acc, item)),
64            None => ControlFlow::Break(try { acc }),
65        })
66        .into_try()
67    }
68
69    impl_fold_via_try_fold! { fold -> try_fold }
70}
71
72#[unstable(issue = "none", feature = "inplace_iteration")]
73unsafe impl<I, P> SourceIter for MapWhile<I, P>
74where
75    I: SourceIter,
76{
77    type Source = I::Source;
78
79    #[inline]
80    unsafe fn as_inner(&mut self) -> &mut I::Source {
81        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
82        unsafe { SourceIter::as_inner(&mut self.iter) }
83    }
84}
85
86#[unstable(issue = "none", feature = "inplace_iteration")]
87unsafe impl<I: InPlaceIterable, P> InPlaceIterable for MapWhile<I, P> {
88    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
89    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
90}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy