From 0a54a9403ddc41d13633c17a8d24c218dc563268 Mon Sep 17 00:00:00 2001 From: Rakshith Ravi Date: Wed, 8 Apr 2020 05:39:00 +0530 Subject: [PATCH 1/3] Added FuseIteratorImpl, FustDoubleEndedIteratorImpl and FuseExactSizeIteratorImpl to avoid exposing default functions outside of the current crate. --- src/libcore/iter/adapters/fuse.rs | 329 +++++++++++++++++++++++------- 1 file changed, 250 insertions(+), 79 deletions(-) diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs index 23bc215aa779d..946cd47536307 100644 --- a/src/libcore/iter/adapters/fuse.rs +++ b/src/libcore/iter/adapters/fuse.rs @@ -52,70 +52,54 @@ where type Item = ::Item; #[inline] - default fn next(&mut self) -> Option<::Item> { - fuse!(self.iter.next()) + fn next(&mut self) -> Option { + FuseIteratorImpl::next(self) } #[inline] - default fn nth(&mut self, n: usize) -> Option { - fuse!(self.iter.nth(n)) + fn nth(&mut self, n: usize) -> Option { + FuseIteratorImpl::nth(self, n) } #[inline] - default fn last(self) -> Option { - match self.iter { - Some(iter) => iter.last(), - None => None, - } + fn last(self) -> Option { + FuseIteratorImpl::last(self) } #[inline] - default fn count(self) -> usize { - match self.iter { - Some(iter) => iter.count(), - None => 0, - } + fn count(self) -> usize { + FuseIteratorImpl::count(self) } #[inline] - default fn size_hint(&self) -> (usize, Option) { - match self.iter { - Some(ref iter) => iter.size_hint(), - None => (0, Some(0)), - } + fn size_hint(&self) -> (usize, Option) { + FuseIteratorImpl::size_hint(self) } #[inline] - default fn try_fold(&mut self, mut acc: Acc, fold: Fold) -> R + fn try_fold(&mut self, acc: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - if let Some(ref mut iter) = self.iter { - acc = iter.try_fold(acc, fold)?; - self.iter = None; - } - Try::from_ok(acc) + FuseIteratorImpl::try_fold(self, acc, fold) } #[inline] - default fn fold(self, mut acc: Acc, fold: Fold) -> Acc + fn fold(self, acc: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - if let Some(iter) = self.iter { - acc = iter.fold(acc, fold); - } - acc + FuseIteratorImpl::fold(self, acc, fold) } #[inline] - default fn find

