core/iter/adapters/
skip_while.rs

1use crate::fmt;
2use crate::iter::adapters::SourceIter;
3use crate::iter::{FusedIterator, InPlaceIterable, TrustedFused};
4use crate::num::NonZero;
5use crate::ops::Try;
6
7/// An iterator that rejects elements while `predicate` returns `true`.
8///
9/// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its
10/// documentation for more.
11///
12/// [`skip_while`]: Iterator::skip_while
13/// [`Iterator`]: trait.Iterator.html
14#[must_use = "iterators are lazy and do nothing unless consumed"]
15#[stable(feature = "rust1", since = "1.0.0")]
16#[derive(Clone)]
17pub struct SkipWhile<I, P> {
18    iter: I,
19    flag: bool,
20    predicate: P,
21}
22
23impl<I, P> SkipWhile<I, P> {
24    pub(in crate::iter) fn new(iter: I, predicate: P) -> SkipWhile<I, P> {
25        SkipWhile { iter, flag: false, predicate }
26    }
27}
28
29#[stable(feature = "core_impl_debug", since = "1.9.0")]
30impl<I: fmt::Debug, P> fmt::Debug for SkipWhile<I, P> {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        f.debug_struct("SkipWhile").field("iter", &self.iter).field("flag", &self.flag).finish()
33    }
34}
35
36#[stable(feature = "rust1", since = "1.0.0")]
37impl<I: Iterator, P> Iterator for SkipWhile<I, P>
38where
39    P: FnMut(&I::Item) -> bool,
40{
41    type Item = I::Item;
42
43    #[inline]
44    fn next(&mut self) -> Option<I::Item> {
45        fn check<'a, T>(
46            flag: &'a mut bool,
47            pred: &'a mut impl FnMut(&T) -> bool,
48        ) -> impl FnMut(&T) -> bool + 'a {
49            move |x| {
50                if *flag || !pred(x) {
51                    *flag = true;
52                    true
53                } else {
54                    false
55                }
56            }
57        }
58
59        let flag = &mut self.flag;
60        let pred = &mut self.predicate;
61        self.iter.find(check(flag, pred))
62    }
63
64    #[inline]
65    fn size_hint(&self) -> (usize, Option<usize>) {
66        let (_, upper) = self.iter.size_hint();
67        (0, upper) // can't know a lower bound, due to the predicate
68    }
69
70    #[inline]
71    fn try_fold<Acc, Fold, R>(&mut self, mut init: Acc, mut fold: Fold) -> R
72    where
73        Self: Sized,
74        Fold: FnMut(Acc, Self::Item) -> R,
75        R: Try<Output = Acc>,
76    {
77        if !self.flag {
78            match self.next() {
79                Some(v) => init = fold(init, v)?,
80                None => return try { init },
81            }
82        }
83        self.iter.try_fold(init, fold)
84    }
85
86    #[inline]
87    fn fold<Acc, Fold>(mut self, mut init: Acc, mut fold: Fold) -> Acc
88    where
89        Fold: FnMut(Acc, Self::Item) -> Acc,
90    {
91        if !self.flag {
92            match self.next() {
93                Some(v) => init = fold(init, v),
94                None => return init,
95            }
96        }
97        self.iter.fold(init, fold)
98    }
99}
100
101#[stable(feature = "fused", since = "1.26.0")]
102impl<I, P> FusedIterator for SkipWhile<I, P>
103where
104    I: FusedIterator,
105    P: FnMut(&I::Item) -> bool,
106{
107}
108
109#[unstable(issue = "none", feature = "trusted_fused")]
110unsafe impl<I: TrustedFused, P> TrustedFused for SkipWhile<I, P> {}
111
112#[unstable(issue = "none", feature = "inplace_iteration")]
113unsafe impl<P, I> SourceIter for SkipWhile<I, P>
114where
115    I: SourceIter,
116{
117    type Source = I::Source;
118
119    #[inline]
120    unsafe fn as_inner(&mut self) -> &mut I::Source {
121        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
122        unsafe { SourceIter::as_inner(&mut self.iter) }
123    }
124}
125
126#[unstable(issue = "none", feature = "inplace_iteration")]
127unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> {
128    const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY;
129    const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY;
130}
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