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 [`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`, this is always assumed `Some`!
22 pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
23 Fuse { iter: Some(iter) }
27 #[stable(feature = "fused", since = "1.26.0")]
28 impl<I> FusedIterator for Fuse<I> where I: Iterator {}
30 /// Fuse the iterator if the expression is `None`.
32 ($self:ident . iter . $($call:tt)+) => {
34 Some(ref mut iter) => match iter.$($call)+ {
46 // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
47 // Implementing this as a directly-expanded macro helps codegen performance.
48 macro_rules! unchecked {
51 Fuse { iter: Some(iter) } => iter,
52 // SAFETY: the specialized iterator never sets `None`
53 Fuse { iter: None } => unsafe { intrinsics::unreachable() },
58 // Any implementation here is made internal to avoid exposing default fns outside this trait
59 #[stable(feature = "rust1", since = "1.0.0")]
60 impl<I> Iterator for Fuse<I>
64 type Item = <I as Iterator>::Item;
67 fn next(&mut self) -> Option<Self::Item> {
72 fn nth(&mut self, n: usize) -> Option<I::Item> {
73 FuseImpl::nth(self, n)
77 fn last(self) -> Option<Self::Item> {
82 fn count(self) -> usize {
87 fn size_hint(&self) -> (usize, Option<usize>) {
88 FuseImpl::size_hint(self)
92 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
95 Fold: FnMut(Acc, Self::Item) -> R,
98 FuseImpl::try_fold(self, acc, fold)
102 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
104 Fold: FnMut(Acc, Self::Item) -> Acc,
106 FuseImpl::fold(self, acc, fold)
110 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
112 P: FnMut(&Self::Item) -> bool,
114 FuseImpl::find(self, predicate)
118 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
120 Self: TrustedRandomAccess,
123 // SAFETY: the caller must uphold the contract for
124 // `Iterator::__iterator_get_unchecked`.
125 Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
126 // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
127 None => unsafe { intrinsics::unreachable() },
132 #[stable(feature = "rust1", since = "1.0.0")]
133 impl<I> DoubleEndedIterator for Fuse<I>
135 I: DoubleEndedIterator,
138 fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
139 FuseImpl::next_back(self)
143 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
144 FuseImpl::nth_back(self, n)
148 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
151 Fold: FnMut(Acc, Self::Item) -> R,
154 FuseImpl::try_rfold(self, acc, fold)
158 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
160 Fold: FnMut(Acc, Self::Item) -> Acc,
162 FuseImpl::rfold(self, acc, fold)
166 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
168 P: FnMut(&Self::Item) -> bool,
170 FuseImpl::rfind(self, predicate)
174 #[stable(feature = "rust1", since = "1.0.0")]
175 impl<I> ExactSizeIterator for Fuse<I>
177 I: ExactSizeIterator,
179 fn len(&self) -> usize {
183 fn is_empty(&self) -> bool {
184 FuseImpl::is_empty(self)
189 #[unstable(feature = "trusted_random_access", issue = "none")]
190 unsafe impl<I> TrustedRandomAccess for Fuse<I>
192 I: TrustedRandomAccess,
194 fn may_have_side_effect() -> bool {
195 I::may_have_side_effect()
199 // Fuse specialization trait
204 // Functions specific to any normal Iterators
205 fn next(&mut self) -> Option<Self::Item>;
206 fn nth(&mut self, n: usize) -> Option<Self::Item>;
207 fn last(self) -> Option<Self::Item>;
208 fn count(self) -> usize;
209 fn size_hint(&self) -> (usize, Option<usize>);
210 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
213 Fold: FnMut(Acc, Self::Item) -> R,
215 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
217 Fold: FnMut(Acc, Self::Item) -> Acc;
218 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
220 P: FnMut(&Self::Item) -> bool;
222 // Functions specific to DoubleEndedIterators
223 fn next_back(&mut self) -> Option<Self::Item>
225 I: DoubleEndedIterator;
226 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
228 I: DoubleEndedIterator;
229 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
232 Fold: FnMut(Acc, Self::Item) -> R,
234 I: DoubleEndedIterator;
235 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
237 Fold: FnMut(Acc, Self::Item) -> Acc,
238 I: DoubleEndedIterator;
239 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
241 P: FnMut(&Self::Item) -> bool,
242 I: DoubleEndedIterator;
244 // Functions specific to ExactSizeIterator
245 fn len(&self) -> usize
247 I: ExactSizeIterator;
248 fn is_empty(&self) -> bool
250 I: ExactSizeIterator;
255 impl<I> FuseImpl<I> for Fuse<I>
259 type Item = <I as Iterator>::Item;
262 default fn next(&mut self) -> Option<<I as Iterator>::Item> {
263 fuse!(self.iter.next())
267 default fn nth(&mut self, n: usize) -> Option<I::Item> {
268 fuse!(self.iter.nth(n))
272 default fn last(self) -> Option<I::Item> {
274 Some(iter) => iter.last(),
280 default fn count(self) -> usize {
282 Some(iter) => iter.count(),
288 default fn size_hint(&self) -> (usize, Option<usize>) {
290 Some(ref iter) => iter.size_hint(),
291 None => (0, Some(0)),
296 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
299 Fold: FnMut(Acc, Self::Item) -> R,
302 if let Some(ref mut iter) = self.iter {
303 acc = iter.try_fold(acc, fold)?;
310 default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
312 Fold: FnMut(Acc, Self::Item) -> Acc,
314 if let Some(iter) = self.iter {
315 acc = iter.fold(acc, fold);
321 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
323 P: FnMut(&Self::Item) -> bool,
325 fuse!(self.iter.find(predicate))
329 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
331 I: DoubleEndedIterator,
333 fuse!(self.iter.next_back())
337 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
339 I: DoubleEndedIterator,
341 fuse!(self.iter.nth_back(n))
345 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
348 Fold: FnMut(Acc, Self::Item) -> R,
350 I: DoubleEndedIterator,
352 if let Some(ref mut iter) = self.iter {
353 acc = iter.try_rfold(acc, fold)?;
360 default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
362 Fold: FnMut(Acc, Self::Item) -> Acc,
363 I: DoubleEndedIterator,
365 if let Some(iter) = self.iter {
366 acc = iter.rfold(acc, fold);
372 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
374 P: FnMut(&Self::Item) -> bool,
375 I: DoubleEndedIterator,
377 fuse!(self.iter.rfind(predicate))
381 default fn len(&self) -> usize
383 I: ExactSizeIterator,
386 Some(ref iter) => iter.len(),
392 default fn is_empty(&self) -> bool
394 I: ExactSizeIterator,
397 Some(ref iter) => iter.is_empty(),
404 impl<I> FuseImpl<I> for Fuse<I>
409 fn next(&mut self) -> Option<<I as Iterator>::Item> {
410 unchecked!(self).next()
414 fn nth(&mut self, n: usize) -> Option<I::Item> {
415 unchecked!(self).nth(n)
419 fn last(self) -> Option<I::Item> {
420 unchecked!(self).last()
424 fn count(self) -> usize {
425 unchecked!(self).count()
429 fn size_hint(&self) -> (usize, Option<usize>) {
430 unchecked!(self).size_hint()
434 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
437 Fold: FnMut(Acc, Self::Item) -> R,
440 unchecked!(self).try_fold(init, fold)
444 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
446 Fold: FnMut(Acc, Self::Item) -> Acc,
448 unchecked!(self).fold(init, fold)
452 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
454 P: FnMut(&Self::Item) -> bool,
456 unchecked!(self).find(predicate)
460 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
462 I: DoubleEndedIterator,
464 unchecked!(self).next_back()
468 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
470 I: DoubleEndedIterator,
472 unchecked!(self).nth_back(n)
476 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
479 Fold: FnMut(Acc, Self::Item) -> R,
481 I: DoubleEndedIterator,
483 unchecked!(self).try_rfold(init, fold)
487 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
489 Fold: FnMut(Acc, Self::Item) -> Acc,
490 I: DoubleEndedIterator,
492 unchecked!(self).rfold(init, fold)
496 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
498 P: FnMut(&Self::Item) -> bool,
499 I: DoubleEndedIterator,
501 unchecked!(self).rfind(predicate)
505 fn len(&self) -> usize
507 I: ExactSizeIterator,
509 unchecked!(self).len()
513 fn is_empty(&self) -> bool
515 I: ExactSizeIterator,
517 unchecked!(self).is_empty()
521 #[unstable(issue = "none", feature = "inplace_iteration")]
522 unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I>
524 I: SourceIter<Source = S>,
529 unsafe fn as_inner(&mut self) -> &mut S {
531 // SAFETY: unsafe function forwarding to unsafe function with the same requirements
532 Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) },
533 // SAFETY: the specialized iterator never sets `None`
534 None => unsafe { intrinsics::unreachable() },
539 #[unstable(issue = "none", feature = "inplace_iteration")]
540 unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {}