1 use super::InPlaceIterable;
3 use crate::iter::adapters::zip::try_get_unchecked;
4 use crate::iter::adapters::SourceIter;
5 use crate::iter::TrustedRandomAccess;
6 use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
9 /// An iterator that yields `None` forever after the underlying iterator
10 /// yields `None` once.
12 /// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
13 /// documentation for more.
15 /// [`fuse`]: trait.Iterator.html#method.fuse
16 /// [`Iterator`]: trait.Iterator.html
17 #[derive(Clone, Debug)]
18 #[must_use = "iterators are lazy and do nothing unless consumed"]
19 #[stable(feature = "rust1", since = "1.0.0")]
21 // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
25 pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
26 Fuse { iter: Some(iter) }
30 #[stable(feature = "fused", since = "1.26.0")]
31 impl<I> FusedIterator for Fuse<I> where I: Iterator {}
33 /// Fuse the iterator if the expression is `None`.
35 ($self:ident . iter . $($call:tt)+) => {
37 Some(ref mut iter) => match iter.$($call)+ {
49 // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
50 // Implementing this as a directly-expanded macro helps codegen performance.
51 macro_rules! unchecked {
54 Fuse { iter: Some(iter) } => iter,
55 // SAFETY: the specialized iterator never sets `None`
56 Fuse { iter: None } => unsafe { intrinsics::unreachable() },
61 // Any implementation here is made internal to avoid exposing default fns outside this trait
62 #[stable(feature = "rust1", since = "1.0.0")]
63 impl<I> Iterator for Fuse<I>
67 type Item = <I as Iterator>::Item;
70 fn next(&mut self) -> Option<Self::Item> {
75 fn nth(&mut self, n: usize) -> Option<I::Item> {
76 FuseImpl::nth(self, n)
80 fn last(self) -> Option<Self::Item> {
85 fn count(self) -> usize {
90 fn size_hint(&self) -> (usize, Option<usize>) {
91 FuseImpl::size_hint(self)
95 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
98 Fold: FnMut(Acc, Self::Item) -> R,
101 FuseImpl::try_fold(self, acc, fold)
105 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
107 Fold: FnMut(Acc, Self::Item) -> Acc,
109 FuseImpl::fold(self, acc, fold)
113 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
115 P: FnMut(&Self::Item) -> bool,
117 FuseImpl::find(self, predicate)
121 unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item
123 Self: TrustedRandomAccess,
126 // SAFETY: the caller must uphold the contract for `Iterator::get_unchecked`.
127 Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
128 // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
129 None => unsafe { intrinsics::unreachable() },
134 #[stable(feature = "rust1", since = "1.0.0")]
135 impl<I> DoubleEndedIterator for Fuse<I>
137 I: DoubleEndedIterator,
140 fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
141 FuseImpl::next_back(self)
145 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
146 FuseImpl::nth_back(self, n)
150 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
153 Fold: FnMut(Acc, Self::Item) -> R,
156 FuseImpl::try_rfold(self, acc, fold)
160 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
162 Fold: FnMut(Acc, Self::Item) -> Acc,
164 FuseImpl::rfold(self, acc, fold)
168 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
170 P: FnMut(&Self::Item) -> bool,
172 FuseImpl::rfind(self, predicate)
176 #[stable(feature = "rust1", since = "1.0.0")]
177 impl<I> ExactSizeIterator for Fuse<I>
179 I: ExactSizeIterator,
181 fn len(&self) -> usize {
185 fn is_empty(&self) -> bool {
186 FuseImpl::is_empty(self)
191 #[unstable(feature = "trusted_random_access", issue = "none")]
192 unsafe impl<I> TrustedRandomAccess for Fuse<I>
194 I: TrustedRandomAccess,
196 fn may_have_side_effect() -> bool {
197 I::may_have_side_effect()
201 // Fuse specialization trait
206 // Functions specific to any normal Iterators
207 fn next(&mut self) -> Option<Self::Item>;
208 fn nth(&mut self, n: usize) -> Option<Self::Item>;
209 fn last(self) -> Option<Self::Item>;
210 fn count(self) -> usize;
211 fn size_hint(&self) -> (usize, Option<usize>);
212 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
215 Fold: FnMut(Acc, Self::Item) -> R,
217 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
219 Fold: FnMut(Acc, Self::Item) -> Acc;
220 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
222 P: FnMut(&Self::Item) -> bool;
224 // Functions specific to DoubleEndedIterators
225 fn next_back(&mut self) -> Option<Self::Item>
227 I: DoubleEndedIterator;
228 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
230 I: DoubleEndedIterator;
231 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
234 Fold: FnMut(Acc, Self::Item) -> R,
236 I: DoubleEndedIterator;
237 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
239 Fold: FnMut(Acc, Self::Item) -> Acc,
240 I: DoubleEndedIterator;
241 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
243 P: FnMut(&Self::Item) -> bool,
244 I: DoubleEndedIterator;
246 // Functions specific to ExactSizeIterator
247 fn len(&self) -> usize
249 I: ExactSizeIterator;
250 fn is_empty(&self) -> bool
252 I: ExactSizeIterator;
257 impl<I> FuseImpl<I> for Fuse<I>
261 type Item = <I as Iterator>::Item;
264 default fn next(&mut self) -> Option<<I as Iterator>::Item> {
265 fuse!(self.iter.next())
269 default fn nth(&mut self, n: usize) -> Option<I::Item> {
270 fuse!(self.iter.nth(n))
274 default fn last(self) -> Option<I::Item> {
276 Some(iter) => iter.last(),
282 default fn count(self) -> usize {
284 Some(iter) => iter.count(),
290 default fn size_hint(&self) -> (usize, Option<usize>) {
292 Some(ref iter) => iter.size_hint(),
293 None => (0, Some(0)),
298 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
301 Fold: FnMut(Acc, Self::Item) -> R,
304 if let Some(ref mut iter) = self.iter {
305 acc = iter.try_fold(acc, fold)?;
312 default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
314 Fold: FnMut(Acc, Self::Item) -> Acc,
316 if let Some(iter) = self.iter {
317 acc = iter.fold(acc, fold);
323 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
325 P: FnMut(&Self::Item) -> bool,
327 fuse!(self.iter.find(predicate))
331 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
333 I: DoubleEndedIterator,
335 fuse!(self.iter.next_back())
339 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
341 I: DoubleEndedIterator,
343 fuse!(self.iter.nth_back(n))
347 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
350 Fold: FnMut(Acc, Self::Item) -> R,
352 I: DoubleEndedIterator,
354 if let Some(ref mut iter) = self.iter {
355 acc = iter.try_rfold(acc, fold)?;
362 default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
364 Fold: FnMut(Acc, Self::Item) -> Acc,
365 I: DoubleEndedIterator,
367 if let Some(iter) = self.iter {
368 acc = iter.rfold(acc, fold);
374 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
376 P: FnMut(&Self::Item) -> bool,
377 I: DoubleEndedIterator,
379 fuse!(self.iter.rfind(predicate))
383 default fn len(&self) -> usize
385 I: ExactSizeIterator,
388 Some(ref iter) => iter.len(),
394 default fn is_empty(&self) -> bool
396 I: ExactSizeIterator,
399 Some(ref iter) => iter.is_empty(),
406 impl<I> FuseImpl<I> for Fuse<I>
411 fn next(&mut self) -> Option<<I as Iterator>::Item> {
412 unchecked!(self).next()
416 fn nth(&mut self, n: usize) -> Option<I::Item> {
417 unchecked!(self).nth(n)
421 fn last(self) -> Option<I::Item> {
422 unchecked!(self).last()
426 fn count(self) -> usize {
427 unchecked!(self).count()
431 fn size_hint(&self) -> (usize, Option<usize>) {
432 unchecked!(self).size_hint()
436 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
439 Fold: FnMut(Acc, Self::Item) -> R,
442 unchecked!(self).try_fold(init, fold)
446 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
448 Fold: FnMut(Acc, Self::Item) -> Acc,
450 unchecked!(self).fold(init, fold)
454 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
456 P: FnMut(&Self::Item) -> bool,
458 unchecked!(self).find(predicate)
462 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
464 I: DoubleEndedIterator,
466 unchecked!(self).next_back()
470 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
472 I: DoubleEndedIterator,
474 unchecked!(self).nth_back(n)
478 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
481 Fold: FnMut(Acc, Self::Item) -> R,
483 I: DoubleEndedIterator,
485 unchecked!(self).try_rfold(init, fold)
489 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
491 Fold: FnMut(Acc, Self::Item) -> Acc,
492 I: DoubleEndedIterator,
494 unchecked!(self).rfold(init, fold)
498 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
500 P: FnMut(&Self::Item) -> bool,
501 I: DoubleEndedIterator,
503 unchecked!(self).rfind(predicate)
507 fn len(&self) -> usize
509 I: ExactSizeIterator,
511 unchecked!(self).len()
515 fn is_empty(&self) -> bool
517 I: ExactSizeIterator,
519 unchecked!(self).is_empty()
523 #[unstable(issue = "none", feature = "inplace_iteration")]
524 unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
526 I: SourceIter<Source = S>,
531 unsafe fn as_inner(&mut self) -> &mut S {
533 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
534 Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
535 // SAFETY: the specialized iterator never sets `None`
536 None => unsafe { intrinsics::unreachable() },
541 #[unstable(issue = "none", feature = "inplace_iteration")]
542 unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}