2 use crate::iter::adapters::{zip::try_get_unchecked, InPlaceIterable, SourceIter};
3 use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedRandomAccess};
6 /// An iterator that yields `None` forever after the underlying iterator
7 /// yields `None` once.
9 /// This `struct` is created by [`Iterator::fuse`]. See its documentation
11 #[derive(Clone, Debug)]
12 #[must_use = "iterators are lazy and do nothing unless consumed"]
13 #[stable(feature = "rust1", since = "1.0.0")]
15 // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
19 pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
20 Fuse { iter: Some(iter) }
24 #[stable(feature = "fused", since = "1.26.0")]
25 impl<I> FusedIterator for Fuse<I> where I: Iterator {}
27 /// Fuse the iterator if the expression is `None`.
29 ($self:ident . iter . $($call:tt)+) => {
31 Some(ref mut iter) => match iter.$($call)+ {
43 // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
44 // Implementing this as a directly-expanded macro helps codegen performance.
45 macro_rules! unchecked {
48 Fuse { iter: Some(iter) } => iter,
49 // SAFETY: the specialized iterator never sets `None`
50 Fuse { iter: None } => unsafe { intrinsics::unreachable() },
55 // Any implementation here is made internal to avoid exposing default fns outside this trait
56 #[stable(feature = "rust1", since = "1.0.0")]
57 impl<I> Iterator for Fuse<I>
61 type Item = <I as Iterator>::Item;
64 fn next(&mut self) -> Option<Self::Item> {
69 fn nth(&mut self, n: usize) -> Option<I::Item> {
70 FuseImpl::nth(self, n)
74 fn last(self) -> Option<Self::Item> {
79 fn count(self) -> usize {
84 fn size_hint(&self) -> (usize, Option<usize>) {
85 FuseImpl::size_hint(self)
89 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
92 Fold: FnMut(Acc, Self::Item) -> R,
95 FuseImpl::try_fold(self, acc, fold)
99 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
101 Fold: FnMut(Acc, Self::Item) -> Acc,
103 FuseImpl::fold(self, acc, fold)
107 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
109 P: FnMut(&Self::Item) -> bool,
111 FuseImpl::find(self, predicate)
115 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
117 Self: TrustedRandomAccess,
120 // SAFETY: the caller must uphold the contract for
121 // `Iterator::__iterator_get_unchecked`.
122 Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
123 // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
124 None => unsafe { intrinsics::unreachable() },
129 #[stable(feature = "rust1", since = "1.0.0")]
130 impl<I> DoubleEndedIterator for Fuse<I>
132 I: DoubleEndedIterator,
135 fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
136 FuseImpl::next_back(self)
140 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
141 FuseImpl::nth_back(self, n)
145 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
148 Fold: FnMut(Acc, Self::Item) -> R,
151 FuseImpl::try_rfold(self, acc, fold)
155 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
157 Fold: FnMut(Acc, Self::Item) -> Acc,
159 FuseImpl::rfold(self, acc, fold)
163 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
165 P: FnMut(&Self::Item) -> bool,
167 FuseImpl::rfind(self, predicate)
171 #[stable(feature = "rust1", since = "1.0.0")]
172 impl<I> ExactSizeIterator for Fuse<I>
174 I: ExactSizeIterator,
176 fn len(&self) -> usize {
180 fn is_empty(&self) -> bool {
181 FuseImpl::is_empty(self)
186 #[unstable(feature = "trusted_random_access", issue = "none")]
187 unsafe impl<I> TrustedRandomAccess for Fuse<I>
189 I: TrustedRandomAccess,
191 fn may_have_side_effect() -> bool {
192 I::may_have_side_effect()
196 // Fuse specialization trait
201 // Functions specific to any normal Iterators
202 fn next(&mut self) -> Option<Self::Item>;
203 fn nth(&mut self, n: usize) -> Option<Self::Item>;
204 fn last(self) -> Option<Self::Item>;
205 fn count(self) -> usize;
206 fn size_hint(&self) -> (usize, Option<usize>);
207 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
210 Fold: FnMut(Acc, Self::Item) -> R,
212 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
214 Fold: FnMut(Acc, Self::Item) -> Acc;
215 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
217 P: FnMut(&Self::Item) -> bool;
219 // Functions specific to DoubleEndedIterators
220 fn next_back(&mut self) -> Option<Self::Item>
222 I: DoubleEndedIterator;
223 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
225 I: DoubleEndedIterator;
226 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
229 Fold: FnMut(Acc, Self::Item) -> R,
231 I: DoubleEndedIterator;
232 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
234 Fold: FnMut(Acc, Self::Item) -> Acc,
235 I: DoubleEndedIterator;
236 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
238 P: FnMut(&Self::Item) -> bool,
239 I: DoubleEndedIterator;
241 // Functions specific to ExactSizeIterator
242 fn len(&self) -> usize
244 I: ExactSizeIterator;
245 fn is_empty(&self) -> bool
247 I: ExactSizeIterator;
252 impl<I> FuseImpl<I> for Fuse<I>
256 type Item = <I as Iterator>::Item;
259 default fn next(&mut self) -> Option<<I as Iterator>::Item> {
260 fuse!(self.iter.next())
264 default fn nth(&mut self, n: usize) -> Option<I::Item> {
265 fuse!(self.iter.nth(n))
269 default fn last(self) -> Option<I::Item> {
271 Some(iter) => iter.last(),
277 default fn count(self) -> usize {
279 Some(iter) => iter.count(),
285 default fn size_hint(&self) -> (usize, Option<usize>) {
287 Some(ref iter) => iter.size_hint(),
288 None => (0, Some(0)),
293 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
296 Fold: FnMut(Acc, Self::Item) -> R,
299 if let Some(ref mut iter) = self.iter {
300 acc = iter.try_fold(acc, fold)?;
307 default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
309 Fold: FnMut(Acc, Self::Item) -> Acc,
311 if let Some(iter) = self.iter {
312 acc = iter.fold(acc, fold);
318 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
320 P: FnMut(&Self::Item) -> bool,
322 fuse!(self.iter.find(predicate))
326 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
328 I: DoubleEndedIterator,
330 fuse!(self.iter.next_back())
334 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
336 I: DoubleEndedIterator,
338 fuse!(self.iter.nth_back(n))
342 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
345 Fold: FnMut(Acc, Self::Item) -> R,
347 I: DoubleEndedIterator,
349 if let Some(ref mut iter) = self.iter {
350 acc = iter.try_rfold(acc, fold)?;
357 default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
359 Fold: FnMut(Acc, Self::Item) -> Acc,
360 I: DoubleEndedIterator,
362 if let Some(iter) = self.iter {
363 acc = iter.rfold(acc, fold);
369 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
371 P: FnMut(&Self::Item) -> bool,
372 I: DoubleEndedIterator,
374 fuse!(self.iter.rfind(predicate))
378 default fn len(&self) -> usize
380 I: ExactSizeIterator,
383 Some(ref iter) => iter.len(),
389 default fn is_empty(&self) -> bool
391 I: ExactSizeIterator,
394 Some(ref iter) => iter.is_empty(),
401 impl<I> FuseImpl<I> for Fuse<I>
406 fn next(&mut self) -> Option<<I as Iterator>::Item> {
407 unchecked!(self).next()
411 fn nth(&mut self, n: usize) -> Option<I::Item> {
412 unchecked!(self).nth(n)
416 fn last(self) -> Option<I::Item> {
417 unchecked!(self).last()
421 fn count(self) -> usize {
422 unchecked!(self).count()
426 fn size_hint(&self) -> (usize, Option<usize>) {
427 unchecked!(self).size_hint()
431 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
434 Fold: FnMut(Acc, Self::Item) -> R,
437 unchecked!(self).try_fold(init, fold)
441 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
443 Fold: FnMut(Acc, Self::Item) -> Acc,
445 unchecked!(self).fold(init, fold)
449 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
451 P: FnMut(&Self::Item) -> bool,
453 unchecked!(self).find(predicate)
457 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
459 I: DoubleEndedIterator,
461 unchecked!(self).next_back()
465 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
467 I: DoubleEndedIterator,
469 unchecked!(self).nth_back(n)
473 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
476 Fold: FnMut(Acc, Self::Item) -> R,
478 I: DoubleEndedIterator,
480 unchecked!(self).try_rfold(init, fold)
484 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
486 Fold: FnMut(Acc, Self::Item) -> Acc,
487 I: DoubleEndedIterator,
489 unchecked!(self).rfold(init, fold)
493 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
495 P: FnMut(&Self::Item) -> bool,
496 I: DoubleEndedIterator,
498 unchecked!(self).rfind(predicate)
502 fn len(&self) -> usize
504 I: ExactSizeIterator,
506 unchecked!(self).len()
510 fn is_empty(&self) -> bool
512 I: ExactSizeIterator,
514 unchecked!(self).is_empty()
518 #[unstable(issue = "none", feature = "inplace_iteration")]
519 unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
521 I: SourceIter<Source = S>,
526 unsafe fn as_inner(&mut self) -> &mut S {
528 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
529 Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
530 // SAFETY: the specialized iterator never sets `None`
531 None => unsafe { intrinsics::unreachable() },
536 #[unstable(issue = "none", feature = "inplace_iteration")]
537 unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}