1use crate::intrinsics;
2use crate::iter::adapters::SourceIter;
3use crate::iter::adapters::zip::try_get_unchecked;
4use crate::iter::{
5 FusedIterator, TrustedFused, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce,
6};
7use crate::ops::Try;
8
9#[derive(Clone, Debug)]
15#[must_use = "iterators are lazy and do nothing unless consumed"]
16#[stable(feature = "rust1", since = "1.0.0")]
17pub struct Fuse<I> {
18 iter: Option<I>,
22}
23impl<I> Fuse<I> {
24 pub(in crate::iter) fn new(iter: I) -> Fuse<I> {
25 Fuse { iter: Some(iter) }
26 }
27
28 pub(crate) fn into_inner(self) -> Option<I> {
29 self.iter
30 }
31}
32
33#[stable(feature = "fused", since = "1.26.0")]
34impl<I> FusedIterator for Fuse<I> where I: Iterator {}
35
36#[unstable(issue = "none", feature = "trusted_fused")]
37unsafe impl<I> TrustedFused for Fuse<I> where I: TrustedFused {}
38
39#[stable(feature = "rust1", since = "1.0.0")]
42impl<I> Iterator for Fuse<I>
43where
44 I: Iterator,
45{
46 type Item = <I as Iterator>::Item;
47
48 #[inline]
49 fn next(&mut self) -> Option<Self::Item> {
50 FuseImpl::next(self)
51 }
52
53 #[inline]
54 fn nth(&mut self, n: usize) -> Option<I::Item> {
55 FuseImpl::nth(self, n)
56 }
57
58 #[inline]
59 fn last(self) -> Option<Self::Item> {
60 match self.iter {
61 Some(iter) => iter.last(),
62 None => None,
63 }
64 }
65
66 #[inline]
67 fn count(self) -> usize {
68 match self.iter {
69 Some(iter) => iter.count(),
70 None => 0,
71 }
72 }
73
74 #[inline]
75 fn size_hint(&self) -> (usize, Option<usize>) {
76 match self.iter {
77 Some(ref iter) => iter.size_hint(),
78 None => (0, Some(0)),
79 }
80 }
81
82 #[inline]
83 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
84 where
85 Self: Sized,
86 Fold: FnMut(Acc, Self::Item) -> R,
87 R: Try<Output = Acc>,
88 {
89 FuseImpl::try_fold(self, acc, fold)
90 }
91
92 #[inline]
93 fn fold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
94 where
95 Fold: FnMut(Acc, Self::Item) -> Acc,
96 {
97 if let Some(iter) = self.iter {
98 acc = iter.fold(acc, fold);
99 }
100 acc
101 }
102
103 #[inline]
104 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
105 where
106 P: FnMut(&Self::Item) -> bool,
107 {
108 FuseImpl::find(self, predicate)
109 }
110
111 #[inline]
112 unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
113 where
114 Self: TrustedRandomAccessNoCoerce,
115 {
116 match self.iter {
117 Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
120 None => unsafe { intrinsics::unreachable() },
122 }
123 }
124}
125
126#[stable(feature = "rust1", since = "1.0.0")]
127impl<I> DoubleEndedIterator for Fuse<I>
128where
129 I: DoubleEndedIterator,
130{
131 #[inline]
132 fn next_back(&mut self) -> Option<<I as Iterator>::Item> {
133 FuseImpl::next_back(self)
134 }
135
136 #[inline]
137 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item> {
138 FuseImpl::nth_back(self, n)
139 }
140
141 #[inline]
142 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
143 where
144 Self: Sized,
145 Fold: FnMut(Acc, Self::Item) -> R,
146 R: Try<Output = Acc>,
147 {
148 FuseImpl::try_rfold(self, acc, fold)
149 }
150
151 #[inline]
152 fn rfold<Acc, Fold>(self, mut acc: Acc, fold: Fold) -> Acc
153 where
154 Fold: FnMut(Acc, Self::Item) -> Acc,
155 {
156 if let Some(iter) = self.iter {
157 acc = iter.rfold(acc, fold);
158 }
159 acc
160 }
161
162 #[inline]
163 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
164 where
165 P: FnMut(&Self::Item) -> bool,
166 {
167 FuseImpl::rfind(self, predicate)
168 }
169}
170
171#[stable(feature = "rust1", since = "1.0.0")]
172impl<I> ExactSizeIterator for Fuse<I>
173where
174 I: ExactSizeIterator,
175{
176 fn len(&self) -> usize {
177 match self.iter {
178 Some(ref iter) => iter.len(),
179 None => 0,
180 }
181 }
182
183 fn is_empty(&self) -> bool {
184 match self.iter {
185 Some(ref iter) => iter.is_empty(),
186 None => true,
187 }
188 }
189}
190
191#[stable(feature = "default_iters", since = "1.70.0")]
192impl<I: Default> Default for Fuse<I> {
193 fn default() -> Self {
224 Fuse { iter: Some(I::default()) }
225 }
226}
227
228#[unstable(feature = "trusted_len", issue = "37572")]
229unsafe impl<I> TrustedLen for Fuse<I> where I: TrustedLen {}
233
234#[doc(hidden)]
235#[unstable(feature = "trusted_random_access", issue = "none")]
236unsafe impl<I> TrustedRandomAccess for Fuse<I> where I: TrustedRandomAccess {}
242
243#[doc(hidden)]
244#[unstable(feature = "trusted_random_access", issue = "none")]
245unsafe impl<I> TrustedRandomAccessNoCoerce for Fuse<I>
246where
247 I: TrustedRandomAccessNoCoerce,
248{
249 const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
250}
251
252#[doc(hidden)]
257trait FuseImpl<I> {
258 type Item;
259
260 fn next(&mut self) -> Option<Self::Item>;
262 fn nth(&mut self, n: usize) -> Option<Self::Item>;
263 fn try_fold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
264 where
265 Self: Sized,
266 Fold: FnMut(Acc, Self::Item) -> R,
267 R: Try<Output = Acc>;
268 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
269 where
270 P: FnMut(&Self::Item) -> bool;
271
272 fn next_back(&mut self) -> Option<Self::Item>
274 where
275 I: DoubleEndedIterator;
276 fn nth_back(&mut self, n: usize) -> Option<Self::Item>
277 where
278 I: DoubleEndedIterator;
279 fn try_rfold<Acc, Fold, R>(&mut self, acc: Acc, fold: Fold) -> R
280 where
281 Self: Sized,
282 Fold: FnMut(Acc, Self::Item) -> R,
283 R: Try<Output = Acc>,
284 I: DoubleEndedIterator;
285 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
286 where
287 P: FnMut(&Self::Item) -> bool,
288 I: DoubleEndedIterator;
289}
290
291#[doc(hidden)]
293impl<I> FuseImpl<I> for Fuse<I>
294where
295 I: Iterator,
296{
297 type Item = <I as Iterator>::Item;
298
299 #[inline]
300 default fn next(&mut self) -> Option<<I as Iterator>::Item> {
301 and_then_or_clear(&mut self.iter, Iterator::next)
302 }
303
304 #[inline]
305 default fn nth(&mut self, n: usize) -> Option<I::Item> {
306 and_then_or_clear(&mut self.iter, |iter| iter.nth(n))
307 }
308
309 #[inline]
310 default fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
311 where
312 Self: Sized,
313 Fold: FnMut(Acc, Self::Item) -> R,
314 R: Try<Output = Acc>,
315 {
316 if let Some(ref mut iter) = self.iter {
317 acc = iter.try_fold(acc, fold)?;
318 self.iter = None;
319 }
320 try { acc }
321 }
322
323 #[inline]
324 default fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
325 where
326 P: FnMut(&Self::Item) -> bool,
327 {
328 and_then_or_clear(&mut self.iter, |iter| iter.find(predicate))
329 }
330
331 #[inline]
332 default fn next_back(&mut self) -> Option<<I as Iterator>::Item>
333 where
334 I: DoubleEndedIterator,
335 {
336 and_then_or_clear(&mut self.iter, |iter| iter.next_back())
337 }
338
339 #[inline]
340 default fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
341 where
342 I: DoubleEndedIterator,
343 {
344 and_then_or_clear(&mut self.iter, |iter| iter.nth_back(n))
345 }
346
347 #[inline]
348 default fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
349 where
350 Self: Sized,
351 Fold: FnMut(Acc, Self::Item) -> R,
352 R: Try<Output = Acc>,
353 I: DoubleEndedIterator,
354 {
355 if let Some(ref mut iter) = self.iter {
356 acc = iter.try_rfold(acc, fold)?;
357 self.iter = None;
358 }
359 try { acc }
360 }
361
362 #[inline]
363 default fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
364 where
365 P: FnMut(&Self::Item) -> bool,
366 I: DoubleEndedIterator,
367 {
368 and_then_or_clear(&mut self.iter, |iter| iter.rfind(predicate))
369 }
370}
371
372#[doc(hidden)]
375impl<I> FuseImpl<I> for Fuse<I>
376where
377 I: FusedIterator,
378{
379 #[inline]
380 fn next(&mut self) -> Option<<I as Iterator>::Item> {
381 self.iter.as_mut()?.next()
382 }
383
384 #[inline]
385 fn nth(&mut self, n: usize) -> Option<I::Item> {
386 self.iter.as_mut()?.nth(n)
387 }
388
389 #[inline]
390 fn try_fold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
391 where
392 Self: Sized,
393 Fold: FnMut(Acc, Self::Item) -> R,
394 R: Try<Output = Acc>,
395 {
396 if let Some(ref mut iter) = self.iter {
397 acc = iter.try_fold(acc, fold)?;
398 }
399 try { acc }
400 }
401
402 #[inline]
403 fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
404 where
405 P: FnMut(&Self::Item) -> bool,
406 {
407 self.iter.as_mut()?.find(predicate)
408 }
409
410 #[inline]
411 fn next_back(&mut self) -> Option<<I as Iterator>::Item>
412 where
413 I: DoubleEndedIterator,
414 {
415 self.iter.as_mut()?.next_back()
416 }
417
418 #[inline]
419 fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>
420 where
421 I: DoubleEndedIterator,
422 {
423 self.iter.as_mut()?.nth_back(n)
424 }
425
426 #[inline]
427 fn try_rfold<Acc, Fold, R>(&mut self, mut acc: Acc, fold: Fold) -> R
428 where
429 Self: Sized,
430 Fold: FnMut(Acc, Self::Item) -> R,
431 R: Try<Output = Acc>,
432 I: DoubleEndedIterator,
433 {
434 if let Some(ref mut iter) = self.iter {
435 acc = iter.try_rfold(acc, fold)?;
436 }
437 try { acc }
438 }
439
440 #[inline]
441 fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
442 where
443 P: FnMut(&Self::Item) -> bool,
444 I: DoubleEndedIterator,
445 {
446 self.iter.as_mut()?.rfind(predicate)
447 }
448}
449
450#[unstable(issue = "none", feature = "inplace_iteration")]
452unsafe impl<I> SourceIter for Fuse<I>
453where
454 I: SourceIter + TrustedFused,
455{
456 type Source = I::Source;
457
458 #[inline]
459 unsafe fn as_inner(&mut self) -> &mut I::Source {
460 unsafe { SourceIter::as_inner(self.iter.as_mut().unwrap_unchecked()) }
464 }
465}
466
467#[inline]
468fn and_then_or_clear<T, U>(opt: &mut Option<T>, f: impl FnOnce(&mut T) -> Option<U>) -> Option<U> {
469 let x = f(opt.as_mut()?);
470 if x.is_none() {
471 *opt = None;
472 }
473 x
474}