core/iter/adapters/
fuse.rs

1use crate::intrinsics;
2use crate::iter::adapters::SourceIter;
3use crate::iter::adapters::zip::try_get_unchecked;
4use crate::iter::{
5    FusedIterator, TrustedFused, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
6};
7use crate::ops::Try;
8
9/// An iterator that yields `None` forever after the underlying iterator
10/// yields `None` once.
11///
12/// This `struct` is created by [`Iterator::fuse`]. See its documentation
13/// for more.
14#[derive(Clone, Debug)]
15#[must_use = "iterators are lazy and do nothing unless consumed"]
16#[stable(feature = "rust1", since = "1.0.0")]
17pub struct Fuse<I> {
18    // NOTE: for `I: FusedIterator`, we never bother setting `None`, but
19    // we still have to be prepared for that state due to variance.
20    // See rust-lang/rust#85863
21    iter: Option<I>,
22}
23impl<I> Fuse<I> {
24    pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
25        Fuse { iter: Some(iter) }
26    }
27
28    pub(crate) fn into_inner(self) -> Option<I> {
29        self.iter
30    }
31}
32
33#[stable(feature = "fused", since = "1.26.0")]
34impl<I> FusedIterator for Fuse<I> where I: Iterator {}
35
36#[unstable(issue = "none", feature = "trusted_fused")]
37unsafe impl<I> TrustedFused for Fuse<I> where I: TrustedFused {}
38
39// Any specialized implementation here is made internal
40// to avoid exposing default fns outside this trait.
41#[stable(feature = "rust1", since = "1.0.0")]
42impl<I> Iterator for Fuse<I>
43where
44    I: Iterator,
45{
46    type Item = <I as Iterator>::Item;
47
48    #[inline]
49    fn next(&mut self) -> Option<Self::Item> {
50        FuseImpl::next(self)
51    }
52
53    #[inline]
54    fn nth(&mut self, n: usize) -> Option<I::Item> {
55        FuseImpl::nth(self, n)
56    }
57
58    #[inline]
59    fn last(self) -> Option<Self::Item> {
60        match self.iter {
61            Some(iter) => iter.last(),
62            None => None,
63        }
64    }
65
66    #[inline]
67    fn count(self) -> usize {
68        match self.iter {
69            Some(iter) => iter.count(),
70            None => 0,
71        }
72    }
73
74    #[inline]
75    fn size_hint(&self) -> (usize, Option<usize>) {
76        match self.iter {
77            Some(ref iter) => iter.size_hint(),
78            None => (0, Some(0)),
79        }
80    }
81
82    #[inline]
83    fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
84    where
85        Self: Sized,
86        Fold: FnMut(Acc, Self::Item) -> R,
87        R: Try<Output = Acc>,
88    {
89        FuseImpl::try_fold(self, acc, fold)
90    }
91
92    #[inline]
93    fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
94    where
95        Fold: FnMut(Acc, Self::Item) -> Acc,
96    {
97        if let Some(iter) = self.iter {
98            acc = iter.fold(acc, fold);
99        }
100        acc
101    }
102
103    #[inline]
104    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
105    where
106        P: FnMut(&Self::Item) -> bool,
107    {
108        FuseImpl::find(self, predicate)
109    }
110
111    #[inline]
112    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
113    where
114        Self: TrustedRandomAccessNoCoerce,
115    {
116        match self.iter {
117            // SAFETY: the caller must uphold the contract for
118            // `Iterator::__iterator_get_unchecked`.
119            Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
120            // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
121            None => unsafe { intrinsics::unreachable() },
122        }
123    }
124}
125
126#[stable(feature = "rust1", since = "1.0.0")]
127impl<I> DoubleEndedIterator for Fuse<I>
128where
129    I: DoubleEndedIterator,
130{
131    #[inline]
132    fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
133        FuseImpl::next_back(self)
134    }
135
136    #[inline]
137    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
138        FuseImpl::nth_back(self, n)
139    }
140
141    #[inline]
142    fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
143    where
144        Self: Sized,
145        Fold: FnMut(Acc, Self::Item) -> R,
146        R: Try<Output = Acc>,
147    {
148        FuseImpl::try_rfold(self, acc, fold)
149    }
150
151    #[inline]
152    fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
153    where
154        Fold: FnMut(Acc, Self::Item) -> Acc,
155    {
156        if let Some(iter) = self.iter {
157            acc = iter.rfold(acc, fold);
158        }
159        acc
160    }
161
162    #[inline]
163    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
164    where
165        P: FnMut(&Self::Item) -> bool,
166    {
167        FuseImpl::rfind(self, predicate)
168    }
169}
170
171#[stable(feature = "rust1", since = "1.0.0")]
172impl<I> ExactSizeIterator for Fuse<I>
173where
174    I: ExactSizeIterator,
175{
176    fn len(&self) -> usize {
177        match self.iter {
178            Some(ref iter) => iter.len(),
179            None => 0,
180        }
181    }
182
183    fn is_empty(&self) -> bool {
184        match self.iter {
185            Some(ref iter) => iter.is_empty(),
186            None => true,
187        }
188    }
189}
190
191#[stable(feature = "default_iters", since = "1.70.0")]
192impl<I: Default> Default for Fuse<I> {
193    /// Creates a `Fuse` iterator from the default value of `I`.
194    ///
195    /// ```
196    /// # use core::slice;
197    /// # use std::iter::Fuse;
198    /// let iter: Fuse<slice::Iter<'_, u8>> = Default::default();
199    /// assert_eq!(iter.len(), 0);
200    /// ```
201    ///
202    /// This is equivalent to `I::default().fuse()`[^fuse_note]; e.g. if
203    /// `I::default()` is not an empty iterator, then this will not be
204    /// an empty iterator.
205    ///
206    /// ```
207    /// # use std::iter::Fuse;
208    /// #[derive(Default)]
209    /// struct Fourever;
210    ///
211    /// impl Iterator for Fourever {
212    ///     type Item = u32;
213    ///     fn next(&mut self) -> Option<u32> {
214    ///         Some(4)
215    ///     }
216    /// }
217    ///
218    /// let mut iter: Fuse<Fourever> = Default::default();
219    /// assert_eq!(iter.next(), Some(4));
220    /// ```
221    ///
222    /// [^fuse_note]: if `I` does not override `Iterator::fuse`'s default implementation
223    fn default() -> Self {
224        Fuse { iter: Some(I::default()) }
225    }
226}
227
228#[unstable(feature = "trusted_len", issue = "37572")]
229// SAFETY: `TrustedLen` requires that an accurate length is reported via `size_hint()`. As `Fuse`
230// is just forwarding this to the wrapped iterator `I` this property is preserved and it is safe to
231// implement `TrustedLen` here.
232unsafe impl<I> TrustedLen for Fuse<I> where I: TrustedLen {}
233
234#[doc(hidden)]
235#[unstable(feature = "trusted_random_access", issue = "none")]
236// SAFETY: `TrustedRandomAccess` requires that `size_hint()` must be exact and cheap to call, and
237// `Iterator::__iterator_get_unchecked()` must be implemented accordingly.
238//
239// This is safe to implement as `Fuse` is just forwarding these to the wrapped iterator `I`, which
240// preserves these properties.
241unsafe impl<I> TrustedRandomAccess for Fuse<I> where I: TrustedRandomAccess {}
242
243#[doc(hidden)]
244#[unstable(feature = "trusted_random_access", issue = "none")]
245unsafe impl<I> TrustedRandomAccessNoCoerce for Fuse<I>
246where
247    I: TrustedRandomAccessNoCoerce,
248{
249    const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
250}
251
252/// Fuse specialization trait
253///
254/// We only need to worry about `&mut self` methods, which
255/// may exhaust the iterator without consuming it.
256#[doc(hidden)]
257trait FuseImpl<I> {
258    type Item;
259
260    // Functions specific to any normal Iterators
261    fn next(&mut self) -> Option<Self::Item>;
262    fn nth(&mut self, n: usize) -> Option<Self::Item>;
263    fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
264    where
265        Self: Sized,
266        Fold: FnMut(Acc, Self::Item) -> R,
267        R: Try<Output = Acc>;
268    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
269    where
270        P: FnMut(&Self::Item) -> bool;
271
272    // Functions specific to DoubleEndedIterators
273    fn next_back(&mut self) -> Option<Self::Item>
274    where
275        I: DoubleEndedIterator;
276    fn nth_back(&mut self, n: usize) -> Option<Self::Item>
277    where
278        I: DoubleEndedIterator;
279    fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
280    where
281        Self: Sized,
282        Fold: FnMut(Acc, Self::Item) -> R,
283        R: Try<Output = Acc>,
284        I: DoubleEndedIterator;
285    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
286    where
287        P: FnMut(&Self::Item) -> bool,
288        I: DoubleEndedIterator;
289}
290
291/// General `Fuse` impl which sets `iter = None` when exhausted.
292#[doc(hidden)]
293impl<I> FuseImpl<I> for Fuse<I>
294where
295    I: Iterator,
296{
297    type Item = <I as Iterator>::Item;
298
299    #[inline]
300    default fn next(&mut self) -> Option<<I as Iterator>::Item> {
301        and_then_or_clear(&mut self.iter, Iterator::next)
302    }
303
304    #[inline]
305    default fn nth(&mut self, n: usize) -> Option<I::Item> {
306        and_then_or_clear(&mut self.iter, |iter| iter.nth(n))
307    }
308
309    #[inline]
310    default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
311    where
312        Self: Sized,
313        Fold: FnMut(Acc, Self::Item) -> R,
314        R: Try<Output = Acc>,
315    {
316        if let Some(ref mut iter) = self.iter {
317            acc = iter.try_fold(acc, fold)?;
318            self.iter = None;
319        }
320        try { acc }
321    }
322
323    #[inline]
324    default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
325    where
326        P: FnMut(&Self::Item) -> bool,
327    {
328        and_then_or_clear(&mut self.iter, |iter| iter.find(predicate))
329    }
330
331    #[inline]
332    default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
333    where
334        I: DoubleEndedIterator,
335    {
336        and_then_or_clear(&mut self.iter, |iter| iter.next_back())
337    }
338
339    #[inline]
340    default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
341    where
342        I: DoubleEndedIterator,
343    {
344        and_then_or_clear(&mut self.iter, |iter| iter.nth_back(n))
345    }
346
347    #[inline]
348    default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
349    where
350        Self: Sized,
351        Fold: FnMut(Acc, Self::Item) -> R,
352        R: Try<Output = Acc>,
353        I: DoubleEndedIterator,
354    {
355        if let Some(ref mut iter) = self.iter {
356            acc = iter.try_rfold(acc, fold)?;
357            self.iter = None;
358        }
359        try { acc }
360    }
361
362    #[inline]
363    default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
364    where
365        P: FnMut(&Self::Item) -> bool,
366        I: DoubleEndedIterator,
367    {
368        and_then_or_clear(&mut self.iter, |iter| iter.rfind(predicate))
369    }
370}
371
372/// Specialized `Fuse` impl which doesn't bother clearing `iter` when exhausted.
373/// However, we must still be prepared for the possibility that it was already cleared!
374#[doc(hidden)]
375impl<I> FuseImpl<I> for Fuse<I>
376where
377    I: FusedIterator,
378{
379    #[inline]
380    fn next(&mut self) -> Option<<I as Iterator>::Item> {
381        self.iter.as_mut()?.next()
382    }
383
384    #[inline]
385    fn nth(&mut self, n: usize) -> Option<I::Item> {
386        self.iter.as_mut()?.nth(n)
387    }
388
389    #[inline]
390    fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
391    where
392        Self: Sized,
393        Fold: FnMut(Acc, Self::Item) -> R,
394        R: Try<Output = Acc>,
395    {
396        if let Some(ref mut iter) = self.iter {
397            acc = iter.try_fold(acc, fold)?;
398        }
399        try { acc }
400    }
401
402    #[inline]
403    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
404    where
405        P: FnMut(&Self::Item) -> bool,
406    {
407        self.iter.as_mut()?.find(predicate)
408    }
409
410    #[inline]
411    fn next_back(&mut self) -> Option<<I as Iterator>::Item>
412    where
413        I: DoubleEndedIterator,
414    {
415        self.iter.as_mut()?.next_back()
416    }
417
418    #[inline]
419    fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
420    where
421        I: DoubleEndedIterator,
422    {
423        self.iter.as_mut()?.nth_back(n)
424    }
425
426    #[inline]
427    fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
428    where
429        Self: Sized,
430        Fold: FnMut(Acc, Self::Item) -> R,
431        R: Try<Output = Acc>,
432        I: DoubleEndedIterator,
433    {
434        if let Some(ref mut iter) = self.iter {
435            acc = iter.try_rfold(acc, fold)?;
436        }
437        try { acc }
438    }
439
440    #[inline]
441    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
442    where
443        P: FnMut(&Self::Item) -> bool,
444        I: DoubleEndedIterator,
445    {
446        self.iter.as_mut()?.rfind(predicate)
447    }
448}
449
450// This is used by Flatten's SourceIter impl
451#[unstable(issue = "none", feature = "inplace_iteration")]
452unsafe impl<I> SourceIter for Fuse<I>
453where
454    I: SourceIter + TrustedFused,
455{
456    type Source = I::Source;
457
458    #[inline]
459    unsafe fn as_inner(&mut self) -> &mut I::Source {
460        // SAFETY: unsafe function forwarding to unsafe function with the same requirements.
461        // TrustedFused guarantees that we'll never encounter a case where `self.iter` would
462        // be set to None.
463        unsafe { SourceIter::as_inner(self.iter.as_mut().unwrap_unchecked()) }
464    }
465}
466
467#[inline]
468fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
469    let x = f(opt.as_mut()?);
470    if x.is_none() {
471        *opt = None;
472    }
473    x
474}
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