(&mut self, predicate: P) -> Option + fn find

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { - fuse!(self.iter.find(predicate)) + FuseIteratorImpl::find(self, predicate) } } @@ -125,46 +109,39 @@ where I: DoubleEndedIterator, { #[inline] - default fn next_back(&mut self) -> Option<::Item> { - fuse!(self.iter.next_back()) + fn next_back(&mut self) -> Option<::Item> { + FuseDoubleEndedIteratorImpl::next_back(self) } #[inline] - default fn nth_back(&mut self, n: usize) -> Option<::Item> { - fuse!(self.iter.nth_back(n)) + fn nth_back(&mut self, n: usize) -> Option<::Item> { + FuseDoubleEndedIteratorImpl::nth_back(self, n) } #[inline] - default fn try_rfold(&mut self, mut acc: Acc, fold: Fold) -> R + fn try_rfold(&mut self, acc: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - if let Some(ref mut iter) = self.iter { - acc = iter.try_rfold(acc, fold)?; - self.iter = None; - } - Try::from_ok(acc) + FuseDoubleEndedIteratorImpl::try_rfold(self, acc, fold) } #[inline] - default fn rfold(self, mut acc: Acc, fold: Fold) -> Acc + fn rfold(self, acc: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - if let Some(iter) = self.iter { - acc = iter.rfold(acc, fold); - } - acc + FuseDoubleEndedIteratorImpl::rfold(self, acc, fold) } #[inline] - default fn rfind

(&mut self, predicate: P) -> Option + fn rfind

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { - fuse!(self.iter.rfind(predicate)) + FuseDoubleEndedIteratorImpl::rfind(self, predicate) } } @@ -173,18 +150,12 @@ impl ExactSizeIterator for Fuse where I: ExactSizeIterator, { - default fn len(&self) -> usize { - match self.iter { - Some(ref iter) => iter.len(), - None => 0, - } + fn len(&self) -> usize { + FuseExactSizeIteratorImpl::len(self) } - default fn is_empty(&self) -> bool { - match self.iter { - Some(ref iter) => iter.is_empty(), - None => true, - } + fn is_empty(&self) -> bool { + FuseExactSizeIteratorImpl::is_empty(self) } } @@ -201,7 +172,131 @@ macro_rules! unchecked { } #[stable(feature = "fused", since = "1.26.0")] -impl Iterator for Fuse +impl Iterator for Fuse where I: FusedIterator {} + +#[stable(feature = "fused", since = "1.26.0")] +impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator + FusedIterator {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Fuse where I: ExactSizeIterator + FusedIterator {} + +unsafe impl TrustedRandomAccess for Fuse +where + I: TrustedRandomAccess, +{ + unsafe fn get_unchecked(&mut self, i: usize) -> I::Item { + match self.iter { + Some(ref mut iter) => iter.get_unchecked(i), + // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted. + None => intrinsics::unreachable(), + } + } + + fn may_have_side_effect() -> bool { + I::may_have_side_effect() + } +} + +// Fuse specialization trait +#[doc(hidden)] +trait FuseIteratorImpl { + type Item; + fn next(&mut self) -> Option; + fn nth(&mut self, n: usize) -> Option; + fn last(self) -> Option; + fn count(self) -> usize; + fn size_hint(&self) -> (usize, Option); + fn try_fold(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try; + fn fold(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc; + fn find

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool; +} + +// General Fuse impl +#[doc(hidden)] +impl FuseIteratorImpl for Fuse +where + I: Iterator, +{ + type Item = ::Item; + + #[inline] + default fn next(&mut self) -> Option<::Item> { + fuse!(self.iter.next()) + } + + #[inline] + default fn nth(&mut self, n: usize) -> Option { + fuse!(self.iter.nth(n)) + } + + #[inline] + default fn last(self) -> Option { + match self.iter { + Some(iter) => iter.last(), + None => None, + } + } + + #[inline] + default fn count(self) -> usize { + match self.iter { + Some(iter) => iter.count(), + None => 0, + } + } + + #[inline] + default fn size_hint(&self) -> (usize, Option) { + match self.iter { + Some(ref iter) => iter.size_hint(), + None => (0, Some(0)), + } + } + + #[inline] + default fn try_fold(&mut self, mut acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try, + { + if let Some(ref mut iter) = self.iter { + acc = iter.try_fold(acc, fold)?; + self.iter = None; + } + Try::from_ok(acc) + } + + #[inline] + default fn fold(self, mut acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + if let Some(iter) = self.iter { + acc = iter.fold(acc, fold); + } + acc + } + + #[inline] + default fn find

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, + { + fuse!(self.iter.find(predicate)) + } +} + +#[doc(hidden)] +impl FuseIteratorImpl for Fuse where I: FusedIterator, { @@ -257,8 +352,77 @@ where } } -#[stable(feature = "fused", since = "1.26.0")] -impl DoubleEndedIterator for Fuse +#[doc(hidden)] +trait FuseDoubleEndedIteratorImpl { + type Item; + fn next_back(&mut self) -> Option; + fn nth_back(&mut self, n: usize) -> Option; + fn try_rfold(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try; + fn rfold(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc; + fn rfind

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool; +} + +#[doc(hidden)] +impl FuseDoubleEndedIteratorImpl for Fuse +where + I: DoubleEndedIterator, +{ + type Item = ::Item; + + #[inline] + default fn next_back(&mut self) -> Option<::Item> { + fuse!(self.iter.next_back()) + } + + #[inline] + default fn nth_back(&mut self, n: usize) -> Option<::Item> { + fuse!(self.iter.nth_back(n)) + } + + #[inline] + default fn try_rfold(&mut self, mut acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try, + { + if let Some(ref mut iter) = self.iter { + acc = iter.try_rfold(acc, fold)?; + self.iter = None; + } + Try::from_ok(acc) + } + + #[inline] + default fn rfold(self, mut acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + if let Some(iter) = self.iter { + acc = iter.rfold(acc, fold); + } + acc + } + + #[inline] + default fn rfind

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, + { + fuse!(self.iter.rfind(predicate)) + } +} + +#[doc(hidden)] +impl FuseDoubleEndedIteratorImpl for Fuse where I: DoubleEndedIterator + FusedIterator, { @@ -299,33 +463,40 @@ where } } -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Fuse +#[doc(hidden)] +trait FuseExactSizeIteratorImpl { + fn len(&self) -> usize; + fn is_empty(&self) -> bool; +} + +impl FuseExactSizeIteratorImpl for Fuse where - I: ExactSizeIterator + FusedIterator, + I: ExactSizeIterator, { - fn len(&self) -> usize { - unchecked!(self).len() + default fn len(&self) -> usize { + match self.iter { + Some(ref iter) => iter.len(), + None => 0, + } } - fn is_empty(&self) -> bool { - unchecked!(self).is_empty() + default fn is_empty(&self) -> bool { + match self.iter { + Some(ref iter) => iter.is_empty(), + None => true, + } } } -unsafe impl TrustedRandomAccess for Fuse +impl FuseExactSizeIteratorImpl for Fuse where - I: TrustedRandomAccess, + I: ExactSizeIterator + FusedIterator, { - unsafe fn get_unchecked(&mut self, i: usize) -> I::Item { - match self.iter { - Some(ref mut iter) => iter.get_unchecked(i), - // SAFETY: the caller asserts there is an item at `i`, so we're not exhausted. - None => intrinsics::unreachable(), - } + fn len(&self) -> usize { + unchecked!(self).len() } - fn may_have_side_effect() -> bool { - I::may_have_side_effect() + fn is_empty(&self) -> bool { + unchecked!(self).is_empty() } } From 51cd29cf6cb4bd4ec025ae436f5d8ae6260335a2 Mon Sep 17 00:00:00 2001 From: Rakshith Ravi Date: Fri, 10 Apr 2020 10:32:23 +0530 Subject: [PATCH 2/3] Added comments. Removed unnecessarry empty impls. Moved code to organise it better --- src/libcore/iter/adapters/fuse.rs | 37 +++++++++++++------------------ 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs index 946cd47536307..c3968b101e504 100644 --- a/src/libcore/iter/adapters/fuse.rs +++ b/src/libcore/iter/adapters/fuse.rs @@ -44,6 +44,19 @@ macro_rules! fuse { }; } +// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`. +// Implementing this as a directly-expanded macro helps codegen performance. +macro_rules! unchecked { + ($self:ident) => { + match $self { + Fuse { iter: Some(iter) } => iter, + // SAFETY: the specialized iterator never sets `None` + Fuse { iter: None } => unsafe { intrinsics::unreachable() }, + } + }; +} + +// Any implementation here is made internal to avoid exposing default fns outside this trait #[stable(feature = "rust1", since = "1.0.0")] impl Iterator for Fuse where @@ -159,27 +172,6 @@ where } } -// NOTE: for `I: FusedIterator`, we assume that the iterator is always `Some`. -// Implementing this as a directly-expanded macro helps codegen performance. -macro_rules! unchecked { - ($self:ident) => { - match $self { - Fuse { iter: Some(iter) } => iter, - // SAFETY: the specialized iterator never sets `None` - Fuse { iter: None } => unsafe { intrinsics::unreachable() }, - } - }; -} - -#[stable(feature = "fused", since = "1.26.0")] -impl Iterator for Fuse where I: FusedIterator {} - -#[stable(feature = "fused", since = "1.26.0")] -impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator + FusedIterator {} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Fuse where I: ExactSizeIterator + FusedIterator {} - unsafe impl TrustedRandomAccess for Fuse where I: TrustedRandomAccess, @@ -198,6 +190,9 @@ where } // Fuse specialization trait +// Iterators and DoubleEndedIterators cannot be overlapped successfully +// So, they're separated into each it's own trait to provide internal implementations +// Similarly, ExactSizeIterators cannot be overlapped, so requires its own trait #[doc(hidden)] trait FuseIteratorImpl { type Item; From abe5973b9d1202f1a6460c0116f22fc33c9506c5 Mon Sep 17 00:00:00 2001 From: Rakshith Ravi Date: Thu, 16 Apr 2020 01:19:51 +0530 Subject: [PATCH 3/3] Inlined everything into a single trait and trait impl --- src/libcore/iter/adapters/fuse.rs | 267 ++++++++++++++++-------------- 1 file changed, 141 insertions(+), 126 deletions(-) diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs index c3968b101e504..502fc2e631502 100644 --- a/src/libcore/iter/adapters/fuse.rs +++ b/src/libcore/iter/adapters/fuse.rs @@ -66,27 +66,27 @@ where #[inline] fn next(&mut self) -> Option { - FuseIteratorImpl::next(self) + FuseImpl::next(self) } #[inline] fn nth(&mut self, n: usize) -> Option { - FuseIteratorImpl::nth(self, n) + FuseImpl::nth(self, n) } #[inline] fn last(self) -> Option { - FuseIteratorImpl::last(self) + FuseImpl::last(self) } #[inline] fn count(self) -> usize { - FuseIteratorImpl::count(self) + FuseImpl::count(self) } #[inline] fn size_hint(&self) -> (usize, Option) { - FuseIteratorImpl::size_hint(self) + FuseImpl::size_hint(self) } #[inline] @@ -96,7 +96,7 @@ where Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - FuseIteratorImpl::try_fold(self, acc, fold) + FuseImpl::try_fold(self, acc, fold) } #[inline] @@ -104,7 +104,7 @@ where where Fold: FnMut(Acc, Self::Item) -> Acc, { - FuseIteratorImpl::fold(self, acc, fold) + FuseImpl::fold(self, acc, fold) } #[inline] @@ -112,7 +112,7 @@ where where P: FnMut(&Self::Item) -> bool, { - FuseIteratorImpl::find(self, predicate) + FuseImpl::find(self, predicate) } } @@ -123,12 +123,12 @@ where { #[inline] fn next_back(&mut self) -> Option<::Item> { - FuseDoubleEndedIteratorImpl::next_back(self) + FuseImpl::next_back(self) } #[inline] fn nth_back(&mut self, n: usize) -> Option<::Item> { - FuseDoubleEndedIteratorImpl::nth_back(self, n) + FuseImpl::nth_back(self, n) } #[inline] @@ -138,7 +138,7 @@ where Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - FuseDoubleEndedIteratorImpl::try_rfold(self, acc, fold) + FuseImpl::try_rfold(self, acc, fold) } #[inline] @@ -146,7 +146,7 @@ where where Fold: FnMut(Acc, Self::Item) -> Acc, { - FuseDoubleEndedIteratorImpl::rfold(self, acc, fold) + FuseImpl::rfold(self, acc, fold) } #[inline] @@ -154,7 +154,7 @@ where where P: FnMut(&Self::Item) -> bool, { - FuseDoubleEndedIteratorImpl::rfind(self, predicate) + FuseImpl::rfind(self, predicate) } } @@ -164,11 +164,11 @@ where I: ExactSizeIterator, { fn len(&self) -> usize { - FuseExactSizeIteratorImpl::len(self) + FuseImpl::len(self) } fn is_empty(&self) -> bool { - FuseExactSizeIteratorImpl::is_empty(self) + FuseImpl::is_empty(self) } } @@ -190,12 +190,11 @@ where } // Fuse specialization trait -// Iterators and DoubleEndedIterators cannot be overlapped successfully -// So, they're separated into each it's own trait to provide internal implementations -// Similarly, ExactSizeIterators cannot be overlapped, so requires its own trait #[doc(hidden)] -trait FuseIteratorImpl { +trait FuseImpl { type Item; + + // Functions specific to any normal Iterators fn next(&mut self) -> Option; fn nth(&mut self, n: usize) -> Option; fn last(self) -> Option; @@ -212,11 +211,41 @@ trait FuseIteratorImpl { fn find

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool; + + // Functions specific to DoubleEndedIterators + fn next_back(&mut self) -> Option + where + I: DoubleEndedIterator; + fn nth_back(&mut self, n: usize) -> Option + where + I: DoubleEndedIterator; + fn try_rfold(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try, + I: DoubleEndedIterator; + fn rfold(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + I: DoubleEndedIterator; + fn rfind

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, + I: DoubleEndedIterator; + + // Functions specific to ExactSizeIterator + fn len(&self) -> usize + where + I: ExactSizeIterator; + fn is_empty(&self) -> bool + where + I: ExactSizeIterator; } // General Fuse impl #[doc(hidden)] -impl FuseIteratorImpl for Fuse +impl FuseImpl for Fuse where I: Iterator, { @@ -288,146 +317,151 @@ where { fuse!(self.iter.find(predicate)) } -} - -#[doc(hidden)] -impl FuseIteratorImpl for Fuse -where - I: FusedIterator, -{ - #[inline] - fn next(&mut self) -> Option<::Item> { - unchecked!(self).next() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - unchecked!(self).nth(n) - } #[inline] - fn last(self) -> Option { - unchecked!(self).last() - } - - #[inline] - fn count(self) -> usize { - unchecked!(self).count() + default fn next_back(&mut self) -> Option<::Item> + where + I: DoubleEndedIterator, + { + fuse!(self.iter.next_back()) } #[inline] - fn size_hint(&self) -> (usize, Option) { - unchecked!(self).size_hint() + default fn nth_back(&mut self, n: usize) -> Option<::Item> + where + I: DoubleEndedIterator, + { + fuse!(self.iter.nth_back(n)) } #[inline] - fn try_fold(&mut self, init: Acc, fold: Fold) -> R + default fn try_rfold(&mut self, mut acc: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, + I: DoubleEndedIterator, { - unchecked!(self).try_fold(init, fold) + if let Some(ref mut iter) = self.iter { + acc = iter.try_rfold(acc, fold)?; + self.iter = None; + } + Try::from_ok(acc) } #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc + default fn rfold(self, mut acc: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, + I: DoubleEndedIterator, { - unchecked!(self).fold(init, fold) + if let Some(iter) = self.iter { + acc = iter.rfold(acc, fold); + } + acc } #[inline] - fn find

