map_while.rs - source
Description: Source of the Rust file `library/core/src/iter/adapters/map_while.rs`.

#
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}