diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 02dc9b8f82ed2..14fd182ece289 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2261,17 +2261,60 @@ where #[stable(feature = "rust1", since = "1.0.0")] pub struct Fuse { iter: I, - done: bool, + done: ::Flag, } impl Fuse { pub(super) fn new(iter: I) -> Fuse { - Fuse { iter, done: false } + Fuse { iter, done: <_>::default() } } } #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Fuse where I: Iterator {} +mod fuse_flag { + pub trait Flag: Clone + crate::fmt::Debug + Default { + fn is_set(&self) -> bool; + fn set(&mut self); + } + + impl Flag for bool { + fn is_set(&self) -> bool { + *self + } + + fn set(&mut self) { + *self = true + } + } + + #[derive(Clone, Debug, Default)] + pub struct False; + + impl Flag for False { + fn is_set(&self) -> bool { + false + } + + fn set(&mut self) { + /* intenionally does nothing */ + } + } + + pub trait FlagType { + type Flag: Flag; + } + + impl FlagType for I { + default type Flag = bool; + } + + impl FlagType for I { + type Flag = False; + } +} +use fuse_flag::Flag; + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Fuse where @@ -2280,64 +2323,68 @@ where type Item = ::Item; #[inline] - default fn next(&mut self) -> Option<::Item> { - if self.done { + fn next(&mut self) -> Option<::Item> { + if self.done.is_set() { None } else { let next = self.iter.next(); - self.done = next.is_none(); + if next.is_none() { + self.done.set(); + } next } } #[inline] - default fn nth(&mut self, n: usize) -> Option { - if self.done { + fn nth(&mut self, n: usize) -> Option { + if self.done.is_set() { None } else { let nth = self.iter.nth(n); - self.done = nth.is_none(); + if nth.is_none() { + self.done.set(); + } nth } } #[inline] - default fn last(self) -> Option { - if self.done { None } else { self.iter.last() } + fn last(self) -> Option { + if self.done.is_set() { None } else { self.iter.last() } } #[inline] - default fn count(self) -> usize { - if self.done { 0 } else { self.iter.count() } + fn count(self) -> usize { + if self.done.is_set() { 0 } else { self.iter.count() } } #[inline] - default fn size_hint(&self) -> (usize, Option) { - if self.done { (0, Some(0)) } else { self.iter.size_hint() } + fn size_hint(&self) -> (usize, Option) { + if self.done.is_set() { (0, Some(0)) } else { self.iter.size_hint() } } #[inline] - default fn try_fold(&mut self, init: Acc, fold: Fold) -> R + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - if self.done { + if self.done.is_set() { Try::from_ok(init) } else { let acc = self.iter.try_fold(init, fold)?; - self.done = true; + self.done.set(); Try::from_ok(acc) } } #[inline] - default fn fold(self, init: Acc, fold: Fold) -> Acc + fn fold(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - if self.done { init } else { self.iter.fold(init, fold) } + if self.done.is_set() { init } else { self.iter.fold(init, fold) } } } @@ -2347,49 +2394,53 @@ where I: DoubleEndedIterator, { #[inline] - default fn next_back(&mut self) -> Option<::Item> { - if self.done { + fn next_back(&mut self) -> Option<::Item> { + if self.done.is_set() { None } else { let next = self.iter.next_back(); - self.done = next.is_none(); + if next.is_none() { + self.done.set(); + } next } } #[inline] - default fn nth_back(&mut self, n: usize) -> Option<::Item> { - if self.done { + fn nth_back(&mut self, n: usize) -> Option<::Item> { + if self.done.is_set() { None } else { let nth = self.iter.nth_back(n); - self.done = nth.is_none(); + if nth.is_none() { + self.done.set(); + } nth } } #[inline] - default fn try_rfold(&mut self, init: Acc, fold: Fold) -> R + fn try_rfold(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - if self.done { + if self.done.is_set() { Try::from_ok(init) } else { let acc = self.iter.try_rfold(init, fold)?; - self.done = true; + self.done.set(); Try::from_ok(acc) } } #[inline] - default fn rfold(self, init: Acc, fold: Fold) -> Acc + fn rfold(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - if self.done { init } else { self.iter.rfold(init, fold) } + if self.done.is_set() { init } else { self.iter.rfold(init, fold) } } } @@ -2406,89 +2457,6 @@ where } } -#[stable(feature = "fused", since = "1.26.0")] -impl Iterator for Fuse -where - I: FusedIterator, -{ - #[inline] - fn next(&mut self) -> Option<::Item> { - self.iter.next() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - self.iter.nth(n) - } - - #[inline] - fn last(self) -> Option { - self.iter.last() - } - - #[inline] - fn count(self) -> usize { - self.iter.count() - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - - #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R - where - Self: Sized, - Fold: FnMut(Acc, Self::Item) -> R, - R: Try, - { - self.iter.try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where - Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.iter.fold(init, fold) - } -} - -#[stable(feature = "fused", since = "1.26.0")] -impl DoubleEndedIterator for Fuse -where - I: DoubleEndedIterator + FusedIterator, -{ - #[inline] - fn next_back(&mut self) -> Option<::Item> { - self.iter.next_back() - } - - #[inline] - fn nth_back(&mut self, n: usize) -> Option<::Item> { - self.iter.nth_back(n) - } - - #[inline] - fn try_rfold(&mut self, init: Acc, fold: Fold) -> R - where - Self: Sized, - Fold: FnMut(Acc, Self::Item) -> R, - R: Try, - { - self.iter.try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where - Fold: FnMut(Acc, Self::Item) -> Acc, - { - self.iter.rfold(init, fold) - } -} - #[stable(feature = "rust1", since = "1.0.0")] impl ExactSizeIterator for Fuse where