(&mut self, predicate: P) -> Option + default fn rfind

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, + I: DoubleEndedIterator, { - unchecked!(self).find(predicate) + fuse!(self.iter.rfind(predicate)) } -} -#[doc(hidden)] -trait FuseDoubleEndedIteratorImpl { - type Item; - fn next_back(&mut self) -> Option; - fn nth_back(&mut self, n: usize) -> Option; - fn try_rfold(&mut self, acc: Acc, fold: Fold) -> R - where - Self: Sized, - Fold: FnMut(Acc, Self::Item) -> R, - R: Try; - fn rfold(self, acc: Acc, fold: Fold) -> Acc + #[inline] + default fn len(&self) -> usize where - Fold: FnMut(Acc, Self::Item) -> Acc; - fn rfind

(&mut self, predicate: P) -> Option + I: ExactSizeIterator, + { + match self.iter { + Some(ref iter) => iter.len(), + None => 0, + } + } + + #[inline] + default fn is_empty(&self) -> bool where - P: FnMut(&Self::Item) -> bool; + I: ExactSizeIterator, + { + match self.iter { + Some(ref iter) => iter.is_empty(), + None => true, + } + } } #[doc(hidden)] -impl FuseDoubleEndedIteratorImpl for Fuse +impl FuseImpl for Fuse where - I: DoubleEndedIterator, + I: FusedIterator, { - type Item = ::Item; + #[inline] + fn next(&mut self) -> Option<::Item> { + unchecked!(self).next() + } #[inline] - default fn next_back(&mut self) -> Option<::Item> { - fuse!(self.iter.next_back()) + fn nth(&mut self, n: usize) -> Option { + unchecked!(self).nth(n) } #[inline] - default fn nth_back(&mut self, n: usize) -> Option<::Item> { - fuse!(self.iter.nth_back(n)) + fn last(self) -> Option { + unchecked!(self).last() } #[inline] - default fn try_rfold(&mut self, mut acc: Acc, fold: Fold) -> R + fn count(self) -> usize { + unchecked!(self).count() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + unchecked!(self).size_hint() + } + + #[inline] + fn try_fold(&mut self, init: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - if let Some(ref mut iter) = self.iter { - acc = iter.try_rfold(acc, fold)?; - self.iter = None; - } - Try::from_ok(acc) + unchecked!(self).try_fold(init, fold) } #[inline] - default fn rfold(self, mut acc: Acc, fold: Fold) -> Acc + fn fold(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - if let Some(iter) = self.iter { - acc = iter.rfold(acc, fold); - } - acc + unchecked!(self).fold(init, fold) } #[inline] - default fn rfind

