diff options
| author | The8472 <git@infinite-source.de> | 2019-11-23 18:59:18 +0100 |
|---|---|---|
| committer | The8472 <git@infinite-source.de> | 2020-09-03 20:59:20 +0200 |
| commit | 21a17d105c9cd81dfa8bd3a178e4a6b095f69e5d (patch) | |
| tree | 75540290319581550abbb71fc47c778fd1b5e0eb | |
| parent | 085eb20a61164067f5c71ec64dc23100006f91c9 (diff) | |
| download | rust-21a17d105c9cd81dfa8bd3a178e4a6b095f69e5d.tar.gz rust-21a17d105c9cd81dfa8bd3a178e4a6b095f69e5d.zip | |
support in-place iteration for most adapters
`Take` is not included since users probably call it with small constants and it doesn't make sense to hold onto huge allocations in that case
| -rw-r--r-- | library/core/src/iter/adapters/fuse.rs | 23 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/mod.rs | 113 |
2 files changed, 136 insertions, 0 deletions
diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index 94ba6f56476..e2613be4a46 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -3,6 +3,8 @@ use crate::iter::adapters::zip::try_get_unchecked; use crate::iter::TrustedRandomAccess; use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator}; use crate::ops::Try; +use crate::iter::adapters::SourceIter; +use super::InPlaceIterable; /// An iterator that yields `None` forever after the underlying iterator /// yields `None` once. @@ -517,3 +519,24 @@ where unchecked!(self).is_empty() } } + + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, I: FusedIterator> SourceIter for Fuse<I> + where + I: SourceIter<Source = S>, +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + match self.iter { + Some(ref mut iter) => SourceIter::as_inner(iter), + // SAFETY: the specialized iterator never sets `None` + None => unsafe { intrinsics::unreachable() }, + } + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<I: InPlaceIterable> InPlaceIterable for Fuse<I> {} diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index aaf3f690490..a8414bf9137 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1152,6 +1152,22 @@ where #[stable(feature = "fused", since = "1.26.0")] impl<I: FusedIterator, P> FusedIterator for Filter<I, P> where P: FnMut(&I::Item) -> bool {} +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, P, I: Iterator> SourceIter for Filter<I, P> where + P: FnMut(&I::Item) -> bool, + I: SourceIter<Source = S> +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<I: InPlaceIterable, P> InPlaceIterable for Filter<I, P> where P: FnMut(&I::Item) -> bool {} + /// An iterator that uses `f` to both filter and map elements from `iter`. /// /// This `struct` is created by the [`filter_map`] method on [`Iterator`]. See its @@ -1278,6 +1294,23 @@ where #[stable(feature = "fused", since = "1.26.0")] impl<B, I: FusedIterator, F> FusedIterator for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {} +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, B, I: Iterator, F> SourceIter for FilterMap<I, F> where + F: FnMut(I::Item) -> Option<B>, + I: SourceIter<Source = S> +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<B, I: InPlaceIterable, F> InPlaceIterable for FilterMap<I, F> where F: FnMut(I::Item) -> Option<B> {} + + /// An iterator that yields the current count and the element during iteration. /// /// This `struct` is created by the [`enumerate`] method on [`Iterator`]. See its @@ -1910,6 +1943,22 @@ where { } +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, P, I: Iterator> SourceIter for SkipWhile<I, P> where + P: FnMut(&I::Item) -> bool, + I: SourceIter<Source = S> +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<I: InPlaceIterable, F> InPlaceIterable for SkipWhile<I, F> where F: FnMut(&I::Item) -> bool {} + /// An iterator that only accepts elements while `predicate` returns `true`. /// /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its @@ -2101,6 +2150,23 @@ where } } +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, P, I: Iterator> SourceIter for TakeWhile<I, P> where + P: FnMut(&I::Item) -> bool, + I: SourceIter<Source = S> +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<I: InPlaceIterable, F> InPlaceIterable for TakeWhile<I, F> where F: FnMut(&I::Item) -> bool {} + + /// An iterator that skips over `n` elements of `iter`. /// /// This `struct` is created by the [`skip`] method on [`Iterator`]. See its @@ -2410,6 +2476,19 @@ where } } +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I> where I: SourceIter<Source = S> { + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {} + #[stable(feature = "double_ended_take_iterator", since = "1.38.0")] impl<I> DoubleEndedIterator for Take<I> where @@ -2574,6 +2653,24 @@ where } } +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<St, F, B, S: Iterator, I: Iterator> SourceIter for Scan<I, St, F> + where I: SourceIter<Source = S>, + F: FnMut(&mut St, I::Item) -> Option<B>, +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<St, F, B, I: InPlaceIterable> InPlaceIterable for Scan<I, St, F> + where F: FnMut(&mut St, I::Item) -> Option<B>, +{} + /// An iterator that calls a function with a reference to each element before /// yielding it. /// @@ -2720,6 +2817,22 @@ where #[stable(feature = "fused", since = "1.26.0")] impl<I: FusedIterator, F> FusedIterator for Inspect<I, F> where F: FnMut(&I::Item) {} +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<S: Iterator, I: Iterator, F> SourceIter for Inspect<I, F> where + F: FnMut(&I::Item), + I: SourceIter<Source = S> +{ + type Source = S; + + #[inline] + fn as_inner(&mut self) -> &mut S { + SourceIter::as_inner(&mut self.iter) + } +} + +#[unstable(issue = "0", feature = "inplace_iteration")] +unsafe impl<I: InPlaceIterable, F> InPlaceIterable for Inspect<I, F> where F: FnMut(&I::Item) {} + /// An iterator adapter that produces output as long as the underlying /// iterator produces `Result::Ok` values. /// |
