From dc49dd0937505020bc9d8bf1d4f9601f4c15b540 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 30 Jun 2021 14:12:16 -0700 Subject: [PATCH] Remove specialization from iter::Fuse --- library/core/src/iter/adapters/fuse.rs | 424 +++---------------------- 1 file changed, 49 insertions(+), 375 deletions(-) diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index 0c21df4f12c60..7608ff1331a1f 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -1,5 +1,5 @@ use crate::intrinsics; -use crate::iter::adapters::{zip::try_get_unchecked, InPlaceIterable, SourceIter}; +use crate::iter::adapters::zip::try_get_unchecked; use crate::iter::{ DoubleEndedIterator, ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess, }; @@ -42,18 +42,6 @@ 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 @@ -64,45 +52,61 @@ where #[inline] fn next(&mut self) -> Option { - FuseImpl::next(self) + fuse!(self.iter.next()) } #[inline] fn nth(&mut self, n: usize) -> Option { - FuseImpl::nth(self, n) + fuse!(self.iter.nth(n)) } #[inline] fn last(self) -> Option { - FuseImpl::last(self) + match self.iter { + Some(iter) => iter.last(), + None => None, + } } #[inline] fn count(self) -> usize { - FuseImpl::count(self) + match self.iter { + Some(iter) => iter.count(), + None => 0, + } } #[inline] fn size_hint(&self) -> (usize, Option) { - FuseImpl::size_hint(self) + match self.iter { + Some(ref iter) => iter.size_hint(), + None => (0, Some(0)), + } } #[inline] - fn try_fold(&mut self, acc: Acc, fold: Fold) -> R + fn try_fold(&mut self, mut acc: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - FuseImpl::try_fold(self, acc, fold) + if let Some(ref mut iter) = self.iter { + acc = iter.try_fold(acc, fold)?; + self.iter = None; + } + try { acc } } #[inline] - fn fold(self, acc: Acc, fold: Fold) -> Acc + fn fold(self, mut acc: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - FuseImpl::fold(self, acc, fold) + if let Some(iter) = self.iter { + acc = iter.fold(acc, fold); + } + acc } #[inline] @@ -110,7 +114,7 @@ where where P: FnMut(&Self::Item) -> bool, { - FuseImpl::find(self, predicate) + fuse!(self.iter.find(predicate)) } #[inline] @@ -136,30 +140,37 @@ where { #[inline] fn next_back(&mut self) -> Option<::Item> { - FuseImpl::next_back(self) + fuse!(self.iter.next_back()) } #[inline] fn nth_back(&mut self, n: usize) -> Option<::Item> { - FuseImpl::nth_back(self, n) + fuse!(self.iter.nth_back(n)) } #[inline] - fn try_rfold(&mut self, acc: Acc, fold: Fold) -> R + fn try_rfold(&mut self, mut acc: Acc, fold: Fold) -> R where Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try, { - FuseImpl::try_rfold(self, acc, fold) + if let Some(ref mut iter) = self.iter { + acc = iter.try_rfold(acc, fold)?; + self.iter = None; + } + try { acc } } #[inline] - fn rfold(self, acc: Acc, fold: Fold) -> Acc + fn rfold(self, mut acc: Acc, fold: Fold) -> Acc where Fold: FnMut(Acc, Self::Item) -> Acc, { - FuseImpl::rfold(self, acc, fold) + if let Some(iter) = self.iter { + acc = iter.rfold(acc, fold); + } + acc } #[inline] @@ -167,7 +178,7 @@ where where P: FnMut(&Self::Item) -> bool, { - FuseImpl::rfind(self, predicate) + fuse!(self.iter.rfind(predicate)) } } @@ -177,11 +188,17 @@ where I: ExactSizeIterator, { fn len(&self) -> usize { - FuseImpl::len(self) + match self.iter { + Some(ref iter) => iter.len(), + None => 0, + } } fn is_empty(&self) -> bool { - FuseImpl::is_empty(self) + match self.iter { + Some(ref iter) => iter.is_empty(), + None => true, + } } } @@ -204,346 +221,3 @@ where { const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT; } - -// Fuse specialization trait -#[doc(hidden)] -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; - 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; - - // 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 FuseImpl 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 { 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)) - } - - #[inline] - default fn next_back(&mut self) -> Option<::Item> - where - I: DoubleEndedIterator, - { - fuse!(self.iter.next_back()) - } - - #[inline] - default fn nth_back(&mut self, n: usize) -> Option<::Item> - where - I: DoubleEndedIterator, - { - 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, - I: DoubleEndedIterator, - { - if let Some(ref mut iter) = self.iter { - acc = iter.try_rfold(acc, fold)?; - self.iter = None; - } - try { acc } - } - - #[inline] - default fn rfold(self, mut acc: Acc, fold: Fold) -> Acc - where - Fold: FnMut(Acc, Self::Item) -> Acc, - I: DoubleEndedIterator, - { - 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, - I: DoubleEndedIterator, - { - fuse!(self.iter.rfind(predicate)) - } - - #[inline] - default fn len(&self) -> usize - where - I: ExactSizeIterator, - { - match self.iter { - Some(ref iter) => iter.len(), - None => 0, - } - } - - #[inline] - default fn is_empty(&self) -> bool - where - I: ExactSizeIterator, - { - match self.iter { - Some(ref iter) => iter.is_empty(), - None => true, - } - } -} - -#[doc(hidden)] -impl FuseImpl 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() - } - - #[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, - { - unchecked!(self).try_fold(init, fold) - } - - #[inline] - fn fold(self, init: Acc, fold: Fold) -> Acc - where - Fold: FnMut(Acc, Self::Item) -> Acc, - { - unchecked!(self).fold(init, fold) - } - - #[inline] - fn find

(&mut self, predicate: P) -> Option - where - P: FnMut(&Self::Item) -> bool, - { - unchecked!(self).find(predicate) - } - - #[inline] - fn next_back(&mut self) -> Option<::Item> - where - I: DoubleEndedIterator, - { - unchecked!(self).next_back() - } - - #[inline] - fn nth_back(&mut self, n: usize) -> Option<::Item> - where - I: DoubleEndedIterator, - { - unchecked!(self).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, - I: DoubleEndedIterator, - { - unchecked!(self).try_rfold(init, fold) - } - - #[inline] - fn rfold(self, init: Acc, fold: Fold) -> Acc - where - Fold: FnMut(Acc, Self::Item) -> Acc, - I: DoubleEndedIterator, - { - unchecked!(self).rfold(init, fold) - } - - #[inline] - fn rfind

(&mut self, predicate: P) -> Option - where - P: FnMut(&Self::Item) -> bool, - I: DoubleEndedIterator, - { - unchecked!(self).rfind(predicate) - } - - #[inline] - fn len(&self) -> usize - where - I: ExactSizeIterator, - { - unchecked!(self).len() - } - - #[inline] - fn is_empty(&self) -> bool - where - I: ExactSizeIterator, - { - unchecked!(self).is_empty() - } -} - -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl SourceIter for Fuse -where - I: SourceIter, -{ - type Source = S; - - #[inline] - unsafe fn as_inner(&mut self) -> &mut S { - match self.iter { - // SAFETY: unsafe function forwarding to unsafe function with the same requirements - Some(ref mut iter) => unsafe { SourceIter::as_inner(iter) }, - // SAFETY: the specialized iterator never sets `None` - None => unsafe { intrinsics::unreachable() }, - } - } -} - -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl InPlaceIterable for Fuse {}