(&mut self, predicate: P) -> Option + fn find

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, { - fuse!(self.iter.rfind(predicate)) + unchecked!(self).find(predicate) } -} -#[doc(hidden)] -impl FuseDoubleEndedIteratorImpl for Fuse -where - I: DoubleEndedIterator + FusedIterator, -{ #[inline] - fn next_back(&mut self) -> Option<::Item> { + fn next_back(&mut self) -> Option<::Item> + where + I: DoubleEndedIterator, + { unchecked!(self).next_back() } #[inline] - fn nth_back(&mut self, n: usize) -> Option<::Item> { + fn nth_back(&mut self, n: usize) -> Option<::Item> + where + I: DoubleEndedIterator, + { unchecked!(self).nth_back(n) } @@ -437,6 +471,7 @@ where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, + I: DoubleEndedIterator, { unchecked!(self).try_rfold(init, fold) } @@ -445,6 +480,7 @@ where fn rfold(self, init: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, + I: DoubleEndedIterator, { unchecked!(self).rfold(init, fold) } @@ -453,45 +489,24 @@ where fn rfind

(&mut self, predicate: P) -> Option where P: FnMut(&Self::Item) -> bool, + I: DoubleEndedIterator, { unchecked!(self).rfind(predicate) } -} - -#[doc(hidden)] -trait FuseExactSizeIteratorImpl { - fn len(&self) -> usize; - fn is_empty(&self) -> bool; -} - -impl FuseExactSizeIteratorImpl for Fuse -where - I: ExactSizeIterator, -{ - default fn len(&self) -> usize { - match self.iter { - Some(ref iter) => iter.len(), - None => 0, - } - } - - default fn is_empty(&self) -> bool { - match self.iter { - Some(ref iter) => iter.is_empty(), - None => true, - } - } -} -impl FuseExactSizeIteratorImpl for Fuse -where - I: ExactSizeIterator + FusedIterator, -{ - fn len(&self) -> usize { + #[inline] + fn len(&self) -> usize + where + I: ExactSizeIterator, + { unchecked!(self).len() } - fn is_empty(&self) -> bool { + #[inline] + fn is_empty(&self) -> bool + where + I: ExactSizeIterator, + { unchecked!(self).is_empty() } }