From 0a54a9403ddc41d13633c17a8d24c218dc563268 Mon Sep 17 00:00:00 2001 From: Rakshith Ravi Date: Wed, 8 Apr 2020 05:39:00 +0530 Subject: [PATCH] Added FuseIteratorImpl, FustDoubleEndedIteratorImpl and FuseExactSizeIteratorImpl to avoid exposing default functions outside of the current crate. --- src/libcore/iter/adapters/fuse.rs | 379 ++++++++++++++++++++++-------- 1 file changed, 275 insertions(+), 104 deletions(-) diff --git a/src/libcore/iter/adapters/fuse.rs b/src/libcore/iter/adapters/fuse.rs index 23bc215aa779..946cd4753630 100644 --- a/src/libcore/iter/adapters/fuse.rs +++ b/src/libcore/iter/adapters/fuse.rs @@ -51,6 +51,182 @@ where { type Item = ::Item; + #[inline] + fn next(&mut self) -> Option { + FuseIteratorImpl::next(self) + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + FuseIteratorImpl::nth(self, n) + } + + #[inline] + fn last(self) -> Option { + FuseIteratorImpl::last(self) + } + + #[inline] + fn count(self) -> usize { + FuseIteratorImpl::count(self) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + FuseIteratorImpl::size_hint(self) + } + + #[inline] + fn try_fold(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try, + { + FuseIteratorImpl::try_fold(self, acc, fold) + } + + #[inline] + fn fold(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + FuseIteratorImpl::fold(self, acc, fold) + } + + #[inline] + fn find

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, + { + FuseIteratorImpl::find(self, predicate) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Fuse +where + I: DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option<::Item> { + FuseDoubleEndedIteratorImpl::next_back(self) + } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option<::Item> { + FuseDoubleEndedIteratorImpl::nth_back(self, n) + } + + #[inline] + fn try_rfold(&mut self, acc: Acc, fold: Fold) -> R + where + Self: Sized, + Fold: FnMut(Acc, Self::Item) -> R, + R: Try, + { + FuseDoubleEndedIteratorImpl::try_rfold(self, acc, fold) + } + + #[inline] + fn rfold(self, acc: Acc, fold: Fold) -> Acc + where + Fold: FnMut(Acc, Self::Item) -> Acc, + { + FuseDoubleEndedIteratorImpl::rfold(self, acc, fold) + } + + #[inline] + fn rfind

(&mut self, predicate: P) -> Option + where + P: FnMut(&Self::Item) -> bool, + { + FuseDoubleEndedIteratorImpl::rfind(self, predicate) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Fuse +where + I: ExactSizeIterator, +{ + fn len(&self) -> usize { + FuseExactSizeIteratorImpl::len(self) + } + + fn is_empty(&self) -> bool { + FuseExactSizeIteratorImpl::is_empty(self) + } +} + +// 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, +{ + 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()) @@ -119,89 +295,8 @@ where } } -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Fuse -where - I: DoubleEndedIterator, -{ - #[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)) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator 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, - } - } -} - -// 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 +#[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,8 +463,32 @@ 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, +{ + 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, { @@ -312,20 +500,3 @@ where unchecked!(self).is_empty() } } - -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() - } -}