3 DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedRandomAccess,
7 /// An iterator that yields `None` forever after the underlying iterator
8 /// yields `None` once.
10 /// This `struct` is created by the [`fuse`] method on [`Iterator`]. See its
11 /// documentation for more.
13 /// [`fuse`]: trait.Iterator.html#method.fuse
14 /// [`Iterator`]: trait.Iterator.html
15 #[derive(Clone, Debug)]
16 #[must_use = "iterators are lazy and do nothing unless consumed"]
17 #[stable(feature = "rust1", since = "1.0.0")]
19 // NOTE: for `I: FusedIterator`, this is always assumed `Some`!
23 pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
24 Fuse { iter: Some(iter) }
28 #[stable(feature = "fused", since = "1.26.0")]
29 impl<I> FusedIterator for Fuse<I> where I: Iterator {}
31 /// Fuse the iterator if the expression is `None`.
33 ($self:ident . iter . $($call:tt)+) => {
35 Some(ref mut iter) => match iter.$($call)+ {
47 // NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`.
48 // Implementing this as a directly-expanded macro helps codegen performance.
49 macro_rules! unchecked {
52 Fuse { iter: Some(iter) } => iter,
53 // SAFETY: the specialized iterator never sets `None`
54 Fuse { iter: None } => unsafe { intrinsics::unreachable() },
59 // Any implementation here is made internal to avoid exposing default fns outside this trait
60 #[stable(feature = "rust1", since = "1.0.0")]
61 impl<I> Iterator for Fuse<I>
65 type Item = <I as Iterator>::Item;
68 fn next(&mut self) -> Option<Self::Item> {
73 fn nth(&mut self, n: usize) -> Option<I::Item> {
74 FuseImpl::nth(self, n)
78 fn last(self) -> Option<Self::Item> {
83 fn count(self) -> usize {
88 fn size_hint(&self) -> (usize, Option<usize>) {
89 FuseImpl::size_hint(self)
93 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
96 Fold: FnMut(Acc, Self::Item) -> R,
99 FuseImpl::try_fold(self, acc, fold)
103 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
105 Fold: FnMut(Acc, Self::Item) -> Acc,
107 FuseImpl::fold(self, acc, fold)
111 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
113 P: FnMut(&Self::Item) -> bool,
115 FuseImpl::find(self, predicate)
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,
141 FuseImpl::try_rfold(self, acc, fold)
145 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
147 Fold: FnMut(Acc, Self::Item) -> Acc,
149 FuseImpl::rfold(self, acc, fold)
153 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
155 P: FnMut(&Self::Item) -> bool,
157 FuseImpl::rfind(self, predicate)
161 #[stable(feature = "rust1", since = "1.0.0")]
162 impl<I> ExactSizeIterator for Fuse<I>
164 I: ExactSizeIterator,
166 fn len(&self) -> usize {
170 fn is_empty(&self) -> bool {
171 FuseImpl::is_empty(self)
175 unsafe impl<I> TrustedRandomAccess for Fuse<I>
177 I: TrustedRandomAccess,
179 unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
181 // SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
182 Some(ref mut iter) => unsafe { iter.get_unchecked(i) },
183 // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
184 None => unsafe { intrinsics::unreachable() },
188 fn may_have_side_effect() -> bool {
189 I::may_have_side_effect()
193 // Fuse specialization trait
198 // Functions specific to any normal Iterators
199 fn next(&mut self) -> Option<Self::Item>;
200 fn nth(&mut self, n: usize) -> Option<Self::Item>;
201 fn last(self) -> Option<Self::Item>;
202 fn count(self) -> usize;
203 fn size_hint(&self) -> (usize, Option<usize>);
204 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
207 Fold: FnMut(Acc, Self::Item) -> R,
209 fn fold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
211 Fold: FnMut(Acc, Self::Item) -> Acc;
212 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
214 P: FnMut(&Self::Item) -> bool;
216 // Functions specific to DoubleEndedIterators
217 fn next_back(&mut self) -> Option<Self::Item>
219 I: DoubleEndedIterator;
220 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
222 I: DoubleEndedIterator;
223 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
226 Fold: FnMut(Acc, Self::Item) -> R,
228 I: DoubleEndedIterator;
229 fn rfold<Acc, Fold>(self, acc: Acc, fold: Fold) -> Acc
231 Fold: FnMut(Acc, Self::Item) -> Acc,
232 I: DoubleEndedIterator;
233 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
235 P: FnMut(&Self::Item) -> bool,
236 I: DoubleEndedIterator;
238 // Functions specific to ExactSizeIterator
239 fn len(&self) -> usize
241 I: ExactSizeIterator;
242 fn is_empty(&self) -> bool
244 I: ExactSizeIterator;
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 fuse!(self.iter.next())
261 default fn nth(&mut self, n: usize) -> Option<I::Item> {
262 fuse!(self.iter.nth(n))
266 default fn last(self) -> Option<I::Item> {
268 Some(iter) => iter.last(),
274 default fn count(self) -> usize {
276 Some(iter) => iter.count(),
282 default fn size_hint(&self) -> (usize, Option<usize>) {
284 Some(ref iter) => iter.size_hint(),
285 None => (0, Some(0)),
290 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
293 Fold: FnMut(Acc, Self::Item) -> R,
296 if let Some(ref mut iter) = self.iter {
297 acc = iter.try_fold(acc, fold)?;
304 default fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
306 Fold: FnMut(Acc, Self::Item) -> Acc,
308 if let Some(iter) = self.iter {
309 acc = iter.fold(acc, fold);
315 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
317 P: FnMut(&Self::Item) -> bool,
319 fuse!(self.iter.find(predicate))
323 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
325 I: DoubleEndedIterator,
327 fuse!(self.iter.next_back())
331 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
333 I: DoubleEndedIterator,
335 fuse!(self.iter.nth_back(n))
339 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
342 Fold: FnMut(Acc, Self::Item) -> R,
344 I: DoubleEndedIterator,
346 if let Some(ref mut iter) = self.iter {
347 acc = iter.try_rfold(acc, fold)?;
354 default fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
356 Fold: FnMut(Acc, Self::Item) -> Acc,
357 I: DoubleEndedIterator,
359 if let Some(iter) = self.iter {
360 acc = iter.rfold(acc, fold);
366 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
368 P: FnMut(&Self::Item) -> bool,
369 I: DoubleEndedIterator,
371 fuse!(self.iter.rfind(predicate))
375 default fn len(&self) -> usize
377 I: ExactSizeIterator,
380 Some(ref iter) => iter.len(),
386 default fn is_empty(&self) -> bool
388 I: ExactSizeIterator,
391 Some(ref iter) => iter.is_empty(),
398 impl<I> FuseImpl<I> for Fuse<I>
403 fn next(&mut self) -> Option<<I as Iterator>::Item> {
404 unchecked!(self).next()
408 fn nth(&mut self, n: usize) -> Option<I::Item> {
409 unchecked!(self).nth(n)
413 fn last(self) -> Option<I::Item> {
414 unchecked!(self).last()
418 fn count(self) -> usize {
419 unchecked!(self).count()
423 fn size_hint(&self) -> (usize, Option<usize>) {
424 unchecked!(self).size_hint()
428 fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
431 Fold: FnMut(Acc, Self::Item) -> R,
434 unchecked!(self).try_fold(init, fold)
438 fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
440 Fold: FnMut(Acc, Self::Item) -> Acc,
442 unchecked!(self).fold(init, fold)
446 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
448 P: FnMut(&Self::Item) -> bool,
450 unchecked!(self).find(predicate)
454 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
456 I: DoubleEndedIterator,
458 unchecked!(self).next_back()
462 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
464 I: DoubleEndedIterator,
466 unchecked!(self).nth_back(n)
470 fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
473 Fold: FnMut(Acc, Self::Item) -> R,
475 I: DoubleEndedIterator,
477 unchecked!(self).try_rfold(init, fold)
481 fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
483 Fold: FnMut(Acc, Self::Item) -> Acc,
484 I: DoubleEndedIterator,
486 unchecked!(self).rfold(init, fold)
490 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
492 P: FnMut(&Self::Item) -> bool,
493 I: DoubleEndedIterator,
495 unchecked!(self).rfind(predicate)
499 fn len(&self) -> usize
501 I: ExactSizeIterator,
503 unchecked!(self).len()
507 fn is_empty(&self) -> bool
509 I: ExactSizeIterator,
511 unchecked!(self).is_empty()