2 use crate::iter::adapters::zip::try_get_unchecked;
4 DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess,
5 TrustedRandomAccessNoCoerce,
9 /// An iterator that yields `None` forever after the underlying iterator
10 /// yields `None` once.
12 /// This `struct` is created by [`Iterator::fuse`]. See its documentation
14 #[derive(Clone, Debug)]
15 #[must_use = "iterators are lazy and do nothing unless consumed"]
16 #[stable(feature = "rust1", since = "1.0.0")]
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
24 pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
25 Fuse { iter: Some(iter) }
29 #[stable(feature = "fused", since = "1.26.0")]
30 impl<I> FusedIterator for Fuse<I> where I: Iterator {}
32 // Any specialized implementation here is made internal
33 // to avoid exposing default fns outside this trait.
34 #[stable(feature = "rust1", since = "1.0.0")]
35 impl<I> Iterator for Fuse<I>
39 type Item = <I as Iterator>::Item;
42 fn next(&mut self) -> Option<Self::Item> {
47 fn nth(&mut self, n: usize) -> Option<I::Item> {
48 FuseImpl::nth(self, n)
52 fn last(self) -> Option<Self::Item> {
54 Some(iter) => iter.last(),
60 fn count(self) -> usize {
62 Some(iter) => iter.count(),
68 fn size_hint(&self) -> (usize, Option<usize>) {
70 Some(ref iter) => iter.size_hint(),
76 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
79 Fold: FnMut(Acc, Self::Item) -> R,
82 FuseImpl::try_fold(self, acc, fold)
86 fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
88 Fold: FnMut(Acc, Self::Item) -> Acc,
90 if let Some(iter) = self.iter {
91 acc = iter.fold(acc, fold);
97 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
99 P: FnMut(&Self::Item) -> bool,
101 FuseImpl::find(self, predicate)
105 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
107 Self: TrustedRandomAccessNoCoerce,
110 // SAFETY: the caller must uphold the contract for
111 // `Iterator::__iterator_get_unchecked`.
112 Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
113 // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
114 None => unsafe { intrinsics::unreachable() },
119 #[stable(feature = "rust1", since = "1.0.0")]
120 impl<I> DoubleEndedIterator for Fuse<I>
122 I: DoubleEndedIterator,
125 fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
126 FuseImpl::next_back(self)
130 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
131 FuseImpl::nth_back(self, n)
135 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
138 Fold: FnMut(Acc, Self::Item) -> R,
139 R: Try<Output = Acc>,
141 FuseImpl::try_rfold(self, acc, fold)
145 fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
147 Fold: FnMut(Acc, Self::Item) -> Acc,
149 if let Some(iter) = self.iter {
150 acc = iter.rfold(acc, fold);
156 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
158 P: FnMut(&Self::Item) -> bool,
160 FuseImpl::rfind(self, predicate)
164 #[stable(feature = "rust1", since = "1.0.0")]
165 impl<I> ExactSizeIterator for Fuse<I>
167 I: ExactSizeIterator,
169 fn len(&self) -> usize {
171 Some(ref iter) => iter.len(),
176 fn is_empty(&self) -> bool {
178 Some(ref iter) => iter.is_empty(),
184 #[unstable(feature = "trusted_len", issue = "37572")]
185 // SAFETY: `TrustedLen` requires that an accurate length is reported via `size_hint()`. As `Fuse`
186 // is just forwarding this to the wrapped iterator `I` this property is preserved and it is safe to
187 // implement `TrustedLen` here.
188 unsafe impl<I> TrustedLen for Fuse<I> where I: TrustedLen {}
191 #[unstable(feature = "trusted_random_access", issue = "none")]
192 // SAFETY: `TrustedRandomAccess` requires that `size_hint()` must be exact and cheap to call, and
193 // `Iterator::__iterator_get_unchecked()` must be implemented accordingly.
195 // This is safe to implement as `Fuse` is just forwarding these to the wrapped iterator `I`, which
196 // preserves these properties.
197 unsafe impl<I> TrustedRandomAccess for Fuse<I> where I: TrustedRandomAccess {}
200 #[unstable(feature = "trusted_random_access", issue = "none")]
201 unsafe impl<I> TrustedRandomAccessNoCoerce for Fuse<I>
203 I: TrustedRandomAccessNoCoerce,
205 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
208 /// Fuse specialization trait
210 /// We only need to worry about `&mut self` methods, which
211 /// may exhaust the iterator without consuming it.
216 // Functions specific to any normal Iterators
217 fn next(&mut self) -> Option<Self::Item>;
218 fn nth(&mut self, n: usize) -> Option<Self::Item>;
219 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
222 Fold: FnMut(Acc, Self::Item) -> R,
223 R: Try<Output = Acc>;
224 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
226 P: FnMut(&Self::Item) -> bool;
228 // Functions specific to DoubleEndedIterators
229 fn next_back(&mut self) -> Option<Self::Item>
231 I: DoubleEndedIterator;
232 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
234 I: DoubleEndedIterator;
235 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
238 Fold: FnMut(Acc, Self::Item) -> R,
239 R: Try<Output = Acc>,
240 I: DoubleEndedIterator;
241 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
243 P: FnMut(&Self::Item) -> bool,
244 I: DoubleEndedIterator;
247 /// General `Fuse` impl which sets `iter = None` when exhausted.
249 impl<I> FuseImpl<I> for Fuse<I>
253 type Item = <I as Iterator>::Item;
256 default fn next(&mut self) -> Option<<I as Iterator>::Item> {
257 and_then_or_clear(&mut self.iter, Iterator::next)
261 default fn nth(&mut self, n: usize) -> Option<I::Item> {
262 and_then_or_clear(&mut self.iter, |iter| iter.nth(n))
266 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
269 Fold: FnMut(Acc, Self::Item) -> R,
270 R: Try<Output = Acc>,
272 if let Some(ref mut iter) = self.iter {
273 acc = iter.try_fold(acc, fold)?;
280 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
282 P: FnMut(&Self::Item) -> bool,
284 and_then_or_clear(&mut self.iter, |iter| iter.find(predicate))
288 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
290 I: DoubleEndedIterator,
292 and_then_or_clear(&mut self.iter, |iter| iter.next_back())
296 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
298 I: DoubleEndedIterator,
300 and_then_or_clear(&mut self.iter, |iter| iter.nth_back(n))
304 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
307 Fold: FnMut(Acc, Self::Item) -> R,
308 R: Try<Output = Acc>,
309 I: DoubleEndedIterator,
311 if let Some(ref mut iter) = self.iter {
312 acc = iter.try_rfold(acc, fold)?;
319 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
321 P: FnMut(&Self::Item) -> bool,
322 I: DoubleEndedIterator,
324 and_then_or_clear(&mut self.iter, |iter| iter.rfind(predicate))
328 /// Specialized `Fuse` impl which doesn't bother clearing `iter` when exhausted.
329 /// However, we must still be prepared for the possibility that it was already cleared!
331 impl<I> FuseImpl<I> for Fuse<I>
336 fn next(&mut self) -> Option<<I as Iterator>::Item> {
337 self.iter.as_mut()?.next()
341 fn nth(&mut self, n: usize) -> Option<I::Item> {
342 self.iter.as_mut()?.nth(n)
346 fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
349 Fold: FnMut(Acc, Self::Item) -> R,
350 R: Try<Output = Acc>,
352 if let Some(ref mut iter) = self.iter {
353 acc = iter.try_fold(acc, fold)?;
359 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
361 P: FnMut(&Self::Item) -> bool,
363 self.iter.as_mut()?.find(predicate)
367 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
369 I: DoubleEndedIterator,
371 self.iter.as_mut()?.next_back()
375 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
377 I: DoubleEndedIterator,
379 self.iter.as_mut()?.nth_back(n)
383 fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
386 Fold: FnMut(Acc, Self::Item) -> R,
387 R: Try<Output = Acc>,
388 I: DoubleEndedIterator,
390 if let Some(ref mut iter) = self.iter {
391 acc = iter.try_rfold(acc, fold)?;
397 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
399 P: FnMut(&Self::Item) -> bool,
400 I: DoubleEndedIterator,
402 self.iter.as_mut()?.rfind(predicate)
407 fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
408 let x = f(opt.as_mut()?);