From ab20a60d61bd20e93dc15cb900f2af36c18cf70b Mon Sep 17 00:00:00 2001 From: AnthonyMikh Date: Tue, 10 Mar 2020 00:25:43 +0300 Subject: [PATCH 1/4] Introduce specializable flags --- src/libcore/iter/adapters/mod.rs | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 02dc9b8f82ed2..8a510b0732d33 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2272,6 +2272,48 @@ impl Fuse { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Fuse where I: Iterator {} +mod fuse_flag { + pub trait Flag: 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(Default)] + struct False; + + impl Flag for False { + fn is_set(&self) -> bool { + false + } + + fn set(&mut self) { + /* intenionally does nothing */ + } + } + + pub trait FlagType: Iterator { + type Flag: Flag; + } + + impl FlagType for I { + default type Flag = bool; + } + + impl FlagType for I { + type Flag = False; + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Fuse where From 17c6b18a6f12a0110dd0493f8457a778dd7add90 Mon Sep 17 00:00:00 2001 From: AnthonyMikh Date: Tue, 10 Mar 2020 00:33:54 +0300 Subject: [PATCH 2/4] Make Fuse use flags from fuse_flag --- src/libcore/iter/adapters/mod.rs | 47 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 8a510b0732d33..60f9cf7decdf6 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2261,11 +2261,11 @@ 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() } } } @@ -2313,6 +2313,7 @@ mod fuse_flag { type Flag = False; } } +use fuse_flag::Flag; #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Fuse @@ -2323,39 +2324,43 @@ where #[inline] default fn next(&mut self) -> Option<::Item> { - if self.done { + 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 { + 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() } + if self.done.is_set() { None } else { self.iter.last() } } #[inline] default fn count(self) -> usize { - if self.done { 0 } else { self.iter.count() } + 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() } + if self.done.is_set() { (0, Some(0)) } else { self.iter.size_hint() } } #[inline] @@ -2365,11 +2370,11 @@ where 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) } } @@ -2379,7 +2384,7 @@ where 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) } } } @@ -2390,22 +2395,26 @@ where { #[inline] default fn next_back(&mut self) -> Option<::Item> { - if self.done { + 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 { + 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 } } @@ -2417,11 +2426,11 @@ where 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) } } @@ -2431,7 +2440,7 @@ where 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) } } } From c484ce0f7193e964fd92a2763d67b63b48055076 Mon Sep 17 00:00:00 2001 From: AnthonyMikh Date: Tue, 10 Mar 2020 00:36:33 +0300 Subject: [PATCH 3/4] Remove specialised impls for Fuse --- src/libcore/iter/adapters/mod.rs | 121 ++++++------------------------- 1 file changed, 22 insertions(+), 99 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index 60f9cf7decdf6..b42782dcce0e0 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2259,11 +2259,17 @@ where #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Fuse { +pub struct Fuse +where + I: Iterator, +{ iter: I, done: ::Flag, } -impl Fuse { +impl Fuse +where + I: Iterator, +{ pub(super) fn new(iter: I) -> Fuse { Fuse { iter, done: <_>::default() } } @@ -2273,7 +2279,7 @@ impl Fuse { impl FusedIterator for Fuse where I: Iterator {} mod fuse_flag { - pub trait Flag: Default { + pub trait Flag: Clone + crate::fmt::Debug + Default { fn is_set(&self) -> bool; fn set(&mut self); } @@ -2288,8 +2294,8 @@ mod fuse_flag { } } - #[derive(Default)] - struct False; + #[derive(Clone, Debug, Default)] + pub struct False; impl Flag for False { fn is_set(&self) -> bool { @@ -2323,7 +2329,7 @@ where type Item = ::Item; #[inline] - default fn next(&mut self) -> Option<::Item> { + fn next(&mut self) -> Option<::Item> { if self.done.is_set() { None } else { @@ -2336,7 +2342,7 @@ where } #[inline] - default fn nth(&mut self, n: usize) -> Option { + fn nth(&mut self, n: usize) -> Option { if self.done.is_set() { None } else { @@ -2349,22 +2355,22 @@ where } #[inline] - default fn last(self) -> Option { + fn last(self) -> Option { if self.done.is_set() { None } else { self.iter.last() } } #[inline] - default fn count(self) -> usize { + fn count(self) -> usize { if self.done.is_set() { 0 } else { self.iter.count() } } #[inline] - default fn size_hint(&self) -> (usize, Option) { + 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, @@ -2380,7 +2386,7 @@ where } #[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, { @@ -2394,7 +2400,7 @@ where I: DoubleEndedIterator, { #[inline] - default fn next_back(&mut self) -> Option<::Item> { + fn next_back(&mut self) -> Option<::Item> { if self.done.is_set() { None } else { @@ -2407,7 +2413,7 @@ where } #[inline] - default fn nth_back(&mut self, n: usize) -> Option<::Item> { + fn nth_back(&mut self, n: usize) -> Option<::Item> { if self.done.is_set() { None } else { @@ -2420,7 +2426,7 @@ where } #[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, @@ -2436,7 +2442,7 @@ where } #[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, { @@ -2457,89 +2463,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 From 89171130ec3015f9a450a44b1de7c8b07c3ba581 Mon Sep 17 00:00:00 2001 From: AnthonyMikh Date: Tue, 10 Mar 2020 02:00:22 +0300 Subject: [PATCH 4/4] remove Iterator supertrait for FlagType --- src/libcore/iter/adapters/mod.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index b42782dcce0e0..14fd182ece289 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -2259,17 +2259,11 @@ where #[derive(Clone, Debug)] #[must_use = "iterators are lazy and do nothing unless consumed"] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Fuse -where - I: Iterator, -{ +pub struct Fuse { iter: I, done: ::Flag, } -impl Fuse -where - I: Iterator, -{ +impl Fuse { pub(super) fn new(iter: I) -> Fuse { Fuse { iter, done: <_>::default() } } @@ -2307,11 +2301,11 @@ mod fuse_flag { } } - pub trait FlagType: Iterator { + pub trait FlagType { type Flag: Flag; } - impl FlagType for I { + impl FlagType for I { default type Flag = bool; }