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